1 /* 2 * Board functions for Compulab CM-FX6 board 3 * 4 * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/ 5 * 6 * Author: Nikita Kiryanov <nikita@compulab.co.il> 7 * 8 * SPDX-License-Identifier: GPL-2.0+ 9 */ 10 11 #include <common.h> 12 #include <fsl_esdhc.h> 13 #include <miiphy.h> 14 #include <netdev.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> 19 #include <asm/io.h> 20 #include <asm/gpio.h> 21 #include "common.h" 22 23 DECLARE_GLOBAL_DATA_PTR; 24 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) 29 30 static int cm_fx6_usb_hub_reset(void) 31 { 32 int err; 33 34 err = gpio_request(CM_FX6_USB_HUB_RST, "usb hub rst"); 35 if (err) { 36 printf("USB hub rst gpio request failed: %d\n", err); 37 return -1; 38 } 39 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); 42 udelay(10); 43 gpio_direction_output(CM_FX6_USB_HUB_RST, 1); 44 mdelay(1); 45 46 return 0; 47 } 48 49 static int cm_fx6_init_usb_otg(void) 50 { 51 int ret; 52 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 53 54 ret = gpio_request(SB_FX6_USB_OTG_PWR, "usb-pwr"); 55 if (ret) { 56 printf("USB OTG pwr gpio request failed: %d\n", ret); 57 return ret; 58 } 59 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); 66 } 67 68 #define MX6_USBNC_BASEADDR 0x2184800 69 #define USBNC_USB_H1_PWR_POL (1 << 9) 70 int board_ehci_hcd_init(int port) 71 { 72 u32 *usbnc_usb_uh1_ctrl = (u32 *)(MX6_USBNC_BASEADDR + 4); 73 74 switch (port) { 75 case 0: 76 return cm_fx6_init_usb_otg(); 77 case 1: 78 SETUP_IOMUX_PAD(PAD_GPIO_0__USB_H1_PWR | 79 MUX_PAD_CTRL(NO_PAD_CTRL)); 80 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(); 84 default: 85 break; 86 } 87 88 return 0; 89 } 90 91 int board_ehci_power(int port, int on) 92 { 93 if (port == 0) 94 return gpio_direction_output(SB_FX6_USB_OTG_PWR, on); 95 96 return 0; 97 } 98 #endif 99 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) 103 104 static int mx6_rgmii_rework(struct phy_device *phydev) 105 { 106 unsigned short val; 107 108 /* Ar8031 phy SmartEEE feature cause link status generates glitch, 109 * which cause ethernet link down/up issue, so disable SmartEEE 110 */ 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); 115 val &= ~(0x1 << 8); 116 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val); 117 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); 122 123 val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe); 124 val &= 0xffe3; 125 val |= 0x18; 126 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val); 127 128 /* introduce tx clock delay */ 129 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5); 130 val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e); 131 val |= 0x0100; 132 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val); 133 134 return 0; 135 } 136 137 int board_phy_config(struct phy_device *phydev) 138 { 139 mx6_rgmii_rework(phydev); 140 141 if (phydev->drv->config) 142 return phydev->drv->config(phydev); 143 144 return 0; 145 } 146 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)), 169 }; 170 171 int board_eth_init(bd_t *bis) 172 { 173 SETUP_IOMUX_PADS(enet_pads); 174 /* phy reset */ 175 gpio_direction_output(CM_FX6_ENET_NRST, 0); 176 udelay(500); 177 gpio_set_value(CM_FX6_ENET_NRST, 1); 178 enable_enet_clk(1); 179 return cpu_eth_init(bis); 180 } 181 #endif 182 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)), 199 }; 200 201 static void cm_fx6_setup_gpmi_nand(void) 202 { 203 SETUP_IOMUX_PADS(nand_pads); 204 /* Enable clock roots */ 205 enable_usdhc_clk(1, 3); 206 enable_usdhc_clk(1, 4); 207 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)); 211 } 212 #else 213 static void cm_fx6_setup_gpmi_nand(void) {} 214 #endif 215 216 #ifdef CONFIG_FSL_ESDHC 217 static struct fsl_esdhc_cfg usdhc_cfg[3] = { 218 {USDHC1_BASE_ADDR}, 219 {USDHC2_BASE_ADDR}, 220 {USDHC3_BASE_ADDR}, 221 }; 222 223 static enum mxc_clock usdhc_clk[3] = { 224 MXC_ESDHC_CLK, 225 MXC_ESDHC2_CLK, 226 MXC_ESDHC3_CLK, 227 }; 228 229 int board_mmc_init(bd_t *bis) 230 { 231 int i; 232 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); 239 } 240 241 return 0; 242 } 243 #endif 244 245 #ifdef CONFIG_OF_BOARD_SETUP 246 void ft_board_setup(void *blob, bd_t *bd) 247 { 248 uint8_t enetaddr[6]; 249 250 /* MAC addr */ 251 if (eth_getenv_enetaddr("ethaddr", enetaddr)) { 252 fdt_find_and_setprop(blob, "/fec", "local-mac-address", 253 enetaddr, 6, 1); 254 } 255 } 256 #endif 257 258 int board_init(void) 259 { 260 gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; 261 cm_fx6_setup_gpmi_nand(); 262 263 return 0; 264 } 265 266 int checkboard(void) 267 { 268 puts("Board: CM-FX6\n"); 269 return 0; 270 } 271 272 void dram_init_banksize(void) 273 { 274 gd->bd->bi_dram[0].start = PHYS_SDRAM_1; 275 gd->bd->bi_dram[1].start = PHYS_SDRAM_2; 276 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; 281 break; 282 case 0x20000000: /* DDR_32BIT_512MB */ 283 gd->bd->bi_dram[0].size = 0x20000000; 284 gd->bd->bi_dram[1].size = 0; 285 break; 286 case 0x40000000: 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; 293 } 294 break; 295 case 0x80000000: /* DDR_64BIT_2GB */ 296 gd->bd->bi_dram[0].size = 0x40000000; 297 gd->bd->bi_dram[1].size = 0x40000000; 298 break; 299 case 0xEFF00000: /* DDR_64BIT_4GB */ 300 gd->bd->bi_dram[0].size = 0x70000000; 301 gd->bd->bi_dram[1].size = 0x7FF00000; 302 break; 303 } 304 } 305 306 int dram_init(void) 307 { 308 gd->ram_size = imx_ddr_size(); 309 switch (gd->ram_size) { 310 case 0x10000000: 311 case 0x20000000: 312 case 0x40000000: 313 case 0x80000000: 314 break; 315 case 0xF0000000: 316 gd->ram_size -= 0x100000; 317 break; 318 default: 319 printf("ERROR: Unsupported DRAM size 0x%lx\n", gd->ram_size); 320 return -1; 321 } 322 323 return 0; 324 } 325