2 * Board functions for Compulab CM-FX6 board
4 * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
6 * Author: Nikita Kiryanov <nikita@compulab.co.il>
8 * SPDX-License-Identifier: GPL-2.0+
12 #include <fsl_esdhc.h>
15 #include <fdt_support.h>
16 #include <asm/arch/crm_regs.h>
17 #include <asm/arch/sys_proto.h>
18 #include <asm/arch/iomux.h>
23 DECLARE_GLOBAL_DATA_PTR;
25 #ifdef CONFIG_USB_EHCI_MX6
26 #define WEAK_PULLDOWN (PAD_CTL_PUS_100K_DOWN | \
27 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
28 PAD_CTL_HYS | PAD_CTL_SRE_SLOW)
30 static int cm_fx6_usb_hub_reset(void)
34 err = gpio_request(CM_FX6_USB_HUB_RST, "usb hub rst");
36 printf("USB hub rst gpio request failed: %d\n", err);
40 SETUP_IOMUX_PAD(PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL));
41 gpio_direction_output(CM_FX6_USB_HUB_RST, 0);
43 gpio_direction_output(CM_FX6_USB_HUB_RST, 1);
49 static int cm_fx6_init_usb_otg(void)
52 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
54 ret = gpio_request(SB_FX6_USB_OTG_PWR, "usb-pwr");
56 printf("USB OTG pwr gpio request failed: %d\n", ret);
60 SETUP_IOMUX_PAD(PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL));
61 SETUP_IOMUX_PAD(PAD_ENET_RX_ER__USB_OTG_ID |
62 MUX_PAD_CTRL(WEAK_PULLDOWN));
63 clrbits_le32(&iomux->gpr[1], IOMUXC_GPR1_OTG_ID_MASK);
64 /* disable ext. charger detect, or it'll affect signal quality at dp. */
65 return gpio_direction_output(SB_FX6_USB_OTG_PWR, 0);
68 #define MX6_USBNC_BASEADDR 0x2184800
69 #define USBNC_USB_H1_PWR_POL (1 << 9)
70 int board_ehci_hcd_init(int port)
72 u32 *usbnc_usb_uh1_ctrl = (u32 *)(MX6_USBNC_BASEADDR + 4);
76 return cm_fx6_init_usb_otg();
78 SETUP_IOMUX_PAD(PAD_GPIO_0__USB_H1_PWR |
79 MUX_PAD_CTRL(NO_PAD_CTRL));
81 /* Set PWR polarity to match power switch's enable polarity */
82 setbits_le32(usbnc_usb_uh1_ctrl, USBNC_USB_H1_PWR_POL);
83 return cm_fx6_usb_hub_reset();
91 int board_ehci_power(int port, int on)
94 return gpio_direction_output(SB_FX6_USB_OTG_PWR, on);
100 #ifdef CONFIG_FEC_MXC
101 #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
102 PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
104 static int mx6_rgmii_rework(struct phy_device *phydev)
108 /* Ar8031 phy SmartEEE feature cause link status generates glitch,
109 * which cause ethernet link down/up issue, so disable SmartEEE
111 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x3);
112 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x805d);
113 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4003);
114 val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
116 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
118 /* To enable AR8031 ouput a 125MHz clk from CLK_25M */
119 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
120 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
121 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
123 val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
126 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
128 /* introduce tx clock delay */
129 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
130 val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
132 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
137 int board_phy_config(struct phy_device *phydev)
139 mx6_rgmii_rework(phydev);
141 if (phydev->drv->config)
142 return phydev->drv->config(phydev);
147 static iomux_v3_cfg_t const enet_pads[] = {
148 IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
149 IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
150 IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
151 IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
152 IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
153 IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
154 IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
155 IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
156 IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
157 IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
158 IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
159 IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
160 IOMUX_PADS(PAD_GPIO_0__CCM_CLKO1 | MUX_PAD_CTRL(NO_PAD_CTRL)),
161 IOMUX_PADS(PAD_GPIO_3__CCM_CLKO2 | MUX_PAD_CTRL(NO_PAD_CTRL)),
162 IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(0x84)),
163 IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK |
164 MUX_PAD_CTRL(ENET_PAD_CTRL)),
165 IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL |
166 MUX_PAD_CTRL(ENET_PAD_CTRL)),
167 IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL |
168 MUX_PAD_CTRL(ENET_PAD_CTRL)),
171 int board_eth_init(bd_t *bis)
173 SETUP_IOMUX_PADS(enet_pads);
175 gpio_direction_output(CM_FX6_ENET_NRST, 0);
177 gpio_set_value(CM_FX6_ENET_NRST, 1);
179 return cpu_eth_init(bis);
183 #ifdef CONFIG_NAND_MXS
184 static iomux_v3_cfg_t const nand_pads[] = {
185 IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NO_PAD_CTRL)),
186 IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NO_PAD_CTRL)),
187 IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
188 IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
189 IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL)),
190 IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL)),
191 IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
192 IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL)),
193 IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL)),
194 IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL)),
195 IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
196 IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
197 IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
198 IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
201 static void cm_fx6_setup_gpmi_nand(void)
203 SETUP_IOMUX_PADS(nand_pads);
204 /* Enable clock roots */
205 enable_usdhc_clk(1, 3);
206 enable_usdhc_clk(1, 4);
208 setup_gpmi_io_clk(MXC_CCM_CS2CDR_ENFC_CLK_PODF(0xf) |
209 MXC_CCM_CS2CDR_ENFC_CLK_PRED(1) |
210 MXC_CCM_CS2CDR_ENFC_CLK_SEL(0));
213 static void cm_fx6_setup_gpmi_nand(void) {}
216 #ifdef CONFIG_FSL_ESDHC
217 static struct fsl_esdhc_cfg usdhc_cfg[3] = {
223 static enum mxc_clock usdhc_clk[3] = {
229 int board_mmc_init(bd_t *bis)
233 cm_fx6_set_usdhc_iomux();
234 for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
235 usdhc_cfg[i].sdhc_clk = mxc_get_clock(usdhc_clk[i]);
236 usdhc_cfg[i].max_bus_width = 4;
237 fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
238 enable_usdhc_clk(1, i);
245 #ifdef CONFIG_OF_BOARD_SETUP
246 void ft_board_setup(void *blob, bd_t *bd)
251 if (eth_getenv_enetaddr("ethaddr", enetaddr)) {
252 fdt_find_and_setprop(blob, "/fec", "local-mac-address",
260 gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
261 cm_fx6_setup_gpmi_nand();
268 puts("Board: CM-FX6\n");
272 void dram_init_banksize(void)
274 gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
275 gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
277 switch (gd->ram_size) {
278 case 0x10000000: /* DDR_16BIT_256MB */
279 gd->bd->bi_dram[0].size = 0x10000000;
280 gd->bd->bi_dram[1].size = 0;
282 case 0x20000000: /* DDR_32BIT_512MB */
283 gd->bd->bi_dram[0].size = 0x20000000;
284 gd->bd->bi_dram[1].size = 0;
287 if (is_cpu_type(MXC_CPU_MX6SOLO)) { /* DDR_32BIT_1GB */
288 gd->bd->bi_dram[0].size = 0x20000000;
289 gd->bd->bi_dram[1].size = 0x20000000;
290 } else { /* DDR_64BIT_1GB */
291 gd->bd->bi_dram[0].size = 0x40000000;
292 gd->bd->bi_dram[1].size = 0;
295 case 0x80000000: /* DDR_64BIT_2GB */
296 gd->bd->bi_dram[0].size = 0x40000000;
297 gd->bd->bi_dram[1].size = 0x40000000;
299 case 0xEFF00000: /* DDR_64BIT_4GB */
300 gd->bd->bi_dram[0].size = 0x70000000;
301 gd->bd->bi_dram[1].size = 0x7FF00000;
308 gd->ram_size = imx_ddr_size();
309 switch (gd->ram_size) {
316 gd->ram_size -= 0x100000;
319 printf("ERROR: Unsupported DRAM size 0x%lx\n", gd->ram_size);