1283276Sgonzo/*- 2283276Sgonzo * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org> 3283276Sgonzo * All rights reserved. 4283276Sgonzo * 5283276Sgonzo * Redistribution and use in source and binary forms, with or without 6283276Sgonzo * modification, are permitted provided that the following conditions 7283276Sgonzo * are met: 8283276Sgonzo * 1. Redistributions of source code must retain the above copyright 9283276Sgonzo * notice, this list of conditions and the following disclaimer. 10283276Sgonzo * 2. Redistributions in binary form must reproduce the above copyright 11283276Sgonzo * notice, this list of conditions and the following disclaimer in the 12283276Sgonzo * documentation and/or other materials provided with the distribution. 13283276Sgonzo * 14283276Sgonzo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15283276Sgonzo * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16283276Sgonzo * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17283276Sgonzo * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 18283276Sgonzo * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19283276Sgonzo * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20283276Sgonzo * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21283276Sgonzo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22283276Sgonzo * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 23283276Sgonzo * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24283276Sgonzo * POSSIBILITY OF SUCH DAMAGE. 25283276Sgonzo * 26283276Sgonzo * $FreeBSD: releng/11.0/sys/arm/ti/ti_hwmods.c 299477 2016-05-11 18:20:02Z gonzo $ 27283276Sgonzo */ 28283276Sgonzo 29283276Sgonzo#include <sys/cdefs.h> 30283276Sgonzo__FBSDID("$FreeBSD: releng/11.0/sys/arm/ti/ti_hwmods.c 299477 2016-05-11 18:20:02Z gonzo $"); 31283276Sgonzo 32283276Sgonzo#include <sys/param.h> 33283276Sgonzo#include <sys/systm.h> 34283276Sgonzo#include <sys/bus.h> 35283276Sgonzo#include <sys/kernel.h> 36283276Sgonzo 37283276Sgonzo#include <dev/fdt/fdt_common.h> 38283276Sgonzo#include <dev/ofw/openfirm.h> 39283276Sgonzo#include <dev/ofw/ofw_bus.h> 40283276Sgonzo#include <dev/ofw/ofw_bus_subr.h> 41283276Sgonzo 42283276Sgonzo#include <machine/bus.h> 43283276Sgonzo#include <machine/fdt.h> 44283276Sgonzo 45283276Sgonzo#include <arm/ti/ti_prcm.h> 46283276Sgonzo#include <arm/ti/ti_hwmods.h> 47283276Sgonzo 48283276Sgonzostruct hwmod { 49283276Sgonzo const char *name; 50283276Sgonzo int clock_id; 51283276Sgonzo}; 52283276Sgonzo 53283276Sgonzostruct hwmod ti_hwmods[] = { 54283276Sgonzo {"i2c1", I2C1_CLK}, 55283276Sgonzo {"i2c2", I2C2_CLK}, 56283276Sgonzo {"i2c3", I2C3_CLK}, 57283276Sgonzo {"i2c4", I2C4_CLK}, 58283276Sgonzo {"i2c5", I2C5_CLK}, 59283276Sgonzo 60283276Sgonzo {"gpio1", GPIO1_CLK}, 61283276Sgonzo {"gpio2", GPIO2_CLK}, 62283276Sgonzo {"gpio3", GPIO3_CLK}, 63283276Sgonzo {"gpio4", GPIO4_CLK}, 64283276Sgonzo {"gpio5", GPIO5_CLK}, 65283276Sgonzo {"gpio6", GPIO6_CLK}, 66283276Sgonzo {"gpio7", GPIO7_CLK}, 67283276Sgonzo 68283276Sgonzo {"mmc1", MMC1_CLK}, 69283276Sgonzo {"mmc2", MMC2_CLK}, 70283276Sgonzo {"mmc3", MMC3_CLK}, 71283276Sgonzo {"mmc4", MMC4_CLK}, 72283276Sgonzo {"mmc5", MMC5_CLK}, 73283276Sgonzo {"mmc6", MMC6_CLK}, 74283276Sgonzo 75283276Sgonzo {"epwmss0", PWMSS0_CLK}, 76283276Sgonzo {"epwmss1", PWMSS1_CLK}, 77283276Sgonzo {"epwmss2", PWMSS2_CLK}, 78283276Sgonzo 79297395Sloos {"spi0", SPI0_CLK}, 80297395Sloos {"spi1", SPI1_CLK}, 81297395Sloos 82283276Sgonzo {"timer1", TIMER1_CLK}, 83283276Sgonzo {"timer2", TIMER2_CLK}, 84283276Sgonzo {"timer3", TIMER3_CLK}, 85283276Sgonzo {"timer4", TIMER4_CLK}, 86283276Sgonzo {"timer5", TIMER5_CLK}, 87283276Sgonzo {"timer6", TIMER6_CLK}, 88283276Sgonzo {"timer7", TIMER7_CLK}, 89283276Sgonzo 90283276Sgonzo {"uart1", UART1_CLK}, 91283276Sgonzo {"uart2", UART2_CLK}, 92283276Sgonzo {"uart3", UART3_CLK}, 93283276Sgonzo {"uart4", UART4_CLK}, 94283276Sgonzo {"uart5", UART5_CLK}, 95283276Sgonzo {"uart6", UART6_CLK}, 96283276Sgonzo {"uart7", UART7_CLK}, 97283276Sgonzo 98283276Sgonzo {NULL, 0} 99283276Sgonzo}; 100283276Sgonzo 101283276Sgonzoclk_ident_t 102283276Sgonzoti_hwmods_get_clock(device_t dev) 103283276Sgonzo{ 104283276Sgonzo phandle_t node; 105283276Sgonzo int len, l; 106283276Sgonzo char *name; 107283276Sgonzo char *buf; 108283276Sgonzo int clk; 109283276Sgonzo struct hwmod *hw; 110283276Sgonzo 111283276Sgonzo if ((node = ofw_bus_get_node(dev)) == 0) 112283276Sgonzo return (INVALID_CLK_IDENT); 113283276Sgonzo 114283276Sgonzo if ((len = OF_getprop_alloc(node, "ti,hwmods", 1, (void**)&name)) <= 0) 115283276Sgonzo return (INVALID_CLK_IDENT); 116283276Sgonzo 117283276Sgonzo buf = name; 118283276Sgonzo 119283276Sgonzo clk = INVALID_CLK_IDENT; 120283276Sgonzo while ((len > 0) && (clk == INVALID_CLK_IDENT)) { 121283276Sgonzo for (hw = ti_hwmods; hw->name != NULL; ++hw) { 122283276Sgonzo if (strcmp(hw->name, name) == 0) { 123283276Sgonzo clk = hw->clock_id; 124283276Sgonzo break; 125283276Sgonzo } 126283276Sgonzo } 127283276Sgonzo 128283276Sgonzo /* Slide to the next sub-string. */ 129283276Sgonzo l = strlen(name) + 1; 130283276Sgonzo name += l; 131283276Sgonzo len -= l; 132283276Sgonzo } 133283276Sgonzo 134283276Sgonzo if (len > 0) 135286615Spfg device_printf(dev, "WARNING: more than one ti,hwmod \n"); 136283276Sgonzo 137299477Sgonzo OF_prop_free(buf); 138283276Sgonzo return (clk); 139283276Sgonzo} 140283276Sgonzo 141283276Sgonzoint ti_hwmods_contains(device_t dev, const char *hwmod) 142283276Sgonzo{ 143283276Sgonzo phandle_t node; 144283276Sgonzo int len, l; 145283276Sgonzo char *name; 146283276Sgonzo char *buf; 147283276Sgonzo int result; 148283276Sgonzo 149283276Sgonzo if ((node = ofw_bus_get_node(dev)) == 0) 150283276Sgonzo return (0); 151283276Sgonzo 152283276Sgonzo if ((len = OF_getprop_alloc(node, "ti,hwmods", 1, (void**)&name)) <= 0) 153283276Sgonzo return (0); 154283276Sgonzo 155283276Sgonzo buf = name; 156283276Sgonzo 157283276Sgonzo result = 0; 158283276Sgonzo while (len > 0) { 159283276Sgonzo if (strcmp(name, hwmod) == 0) { 160283276Sgonzo result = 1; 161283276Sgonzo break; 162283276Sgonzo } 163283276Sgonzo 164283276Sgonzo /* Slide to the next sub-string. */ 165283276Sgonzo l = strlen(name) + 1; 166283276Sgonzo name += l; 167283276Sgonzo len -= l; 168283276Sgonzo } 169283276Sgonzo 170299477Sgonzo OF_prop_free(buf); 171283276Sgonzo 172283276Sgonzo return (result); 173283276Sgonzo} 174286678Sian 175286678Sianint 176286678Sianti_hwmods_get_unit(device_t dev, const char *hwmod) 177286678Sian{ 178286678Sian phandle_t node; 179286678Sian int l, len, hwmodlen, result; 180286678Sian char *name; 181286678Sian char *buf; 182286678Sian 183286678Sian if ((node = ofw_bus_get_node(dev)) == 0) 184286678Sian return (0); 185286678Sian 186286678Sian if ((len = OF_getprop_alloc(node, "ti,hwmods", 1, (void**)&name)) <= 0) 187286678Sian return (0); 188286678Sian 189286678Sian buf = name; 190286678Sian hwmodlen = strlen(hwmod); 191286678Sian result = 0; 192286678Sian while (len > 0) { 193286678Sian if (strncmp(name, hwmod, hwmodlen) == 0) { 194286678Sian result = (int)strtoul(name + hwmodlen, NULL, 10); 195286678Sian break; 196286678Sian } 197286678Sian /* Slide to the next sub-string. */ 198286678Sian l = strlen(name) + 1; 199286678Sian name += l; 200286678Sian len -= l; 201286678Sian } 202286678Sian 203299477Sgonzo OF_prop_free(buf); 204286678Sian return (result); 205286678Sian} 206