]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
cf94a342 YL |
2 | /* |
3 | * Copyright (C) 2014 Freescale Semiconductor, Inc. | |
4 | * | |
5 | * Author: Ye Li <ye.li@nxp.com> | |
cf94a342 YL |
6 | */ |
7 | ||
8 | #include <asm/arch/clock.h> | |
9 | #include <asm/arch/crm_regs.h> | |
10 | #include <asm/arch/iomux.h> | |
11 | #include <asm/arch/imx-regs.h> | |
12 | #include <asm/arch/mx6-pins.h> | |
13 | #include <asm/arch/sys_proto.h> | |
14 | #include <asm/gpio.h> | |
552a848e SB |
15 | #include <asm/mach-imx/iomux-v3.h> |
16 | #include <asm/mach-imx/boot_mode.h> | |
cf94a342 | 17 | #include <asm/io.h> |
cf94a342 YL |
18 | #include <linux/sizes.h> |
19 | #include <common.h> | |
e37ac717 | 20 | #include <fsl_esdhc_imx.h> |
cf94a342 YL |
21 | #include <miiphy.h> |
22 | #include <netdev.h> | |
23 | #include <power/pmic.h> | |
24 | #include <power/pfuze100_pmic.h> | |
25 | #include "../common/pfuze.h" | |
26 | #include <usb.h> | |
e162c6b1 | 27 | #include <usb/ehci-ci.h> |
cf94a342 YL |
28 | #include <pca953x.h> |
29 | ||
30 | DECLARE_GLOBAL_DATA_PTR; | |
31 | ||
32 | #define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ | |
33 | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ | |
34 | PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) | |
35 | ||
cf94a342 YL |
36 | #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \ |
37 | PAD_CTL_SPEED_HIGH | \ | |
38 | PAD_CTL_DSE_48ohm | PAD_CTL_SRE_FAST) | |
39 | ||
40 | #define ENET_CLK_PAD_CTRL (PAD_CTL_SPEED_MED | \ | |
41 | PAD_CTL_DSE_120ohm | PAD_CTL_SRE_FAST) | |
42 | ||
43 | #define ENET_RX_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ | |
44 | PAD_CTL_SPEED_HIGH | PAD_CTL_SRE_FAST) | |
45 | ||
cf94a342 YL |
46 | #define GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP) |
47 | #define GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \ | |
48 | PAD_CTL_SRE_FAST) | |
49 | #define GPMI_PAD_CTRL2 (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1) | |
50 | ||
cf94a342 YL |
51 | int dram_init(void) |
52 | { | |
432a8a55 | 53 | gd->ram_size = imx_ddr_size(); |
cf94a342 YL |
54 | |
55 | return 0; | |
56 | } | |
57 | ||
58 | static iomux_v3_cfg_t const uart1_pads[] = { | |
59 | MX6_PAD_GPIO1_IO04__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), | |
60 | MX6_PAD_GPIO1_IO05__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), | |
61 | }; | |
62 | ||
cf94a342 YL |
63 | static iomux_v3_cfg_t const fec2_pads[] = { |
64 | MX6_PAD_ENET1_MDC__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
65 | MX6_PAD_ENET1_MDIO__ENET2_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
66 | MX6_PAD_RGMII2_RX_CTL__ENET2_RX_EN | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
67 | MX6_PAD_RGMII2_RD0__ENET2_RX_DATA_0 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
68 | MX6_PAD_RGMII2_RD1__ENET2_RX_DATA_1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
69 | MX6_PAD_RGMII2_RD2__ENET2_RX_DATA_2 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
70 | MX6_PAD_RGMII2_RD3__ENET2_RX_DATA_3 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
71 | MX6_PAD_RGMII2_RXC__ENET2_RX_CLK | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
72 | MX6_PAD_RGMII2_TX_CTL__ENET2_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
73 | MX6_PAD_RGMII2_TD0__ENET2_TX_DATA_0 | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
74 | MX6_PAD_RGMII2_TD1__ENET2_TX_DATA_1 | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
75 | MX6_PAD_RGMII2_TD2__ENET2_TX_DATA_2 | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
76 | MX6_PAD_RGMII2_TD3__ENET2_TX_DATA_3 | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
77 | MX6_PAD_RGMII2_TXC__ENET2_RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
78 | }; | |
79 | ||
80 | static void setup_iomux_uart(void) | |
81 | { | |
82 | imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); | |
83 | } | |
84 | ||
85 | static int setup_fec(void) | |
86 | { | |
87 | struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; | |
88 | ||
89 | /* Use 125MHz anatop loopback REF_CLK1 for ENET2 */ | |
90 | clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC2_MASK, 0); | |
91 | ||
92 | return enable_fec_anatop_clock(1, ENET_125MHZ); | |
93 | } | |
94 | ||
95 | int board_eth_init(bd_t *bis) | |
96 | { | |
97 | int ret; | |
98 | ||
99 | imx_iomux_v3_setup_multiple_pads(fec2_pads, ARRAY_SIZE(fec2_pads)); | |
100 | setup_fec(); | |
101 | ||
102 | ret = fecmxc_initialize_multi(bis, 1, | |
103 | CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); | |
104 | if (ret) | |
105 | printf("FEC%d MXC: %s:failed\n", 1, __func__); | |
106 | ||
107 | return ret; | |
108 | } | |
109 | ||
110 | int board_phy_config(struct phy_device *phydev) | |
111 | { | |
112 | /* | |
113 | * Enable 1.8V(SEL_1P5_1P8_POS_REG) on | |
114 | * Phy control debug reg 0 | |
115 | */ | |
116 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); | |
117 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); | |
118 | ||
119 | /* rgmii tx clock delay enable */ | |
120 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); | |
121 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); | |
122 | ||
123 | if (phydev->drv->config) | |
124 | phydev->drv->config(phydev); | |
125 | ||
126 | return 0; | |
127 | } | |
128 | ||
cf94a342 YL |
129 | int power_init_board(void) |
130 | { | |
e389033f PF |
131 | struct udevice *dev; |
132 | int ret; | |
133 | u32 dev_id, rev_id, i; | |
134 | u32 switch_num = 6; | |
135 | u32 offset = PFUZE100_SW1CMODE; | |
136 | ||
137 | ret = pmic_get("pfuze100", &dev); | |
138 | if (ret == -ENODEV) | |
139 | return 0; | |
140 | ||
141 | if (ret != 0) | |
142 | return ret; | |
143 | ||
144 | dev_id = pmic_reg_read(dev, PFUZE100_DEVICEID); | |
145 | rev_id = pmic_reg_read(dev, PFUZE100_REVID); | |
146 | printf("PMIC: PFUZE100! DEV_ID=0x%x REV_ID=0x%x\n", dev_id, rev_id); | |
cf94a342 | 147 | |
e389033f PF |
148 | |
149 | /* Init mode to APS_PFM */ | |
150 | pmic_reg_write(dev, PFUZE100_SW1ABMODE, APS_PFM); | |
151 | ||
152 | for (i = 0; i < switch_num - 1; i++) | |
153 | pmic_reg_write(dev, offset + i * SWITCH_SIZE, APS_PFM); | |
154 | ||
155 | /* set SW1AB staby volatage 0.975V */ | |
156 | pmic_clrsetbits(dev, PFUZE100_SW1ABSTBY, 0x3f, 0x1b); | |
157 | ||
158 | /* set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */ | |
159 | pmic_clrsetbits(dev, PFUZE100_SW1ABCONF, 0xc0, 0x40); | |
160 | ||
161 | /* set SW1C staby volatage 1.10V */ | |
162 | pmic_clrsetbits(dev, PFUZE100_SW1CSTBY, 0x3f, 0x20); | |
163 | ||
164 | /* set SW1C/VDDSOC step ramp up time to from 16us to 4us/25mV */ | |
165 | pmic_clrsetbits(dev, PFUZE100_SW1CCONF, 0xc0, 0x40); | |
cf94a342 YL |
166 | |
167 | return 0; | |
168 | } | |
169 | ||
170 | #ifdef CONFIG_USB_EHCI_MX6 | |
171 | #define USB_OTHERREGS_OFFSET 0x800 | |
172 | #define UCTRL_PWR_POL (1 << 9) | |
173 | ||
174 | static iomux_v3_cfg_t const usb_otg_pads[] = { | |
175 | /* OGT1 */ | |
176 | MX6_PAD_GPIO1_IO09__USB_OTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL), | |
177 | MX6_PAD_GPIO1_IO10__ANATOP_OTG1_ID | MUX_PAD_CTRL(NO_PAD_CTRL), | |
178 | /* OTG2 */ | |
179 | MX6_PAD_GPIO1_IO12__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL) | |
180 | }; | |
181 | ||
182 | static void setup_usb(void) | |
183 | { | |
184 | imx_iomux_v3_setup_multiple_pads(usb_otg_pads, | |
185 | ARRAY_SIZE(usb_otg_pads)); | |
186 | } | |
187 | ||
188 | int board_usb_phy_mode(int port) | |
189 | { | |
190 | if (port == 1) | |
191 | return USB_INIT_HOST; | |
192 | else | |
193 | return usb_phy_mode(port); | |
194 | } | |
195 | ||
196 | int board_ehci_hcd_init(int port) | |
197 | { | |
198 | u32 *usbnc_usb_ctrl; | |
199 | ||
200 | if (port > 1) | |
201 | return -EINVAL; | |
202 | ||
203 | usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET + | |
204 | port * 4); | |
205 | ||
206 | /* Set Power polarity */ | |
207 | setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL); | |
208 | ||
209 | return 0; | |
210 | } | |
211 | #endif | |
212 | ||
213 | int board_early_init_f(void) | |
214 | { | |
215 | setup_iomux_uart(); | |
216 | ||
217 | return 0; | |
218 | } | |
219 | ||
cf94a342 | 220 | #ifdef CONFIG_FSL_QSPI |
cf94a342 YL |
221 | int board_qspi_init(void) |
222 | { | |
cf94a342 YL |
223 | /* Set the clock */ |
224 | enable_qspi_clk(0); | |
225 | ||
226 | return 0; | |
227 | } | |
228 | #endif | |
229 | ||
230 | #ifdef CONFIG_NAND_MXS | |
231 | iomux_v3_cfg_t gpmi_pads[] = { | |
232 | MX6_PAD_NAND_CLE__RAWNAND_CLE | MUX_PAD_CTRL(GPMI_PAD_CTRL2), | |
233 | MX6_PAD_NAND_ALE__RAWNAND_ALE | MUX_PAD_CTRL(GPMI_PAD_CTRL2), | |
234 | MX6_PAD_NAND_WP_B__RAWNAND_WP_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2), | |
235 | MX6_PAD_NAND_READY_B__RAWNAND_READY_B | MUX_PAD_CTRL(GPMI_PAD_CTRL0), | |
236 | MX6_PAD_NAND_CE0_B__RAWNAND_CE0_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2), | |
237 | MX6_PAD_NAND_RE_B__RAWNAND_RE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2), | |
238 | MX6_PAD_NAND_WE_B__RAWNAND_WE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2), | |
239 | MX6_PAD_NAND_DATA00__RAWNAND_DATA00 | MUX_PAD_CTRL(GPMI_PAD_CTRL2), | |
240 | MX6_PAD_NAND_DATA01__RAWNAND_DATA01 | MUX_PAD_CTRL(GPMI_PAD_CTRL2), | |
241 | MX6_PAD_NAND_DATA02__RAWNAND_DATA02 | MUX_PAD_CTRL(GPMI_PAD_CTRL2), | |
242 | MX6_PAD_NAND_DATA03__RAWNAND_DATA03 | MUX_PAD_CTRL(GPMI_PAD_CTRL2), | |
243 | MX6_PAD_NAND_DATA04__RAWNAND_DATA04 | MUX_PAD_CTRL(GPMI_PAD_CTRL2), | |
244 | MX6_PAD_NAND_DATA05__RAWNAND_DATA05 | MUX_PAD_CTRL(GPMI_PAD_CTRL2), | |
245 | MX6_PAD_NAND_DATA06__RAWNAND_DATA06 | MUX_PAD_CTRL(GPMI_PAD_CTRL2), | |
246 | MX6_PAD_NAND_DATA07__RAWNAND_DATA07 | MUX_PAD_CTRL(GPMI_PAD_CTRL2), | |
247 | }; | |
248 | ||
249 | static void setup_gpmi_nand(void) | |
250 | { | |
251 | struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; | |
252 | ||
253 | /* config gpmi nand iomux */ | |
254 | imx_iomux_v3_setup_multiple_pads(gpmi_pads, ARRAY_SIZE(gpmi_pads)); | |
255 | ||
256 | setup_gpmi_io_clk((MXC_CCM_CS2CDR_QSPI2_CLK_PODF(0) | | |
257 | MXC_CCM_CS2CDR_QSPI2_CLK_PRED(3) | | |
258 | MXC_CCM_CS2CDR_QSPI2_CLK_SEL(3))); | |
259 | ||
260 | /* enable apbh clock gating */ | |
261 | setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK); | |
262 | } | |
263 | #endif | |
264 | ||
265 | int board_init(void) | |
266 | { | |
e389033f PF |
267 | struct gpio_desc desc; |
268 | int ret; | |
269 | ||
cf94a342 YL |
270 | /* Address of boot parameters */ |
271 | gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; | |
272 | ||
e389033f PF |
273 | ret = dm_gpio_lookup_name("gpio@30_4", &desc); |
274 | if (ret) | |
275 | return ret; | |
cf94a342 | 276 | |
e389033f PF |
277 | ret = dm_gpio_request(&desc, "cpu_per_rst_b"); |
278 | if (ret) | |
279 | return ret; | |
cf94a342 | 280 | /* Reset CPU_PER_RST_B signal for enet phy and PCIE */ |
e389033f | 281 | dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT); |
cf94a342 | 282 | udelay(500); |
e389033f PF |
283 | dm_gpio_set_value(&desc, 1); |
284 | ||
285 | ret = dm_gpio_lookup_name("gpio@32_2", &desc); | |
286 | if (ret) | |
287 | return ret; | |
cf94a342 | 288 | |
e389033f PF |
289 | ret = dm_gpio_request(&desc, "steer_enet"); |
290 | if (ret) | |
291 | return ret; | |
292 | ||
293 | dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT); | |
294 | udelay(500); | |
cf94a342 | 295 | /* Set steering signal to L for selecting B0 */ |
e389033f | 296 | dm_gpio_set_value(&desc, 0); |
cf94a342 YL |
297 | |
298 | #ifdef CONFIG_USB_EHCI_MX6 | |
299 | setup_usb(); | |
300 | #endif | |
301 | ||
302 | #ifdef CONFIG_FSL_QSPI | |
303 | board_qspi_init(); | |
304 | #endif | |
305 | ||
306 | #ifdef CONFIG_NAND_MXS | |
307 | setup_gpmi_nand(); | |
308 | #endif | |
309 | ||
310 | return 0; | |
311 | } | |
312 | ||
313 | #ifdef CONFIG_CMD_BMODE | |
314 | static const struct boot_mode board_boot_modes[] = { | |
315 | {"sda", MAKE_CFGVAL(0x42, 0x30, 0x00, 0x00)}, | |
316 | {"sdb", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)}, | |
317 | {"qspi1", MAKE_CFGVAL(0x10, 0x00, 0x00, 0x00)}, | |
318 | {"nand", MAKE_CFGVAL(0x82, 0x00, 0x00, 0x00)}, | |
319 | {NULL, 0}, | |
320 | }; | |
321 | #endif | |
322 | ||
323 | int board_late_init(void) | |
324 | { | |
325 | #ifdef CONFIG_CMD_BMODE | |
326 | add_board_boot_modes(board_boot_modes); | |
327 | #endif | |
328 | ||
329 | return 0; | |
330 | } | |
331 | ||
332 | int checkboard(void) | |
333 | { | |
334 | puts("Board: MX6SX SABRE AUTO\n"); | |
335 | ||
336 | return 0; | |
337 | } |