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