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 #if defined(CONFIG_VIDEO_IPUV3) 366 static void disable_lvds(struct display_info_t const *dev) 367 { 368 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 369 370 int reg = readl(&iomux->gpr[2]); 371 372 reg &= ~(IOMUXC_GPR2_LVDS_CH0_MODE_MASK | 373 IOMUXC_GPR2_LVDS_CH1_MODE_MASK); 374 375 writel(reg, &iomux->gpr[2]); 376 } 377 378 static void do_enable_hdmi(struct display_info_t const *dev) 379 { 380 disable_lvds(dev); 381 imx_enable_hdmi_phy(); 382 } 383 384 struct display_info_t const displays[] = {{ 385 .bus = -1, 386 .addr = 0, 387 .pixfmt = IPU_PIX_FMT_RGB666, 388 .detect = NULL, 389 .enable = enable_lvds, 390 .mode = { 391 .name = "Hannstar-XGA", 392 .refresh = 60, 393 .xres = 1024, 394 .yres = 768, 395 .pixclock = 15384, 396 .left_margin = 160, 397 .right_margin = 24, 398 .upper_margin = 29, 399 .lower_margin = 3, 400 .hsync_len = 136, 401 .vsync_len = 6, 402 .sync = FB_SYNC_EXT, 403 .vmode = FB_VMODE_NONINTERLACED 404 } }, { 405 .bus = -1, 406 .addr = 0, 407 .pixfmt = IPU_PIX_FMT_RGB24, 408 .detect = detect_hdmi, 409 .enable = do_enable_hdmi, 410 .mode = { 411 .name = "HDMI", 412 .refresh = 60, 413 .xres = 1024, 414 .yres = 768, 415 .pixclock = 15384, 416 .left_margin = 160, 417 .right_margin = 24, 418 .upper_margin = 29, 419 .lower_margin = 3, 420 .hsync_len = 136, 421 .vsync_len = 6, 422 .sync = FB_SYNC_EXT, 423 .vmode = FB_VMODE_NONINTERLACED 424 } }, { 425 .bus = 0, 426 .addr = 0, 427 .pixfmt = IPU_PIX_FMT_RGB24, 428 .detect = NULL, 429 .enable = enable_rgb, 430 .mode = { 431 .name = "SEIKO-WVGA", 432 .refresh = 60, 433 .xres = 800, 434 .yres = 480, 435 .pixclock = 29850, 436 .left_margin = 89, 437 .right_margin = 164, 438 .upper_margin = 23, 439 .lower_margin = 10, 440 .hsync_len = 10, 441 .vsync_len = 10, 442 .sync = 0, 443 .vmode = FB_VMODE_NONINTERLACED 444 } } }; 445 size_t display_count = ARRAY_SIZE(displays); 446 447 static void setup_display(void) 448 { 449 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 450 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 451 int reg; 452 453 /* Setup HSYNC, VSYNC, DISP_CLK for debugging purposes */ 454 imx_iomux_v3_setup_multiple_pads(di0_pads, ARRAY_SIZE(di0_pads)); 455 456 enable_ipu_clock(); 457 imx_setup_hdmi(); 458 459 /* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */ 460 reg = readl(&mxc_ccm->CCGR3); 461 reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK; 462 writel(reg, &mxc_ccm->CCGR3); 463 464 /* set LDB0, LDB1 clk select to 011/011 */ 465 reg = readl(&mxc_ccm->cs2cdr); 466 reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK 467 | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK); 468 reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) 469 | (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET); 470 writel(reg, &mxc_ccm->cs2cdr); 471 472 reg = readl(&mxc_ccm->cscmr2); 473 reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV; 474 writel(reg, &mxc_ccm->cscmr2); 475 476 reg = readl(&mxc_ccm->chsccdr); 477 reg |= (CHSCCDR_CLK_SEL_LDB_DI0 478 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET); 479 reg |= (CHSCCDR_CLK_SEL_LDB_DI0 480 << MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET); 481 writel(reg, &mxc_ccm->chsccdr); 482 483 reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES 484 | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW 485 | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW 486 | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG 487 | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT 488 | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG 489 | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT 490 | IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED 491 | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0; 492 writel(reg, &iomux->gpr[2]); 493 494 reg = readl(&iomux->gpr[3]); 495 reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK 496 | IOMUXC_GPR3_HDMI_MUX_CTL_MASK)) 497 | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 498 << IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET); 499 writel(reg, &iomux->gpr[3]); 500 } 501 #endif /* CONFIG_VIDEO_IPUV3 */ 502 503 /* 504 * Do not overwrite the console 505 * Use always serial for U-Boot console 506 */ 507 int overwrite_console(void) 508 { 509 return 1; 510 } 511 512 int board_eth_init(bd_t *bis) 513 { 514 setup_iomux_enet(); 515 setup_pcie(); 516 517 return cpu_eth_init(bis); 518 } 519 520 #ifdef CONFIG_USB_EHCI_MX6 521 #define USB_OTHERREGS_OFFSET 0x800 522 #define UCTRL_PWR_POL (1 << 9) 523 524 static iomux_v3_cfg_t const usb_otg_pads[] = { 525 MX6_PAD_EIM_D22__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL), 526 MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL), 527 }; 528 529 static iomux_v3_cfg_t const usb_hc1_pads[] = { 530 MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL), 531 }; 532 533 static void setup_usb(void) 534 { 535 imx_iomux_v3_setup_multiple_pads(usb_otg_pads, 536 ARRAY_SIZE(usb_otg_pads)); 537 538 /* 539 * set daisy chain for otg_pin_id on 6q. 540 * for 6dl, this bit is reserved 541 */ 542 imx_iomux_set_gpr_register(1, 13, 1, 0); 543 544 imx_iomux_v3_setup_multiple_pads(usb_hc1_pads, 545 ARRAY_SIZE(usb_hc1_pads)); 546 } 547 548 int board_ehci_hcd_init(int port) 549 { 550 u32 *usbnc_usb_ctrl; 551 552 if (port > 1) 553 return -EINVAL; 554 555 usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET + 556 port * 4); 557 558 setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL); 559 560 return 0; 561 } 562 563 int board_ehci_power(int port, int on) 564 { 565 switch (port) { 566 case 0: 567 break; 568 case 1: 569 if (on) 570 gpio_direction_output(IMX_GPIO_NR(1, 29), 1); 571 else 572 gpio_direction_output(IMX_GPIO_NR(1, 29), 0); 573 break; 574 default: 575 printf("MXC USB port %d not yet supported\n", port); 576 return -EINVAL; 577 } 578 579 return 0; 580 } 581 #endif 582 583 int board_early_init_f(void) 584 { 585 setup_iomux_uart(); 586 #if defined(CONFIG_VIDEO_IPUV3) 587 setup_display(); 588 #endif 589 590 return 0; 591 } 592 593 int board_init(void) 594 { 595 /* address of boot parameters */ 596 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; 597 598 #ifdef CONFIG_MXC_SPI 599 setup_spi(); 600 #endif 601 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); 602 603 #ifdef CONFIG_USB_EHCI_MX6 604 setup_usb(); 605 #endif 606 607 return 0; 608 } 609 610 int power_init_board(void) 611 { 612 struct pmic *p; 613 unsigned int reg; 614 int ret; 615 616 p = pfuze_common_init(I2C_PMIC); 617 if (!p) 618 return -ENODEV; 619 620 ret = pfuze_mode_init(p, APS_PFM); 621 if (ret < 0) 622 return ret; 623 624 /* Increase VGEN3 from 2.5 to 2.8V */ 625 pmic_reg_read(p, PFUZE100_VGEN3VOL, ®); 626 reg &= ~LDO_VOL_MASK; 627 reg |= LDOB_2_80V; 628 pmic_reg_write(p, PFUZE100_VGEN3VOL, reg); 629 630 /* Increase VGEN5 from 2.8 to 3V */ 631 pmic_reg_read(p, PFUZE100_VGEN5VOL, ®); 632 reg &= ~LDO_VOL_MASK; 633 reg |= LDOB_3_00V; 634 pmic_reg_write(p, PFUZE100_VGEN5VOL, reg); 635 636 return 0; 637 } 638 639 #ifdef CONFIG_MXC_SPI 640 int board_spi_cs_gpio(unsigned bus, unsigned cs) 641 { 642 return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1; 643 } 644 #endif 645 646 #ifdef CONFIG_CMD_BMODE 647 static const struct boot_mode board_boot_modes[] = { 648 /* 4 bit bus width */ 649 {"sd2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)}, 650 {"sd3", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)}, 651 /* 8 bit bus width */ 652 {"emmc", MAKE_CFGVAL(0x60, 0x58, 0x00, 0x00)}, 653 {NULL, 0}, 654 }; 655 #endif 656 657 int board_late_init(void) 658 { 659 #ifdef CONFIG_CMD_BMODE 660 add_board_boot_modes(board_boot_modes); 661 #endif 662 663 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 664 setenv("board_name", "SABRESD"); 665 666 if (is_mx6dqp()) 667 setenv("board_rev", "MX6QP"); 668 else if (is_mx6dq()) 669 setenv("board_rev", "MX6Q"); 670 else if (is_mx6sdl()) 671 setenv("board_rev", "MX6DL"); 672 #endif 673 674 return 0; 675 } 676 677 int checkboard(void) 678 { 679 puts("Board: MX6-SabreSD\n"); 680 return 0; 681 } 682 683 #ifdef CONFIG_SPL_BUILD 684 #include <spl.h> 685 #include <libfdt.h> 686 687 #ifdef CONFIG_SPL_OS_BOOT 688 int spl_start_uboot(void) 689 { 690 gpio_direction_input(KEY_VOL_UP); 691 692 /* Only enter in Falcon mode if KEY_VOL_UP is pressed */ 693 return gpio_get_value(KEY_VOL_UP); 694 } 695 #endif 696 697 static void ccgr_init(void) 698 { 699 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 700 701 writel(0x00C03F3F, &ccm->CCGR0); 702 writel(0x0030FC03, &ccm->CCGR1); 703 writel(0x0FFFC000, &ccm->CCGR2); 704 writel(0x3FF00000, &ccm->CCGR3); 705 writel(0x00FFF300, &ccm->CCGR4); 706 writel(0x0F0000C3, &ccm->CCGR5); 707 writel(0x000003FF, &ccm->CCGR6); 708 } 709 710 static void gpr_init(void) 711 { 712 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 713 714 /* enable AXI cache for VDOA/VPU/IPU */ 715 writel(0xF00000CF, &iomux->gpr[4]); 716 if (is_mx6dqp()) { 717 /* set IPU AXI-id1 Qos=0x1 AXI-id0/2/3 Qos=0x7 */ 718 writel(0x007F007F, &iomux->gpr[6]); 719 writel(0x007F007F, &iomux->gpr[7]); 720 } else { 721 /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ 722 writel(0x007F007F, &iomux->gpr[6]); 723 writel(0x007F007F, &iomux->gpr[7]); 724 } 725 } 726 727 static int mx6q_dcd_table[] = { 728 0x020e0798, 0x000C0000, 729 0x020e0758, 0x00000000, 730 0x020e0588, 0x00000030, 731 0x020e0594, 0x00000030, 732 0x020e056c, 0x00000030, 733 0x020e0578, 0x00000030, 734 0x020e074c, 0x00000030, 735 0x020e057c, 0x00000030, 736 0x020e058c, 0x00000000, 737 0x020e059c, 0x00000030, 738 0x020e05a0, 0x00000030, 739 0x020e078c, 0x00000030, 740 0x020e0750, 0x00020000, 741 0x020e05a8, 0x00000030, 742 0x020e05b0, 0x00000030, 743 0x020e0524, 0x00000030, 744 0x020e051c, 0x00000030, 745 0x020e0518, 0x00000030, 746 0x020e050c, 0x00000030, 747 0x020e05b8, 0x00000030, 748 0x020e05c0, 0x00000030, 749 0x020e0774, 0x00020000, 750 0x020e0784, 0x00000030, 751 0x020e0788, 0x00000030, 752 0x020e0794, 0x00000030, 753 0x020e079c, 0x00000030, 754 0x020e07a0, 0x00000030, 755 0x020e07a4, 0x00000030, 756 0x020e07a8, 0x00000030, 757 0x020e0748, 0x00000030, 758 0x020e05ac, 0x00000030, 759 0x020e05b4, 0x00000030, 760 0x020e0528, 0x00000030, 761 0x020e0520, 0x00000030, 762 0x020e0514, 0x00000030, 763 0x020e0510, 0x00000030, 764 0x020e05bc, 0x00000030, 765 0x020e05c4, 0x00000030, 766 0x021b0800, 0xa1390003, 767 0x021b080c, 0x001F001F, 768 0x021b0810, 0x001F001F, 769 0x021b480c, 0x001F001F, 770 0x021b4810, 0x001F001F, 771 0x021b083c, 0x43270338, 772 0x021b0840, 0x03200314, 773 0x021b483c, 0x431A032F, 774 0x021b4840, 0x03200263, 775 0x021b0848, 0x4B434748, 776 0x021b4848, 0x4445404C, 777 0x021b0850, 0x38444542, 778 0x021b4850, 0x4935493A, 779 0x021b081c, 0x33333333, 780 0x021b0820, 0x33333333, 781 0x021b0824, 0x33333333, 782 0x021b0828, 0x33333333, 783 0x021b481c, 0x33333333, 784 0x021b4820, 0x33333333, 785 0x021b4824, 0x33333333, 786 0x021b4828, 0x33333333, 787 0x021b08b8, 0x00000800, 788 0x021b48b8, 0x00000800, 789 0x021b0004, 0x00020036, 790 0x021b0008, 0x09444040, 791 0x021b000c, 0x555A7975, 792 0x021b0010, 0xFF538F64, 793 0x021b0014, 0x01FF00DB, 794 0x021b0018, 0x00001740, 795 0x021b001c, 0x00008000, 796 0x021b002c, 0x000026d2, 797 0x021b0030, 0x005A1023, 798 0x021b0040, 0x00000027, 799 0x021b0000, 0x831A0000, 800 0x021b001c, 0x04088032, 801 0x021b001c, 0x00008033, 802 0x021b001c, 0x00048031, 803 0x021b001c, 0x09408030, 804 0x021b001c, 0x04008040, 805 0x021b0020, 0x00005800, 806 0x021b0818, 0x00011117, 807 0x021b4818, 0x00011117, 808 0x021b0004, 0x00025576, 809 0x021b0404, 0x00011006, 810 0x021b001c, 0x00000000, 811 }; 812 813 static int mx6qp_dcd_table[] = { 814 0x020e0798, 0x000c0000, 815 0x020e0758, 0x00000000, 816 0x020e0588, 0x00000030, 817 0x020e0594, 0x00000030, 818 0x020e056c, 0x00000030, 819 0x020e0578, 0x00000030, 820 0x020e074c, 0x00000030, 821 0x020e057c, 0x00000030, 822 0x020e058c, 0x00000000, 823 0x020e059c, 0x00000030, 824 0x020e05a0, 0x00000030, 825 0x020e078c, 0x00000030, 826 0x020e0750, 0x00020000, 827 0x020e05a8, 0x00000030, 828 0x020e05b0, 0x00000030, 829 0x020e0524, 0x00000030, 830 0x020e051c, 0x00000030, 831 0x020e0518, 0x00000030, 832 0x020e050c, 0x00000030, 833 0x020e05b8, 0x00000030, 834 0x020e05c0, 0x00000030, 835 0x020e0774, 0x00020000, 836 0x020e0784, 0x00000030, 837 0x020e0788, 0x00000030, 838 0x020e0794, 0x00000030, 839 0x020e079c, 0x00000030, 840 0x020e07a0, 0x00000030, 841 0x020e07a4, 0x00000030, 842 0x020e07a8, 0x00000030, 843 0x020e0748, 0x00000030, 844 0x020e05ac, 0x00000030, 845 0x020e05b4, 0x00000030, 846 0x020e0528, 0x00000030, 847 0x020e0520, 0x00000030, 848 0x020e0514, 0x00000030, 849 0x020e0510, 0x00000030, 850 0x020e05bc, 0x00000030, 851 0x020e05c4, 0x00000030, 852 0x021b0800, 0xa1390003, 853 0x021b080c, 0x001b001e, 854 0x021b0810, 0x002e0029, 855 0x021b480c, 0x001b002a, 856 0x021b4810, 0x0019002c, 857 0x021b083c, 0x43240334, 858 0x021b0840, 0x0324031a, 859 0x021b483c, 0x43340344, 860 0x021b4840, 0x03280276, 861 0x021b0848, 0x44383A3E, 862 0x021b4848, 0x3C3C3846, 863 0x021b0850, 0x2e303230, 864 0x021b4850, 0x38283E34, 865 0x021b081c, 0x33333333, 866 0x021b0820, 0x33333333, 867 0x021b0824, 0x33333333, 868 0x021b0828, 0x33333333, 869 0x021b481c, 0x33333333, 870 0x021b4820, 0x33333333, 871 0x021b4824, 0x33333333, 872 0x021b4828, 0x33333333, 873 0x021b08c0, 0x24912249, 874 0x021b48c0, 0x24914289, 875 0x021b08b8, 0x00000800, 876 0x021b48b8, 0x00000800, 877 0x021b0004, 0x00020036, 878 0x021b0008, 0x24444040, 879 0x021b000c, 0x555A7955, 880 0x021b0010, 0xFF320F64, 881 0x021b0014, 0x01ff00db, 882 0x021b0018, 0x00001740, 883 0x021b001c, 0x00008000, 884 0x021b002c, 0x000026d2, 885 0x021b0030, 0x005A1023, 886 0x021b0040, 0x00000027, 887 0x021b0400, 0x14420000, 888 0x021b0000, 0x831A0000, 889 0x021b0890, 0x00400C58, 890 0x00bb0008, 0x00000000, 891 0x00bb000c, 0x2891E41A, 892 0x00bb0038, 0x00000564, 893 0x00bb0014, 0x00000040, 894 0x00bb0028, 0x00000020, 895 0x00bb002c, 0x00000020, 896 0x021b001c, 0x04088032, 897 0x021b001c, 0x00008033, 898 0x021b001c, 0x00048031, 899 0x021b001c, 0x09408030, 900 0x021b001c, 0x04008040, 901 0x021b0020, 0x00005800, 902 0x021b0818, 0x00011117, 903 0x021b4818, 0x00011117, 904 0x021b0004, 0x00025576, 905 0x021b0404, 0x00011006, 906 0x021b001c, 0x00000000, 907 }; 908 909 static void ddr_init(int *table, int size) 910 { 911 int i; 912 913 for (i = 0; i < size / 2 ; i++) 914 writel(table[2 * i + 1], table[2 * i]); 915 } 916 917 static void spl_dram_init(void) 918 { 919 if (is_mx6dq()) 920 ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table)); 921 else if (is_mx6dqp()) 922 ddr_init(mx6qp_dcd_table, ARRAY_SIZE(mx6qp_dcd_table)); 923 } 924 925 void board_init_f(ulong dummy) 926 { 927 /* DDR initialization */ 928 spl_dram_init(); 929 930 /* setup AIPS and disable watchdog */ 931 arch_cpu_init(); 932 933 ccgr_init(); 934 gpr_init(); 935 936 /* iomux and setup of i2c */ 937 board_early_init_f(); 938 939 /* setup GP timer */ 940 timer_init(); 941 942 /* UART clocks enabled and gd valid - init serial console */ 943 preloader_console_init(); 944 945 /* Clear the BSS. */ 946 memset(__bss_start, 0, __bss_end - __bss_start); 947 948 /* load/boot image from boot device */ 949 board_init_r(NULL, 0); 950 } 951 #endif 952