2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd.
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:
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
13 #include <linux/clk.h>
14 #include <linux/clk/mxs.h>
15 #include <linux/clkdev.h>
16 #include <linux/clocksource.h>
17 #include <linux/delay.h>
18 #include <linux/err.h>
19 #include <linux/gpio.h>
20 #include <linux/init.h>
21 #include <linux/irqchip.h>
22 #include <linux/irqchip/mxs.h>
23 #include <linux/micrel_phy.h>
24 #include <linux/of_address.h>
25 #include <linux/of_platform.h>
26 #include <linux/phy.h>
27 #include <linux/pinctrl/consumer.h>
28 #include <asm/mach/arch.h>
29 #include <asm/mach/map.h>
30 #include <asm/mach/time.h>
31 #include <asm/system_misc.h>
35 /* MXS DIGCTL SAIF CLKMUX */
36 #define MXS_DIGCTL_SAIF_CLKMUX_DIRECT 0x0
37 #define MXS_DIGCTL_SAIF_CLKMUX_CROSSINPUT 0x1
38 #define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0 0x2
39 #define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1 0x3
41 #define MXS_GPIO_NR(bank, nr) ((bank) * 32 + (nr))
43 #define MXS_SET_ADDR 0x4
44 #define MXS_CLR_ADDR 0x8
45 #define MXS_TOG_ADDR 0xc
47 static inline void __mxs_setl(u32 mask, void __iomem *reg)
49 __raw_writel(mask, reg + MXS_SET_ADDR);
52 static inline void __mxs_clrl(u32 mask, void __iomem *reg)
54 __raw_writel(mask, reg + MXS_CLR_ADDR);
57 static inline void __mxs_togl(u32 mask, void __iomem *reg)
59 __raw_writel(mask, reg + MXS_TOG_ADDR);
62 #define OCOTP_WORD_OFFSET 0x20
63 #define OCOTP_WORD_COUNT 0x20
65 #define BM_OCOTP_CTRL_BUSY (1 << 8)
66 #define BM_OCOTP_CTRL_ERROR (1 << 9)
67 #define BM_OCOTP_CTRL_RD_BANK_OPEN (1 << 12)
69 static DEFINE_MUTEX(ocotp_mutex);
70 static u32 ocotp_words[OCOTP_WORD_COUNT];
72 static const u32 *mxs_get_ocotp(void)
74 struct device_node *np;
75 void __iomem *ocotp_base;
83 np = of_find_compatible_node(NULL, NULL, "fsl,ocotp");
84 ocotp_base = of_iomap(np, 0);
87 mutex_lock(&ocotp_mutex);
90 * clk_enable(hbus_clk) for ocotp can be skipped
91 * as it must be on when system is running.
94 /* try to clear ERROR bit */
95 __mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
97 /* check both BUSY and ERROR cleared */
98 while ((__raw_readl(ocotp_base) &
99 (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
102 if (unlikely(!timeout))
105 /* open OCOTP banks for read */
106 __mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
108 /* approximately wait 32 hclk cycles */
111 /* poll BUSY bit becoming cleared */
113 while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
116 if (unlikely(!timeout))
119 for (i = 0; i < OCOTP_WORD_COUNT; i++)
120 ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
123 /* close banks for power saving */
124 __mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
128 mutex_unlock(&ocotp_mutex);
133 mutex_unlock(&ocotp_mutex);
134 pr_err("%s: timeout in reading OCOTP\n", __func__);
144 static void __init update_fec_mac_prop(enum mac_oui oui)
146 struct device_node *np, *from = NULL;
147 struct property *newmac;
148 const u32 *ocotp = mxs_get_ocotp();
153 for (i = 0; i < 2; i++) {
154 np = of_find_compatible_node(from, NULL, "fsl,imx28-fec");
160 if (of_get_property(np, "local-mac-address", NULL))
163 newmac = kzalloc(sizeof(*newmac) + 6, GFP_KERNEL);
166 newmac->value = newmac + 1;
169 newmac->name = kstrdup("local-mac-address", GFP_KERNEL);
176 * OCOTP only stores the last 4 octets for each mac address,
177 * so hard-code OUI here.
179 macaddr = newmac->value;
191 case OUI_CRYSTALFONTZ:
198 macaddr[3] = (val >> 16) & 0xff;
199 macaddr[4] = (val >> 8) & 0xff;
200 macaddr[5] = (val >> 0) & 0xff;
202 of_update_property(np, newmac);
206 static inline void enable_clk_enet_out(void)
208 struct clk *clk = clk_get_sys("enet_out", NULL);
211 clk_prepare_enable(clk);
214 static void __init imx28_evk_init(void)
216 update_fec_mac_prop(OUI_FSL);
218 mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
221 static int apx4devkit_phy_fixup(struct phy_device *phy)
223 phy->dev_flags |= MICREL_PHY_50MHZ_CLK;
227 static void __init apx4devkit_init(void)
229 enable_clk_enet_out();
231 if (IS_BUILTIN(CONFIG_PHYLIB))
232 phy_register_fixup_for_uid(PHY_ID_KSZ8051, MICREL_PHY_ID_MASK,
233 apx4devkit_phy_fixup);
236 #define ENET0_MDC__GPIO_4_0 MXS_GPIO_NR(4, 0)
237 #define ENET0_MDIO__GPIO_4_1 MXS_GPIO_NR(4, 1)
238 #define ENET0_RX_EN__GPIO_4_2 MXS_GPIO_NR(4, 2)
239 #define ENET0_RXD0__GPIO_4_3 MXS_GPIO_NR(4, 3)
240 #define ENET0_RXD1__GPIO_4_4 MXS_GPIO_NR(4, 4)
241 #define ENET0_TX_EN__GPIO_4_6 MXS_GPIO_NR(4, 6)
242 #define ENET0_TXD0__GPIO_4_7 MXS_GPIO_NR(4, 7)
243 #define ENET0_TXD1__GPIO_4_8 MXS_GPIO_NR(4, 8)
244 #define ENET_CLK__GPIO_4_16 MXS_GPIO_NR(4, 16)
246 #define TX28_FEC_PHY_POWER MXS_GPIO_NR(3, 29)
247 #define TX28_FEC_PHY_RESET MXS_GPIO_NR(4, 13)
248 #define TX28_FEC_nINT MXS_GPIO_NR(4, 5)
250 static const struct gpio tx28_gpios[] __initconst = {
251 { ENET0_MDC__GPIO_4_0, GPIOF_OUT_INIT_LOW, "GPIO_4_0" },
252 { ENET0_MDIO__GPIO_4_1, GPIOF_OUT_INIT_LOW, "GPIO_4_1" },
253 { ENET0_RX_EN__GPIO_4_2, GPIOF_OUT_INIT_LOW, "GPIO_4_2" },
254 { ENET0_RXD0__GPIO_4_3, GPIOF_OUT_INIT_LOW, "GPIO_4_3" },
255 { ENET0_RXD1__GPIO_4_4, GPIOF_OUT_INIT_LOW, "GPIO_4_4" },
256 { ENET0_TX_EN__GPIO_4_6, GPIOF_OUT_INIT_LOW, "GPIO_4_6" },
257 { ENET0_TXD0__GPIO_4_7, GPIOF_OUT_INIT_LOW, "GPIO_4_7" },
258 { ENET0_TXD1__GPIO_4_8, GPIOF_OUT_INIT_LOW, "GPIO_4_8" },
259 { ENET_CLK__GPIO_4_16, GPIOF_OUT_INIT_LOW, "GPIO_4_16" },
260 { TX28_FEC_PHY_POWER, GPIOF_OUT_INIT_LOW, "fec-phy-power" },
261 { TX28_FEC_PHY_RESET, GPIOF_OUT_INIT_LOW, "fec-phy-reset" },
262 { TX28_FEC_nINT, GPIOF_DIR_IN, "fec-int" },
265 static void __init tx28_post_init(void)
267 struct device_node *np;
268 struct platform_device *pdev;
269 struct pinctrl *pctl;
272 enable_clk_enet_out();
274 np = of_find_compatible_node(NULL, NULL, "fsl,imx28-fec");
275 pdev = of_find_device_by_node(np);
277 pr_err("%s: failed to find fec device\n", __func__);
281 pctl = pinctrl_get_select(&pdev->dev, "gpio_mode");
283 pr_err("%s: failed to get pinctrl state\n", __func__);
287 ret = gpio_request_array(tx28_gpios, ARRAY_SIZE(tx28_gpios));
289 pr_err("%s: failed to request gpios: %d\n", __func__, ret);
293 /* Power up fec phy */
294 gpio_set_value(TX28_FEC_PHY_POWER, 1);
295 msleep(26); /* 25ms according to data sheet */
297 /* Mode strap pins */
298 gpio_set_value(ENET0_RX_EN__GPIO_4_2, 1);
299 gpio_set_value(ENET0_RXD0__GPIO_4_3, 1);
300 gpio_set_value(ENET0_RXD1__GPIO_4_4, 1);
302 udelay(100); /* minimum assertion time for nRST */
304 /* Deasserting FEC PHY RESET */
305 gpio_set_value(TX28_FEC_PHY_RESET, 1);
310 static void __init cfa10049_init(void)
312 update_fec_mac_prop(OUI_CRYSTALFONTZ);
315 static void __init cfa10037_init(void)
317 update_fec_mac_prop(OUI_CRYSTALFONTZ);
320 static void __init mxs_machine_init(void)
322 if (of_machine_is_compatible("fsl,imx28-evk"))
324 else if (of_machine_is_compatible("bluegiga,apx4devkit"))
326 else if (of_machine_is_compatible("crystalfontz,cfa10037"))
328 else if (of_machine_is_compatible("crystalfontz,cfa10049"))
331 of_platform_populate(NULL, of_default_bus_match_table,
334 if (of_machine_is_compatible("karo,tx28"))
338 #define MX23_CLKCTRL_RESET_OFFSET 0x120
339 #define MX28_CLKCTRL_RESET_OFFSET 0x1e0
340 #define MXS_CLKCTRL_RESET_CHIP (1 << 1)
343 * Reset the system. It is called by machine_restart().
345 static void mxs_restart(char mode, const char *cmd)
347 struct device_node *np;
348 void __iomem *reset_addr;
350 np = of_find_compatible_node(NULL, NULL, "fsl,clkctrl");
351 reset_addr = of_iomap(np, 0);
355 if (of_device_is_compatible(np, "fsl,imx23-clkctrl"))
356 reset_addr += MX23_CLKCTRL_RESET_OFFSET;
358 reset_addr += MX28_CLKCTRL_RESET_OFFSET;
361 __mxs_setl(MXS_CLKCTRL_RESET_CHIP, reset_addr);
363 pr_err("Failed to assert the chip reset\n");
365 /* Delay to allow the serial port to show the message */
369 /* We'll take a jump through zero as a poor second */
373 static void __init mxs_timer_init(void)
375 if (of_machine_is_compatible("fsl,imx23"))
379 clocksource_of_init();
382 static const char *mxs_dt_compat[] __initdata = {
388 DT_MACHINE_START(MXS, "Freescale MXS (Device Tree)")
389 .map_io = debug_ll_io_init,
390 .init_irq = irqchip_init,
391 .handle_irq = icoll_handle_irq,
392 .init_time = mxs_timer_init,
393 .init_machine = mxs_machine_init,
394 .init_late = mxs_pm_init,
395 .dt_compat = mxs_dt_compat,
396 .restart = mxs_restart,