1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2012 Freescale Semiconductor, Inc.
4 * Author: Fabio Estevam <fabio.estevam@freescale.com>
5 *
6 * Copyright (C) 2013, 2014 TQ-Systems (ported SabreSD to TQMa6x)
7 * Author: Markus Niebel <markus.niebel@tq-group.com>
8 */
9
10 #include <init.h>
11 #include <net.h>
12 #include <asm/io.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/mx6-pins.h>
15 #include <asm/arch/imx-regs.h>
16 #include <asm/arch/iomux.h>
17 #include <asm/arch/sys_proto.h>
18 #include <linux/delay.h>
19 #include <linux/errno.h>
20 #include <asm/gpio.h>
21 #include <asm/mach-imx/mxc_i2c.h>
22
23 #include <fsl_esdhc_imx.h>
24 #include <linux/libfdt.h>
25 #include <malloc.h>
26 #include <i2c.h>
27 #include <micrel.h>
28 #include <miiphy.h>
29 #include <mmc.h>
30 #include <netdev.h>
31
32 #include "tqma6_bb.h"
33
34 #if defined(CONFIG_TQMA6Q)
35
36 #define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII 0x02e0790
37 #define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM 0x02e07ac
38
39 #elif defined(CONFIG_TQMA6S) || defined(CONFIG_TQMA6DL)
40
41 #define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII 0x02e0768
42 #define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM 0x02e0788
43
44 #else
45
46 #error "need to select module"
47
48 #endif
49
50 /* disable on die termination for RGMII */
51 #define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE 0x00000000
52 /* optimised drive strength for 1.0 .. 1.3 V signal on RGMII */
53 #define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P2V 0x00080000
54 /* optimised drive strength for 1.3 .. 2.5 V signal on RGMII */
55 #define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V 0x000C0000
56
mba6_setup_iomuxc_enet(void)57 static void mba6_setup_iomuxc_enet(void)
58 {
59 struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
60
61 /* clear gpr1[ENET_CLK_SEL] for externel clock */
62 clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK);
63
64 __raw_writel(IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE,
65 (void *)IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM);
66 __raw_writel(IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V,
67 (void *)IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII);
68 }
69
board_mmc_get_env_dev(int devno)70 int board_mmc_get_env_dev(int devno)
71 {
72 /*
73 * This assumes that the baseboard registered
74 * the boot device first ...
75 * Note: SDHC3 == idx2
76 */
77 return (2 == devno) ? 0 : 1;
78 }
79
board_phy_config(struct phy_device * phydev)80 int board_phy_config(struct phy_device *phydev)
81 {
82 /*
83 * optimized pad skew values depends on CPU variant on the TQMa6x module:
84 * CONFIG_TQMA6Q: i.MX6Q/D
85 * CONFIG_TQMA6S: i.MX6S
86 * CONFIG_TQMA6DL: i.MX6DL
87 */
88 #if defined(CONFIG_TQMA6Q)
89 #define MBA6X_KSZ9031_CTRL_SKEW 0x0032
90 #define MBA6X_KSZ9031_CLK_SKEW 0x03ff
91 #define MBA6X_KSZ9031_RX_SKEW 0x3333
92 #define MBA6X_KSZ9031_TX_SKEW 0x2036
93 #elif defined(CONFIG_TQMA6S) || defined(CONFIG_TQMA6DL)
94 #define MBA6X_KSZ9031_CTRL_SKEW 0x0030
95 #define MBA6X_KSZ9031_CLK_SKEW 0x03ff
96 #define MBA6X_KSZ9031_RX_SKEW 0x3333
97 #define MBA6X_KSZ9031_TX_SKEW 0x2052
98 #else
99 #error
100 #endif
101 /* min rx/tx ctrl delay */
102 ksz9031_phy_extended_write(phydev, 2,
103 MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
104 MII_KSZ9031_MOD_DATA_NO_POST_INC,
105 MBA6X_KSZ9031_CTRL_SKEW);
106 /* min rx delay */
107 ksz9031_phy_extended_write(phydev, 2,
108 MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
109 MII_KSZ9031_MOD_DATA_NO_POST_INC,
110 MBA6X_KSZ9031_RX_SKEW);
111 /* max tx delay */
112 ksz9031_phy_extended_write(phydev, 2,
113 MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
114 MII_KSZ9031_MOD_DATA_NO_POST_INC,
115 MBA6X_KSZ9031_TX_SKEW);
116 /* rx/tx clk skew */
117 ksz9031_phy_extended_write(phydev, 2,
118 MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
119 MII_KSZ9031_MOD_DATA_NO_POST_INC,
120 MBA6X_KSZ9031_CLK_SKEW);
121
122 phydev->drv->config(phydev);
123
124 return 0;
125 }
126
tqma6_bb_board_early_init_f(void)127 int tqma6_bb_board_early_init_f(void)
128 {
129 return 0;
130 }
131
tqma6_bb_board_init(void)132 int tqma6_bb_board_init(void)
133 {
134 mba6_setup_iomuxc_enet();
135
136 return 0;
137 }
138
tqma6_bb_board_late_init(void)139 int tqma6_bb_board_late_init(void)
140 {
141 return 0;
142 }
143
tqma6_bb_get_boardname(void)144 const char *tqma6_bb_get_boardname(void)
145 {
146 return "MBa6x";
147 }
148
149 /*
150 * Device Tree Support
151 */
152 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
tqma6_bb_ft_board_setup(void * blob,struct bd_info * bd)153 void tqma6_bb_ft_board_setup(void *blob, struct bd_info *bd)
154 {
155 /* TBD */
156 }
157 #endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */
158