113eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo/*
213eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo * Copyright 2011 Freescale Semiconductor, Inc.
313eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo * Copyright 2011 Linaro Ltd.
413eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo *
513eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo * The code contained herein is licensed under the GNU General Public
613eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo * License. You may obtain a copy of the GNU General Public License
713eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo * Version 2 or later at the following locations:
813eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo *
913eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo * http://www.opensource.org/licenses/gpl-license.html
1013eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo * http://www.gnu.org/copyleft/gpl.html
1113eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo */
1213eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo
130575fb754dbfc32a01f297e778533340a533ec68Shawn Guo#include <linux/delay.h>
1413eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo#include <linux/init.h>
150575fb754dbfc32a01f297e778533340a533ec68Shawn Guo#include <linux/io.h>
1613eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo#include <linux/irq.h>
1713eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo#include <linux/irqdomain.h>
1813eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo#include <linux/of.h>
190575fb754dbfc32a01f297e778533340a533ec68Shawn Guo#include <linux/of_address.h>
2013eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo#include <linux/of_irq.h>
2113eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo#include <linux/of_platform.h>
22477fce49aef4096639ca169556435c1f9068ce33Richard Zhao#include <linux/phy.h>
23477fce49aef4096639ca169556435c1f9068ce33Richard Zhao#include <linux/micrel_phy.h>
2458458e0327f7a34ef9c8bc512290bf47e3de811bMarc Zyngier#include <asm/smp_twd.h>
2513eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo#include <asm/hardware/cache-l2x0.h>
2613eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo#include <asm/hardware/gic.h>
2713eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo#include <asm/mach/arch.h>
2813eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo#include <asm/mach/time.h>
299f97da78bf018206fb623cd351d454af2f105fe0David Howells#include <asm/system_misc.h>
3013eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo#include <mach/common.h>
3113eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo#include <mach/hardware.h>
3213eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo
330575fb754dbfc32a01f297e778533340a533ec68Shawn Guovoid imx6q_restart(char mode, const char *cmd)
340575fb754dbfc32a01f297e778533340a533ec68Shawn Guo{
350575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	struct device_node *np;
360575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	void __iomem *wdog_base;
370575fb754dbfc32a01f297e778533340a533ec68Shawn Guo
380575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-wdt");
390575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	wdog_base = of_iomap(np, 0);
400575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	if (!wdog_base)
410575fb754dbfc32a01f297e778533340a533ec68Shawn Guo		goto soft;
420575fb754dbfc32a01f297e778533340a533ec68Shawn Guo
430575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	imx_src_prepare_restart();
440575fb754dbfc32a01f297e778533340a533ec68Shawn Guo
450575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	/* enable wdog */
460575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	writew_relaxed(1 << 2, wdog_base);
470575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	/* write twice to ensure the request will not get ignored */
480575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	writew_relaxed(1 << 2, wdog_base);
490575fb754dbfc32a01f297e778533340a533ec68Shawn Guo
500575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	/* wait for reset to assert ... */
510575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	mdelay(500);
520575fb754dbfc32a01f297e778533340a533ec68Shawn Guo
530575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	pr_err("Watchdog reset failed to assert reset\n");
540575fb754dbfc32a01f297e778533340a533ec68Shawn Guo
550575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	/* delay to allow the serial port to show the message */
560575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	mdelay(50);
570575fb754dbfc32a01f297e778533340a533ec68Shawn Guo
580575fb754dbfc32a01f297e778533340a533ec68Shawn Guosoft:
590575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	/* we'll take a jump through zero as a poor second */
600575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	soft_restart(0);
610575fb754dbfc32a01f297e778533340a533ec68Shawn Guo}
620575fb754dbfc32a01f297e778533340a533ec68Shawn Guo
63477fce49aef4096639ca169556435c1f9068ce33Richard Zhao/* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */
64477fce49aef4096639ca169556435c1f9068ce33Richard Zhaostatic int ksz9021rn_phy_fixup(struct phy_device *phydev)
65477fce49aef4096639ca169556435c1f9068ce33Richard Zhao{
66477fce49aef4096639ca169556435c1f9068ce33Richard Zhao	/* min rx data delay */
67477fce49aef4096639ca169556435c1f9068ce33Richard Zhao	phy_write(phydev, 0x0b, 0x8105);
68477fce49aef4096639ca169556435c1f9068ce33Richard Zhao	phy_write(phydev, 0x0c, 0x0000);
69477fce49aef4096639ca169556435c1f9068ce33Richard Zhao
70477fce49aef4096639ca169556435c1f9068ce33Richard Zhao	/* max rx/tx clock delay, min rx/tx control delay */
71477fce49aef4096639ca169556435c1f9068ce33Richard Zhao	phy_write(phydev, 0x0b, 0x8104);
72477fce49aef4096639ca169556435c1f9068ce33Richard Zhao	phy_write(phydev, 0x0c, 0xf0f0);
73477fce49aef4096639ca169556435c1f9068ce33Richard Zhao	phy_write(phydev, 0x0b, 0x104);
74477fce49aef4096639ca169556435c1f9068ce33Richard Zhao
75477fce49aef4096639ca169556435c1f9068ce33Richard Zhao	return 0;
76477fce49aef4096639ca169556435c1f9068ce33Richard Zhao}
77477fce49aef4096639ca169556435c1f9068ce33Richard Zhao
7813eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guostatic void __init imx6q_init_machine(void)
7913eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo{
80477fce49aef4096639ca169556435c1f9068ce33Richard Zhao	if (of_machine_is_compatible("fsl,imx6q-sabrelite"))
81477fce49aef4096639ca169556435c1f9068ce33Richard Zhao		phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
82477fce49aef4096639ca169556435c1f9068ce33Richard Zhao					   ksz9021rn_phy_fixup);
83477fce49aef4096639ca169556435c1f9068ce33Richard Zhao
8413eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
8513eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo
8613eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	imx6q_pm_init();
8713eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo}
8813eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo
8913eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guostatic void __init imx6q_map_io(void)
9013eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo{
9113eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	imx_lluart_map_io();
9213eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	imx_scu_map_io();
93f475058f48d3acb3c3979311c9532f3113839468Richard Zhao	imx6q_clock_map_io();
9413eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo}
9513eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo
962a3267a489f1dc4284b64a4b88c62011946dc7ffShawn Guostatic int __init imx6q_gpio_add_irq_domain(struct device_node *np,
9713eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo				struct device_node *interrupt_parent)
9813eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo{
9904aafd713bae8a75933c7821dc012b0ec9046bcaShawn Guo	static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
10013eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo
10104aafd713bae8a75933c7821dc012b0ec9046bcaShawn Guo	gpio_irq_base -= 32;
1026b783f7c5dde2648fa0bbe7fc8ac80d78699e67fGrant Likely	irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops,
1036b783f7c5dde2648fa0bbe7fc8ac80d78699e67fGrant Likely			      NULL);
1042a3267a489f1dc4284b64a4b88c62011946dc7ffShawn Guo
1052a3267a489f1dc4284b64a4b88c62011946dc7ffShawn Guo	return 0;
10613eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo}
10713eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo
10813eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guostatic const struct of_device_id imx6q_irq_match[] __initconst = {
10913eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
11013eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	{ .compatible = "fsl,imx6q-gpio", .data = imx6q_gpio_add_irq_domain, },
11113eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	{ /* sentinel */ }
11213eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo};
11313eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo
11413eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guostatic void __init imx6q_init_irq(void)
11513eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo{
11613eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	l2x0_of_init(0, ~0UL);
11713eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	imx_src_init();
11813eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	imx_gpc_init();
11913eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	of_irq_init(imx6q_irq_match);
12013eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo}
12113eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo
12213eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guostatic void __init imx6q_timer_init(void)
12313eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo{
12413eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	mx6q_clocks_init();
12558458e0327f7a34ef9c8bc512290bf47e3de811bMarc Zyngier	twd_local_timer_of_register();
12613eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo}
12713eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo
12813eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guostatic struct sys_timer imx6q_timer = {
12913eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	.init = imx6q_timer_init,
13013eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo};
13113eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo
13213eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guostatic const char *imx6q_dt_compat[] __initdata = {
133752baf5647d40dc67dc1b74125fa693ac2137563Dirk Behme	"fsl,imx6q-arm2",
1343c8276c6bc912025db50ff7e93af6bc7c3de0c8cRichard Zhao	"fsl,imx6q-sabrelite",
1353f8976d90bc7714e03c54778e2f6ab78436cb829Sascha Hauer	"fsl,imx6q",
13613eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	NULL,
13713eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo};
13813eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo
13913eed9897a2160272df2804ac3bbd4d91c76e577Shawn GuoDT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)")
14013eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	.map_io		= imx6q_map_io,
14113eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	.init_irq	= imx6q_init_irq,
14213eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	.handle_irq	= imx6q_handle_irq,
14313eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	.timer		= &imx6q_timer,
14413eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	.init_machine	= imx6q_init_machine,
14513eed9897a2160272df2804ac3bbd4d91c76e577Shawn Guo	.dt_compat	= imx6q_dt_compat,
1460575fb754dbfc32a01f297e778533340a533ec68Shawn Guo	.restart	= imx6q_restart,
14713eed9897a2160272df2804ac3bbd4d91c76e577Shawn GuoMACHINE_END
148