1 /* 2 * Legacy platform_data quirks 3 * 4 * Copyright (C) 2013 Texas Instruments 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 #include <linux/clk.h> 11 #include <linux/davinci_emac.h> 12 #include <linux/gpio.h> 13 #include <linux/init.h> 14 #include <linux/kernel.h> 15 #include <linux/of_platform.h> 16 #include <linux/wl12xx.h> 17 18 #include <linux/platform_data/pinctrl-single.h> 19 20 #include "am35xx.h" 21 #include "common.h" 22 #include "common-board-devices.h" 23 #include "dss-common.h" 24 #include "control.h" 25 26 struct pdata_init { 27 const char *compatible; 28 void (*fn)(void); 29 }; 30 31 struct of_dev_auxdata omap_auxdata_lookup[]; 32 static struct twl4030_gpio_platform_data twl_gpio_auxdata; 33 34 /* 35 * Create alias for USB host PHY clock. 36 * Remove this when clock phandle can be provided via DT 37 */ 38 static void __init __used legacy_init_ehci_clk(char *clkname) 39 { 40 int ret; 41 42 ret = clk_add_alias("main_clk", NULL, clkname, NULL); 43 if (ret) 44 pr_err("%s:Failed to add main_clk alias to %s :%d\n", 45 __func__, clkname, ret); 46 } 47 48 #if IS_ENABLED(CONFIG_WL12XX) 49 50 static struct wl12xx_platform_data wl12xx __initdata; 51 52 static void __init __used legacy_init_wl12xx(unsigned ref_clock, 53 unsigned tcxo_clock, 54 int gpio) 55 { 56 int res; 57 58 wl12xx.board_ref_clock = ref_clock; 59 wl12xx.board_tcxo_clock = tcxo_clock; 60 wl12xx.irq = gpio_to_irq(gpio); 61 62 res = wl12xx_set_platform_data(&wl12xx); 63 if (res) { 64 pr_err("error setting wl12xx data: %d\n", res); 65 return; 66 } 67 } 68 #else 69 static inline void legacy_init_wl12xx(unsigned ref_clock, 70 unsigned tcxo_clock, 71 int gpio) 72 { 73 } 74 #endif 75 76 #ifdef CONFIG_MACH_NOKIA_N8X0 77 static void __init omap2420_n8x0_legacy_init(void) 78 { 79 omap_auxdata_lookup[0].platform_data = n8x0_legacy_init(); 80 } 81 #else 82 #define omap2420_n8x0_legacy_init NULL 83 #endif 84 85 #ifdef CONFIG_ARCH_OMAP3 86 static void __init hsmmc2_internal_input_clk(void) 87 { 88 u32 reg; 89 90 reg = omap_ctrl_readl(OMAP343X_CONTROL_DEVCONF1); 91 reg |= OMAP2_MMCSDIO2ADPCLKISEL; 92 omap_ctrl_writel(reg, OMAP343X_CONTROL_DEVCONF1); 93 } 94 95 static int omap3_sbc_t3730_twl_callback(struct device *dev, 96 unsigned gpio, 97 unsigned ngpio) 98 { 99 int res; 100 101 res = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH, 102 "wlan rst"); 103 if (res) 104 return res; 105 106 gpio_export(gpio, 0); 107 108 return 0; 109 } 110 111 static void __init omap3_sbc_t3730_twl_init(void) 112 { 113 twl_gpio_auxdata.setup = omap3_sbc_t3730_twl_callback; 114 } 115 116 static void __init omap3_sbc_t3730_legacy_init(void) 117 { 118 legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 136); 119 omap_ads7846_init(1, 57, 0, NULL); 120 } 121 122 static void __init omap3_igep0020_legacy_init(void) 123 { 124 omap3_igep2_display_init_of(); 125 } 126 127 static void __init omap3_evm_legacy_init(void) 128 { 129 legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 149); 130 } 131 132 static void __init omap3_zoom_legacy_init(void) 133 { 134 legacy_init_wl12xx(WL12XX_REFCLOCK_26, 0, 162); 135 } 136 137 static void am35xx_enable_emac_int(void) 138 { 139 u32 v; 140 141 v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); 142 v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR | 143 AM35XX_CPGMAC_C0_MISC_PULSE_CLR | AM35XX_CPGMAC_C0_RX_THRESH_CLR); 144 omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR); 145 omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */ 146 } 147 148 static void am35xx_disable_emac_int(void) 149 { 150 u32 v; 151 152 v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); 153 v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR); 154 omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR); 155 omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */ 156 } 157 158 static struct emac_platform_data am35xx_emac_pdata = { 159 .interrupt_enable = am35xx_enable_emac_int, 160 .interrupt_disable = am35xx_disable_emac_int, 161 }; 162 163 static void __init am3517_evm_legacy_init(void) 164 { 165 u32 v; 166 167 v = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); 168 v &= ~AM35XX_CPGMACSS_SW_RST; 169 omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET); 170 omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */ 171 } 172 #endif /* CONFIG_ARCH_OMAP3 */ 173 174 #ifdef CONFIG_ARCH_OMAP4 175 static void __init omap4_sdp_legacy_init(void) 176 { 177 omap_4430sdp_display_init_of(); 178 legacy_init_wl12xx(WL12XX_REFCLOCK_26, 179 WL12XX_TCXOCLOCK_26, 53); 180 } 181 182 static void __init omap4_panda_legacy_init(void) 183 { 184 omap4_panda_display_init_of(); 185 legacy_init_ehci_clk("auxclk3_ck"); 186 legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 53); 187 } 188 #endif 189 190 #ifdef CONFIG_SOC_OMAP5 191 static void __init omap5_uevm_legacy_init(void) 192 { 193 legacy_init_ehci_clk("auxclk1_ck"); 194 } 195 #endif 196 197 static struct pcs_pdata pcs_pdata; 198 199 void omap_pcs_legacy_init(int irq, void (*rearm)(void)) 200 { 201 pcs_pdata.irq = irq; 202 pcs_pdata.rearm = rearm; 203 } 204 205 /* 206 * GPIOs for TWL are initialized by the I2C bus and need custom 207 * handing until DSS has device tree bindings. 208 */ 209 void omap_auxdata_legacy_init(struct device *dev) 210 { 211 if (dev->platform_data) 212 return; 213 214 if (strcmp("twl4030-gpio", dev_name(dev))) 215 return; 216 217 dev->platform_data = &twl_gpio_auxdata; 218 } 219 220 /* 221 * Few boards still need auxdata populated before we populate 222 * the dev entries in of_platform_populate(). 223 */ 224 static struct pdata_init auxdata_quirks[] __initdata = { 225 #ifdef CONFIG_SOC_OMAP2420 226 { "nokia,n800", omap2420_n8x0_legacy_init, }, 227 { "nokia,n810", omap2420_n8x0_legacy_init, }, 228 { "nokia,n810-wimax", omap2420_n8x0_legacy_init, }, 229 #endif 230 #ifdef CONFIG_ARCH_OMAP3 231 { "compulab,omap3-sbc-t3730", omap3_sbc_t3730_twl_init, }, 232 #endif 233 { /* sentinel */ }, 234 }; 235 236 struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { 237 #ifdef CONFIG_MACH_NOKIA_N8X0 238 OF_DEV_AUXDATA("ti,omap2420-mmc", 0x4809c000, "mmci-omap.0", NULL), 239 #endif 240 #ifdef CONFIG_ARCH_OMAP3 241 OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002030, "48002030.pinmux", &pcs_pdata), 242 OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002a00, "48002a00.pinmux", &pcs_pdata), 243 /* Only on am3517 */ 244 OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL), 245 OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0", 246 &am35xx_emac_pdata), 247 #endif 248 #ifdef CONFIG_ARCH_OMAP4 249 OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a100040, "4a100040.pinmux", &pcs_pdata), 250 OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a31e040, "4a31e040.pinmux", &pcs_pdata), 251 #endif 252 { /* sentinel */ }, 253 }; 254 255 /* 256 * Few boards still need to initialize some legacy devices with 257 * platform data until the drivers support device tree. 258 */ 259 static struct pdata_init pdata_quirks[] __initdata = { 260 #ifdef CONFIG_ARCH_OMAP3 261 { "compulab,omap3-sbc-t3730", omap3_sbc_t3730_legacy_init, }, 262 { "nokia,omap3-n900", hsmmc2_internal_input_clk, }, 263 { "nokia,omap3-n9", hsmmc2_internal_input_clk, }, 264 { "nokia,omap3-n950", hsmmc2_internal_input_clk, }, 265 { "isee,omap3-igep0020", omap3_igep0020_legacy_init, }, 266 { "ti,omap3-evm-37xx", omap3_evm_legacy_init, }, 267 { "ti,omap3-zoom3", omap3_zoom_legacy_init, }, 268 { "ti,am3517-evm", am3517_evm_legacy_init, }, 269 #endif 270 #ifdef CONFIG_ARCH_OMAP4 271 { "ti,omap4-sdp", omap4_sdp_legacy_init, }, 272 { "ti,omap4-panda", omap4_panda_legacy_init, }, 273 #endif 274 #ifdef CONFIG_SOC_OMAP5 275 { "ti,omap5-uevm", omap5_uevm_legacy_init, }, 276 #endif 277 { /* sentinel */ }, 278 }; 279 280 static void pdata_quirks_check(struct pdata_init *quirks) 281 { 282 while (quirks->compatible) { 283 if (of_machine_is_compatible(quirks->compatible)) { 284 if (quirks->fn) 285 quirks->fn(); 286 break; 287 } 288 quirks++; 289 } 290 } 291 292 void __init pdata_quirks_init(struct of_device_id *omap_dt_match_table) 293 { 294 omap_sdrc_init(NULL, NULL); 295 pdata_quirks_check(auxdata_quirks); 296 of_platform_populate(NULL, omap_dt_match_table, 297 omap_auxdata_lookup, NULL); 298 pdata_quirks_check(pdata_quirks); 299 } 300