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/imx-common/mxc_i2c.h> 20 #include <asm/io.h> 21 #include <asm/gpio.h> 22 #include "common.h" 23 24 DECLARE_GLOBAL_DATA_PTR; 25 26 #ifdef CONFIG_SYS_I2C_MXC 27 #define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 28 PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ 29 PAD_CTL_ODE | PAD_CTL_SRE_FAST) 30 31 I2C_PADS(i2c0_pads, 32 PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL), 33 PAD_EIM_D21__GPIO3_IO21 | MUX_PAD_CTRL(I2C_PAD_CTRL), 34 IMX_GPIO_NR(3, 21), 35 PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL), 36 PAD_EIM_D28__GPIO3_IO28 | MUX_PAD_CTRL(I2C_PAD_CTRL), 37 IMX_GPIO_NR(3, 28)); 38 39 I2C_PADS(i2c1_pads, 40 PAD_KEY_COL3__I2C2_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL), 41 PAD_KEY_COL3__GPIO4_IO12 | MUX_PAD_CTRL(I2C_PAD_CTRL), 42 IMX_GPIO_NR(4, 12), 43 PAD_KEY_ROW3__I2C2_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL), 44 PAD_KEY_ROW3__GPIO4_IO13 | MUX_PAD_CTRL(I2C_PAD_CTRL), 45 IMX_GPIO_NR(4, 13)); 46 47 I2C_PADS(i2c2_pads, 48 PAD_GPIO_3__I2C3_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL), 49 PAD_GPIO_3__GPIO1_IO03 | MUX_PAD_CTRL(I2C_PAD_CTRL), 50 IMX_GPIO_NR(1, 3), 51 PAD_GPIO_6__I2C3_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL), 52 PAD_GPIO_6__GPIO1_IO06 | MUX_PAD_CTRL(I2C_PAD_CTRL), 53 IMX_GPIO_NR(1, 6)); 54 55 56 static void cm_fx6_setup_i2c(void) 57 { 58 setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c0_pads)); 59 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c1_pads)); 60 setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c2_pads)); 61 } 62 #else 63 static void cm_fx6_setup_i2c(void) { } 64 #endif 65 66 #ifdef CONFIG_USB_EHCI_MX6 67 #define WEAK_PULLDOWN (PAD_CTL_PUS_100K_DOWN | \ 68 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ 69 PAD_CTL_HYS | PAD_CTL_SRE_SLOW) 70 71 static int cm_fx6_usb_hub_reset(void) 72 { 73 int err; 74 75 err = gpio_request(CM_FX6_USB_HUB_RST, "usb hub rst"); 76 if (err) { 77 printf("USB hub rst gpio request failed: %d\n", err); 78 return -1; 79 } 80 81 SETUP_IOMUX_PAD(PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL)); 82 gpio_direction_output(CM_FX6_USB_HUB_RST, 0); 83 udelay(10); 84 gpio_direction_output(CM_FX6_USB_HUB_RST, 1); 85 mdelay(1); 86 87 return 0; 88 } 89 90 static int cm_fx6_init_usb_otg(void) 91 { 92 int ret; 93 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 94 95 ret = gpio_request(SB_FX6_USB_OTG_PWR, "usb-pwr"); 96 if (ret) { 97 printf("USB OTG pwr gpio request failed: %d\n", ret); 98 return ret; 99 } 100 101 SETUP_IOMUX_PAD(PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL)); 102 SETUP_IOMUX_PAD(PAD_ENET_RX_ER__USB_OTG_ID | 103 MUX_PAD_CTRL(WEAK_PULLDOWN)); 104 clrbits_le32(&iomux->gpr[1], IOMUXC_GPR1_OTG_ID_MASK); 105 /* disable ext. charger detect, or it'll affect signal quality at dp. */ 106 return gpio_direction_output(SB_FX6_USB_OTG_PWR, 0); 107 } 108 109 #define MX6_USBNC_BASEADDR 0x2184800 110 #define USBNC_USB_H1_PWR_POL (1 << 9) 111 int board_ehci_hcd_init(int port) 112 { 113 u32 *usbnc_usb_uh1_ctrl = (u32 *)(MX6_USBNC_BASEADDR + 4); 114 115 switch (port) { 116 case 0: 117 return cm_fx6_init_usb_otg(); 118 case 1: 119 SETUP_IOMUX_PAD(PAD_GPIO_0__USB_H1_PWR | 120 MUX_PAD_CTRL(NO_PAD_CTRL)); 121 122 /* Set PWR polarity to match power switch's enable polarity */ 123 setbits_le32(usbnc_usb_uh1_ctrl, USBNC_USB_H1_PWR_POL); 124 return cm_fx6_usb_hub_reset(); 125 default: 126 break; 127 } 128 129 return 0; 130 } 131 132 int board_ehci_power(int port, int on) 133 { 134 if (port == 0) 135 return gpio_direction_output(SB_FX6_USB_OTG_PWR, on); 136 137 return 0; 138 } 139 #endif 140 141 #ifdef CONFIG_FEC_MXC 142 #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 143 PAD_CTL_DSE_40ohm | PAD_CTL_HYS) 144 145 static int mx6_rgmii_rework(struct phy_device *phydev) 146 { 147 unsigned short val; 148 149 /* Ar8031 phy SmartEEE feature cause link status generates glitch, 150 * which cause ethernet link down/up issue, so disable SmartEEE 151 */ 152 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x3); 153 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x805d); 154 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4003); 155 val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe); 156 val &= ~(0x1 << 8); 157 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val); 158 159 /* To enable AR8031 ouput a 125MHz clk from CLK_25M */ 160 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7); 161 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016); 162 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007); 163 164 val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe); 165 val &= 0xffe3; 166 val |= 0x18; 167 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val); 168 169 /* introduce tx clock delay */ 170 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5); 171 val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e); 172 val |= 0x0100; 173 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val); 174 175 return 0; 176 } 177 178 int board_phy_config(struct phy_device *phydev) 179 { 180 mx6_rgmii_rework(phydev); 181 182 if (phydev->drv->config) 183 return phydev->drv->config(phydev); 184 185 return 0; 186 } 187 188 static iomux_v3_cfg_t const enet_pads[] = { 189 IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)), 190 IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)), 191 IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)), 192 IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 193 IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 194 IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 195 IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 196 IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)), 197 IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 198 IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 199 IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 200 IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 201 IOMUX_PADS(PAD_GPIO_0__CCM_CLKO1 | MUX_PAD_CTRL(NO_PAD_CTRL)), 202 IOMUX_PADS(PAD_GPIO_3__CCM_CLKO2 | MUX_PAD_CTRL(NO_PAD_CTRL)), 203 IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(0x84)), 204 IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | 205 MUX_PAD_CTRL(ENET_PAD_CTRL)), 206 IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | 207 MUX_PAD_CTRL(ENET_PAD_CTRL)), 208 IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | 209 MUX_PAD_CTRL(ENET_PAD_CTRL)), 210 }; 211 212 int board_eth_init(bd_t *bis) 213 { 214 SETUP_IOMUX_PADS(enet_pads); 215 /* phy reset */ 216 gpio_direction_output(CM_FX6_ENET_NRST, 0); 217 udelay(500); 218 gpio_set_value(CM_FX6_ENET_NRST, 1); 219 enable_enet_clk(1); 220 return cpu_eth_init(bis); 221 } 222 #endif 223 224 #ifdef CONFIG_NAND_MXS 225 static iomux_v3_cfg_t const nand_pads[] = { 226 IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NO_PAD_CTRL)), 227 IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NO_PAD_CTRL)), 228 IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NO_PAD_CTRL)), 229 IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL)), 230 IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL)), 231 IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL)), 232 IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL)), 233 IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL)), 234 IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL)), 235 IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL)), 236 IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL)), 237 IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL)), 238 IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NO_PAD_CTRL)), 239 IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NO_PAD_CTRL)), 240 }; 241 242 static void cm_fx6_setup_gpmi_nand(void) 243 { 244 SETUP_IOMUX_PADS(nand_pads); 245 /* Enable clock roots */ 246 enable_usdhc_clk(1, 3); 247 enable_usdhc_clk(1, 4); 248 249 setup_gpmi_io_clk(MXC_CCM_CS2CDR_ENFC_CLK_PODF(0xf) | 250 MXC_CCM_CS2CDR_ENFC_CLK_PRED(1) | 251 MXC_CCM_CS2CDR_ENFC_CLK_SEL(0)); 252 } 253 #else 254 static void cm_fx6_setup_gpmi_nand(void) {} 255 #endif 256 257 #ifdef CONFIG_FSL_ESDHC 258 static struct fsl_esdhc_cfg usdhc_cfg[3] = { 259 {USDHC1_BASE_ADDR}, 260 {USDHC2_BASE_ADDR}, 261 {USDHC3_BASE_ADDR}, 262 }; 263 264 static enum mxc_clock usdhc_clk[3] = { 265 MXC_ESDHC_CLK, 266 MXC_ESDHC2_CLK, 267 MXC_ESDHC3_CLK, 268 }; 269 270 int board_mmc_init(bd_t *bis) 271 { 272 int i; 273 274 cm_fx6_set_usdhc_iomux(); 275 for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { 276 usdhc_cfg[i].sdhc_clk = mxc_get_clock(usdhc_clk[i]); 277 usdhc_cfg[i].max_bus_width = 4; 278 fsl_esdhc_initialize(bis, &usdhc_cfg[i]); 279 enable_usdhc_clk(1, i); 280 } 281 282 return 0; 283 } 284 #endif 285 286 #ifdef CONFIG_OF_BOARD_SETUP 287 void ft_board_setup(void *blob, bd_t *bd) 288 { 289 uint8_t enetaddr[6]; 290 291 /* MAC addr */ 292 if (eth_getenv_enetaddr("ethaddr", enetaddr)) { 293 fdt_find_and_setprop(blob, "/fec", "local-mac-address", 294 enetaddr, 6, 1); 295 } 296 } 297 #endif 298 299 int board_init(void) 300 { 301 gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; 302 cm_fx6_setup_gpmi_nand(); 303 cm_fx6_setup_i2c(); 304 305 return 0; 306 } 307 308 int checkboard(void) 309 { 310 puts("Board: CM-FX6\n"); 311 return 0; 312 } 313 314 void dram_init_banksize(void) 315 { 316 gd->bd->bi_dram[0].start = PHYS_SDRAM_1; 317 gd->bd->bi_dram[1].start = PHYS_SDRAM_2; 318 319 switch (gd->ram_size) { 320 case 0x10000000: /* DDR_16BIT_256MB */ 321 gd->bd->bi_dram[0].size = 0x10000000; 322 gd->bd->bi_dram[1].size = 0; 323 break; 324 case 0x20000000: /* DDR_32BIT_512MB */ 325 gd->bd->bi_dram[0].size = 0x20000000; 326 gd->bd->bi_dram[1].size = 0; 327 break; 328 case 0x40000000: 329 if (is_cpu_type(MXC_CPU_MX6SOLO)) { /* DDR_32BIT_1GB */ 330 gd->bd->bi_dram[0].size = 0x20000000; 331 gd->bd->bi_dram[1].size = 0x20000000; 332 } else { /* DDR_64BIT_1GB */ 333 gd->bd->bi_dram[0].size = 0x40000000; 334 gd->bd->bi_dram[1].size = 0; 335 } 336 break; 337 case 0x80000000: /* DDR_64BIT_2GB */ 338 gd->bd->bi_dram[0].size = 0x40000000; 339 gd->bd->bi_dram[1].size = 0x40000000; 340 break; 341 case 0xEFF00000: /* DDR_64BIT_4GB */ 342 gd->bd->bi_dram[0].size = 0x70000000; 343 gd->bd->bi_dram[1].size = 0x7FF00000; 344 break; 345 } 346 } 347 348 int dram_init(void) 349 { 350 gd->ram_size = imx_ddr_size(); 351 switch (gd->ram_size) { 352 case 0x10000000: 353 case 0x20000000: 354 case 0x40000000: 355 case 0x80000000: 356 break; 357 case 0xF0000000: 358 gd->ram_size -= 0x100000; 359 break; 360 default: 361 printf("ERROR: Unsupported DRAM size 0x%lx\n", gd->ram_size); 362 return -1; 363 } 364 365 return 0; 366 } 367