xref: /linux/arch/arm/mach-imx/mach-imx6q.c (revision ff5599816711d2e67da2d7561fd36ac48debd433)
1 /*
2  * Copyright 2011-2013 Freescale Semiconductor, Inc.
3  * Copyright 2011 Linaro Ltd.
4  *
5  * The code contained herein is licensed under the GNU General Public
6  * License. You may obtain a copy of the GNU General Public License
7  * Version 2 or later at the following locations:
8  *
9  * http://www.opensource.org/licenses/gpl-license.html
10  * http://www.gnu.org/copyleft/gpl.html
11  */
12 
13 #include <linux/clk.h>
14 #include <linux/clk-provider.h>
15 #include <linux/clkdev.h>
16 #include <linux/clocksource.h>
17 #include <linux/cpu.h>
18 #include <linux/delay.h>
19 #include <linux/export.h>
20 #include <linux/init.h>
21 #include <linux/io.h>
22 #include <linux/irq.h>
23 #include <linux/irqchip.h>
24 #include <linux/of.h>
25 #include <linux/of_address.h>
26 #include <linux/of_irq.h>
27 #include <linux/of_platform.h>
28 #include <linux/opp.h>
29 #include <linux/phy.h>
30 #include <linux/reboot.h>
31 #include <linux/regmap.h>
32 #include <linux/micrel_phy.h>
33 #include <linux/mfd/syscon.h>
34 #include <asm/hardware/cache-l2x0.h>
35 #include <asm/mach/arch.h>
36 #include <asm/mach/map.h>
37 #include <asm/system_misc.h>
38 
39 #include "common.h"
40 #include "cpuidle.h"
41 #include "hardware.h"
42 
43 static u32 chip_revision;
44 
45 int imx6q_revision(void)
46 {
47 	return chip_revision;
48 }
49 
50 static void __init imx6q_init_revision(void)
51 {
52 	u32 rev = imx_anatop_get_digprog();
53 
54 	switch (rev & 0xff) {
55 	case 0:
56 		chip_revision = IMX_CHIP_REVISION_1_0;
57 		break;
58 	case 1:
59 		chip_revision = IMX_CHIP_REVISION_1_1;
60 		break;
61 	case 2:
62 		chip_revision = IMX_CHIP_REVISION_1_2;
63 		break;
64 	default:
65 		chip_revision = IMX_CHIP_REVISION_UNKNOWN;
66 	}
67 
68 	mxc_set_cpu_type(rev >> 16 & 0xff);
69 }
70 
71 static void imx6q_restart(enum reboot_mode mode, const char *cmd)
72 {
73 	struct device_node *np;
74 	void __iomem *wdog_base;
75 
76 	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-wdt");
77 	wdog_base = of_iomap(np, 0);
78 	if (!wdog_base)
79 		goto soft;
80 
81 	imx_src_prepare_restart();
82 
83 	/* enable wdog */
84 	writew_relaxed(1 << 2, wdog_base);
85 	/* write twice to ensure the request will not get ignored */
86 	writew_relaxed(1 << 2, wdog_base);
87 
88 	/* wait for reset to assert ... */
89 	mdelay(500);
90 
91 	pr_err("Watchdog reset failed to assert reset\n");
92 
93 	/* delay to allow the serial port to show the message */
94 	mdelay(50);
95 
96 soft:
97 	/* we'll take a jump through zero as a poor second */
98 	soft_restart(0);
99 }
100 
101 /* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */
102 static int ksz9021rn_phy_fixup(struct phy_device *phydev)
103 {
104 	if (IS_BUILTIN(CONFIG_PHYLIB)) {
105 		/* min rx data delay */
106 		phy_write(phydev, 0x0b, 0x8105);
107 		phy_write(phydev, 0x0c, 0x0000);
108 
109 		/* max rx/tx clock delay, min rx/tx control delay */
110 		phy_write(phydev, 0x0b, 0x8104);
111 		phy_write(phydev, 0x0c, 0xf0f0);
112 		phy_write(phydev, 0x0b, 0x104);
113 	}
114 
115 	return 0;
116 }
117 
118 static void __init imx6q_sabrelite_cko1_setup(void)
119 {
120 	struct clk *cko1_sel, *ahb, *cko1;
121 	unsigned long rate;
122 
123 	cko1_sel = clk_get_sys(NULL, "cko1_sel");
124 	ahb = clk_get_sys(NULL, "ahb");
125 	cko1 = clk_get_sys(NULL, "cko1");
126 	if (IS_ERR(cko1_sel) || IS_ERR(ahb) || IS_ERR(cko1)) {
127 		pr_err("cko1 setup failed!\n");
128 		goto put_clk;
129 	}
130 	clk_set_parent(cko1_sel, ahb);
131 	rate = clk_round_rate(cko1, 16000000);
132 	clk_set_rate(cko1, rate);
133 put_clk:
134 	if (!IS_ERR(cko1_sel))
135 		clk_put(cko1_sel);
136 	if (!IS_ERR(ahb))
137 		clk_put(ahb);
138 	if (!IS_ERR(cko1))
139 		clk_put(cko1);
140 }
141 
142 static void __init imx6q_sabrelite_init(void)
143 {
144 	if (IS_BUILTIN(CONFIG_PHYLIB))
145 		phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
146 				ksz9021rn_phy_fixup);
147 	imx6q_sabrelite_cko1_setup();
148 }
149 
150 static void __init imx6q_sabresd_cko1_setup(void)
151 {
152 	struct clk *cko1_sel, *pll4, *pll4_post, *cko1;
153 	unsigned long rate;
154 
155 	cko1_sel = clk_get_sys(NULL, "cko1_sel");
156 	pll4 = clk_get_sys(NULL, "pll4_audio");
157 	pll4_post = clk_get_sys(NULL, "pll4_post_div");
158 	cko1 = clk_get_sys(NULL, "cko1");
159 	if (IS_ERR(cko1_sel) || IS_ERR(pll4)
160 			|| IS_ERR(pll4_post) || IS_ERR(cko1)) {
161 		pr_err("cko1 setup failed!\n");
162 		goto put_clk;
163 	}
164 	/*
165 	 * Setting pll4 at 768MHz (24MHz * 32)
166 	 * So its child clock can get 24MHz easily
167 	 */
168 	clk_set_rate(pll4, 768000000);
169 
170 	clk_set_parent(cko1_sel, pll4_post);
171 	rate = clk_round_rate(cko1, 24000000);
172 	clk_set_rate(cko1, rate);
173 put_clk:
174 	if (!IS_ERR(cko1_sel))
175 		clk_put(cko1_sel);
176 	if (!IS_ERR(pll4_post))
177 		clk_put(pll4_post);
178 	if (!IS_ERR(pll4))
179 		clk_put(pll4);
180 	if (!IS_ERR(cko1))
181 		clk_put(cko1);
182 }
183 
184 static void __init imx6q_sabresd_init(void)
185 {
186 	imx6q_sabresd_cko1_setup();
187 }
188 
189 static void __init imx6q_1588_init(void)
190 {
191 	struct regmap *gpr;
192 
193 	gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
194 	if (!IS_ERR(gpr))
195 		regmap_update_bits(gpr, 0x4, 1 << 21, 1 << 21);
196 	else
197 		pr_err("failed to find fsl,imx6q-iomux-gpr regmap\n");
198 
199 }
200 static void __init imx6q_usb_init(void)
201 {
202 	imx_anatop_usb_chrg_detect_disable();
203 }
204 
205 static void __init imx6q_init_machine(void)
206 {
207 	if (of_machine_is_compatible("fsl,imx6q-sabrelite"))
208 		imx6q_sabrelite_init();
209 	else if (of_machine_is_compatible("fsl,imx6q-sabresd") ||
210 			of_machine_is_compatible("fsl,imx6dl-sabresd"))
211 		imx6q_sabresd_init();
212 
213 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
214 
215 	imx_anatop_init();
216 	imx6q_pm_init();
217 	imx6q_usb_init();
218 	imx6q_1588_init();
219 }
220 
221 #define OCOTP_CFG3			0x440
222 #define OCOTP_CFG3_SPEED_SHIFT		16
223 #define OCOTP_CFG3_SPEED_1P2GHZ		0x3
224 
225 static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev)
226 {
227 	struct device_node *np;
228 	void __iomem *base;
229 	u32 val;
230 
231 	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
232 	if (!np) {
233 		pr_warn("failed to find ocotp node\n");
234 		return;
235 	}
236 
237 	base = of_iomap(np, 0);
238 	if (!base) {
239 		pr_warn("failed to map ocotp\n");
240 		goto put_node;
241 	}
242 
243 	val = readl_relaxed(base + OCOTP_CFG3);
244 	val >>= OCOTP_CFG3_SPEED_SHIFT;
245 	if ((val & 0x3) != OCOTP_CFG3_SPEED_1P2GHZ)
246 		if (opp_disable(cpu_dev, 1200000000))
247 			pr_warn("failed to disable 1.2 GHz OPP\n");
248 
249 put_node:
250 	of_node_put(np);
251 }
252 
253 static void __init imx6q_opp_init(struct device *cpu_dev)
254 {
255 	struct device_node *np;
256 
257 	np = of_find_node_by_path("/cpus/cpu@0");
258 	if (!np) {
259 		pr_warn("failed to find cpu0 node\n");
260 		return;
261 	}
262 
263 	cpu_dev->of_node = np;
264 	if (of_init_opp_table(cpu_dev)) {
265 		pr_warn("failed to init OPP table\n");
266 		goto put_node;
267 	}
268 
269 	imx6q_opp_check_1p2ghz(cpu_dev);
270 
271 put_node:
272 	of_node_put(np);
273 }
274 
275 static struct platform_device imx6q_cpufreq_pdev = {
276 	.name = "imx6q-cpufreq",
277 };
278 
279 static void __init imx6q_init_late(void)
280 {
281 	/*
282 	 * WAIT mode is broken on TO 1.0 and 1.1, so there is no point
283 	 * to run cpuidle on them.
284 	 */
285 	if (imx6q_revision() > IMX_CHIP_REVISION_1_1)
286 		imx6q_cpuidle_init();
287 
288 	if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
289 		imx6q_opp_init(&imx6q_cpufreq_pdev.dev);
290 		platform_device_register(&imx6q_cpufreq_pdev);
291 	}
292 }
293 
294 static void __init imx6q_map_io(void)
295 {
296 	debug_ll_io_init();
297 	imx_scu_map_io();
298 }
299 
300 #ifdef CONFIG_CACHE_L2X0
301 static void __init imx6q_init_l2cache(void)
302 {
303 	void __iomem *l2x0_base;
304 	struct device_node *np;
305 	unsigned int val;
306 
307 	np = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
308 	if (!np)
309 		goto out;
310 
311 	l2x0_base = of_iomap(np, 0);
312 	if (!l2x0_base) {
313 		of_node_put(np);
314 		goto out;
315 	}
316 
317 	/* Configure the L2 PREFETCH and POWER registers */
318 	val = readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL);
319 	val |= 0x70800000;
320 	writel_relaxed(val, l2x0_base + L2X0_PREFETCH_CTRL);
321 	val = L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN;
322 	writel_relaxed(val, l2x0_base + L2X0_POWER_CTRL);
323 
324 	iounmap(l2x0_base);
325 	of_node_put(np);
326 
327 out:
328 	l2x0_of_init(0, ~0UL);
329 }
330 #else
331 static inline void imx6q_init_l2cache(void) {}
332 #endif
333 
334 static void __init imx6q_init_irq(void)
335 {
336 	imx6q_init_revision();
337 	imx6q_init_l2cache();
338 	imx_src_init();
339 	imx_gpc_init();
340 	irqchip_init();
341 }
342 
343 static void __init imx6q_timer_init(void)
344 {
345 	of_clk_init(NULL);
346 	clocksource_of_init();
347 	imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
348 			      imx6q_revision());
349 }
350 
351 static const char *imx6q_dt_compat[] __initdata = {
352 	"fsl,imx6dl",
353 	"fsl,imx6q",
354 	NULL,
355 };
356 
357 DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
358 	.smp		= smp_ops(imx_smp_ops),
359 	.map_io		= imx6q_map_io,
360 	.init_irq	= imx6q_init_irq,
361 	.init_time	= imx6q_timer_init,
362 	.init_machine	= imx6q_init_machine,
363 	.init_late      = imx6q_init_late,
364 	.dt_compat	= imx6q_dt_compat,
365 	.restart	= imx6q_restart,
366 MACHINE_END
367