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