1 /* 2 * Copyright (C) 2012 Freescale Semiconductor, Inc. 3 * 4 * Author: Fabio Estevam <fabio.estevam@freescale.com> 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include <asm/arch/clock.h> 10 #include <asm/arch/imx-regs.h> 11 #include <asm/arch/iomux.h> 12 #include <asm/arch/mx6-pins.h> 13 #include <linux/errno.h> 14 #include <asm/gpio.h> 15 #include <asm/imx-common/mxc_i2c.h> 16 #include <asm/imx-common/iomux-v3.h> 17 #include <asm/imx-common/boot_mode.h> 18 #include <asm/imx-common/video.h> 19 #include <mmc.h> 20 #include <fsl_esdhc.h> 21 #include <miiphy.h> 22 #include <netdev.h> 23 #include <asm/arch/mxc_hdmi.h> 24 #include <asm/arch/crm_regs.h> 25 #include <asm/io.h> 26 #include <asm/arch/sys_proto.h> 27 #include <i2c.h> 28 #include <power/pmic.h> 29 #include <power/pfuze100_pmic.h> 30 #include "../common/pfuze.h" 31 #include <asm/arch/mx6-ddr.h> 32 #include <usb.h> 33 34 DECLARE_GLOBAL_DATA_PTR; 35 36 #define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ 37 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ 38 PAD_CTL_SRE_FAST | PAD_CTL_HYS) 39 40 #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ 41 PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ 42 PAD_CTL_SRE_FAST | PAD_CTL_HYS) 43 44 #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ 45 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) 46 47 #define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \ 48 PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) 49 50 #define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ 51 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ 52 PAD_CTL_ODE | PAD_CTL_SRE_FAST) 53 54 #define I2C_PMIC 1 55 56 #define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL) 57 58 #define DISP0_PWR_EN IMX_GPIO_NR(1, 21) 59 60 #define KEY_VOL_UP IMX_GPIO_NR(1, 4) 61 62 int dram_init(void) 63 { 64 gd->ram_size = imx_ddr_size(); 65 return 0; 66 } 67 68 static iomux_v3_cfg_t const uart1_pads[] = { 69 MX6_PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), 70 MX6_PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), 71 }; 72 73 static iomux_v3_cfg_t const enet_pads[] = { 74 MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), 75 MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), 76 MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), 77 MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), 78 MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), 79 MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), 80 MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), 81 MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), 82 MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL), 83 MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL), 84 MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), 85 MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), 86 MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), 87 MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), 88 MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), 89 /* AR8031 PHY Reset */ 90 MX6_PAD_ENET_CRS_DV__GPIO1_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL), 91 }; 92 93 static void setup_iomux_enet(void) 94 { 95 imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads)); 96 97 /* Reset AR8031 PHY */ 98 gpio_direction_output(IMX_GPIO_NR(1, 25) , 0); 99 mdelay(10); 100 gpio_set_value(IMX_GPIO_NR(1, 25), 1); 101 udelay(100); 102 } 103 104 static iomux_v3_cfg_t const usdhc2_pads[] = { 105 MX6_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), 106 MX6_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), 107 MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 108 MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 109 MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 110 MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 111 MX6_PAD_NANDF_D4__SD2_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 112 MX6_PAD_NANDF_D5__SD2_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 113 MX6_PAD_NANDF_D6__SD2_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 114 MX6_PAD_NANDF_D7__SD2_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 115 MX6_PAD_NANDF_D2__GPIO2_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ 116 }; 117 118 static iomux_v3_cfg_t const usdhc3_pads[] = { 119 MX6_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), 120 MX6_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), 121 MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 122 MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 123 MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 124 MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 125 MX6_PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 126 MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 127 MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 128 MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 129 MX6_PAD_NANDF_D0__GPIO2_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ 130 }; 131 132 static iomux_v3_cfg_t const usdhc4_pads[] = { 133 MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), 134 MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), 135 MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 136 MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 137 MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 138 MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 139 MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 140 MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 141 MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 142 MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 143 }; 144 145 static iomux_v3_cfg_t const ecspi1_pads[] = { 146 MX6_PAD_KEY_COL0__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), 147 MX6_PAD_KEY_COL1__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), 148 MX6_PAD_KEY_ROW0__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), 149 MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL), 150 }; 151 152 static iomux_v3_cfg_t const rgb_pads[] = { 153 MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL), 154 MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL), 155 MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02 | MUX_PAD_CTRL(NO_PAD_CTRL), 156 MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03 | MUX_PAD_CTRL(NO_PAD_CTRL), 157 MX6_PAD_DI0_PIN4__IPU1_DI0_PIN04 | MUX_PAD_CTRL(NO_PAD_CTRL), 158 MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL), 159 MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL), 160 MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL), 161 MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL), 162 MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL), 163 MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL), 164 MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL), 165 MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL), 166 MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 | MUX_PAD_CTRL(NO_PAD_CTRL), 167 MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 | MUX_PAD_CTRL(NO_PAD_CTRL), 168 MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 | MUX_PAD_CTRL(NO_PAD_CTRL), 169 MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 | MUX_PAD_CTRL(NO_PAD_CTRL), 170 MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 | MUX_PAD_CTRL(NO_PAD_CTRL), 171 MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 | MUX_PAD_CTRL(NO_PAD_CTRL), 172 MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 | MUX_PAD_CTRL(NO_PAD_CTRL), 173 MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 | MUX_PAD_CTRL(NO_PAD_CTRL), 174 MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 | MUX_PAD_CTRL(NO_PAD_CTRL), 175 MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 | MUX_PAD_CTRL(NO_PAD_CTRL), 176 MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 | MUX_PAD_CTRL(NO_PAD_CTRL), 177 MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 | MUX_PAD_CTRL(NO_PAD_CTRL), 178 MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 | MUX_PAD_CTRL(NO_PAD_CTRL), 179 MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 | MUX_PAD_CTRL(NO_PAD_CTRL), 180 MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 | MUX_PAD_CTRL(NO_PAD_CTRL), 181 MX6_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 | MUX_PAD_CTRL(NO_PAD_CTRL), 182 }; 183 184 static iomux_v3_cfg_t const bl_pads[] = { 185 MX6_PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL), 186 }; 187 188 static void enable_backlight(void) 189 { 190 imx_iomux_v3_setup_multiple_pads(bl_pads, ARRAY_SIZE(bl_pads)); 191 gpio_direction_output(DISP0_PWR_EN, 1); 192 } 193 194 static void enable_rgb(struct display_info_t const *dev) 195 { 196 imx_iomux_v3_setup_multiple_pads(rgb_pads, ARRAY_SIZE(rgb_pads)); 197 enable_backlight(); 198 } 199 200 static void enable_lvds(struct display_info_t const *dev) 201 { 202 enable_backlight(); 203 } 204 205 static struct i2c_pads_info i2c_pad_info1 = { 206 .scl = { 207 .i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | I2C_PAD, 208 .gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12 | I2C_PAD, 209 .gp = IMX_GPIO_NR(4, 12) 210 }, 211 .sda = { 212 .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | I2C_PAD, 213 .gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | I2C_PAD, 214 .gp = IMX_GPIO_NR(4, 13) 215 } 216 }; 217 218 static void setup_spi(void) 219 { 220 imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads)); 221 } 222 223 iomux_v3_cfg_t const pcie_pads[] = { 224 MX6_PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL), /* POWER */ 225 MX6_PAD_GPIO_17__GPIO7_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL), /* RESET */ 226 }; 227 228 static void setup_pcie(void) 229 { 230 imx_iomux_v3_setup_multiple_pads(pcie_pads, ARRAY_SIZE(pcie_pads)); 231 } 232 233 iomux_v3_cfg_t const di0_pads[] = { 234 MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK, /* DISP0_CLK */ 235 MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02, /* DISP0_HSYNC */ 236 MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03, /* DISP0_VSYNC */ 237 }; 238 239 static void setup_iomux_uart(void) 240 { 241 imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); 242 } 243 244 #ifdef CONFIG_FSL_ESDHC 245 struct fsl_esdhc_cfg usdhc_cfg[3] = { 246 {USDHC2_BASE_ADDR}, 247 {USDHC3_BASE_ADDR}, 248 {USDHC4_BASE_ADDR}, 249 }; 250 251 #define USDHC2_CD_GPIO IMX_GPIO_NR(2, 2) 252 #define USDHC3_CD_GPIO IMX_GPIO_NR(2, 0) 253 254 int board_mmc_get_env_dev(int devno) 255 { 256 return devno - 1; 257 } 258 259 int board_mmc_getcd(struct mmc *mmc) 260 { 261 struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; 262 int ret = 0; 263 264 switch (cfg->esdhc_base) { 265 case USDHC2_BASE_ADDR: 266 ret = !gpio_get_value(USDHC2_CD_GPIO); 267 break; 268 case USDHC3_BASE_ADDR: 269 ret = !gpio_get_value(USDHC3_CD_GPIO); 270 break; 271 case USDHC4_BASE_ADDR: 272 ret = 1; /* eMMC/uSDHC4 is always present */ 273 break; 274 } 275 276 return ret; 277 } 278 279 int board_mmc_init(bd_t *bis) 280 { 281 #ifndef CONFIG_SPL_BUILD 282 int ret; 283 int i; 284 285 /* 286 * According to the board_mmc_init() the following map is done: 287 * (U-Boot device node) (Physical Port) 288 * mmc0 SD2 289 * mmc1 SD3 290 * mmc2 eMMC 291 */ 292 for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { 293 switch (i) { 294 case 0: 295 imx_iomux_v3_setup_multiple_pads( 296 usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); 297 gpio_direction_input(USDHC2_CD_GPIO); 298 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); 299 break; 300 case 1: 301 imx_iomux_v3_setup_multiple_pads( 302 usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); 303 gpio_direction_input(USDHC3_CD_GPIO); 304 usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); 305 break; 306 case 2: 307 imx_iomux_v3_setup_multiple_pads( 308 usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); 309 usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); 310 break; 311 default: 312 printf("Warning: you configured more USDHC controllers" 313 "(%d) then supported by the board (%d)\n", 314 i + 1, CONFIG_SYS_FSL_USDHC_NUM); 315 return -EINVAL; 316 } 317 318 ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); 319 if (ret) 320 return ret; 321 } 322 323 return 0; 324 #else 325 struct src *psrc = (struct src *)SRC_BASE_ADDR; 326 unsigned reg = readl(&psrc->sbmr1) >> 11; 327 /* 328 * Upon reading BOOT_CFG register the following map is done: 329 * Bit 11 and 12 of BOOT_CFG register can determine the current 330 * mmc port 331 * 0x1 SD1 332 * 0x2 SD2 333 * 0x3 SD4 334 */ 335 336 switch (reg & 0x3) { 337 case 0x1: 338 imx_iomux_v3_setup_multiple_pads( 339 usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); 340 usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR; 341 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); 342 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; 343 break; 344 case 0x2: 345 imx_iomux_v3_setup_multiple_pads( 346 usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); 347 usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR; 348 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); 349 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; 350 break; 351 case 0x3: 352 imx_iomux_v3_setup_multiple_pads( 353 usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); 354 usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR; 355 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); 356 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; 357 break; 358 } 359 360 return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); 361 #endif 362 } 363 #endif 364 365 static int ar8031_phy_fixup(struct phy_device *phydev) 366 { 367 unsigned short val; 368 369 /* To enable AR8031 ouput a 125MHz clk from CLK_25M */ 370 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7); 371 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016); 372 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007); 373 374 val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe); 375 val &= 0xffe3; 376 val |= 0x18; 377 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val); 378 379 /* introduce tx clock delay */ 380 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5); 381 val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e); 382 val |= 0x0100; 383 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val); 384 385 return 0; 386 } 387 388 int board_phy_config(struct phy_device *phydev) 389 { 390 ar8031_phy_fixup(phydev); 391 392 if (phydev->drv->config) 393 phydev->drv->config(phydev); 394 395 return 0; 396 } 397 398 #if defined(CONFIG_VIDEO_IPUV3) 399 static void disable_lvds(struct display_info_t const *dev) 400 { 401 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 402 403 int reg = readl(&iomux->gpr[2]); 404 405 reg &= ~(IOMUXC_GPR2_LVDS_CH0_MODE_MASK | 406 IOMUXC_GPR2_LVDS_CH1_MODE_MASK); 407 408 writel(reg, &iomux->gpr[2]); 409 } 410 411 static void do_enable_hdmi(struct display_info_t const *dev) 412 { 413 disable_lvds(dev); 414 imx_enable_hdmi_phy(); 415 } 416 417 struct display_info_t const displays[] = {{ 418 .bus = -1, 419 .addr = 0, 420 .pixfmt = IPU_PIX_FMT_RGB666, 421 .detect = NULL, 422 .enable = enable_lvds, 423 .mode = { 424 .name = "Hannstar-XGA", 425 .refresh = 60, 426 .xres = 1024, 427 .yres = 768, 428 .pixclock = 15384, 429 .left_margin = 160, 430 .right_margin = 24, 431 .upper_margin = 29, 432 .lower_margin = 3, 433 .hsync_len = 136, 434 .vsync_len = 6, 435 .sync = FB_SYNC_EXT, 436 .vmode = FB_VMODE_NONINTERLACED 437 } }, { 438 .bus = -1, 439 .addr = 0, 440 .pixfmt = IPU_PIX_FMT_RGB24, 441 .detect = detect_hdmi, 442 .enable = do_enable_hdmi, 443 .mode = { 444 .name = "HDMI", 445 .refresh = 60, 446 .xres = 1024, 447 .yres = 768, 448 .pixclock = 15384, 449 .left_margin = 160, 450 .right_margin = 24, 451 .upper_margin = 29, 452 .lower_margin = 3, 453 .hsync_len = 136, 454 .vsync_len = 6, 455 .sync = FB_SYNC_EXT, 456 .vmode = FB_VMODE_NONINTERLACED 457 } }, { 458 .bus = 0, 459 .addr = 0, 460 .pixfmt = IPU_PIX_FMT_RGB24, 461 .detect = NULL, 462 .enable = enable_rgb, 463 .mode = { 464 .name = "SEIKO-WVGA", 465 .refresh = 60, 466 .xres = 800, 467 .yres = 480, 468 .pixclock = 29850, 469 .left_margin = 89, 470 .right_margin = 164, 471 .upper_margin = 23, 472 .lower_margin = 10, 473 .hsync_len = 10, 474 .vsync_len = 10, 475 .sync = 0, 476 .vmode = FB_VMODE_NONINTERLACED 477 } } }; 478 size_t display_count = ARRAY_SIZE(displays); 479 480 static void setup_display(void) 481 { 482 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 483 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 484 int reg; 485 486 /* Setup HSYNC, VSYNC, DISP_CLK for debugging purposes */ 487 imx_iomux_v3_setup_multiple_pads(di0_pads, ARRAY_SIZE(di0_pads)); 488 489 enable_ipu_clock(); 490 imx_setup_hdmi(); 491 492 /* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */ 493 reg = readl(&mxc_ccm->CCGR3); 494 reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK; 495 writel(reg, &mxc_ccm->CCGR3); 496 497 /* set LDB0, LDB1 clk select to 011/011 */ 498 reg = readl(&mxc_ccm->cs2cdr); 499 reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK 500 | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK); 501 reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) 502 | (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET); 503 writel(reg, &mxc_ccm->cs2cdr); 504 505 reg = readl(&mxc_ccm->cscmr2); 506 reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV; 507 writel(reg, &mxc_ccm->cscmr2); 508 509 reg = readl(&mxc_ccm->chsccdr); 510 reg |= (CHSCCDR_CLK_SEL_LDB_DI0 511 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET); 512 reg |= (CHSCCDR_CLK_SEL_LDB_DI0 513 << MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET); 514 writel(reg, &mxc_ccm->chsccdr); 515 516 reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES 517 | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW 518 | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW 519 | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG 520 | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT 521 | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG 522 | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT 523 | IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED 524 | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0; 525 writel(reg, &iomux->gpr[2]); 526 527 reg = readl(&iomux->gpr[3]); 528 reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK 529 | IOMUXC_GPR3_HDMI_MUX_CTL_MASK)) 530 | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 531 << IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET); 532 writel(reg, &iomux->gpr[3]); 533 } 534 #endif /* CONFIG_VIDEO_IPUV3 */ 535 536 /* 537 * Do not overwrite the console 538 * Use always serial for U-Boot console 539 */ 540 int overwrite_console(void) 541 { 542 return 1; 543 } 544 545 int board_eth_init(bd_t *bis) 546 { 547 setup_iomux_enet(); 548 setup_pcie(); 549 550 return cpu_eth_init(bis); 551 } 552 553 #ifdef CONFIG_USB_EHCI_MX6 554 #define USB_OTHERREGS_OFFSET 0x800 555 #define UCTRL_PWR_POL (1 << 9) 556 557 static iomux_v3_cfg_t const usb_otg_pads[] = { 558 MX6_PAD_EIM_D22__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL), 559 MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL), 560 }; 561 562 static iomux_v3_cfg_t const usb_hc1_pads[] = { 563 MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL), 564 }; 565 566 static void setup_usb(void) 567 { 568 imx_iomux_v3_setup_multiple_pads(usb_otg_pads, 569 ARRAY_SIZE(usb_otg_pads)); 570 571 /* 572 * set daisy chain for otg_pin_id on 6q. 573 * for 6dl, this bit is reserved 574 */ 575 imx_iomux_set_gpr_register(1, 13, 1, 0); 576 577 imx_iomux_v3_setup_multiple_pads(usb_hc1_pads, 578 ARRAY_SIZE(usb_hc1_pads)); 579 } 580 581 int board_ehci_hcd_init(int port) 582 { 583 u32 *usbnc_usb_ctrl; 584 585 if (port > 1) 586 return -EINVAL; 587 588 usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET + 589 port * 4); 590 591 setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL); 592 593 return 0; 594 } 595 596 int board_ehci_power(int port, int on) 597 { 598 switch (port) { 599 case 0: 600 break; 601 case 1: 602 if (on) 603 gpio_direction_output(IMX_GPIO_NR(1, 29), 1); 604 else 605 gpio_direction_output(IMX_GPIO_NR(1, 29), 0); 606 break; 607 default: 608 printf("MXC USB port %d not yet supported\n", port); 609 return -EINVAL; 610 } 611 612 return 0; 613 } 614 #endif 615 616 int board_early_init_f(void) 617 { 618 setup_iomux_uart(); 619 #if defined(CONFIG_VIDEO_IPUV3) 620 setup_display(); 621 #endif 622 623 return 0; 624 } 625 626 int board_init(void) 627 { 628 /* address of boot parameters */ 629 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; 630 631 #ifdef CONFIG_MXC_SPI 632 setup_spi(); 633 #endif 634 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); 635 636 #ifdef CONFIG_USB_EHCI_MX6 637 setup_usb(); 638 #endif 639 640 return 0; 641 } 642 643 int power_init_board(void) 644 { 645 struct pmic *p; 646 unsigned int reg; 647 int ret; 648 649 p = pfuze_common_init(I2C_PMIC); 650 if (!p) 651 return -ENODEV; 652 653 ret = pfuze_mode_init(p, APS_PFM); 654 if (ret < 0) 655 return ret; 656 657 /* Increase VGEN3 from 2.5 to 2.8V */ 658 pmic_reg_read(p, PFUZE100_VGEN3VOL, ®); 659 reg &= ~LDO_VOL_MASK; 660 reg |= LDOB_2_80V; 661 pmic_reg_write(p, PFUZE100_VGEN3VOL, reg); 662 663 /* Increase VGEN5 from 2.8 to 3V */ 664 pmic_reg_read(p, PFUZE100_VGEN5VOL, ®); 665 reg &= ~LDO_VOL_MASK; 666 reg |= LDOB_3_00V; 667 pmic_reg_write(p, PFUZE100_VGEN5VOL, reg); 668 669 return 0; 670 } 671 672 #ifdef CONFIG_MXC_SPI 673 int board_spi_cs_gpio(unsigned bus, unsigned cs) 674 { 675 return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1; 676 } 677 #endif 678 679 #ifdef CONFIG_CMD_BMODE 680 static const struct boot_mode board_boot_modes[] = { 681 /* 4 bit bus width */ 682 {"sd2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)}, 683 {"sd3", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)}, 684 /* 8 bit bus width */ 685 {"emmc", MAKE_CFGVAL(0x60, 0x58, 0x00, 0x00)}, 686 {NULL, 0}, 687 }; 688 #endif 689 690 int board_late_init(void) 691 { 692 #ifdef CONFIG_CMD_BMODE 693 add_board_boot_modes(board_boot_modes); 694 #endif 695 696 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 697 setenv("board_name", "SABRESD"); 698 699 if (is_mx6dqp()) 700 setenv("board_rev", "MX6QP"); 701 else if (is_mx6dq()) 702 setenv("board_rev", "MX6Q"); 703 else if (is_mx6sdl()) 704 setenv("board_rev", "MX6DL"); 705 #endif 706 707 return 0; 708 } 709 710 int checkboard(void) 711 { 712 puts("Board: MX6-SabreSD\n"); 713 return 0; 714 } 715 716 #ifdef CONFIG_SPL_BUILD 717 #include <spl.h> 718 #include <libfdt.h> 719 720 #ifdef CONFIG_SPL_OS_BOOT 721 int spl_start_uboot(void) 722 { 723 gpio_direction_input(KEY_VOL_UP); 724 725 /* Only enter in Falcon mode if KEY_VOL_UP is pressed */ 726 return gpio_get_value(KEY_VOL_UP); 727 } 728 #endif 729 730 static void ccgr_init(void) 731 { 732 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 733 734 writel(0x00C03F3F, &ccm->CCGR0); 735 writel(0x0030FC03, &ccm->CCGR1); 736 writel(0x0FFFC000, &ccm->CCGR2); 737 writel(0x3FF00000, &ccm->CCGR3); 738 writel(0x00FFF300, &ccm->CCGR4); 739 writel(0x0F0000C3, &ccm->CCGR5); 740 writel(0x000003FF, &ccm->CCGR6); 741 } 742 743 static void gpr_init(void) 744 { 745 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 746 747 /* enable AXI cache for VDOA/VPU/IPU */ 748 writel(0xF00000CF, &iomux->gpr[4]); 749 if (is_mx6dqp()) { 750 /* set IPU AXI-id1 Qos=0x1 AXI-id0/2/3 Qos=0x7 */ 751 writel(0x007F007F, &iomux->gpr[6]); 752 writel(0x007F007F, &iomux->gpr[7]); 753 } else { 754 /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ 755 writel(0x007F007F, &iomux->gpr[6]); 756 writel(0x007F007F, &iomux->gpr[7]); 757 } 758 } 759 760 static int mx6q_dcd_table[] = { 761 0x020e0798, 0x000C0000, 762 0x020e0758, 0x00000000, 763 0x020e0588, 0x00000030, 764 0x020e0594, 0x00000030, 765 0x020e056c, 0x00000030, 766 0x020e0578, 0x00000030, 767 0x020e074c, 0x00000030, 768 0x020e057c, 0x00000030, 769 0x020e058c, 0x00000000, 770 0x020e059c, 0x00000030, 771 0x020e05a0, 0x00000030, 772 0x020e078c, 0x00000030, 773 0x020e0750, 0x00020000, 774 0x020e05a8, 0x00000030, 775 0x020e05b0, 0x00000030, 776 0x020e0524, 0x00000030, 777 0x020e051c, 0x00000030, 778 0x020e0518, 0x00000030, 779 0x020e050c, 0x00000030, 780 0x020e05b8, 0x00000030, 781 0x020e05c0, 0x00000030, 782 0x020e0774, 0x00020000, 783 0x020e0784, 0x00000030, 784 0x020e0788, 0x00000030, 785 0x020e0794, 0x00000030, 786 0x020e079c, 0x00000030, 787 0x020e07a0, 0x00000030, 788 0x020e07a4, 0x00000030, 789 0x020e07a8, 0x00000030, 790 0x020e0748, 0x00000030, 791 0x020e05ac, 0x00000030, 792 0x020e05b4, 0x00000030, 793 0x020e0528, 0x00000030, 794 0x020e0520, 0x00000030, 795 0x020e0514, 0x00000030, 796 0x020e0510, 0x00000030, 797 0x020e05bc, 0x00000030, 798 0x020e05c4, 0x00000030, 799 0x021b0800, 0xa1390003, 800 0x021b080c, 0x001F001F, 801 0x021b0810, 0x001F001F, 802 0x021b480c, 0x001F001F, 803 0x021b4810, 0x001F001F, 804 0x021b083c, 0x43270338, 805 0x021b0840, 0x03200314, 806 0x021b483c, 0x431A032F, 807 0x021b4840, 0x03200263, 808 0x021b0848, 0x4B434748, 809 0x021b4848, 0x4445404C, 810 0x021b0850, 0x38444542, 811 0x021b4850, 0x4935493A, 812 0x021b081c, 0x33333333, 813 0x021b0820, 0x33333333, 814 0x021b0824, 0x33333333, 815 0x021b0828, 0x33333333, 816 0x021b481c, 0x33333333, 817 0x021b4820, 0x33333333, 818 0x021b4824, 0x33333333, 819 0x021b4828, 0x33333333, 820 0x021b08b8, 0x00000800, 821 0x021b48b8, 0x00000800, 822 0x021b0004, 0x00020036, 823 0x021b0008, 0x09444040, 824 0x021b000c, 0x555A7975, 825 0x021b0010, 0xFF538F64, 826 0x021b0014, 0x01FF00DB, 827 0x021b0018, 0x00001740, 828 0x021b001c, 0x00008000, 829 0x021b002c, 0x000026d2, 830 0x021b0030, 0x005A1023, 831 0x021b0040, 0x00000027, 832 0x021b0000, 0x831A0000, 833 0x021b001c, 0x04088032, 834 0x021b001c, 0x00008033, 835 0x021b001c, 0x00048031, 836 0x021b001c, 0x09408030, 837 0x021b001c, 0x04008040, 838 0x021b0020, 0x00005800, 839 0x021b0818, 0x00011117, 840 0x021b4818, 0x00011117, 841 0x021b0004, 0x00025576, 842 0x021b0404, 0x00011006, 843 0x021b001c, 0x00000000, 844 }; 845 846 static int mx6qp_dcd_table[] = { 847 0x020e0798, 0x000c0000, 848 0x020e0758, 0x00000000, 849 0x020e0588, 0x00000030, 850 0x020e0594, 0x00000030, 851 0x020e056c, 0x00000030, 852 0x020e0578, 0x00000030, 853 0x020e074c, 0x00000030, 854 0x020e057c, 0x00000030, 855 0x020e058c, 0x00000000, 856 0x020e059c, 0x00000030, 857 0x020e05a0, 0x00000030, 858 0x020e078c, 0x00000030, 859 0x020e0750, 0x00020000, 860 0x020e05a8, 0x00000030, 861 0x020e05b0, 0x00000030, 862 0x020e0524, 0x00000030, 863 0x020e051c, 0x00000030, 864 0x020e0518, 0x00000030, 865 0x020e050c, 0x00000030, 866 0x020e05b8, 0x00000030, 867 0x020e05c0, 0x00000030, 868 0x020e0774, 0x00020000, 869 0x020e0784, 0x00000030, 870 0x020e0788, 0x00000030, 871 0x020e0794, 0x00000030, 872 0x020e079c, 0x00000030, 873 0x020e07a0, 0x00000030, 874 0x020e07a4, 0x00000030, 875 0x020e07a8, 0x00000030, 876 0x020e0748, 0x00000030, 877 0x020e05ac, 0x00000030, 878 0x020e05b4, 0x00000030, 879 0x020e0528, 0x00000030, 880 0x020e0520, 0x00000030, 881 0x020e0514, 0x00000030, 882 0x020e0510, 0x00000030, 883 0x020e05bc, 0x00000030, 884 0x020e05c4, 0x00000030, 885 0x021b0800, 0xa1390003, 886 0x021b080c, 0x001b001e, 887 0x021b0810, 0x002e0029, 888 0x021b480c, 0x001b002a, 889 0x021b4810, 0x0019002c, 890 0x021b083c, 0x43240334, 891 0x021b0840, 0x0324031a, 892 0x021b483c, 0x43340344, 893 0x021b4840, 0x03280276, 894 0x021b0848, 0x44383A3E, 895 0x021b4848, 0x3C3C3846, 896 0x021b0850, 0x2e303230, 897 0x021b4850, 0x38283E34, 898 0x021b081c, 0x33333333, 899 0x021b0820, 0x33333333, 900 0x021b0824, 0x33333333, 901 0x021b0828, 0x33333333, 902 0x021b481c, 0x33333333, 903 0x021b4820, 0x33333333, 904 0x021b4824, 0x33333333, 905 0x021b4828, 0x33333333, 906 0x021b08c0, 0x24912249, 907 0x021b48c0, 0x24914289, 908 0x021b08b8, 0x00000800, 909 0x021b48b8, 0x00000800, 910 0x021b0004, 0x00020036, 911 0x021b0008, 0x24444040, 912 0x021b000c, 0x555A7955, 913 0x021b0010, 0xFF320F64, 914 0x021b0014, 0x01ff00db, 915 0x021b0018, 0x00001740, 916 0x021b001c, 0x00008000, 917 0x021b002c, 0x000026d2, 918 0x021b0030, 0x005A1023, 919 0x021b0040, 0x00000027, 920 0x021b0400, 0x14420000, 921 0x021b0000, 0x831A0000, 922 0x021b0890, 0x00400C58, 923 0x00bb0008, 0x00000000, 924 0x00bb000c, 0x2891E41A, 925 0x00bb0038, 0x00000564, 926 0x00bb0014, 0x00000040, 927 0x00bb0028, 0x00000020, 928 0x00bb002c, 0x00000020, 929 0x021b001c, 0x04088032, 930 0x021b001c, 0x00008033, 931 0x021b001c, 0x00048031, 932 0x021b001c, 0x09408030, 933 0x021b001c, 0x04008040, 934 0x021b0020, 0x00005800, 935 0x021b0818, 0x00011117, 936 0x021b4818, 0x00011117, 937 0x021b0004, 0x00025576, 938 0x021b0404, 0x00011006, 939 0x021b001c, 0x00000000, 940 }; 941 942 static void ddr_init(int *table, int size) 943 { 944 int i; 945 946 for (i = 0; i < size / 2 ; i++) 947 writel(table[2 * i + 1], table[2 * i]); 948 } 949 950 static void spl_dram_init(void) 951 { 952 if (is_mx6dq()) 953 ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table)); 954 else if (is_mx6dqp()) 955 ddr_init(mx6qp_dcd_table, ARRAY_SIZE(mx6qp_dcd_table)); 956 } 957 958 void board_init_f(ulong dummy) 959 { 960 /* DDR initialization */ 961 spl_dram_init(); 962 963 /* setup AIPS and disable watchdog */ 964 arch_cpu_init(); 965 966 ccgr_init(); 967 gpr_init(); 968 969 /* iomux and setup of i2c */ 970 board_early_init_f(); 971 972 /* setup GP timer */ 973 timer_init(); 974 975 /* UART clocks enabled and gd valid - init serial console */ 976 preloader_console_init(); 977 978 /* Clear the BSS. */ 979 memset(__bss_start, 0, __bss_end - __bss_start); 980 981 /* load/boot image from boot device */ 982 board_init_r(NULL, 0); 983 } 984 #endif 985