1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2011 Freescale Semiconductor, Inc. 4 * Jason Liu <r64343@freescale.com> 5 */ 6 7 #include <common.h> 8 #include <asm/io.h> 9 #include <asm/arch/imx-regs.h> 10 #include <asm/arch/sys_proto.h> 11 #include <asm/arch/crm_regs.h> 12 #include <asm/arch/clock.h> 13 #include <asm/arch/iomux-mx53.h> 14 #include <asm/arch/clock.h> 15 #include <linux/errno.h> 16 #include <asm/mach-imx/mx5_video.h> 17 #include <netdev.h> 18 #include <i2c.h> 19 #include <input.h> 20 #include <mmc.h> 21 #include <fsl_esdhc.h> 22 #include <asm/gpio.h> 23 #include <power/pmic.h> 24 #include <dialog_pmic.h> 25 #include <fsl_pmic.h> 26 #include <linux/fb.h> 27 #include <ipu_pixfmt.h> 28 29 #define MX53LOCO_LCD_POWER IMX_GPIO_NR(3, 24) 30 31 DECLARE_GLOBAL_DATA_PTR; 32 33 u32 get_board_rev(void) 34 { 35 struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE; 36 struct fuse_bank *bank = &iim->bank[0]; 37 struct fuse_bank0_regs *fuse = 38 (struct fuse_bank0_regs *)bank->fuse_regs; 39 40 int rev = readl(&fuse->gp[6]); 41 42 if (!i2c_probe(CONFIG_SYS_DIALOG_PMIC_I2C_ADDR)) 43 rev = 0; 44 45 return (get_cpu_rev() & ~(0xF << 8)) | (rev & 0xF) << 8; 46 } 47 48 #define UART_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_DSE_HIGH | \ 49 PAD_CTL_PUS_100K_UP | PAD_CTL_ODE) 50 51 static void setup_iomux_uart(void) 52 { 53 static const iomux_v3_cfg_t uart_pads[] = { 54 NEW_PAD_CTRL(MX53_PAD_CSI0_DAT11__UART1_RXD_MUX, UART_PAD_CTRL), 55 NEW_PAD_CTRL(MX53_PAD_CSI0_DAT10__UART1_TXD_MUX, UART_PAD_CTRL), 56 }; 57 58 imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads)); 59 } 60 61 #ifdef CONFIG_USB_EHCI_MX5 62 int board_ehci_hcd_init(int port) 63 { 64 /* request VBUS power enable pin, GPIO7_8 */ 65 imx_iomux_v3_setup_pad(MX53_PAD_PATA_DA_2__GPIO7_8); 66 gpio_direction_output(IMX_GPIO_NR(7, 8), 1); 67 return 0; 68 } 69 #endif 70 71 static void setup_iomux_fec(void) 72 { 73 static const iomux_v3_cfg_t fec_pads[] = { 74 NEW_PAD_CTRL(MX53_PAD_FEC_MDIO__FEC_MDIO, PAD_CTL_HYS | 75 PAD_CTL_DSE_HIGH | PAD_CTL_PUS_22K_UP | PAD_CTL_ODE), 76 NEW_PAD_CTRL(MX53_PAD_FEC_MDC__FEC_MDC, PAD_CTL_DSE_HIGH), 77 NEW_PAD_CTRL(MX53_PAD_FEC_RXD1__FEC_RDATA_1, 78 PAD_CTL_HYS | PAD_CTL_PKE), 79 NEW_PAD_CTRL(MX53_PAD_FEC_RXD0__FEC_RDATA_0, 80 PAD_CTL_HYS | PAD_CTL_PKE), 81 NEW_PAD_CTRL(MX53_PAD_FEC_TXD1__FEC_TDATA_1, PAD_CTL_DSE_HIGH), 82 NEW_PAD_CTRL(MX53_PAD_FEC_TXD0__FEC_TDATA_0, PAD_CTL_DSE_HIGH), 83 NEW_PAD_CTRL(MX53_PAD_FEC_TX_EN__FEC_TX_EN, PAD_CTL_DSE_HIGH), 84 NEW_PAD_CTRL(MX53_PAD_FEC_REF_CLK__FEC_TX_CLK, 85 PAD_CTL_HYS | PAD_CTL_PKE), 86 NEW_PAD_CTRL(MX53_PAD_FEC_RX_ER__FEC_RX_ER, 87 PAD_CTL_HYS | PAD_CTL_PKE), 88 NEW_PAD_CTRL(MX53_PAD_FEC_CRS_DV__FEC_RX_DV, 89 PAD_CTL_HYS | PAD_CTL_PKE), 90 }; 91 92 imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads)); 93 } 94 95 #ifdef CONFIG_FSL_ESDHC 96 struct fsl_esdhc_cfg esdhc_cfg[2] = { 97 {MMC_SDHC1_BASE_ADDR}, 98 {MMC_SDHC3_BASE_ADDR}, 99 }; 100 101 int board_mmc_getcd(struct mmc *mmc) 102 { 103 struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; 104 int ret; 105 106 imx_iomux_v3_setup_pad(MX53_PAD_EIM_DA11__GPIO3_11); 107 gpio_direction_input(IMX_GPIO_NR(3, 11)); 108 imx_iomux_v3_setup_pad(MX53_PAD_EIM_DA13__GPIO3_13); 109 gpio_direction_input(IMX_GPIO_NR(3, 13)); 110 111 if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR) 112 ret = !gpio_get_value(IMX_GPIO_NR(3, 13)); 113 else 114 ret = !gpio_get_value(IMX_GPIO_NR(3, 11)); 115 116 return ret; 117 } 118 119 #define SD_CMD_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_DSE_HIGH | \ 120 PAD_CTL_PUS_100K_UP) 121 #define SD_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | \ 122 PAD_CTL_DSE_HIGH) 123 124 int board_mmc_init(bd_t *bis) 125 { 126 static const iomux_v3_cfg_t sd1_pads[] = { 127 NEW_PAD_CTRL(MX53_PAD_SD1_CMD__ESDHC1_CMD, SD_CMD_PAD_CTRL), 128 NEW_PAD_CTRL(MX53_PAD_SD1_CLK__ESDHC1_CLK, SD_PAD_CTRL), 129 NEW_PAD_CTRL(MX53_PAD_SD1_DATA0__ESDHC1_DAT0, SD_PAD_CTRL), 130 NEW_PAD_CTRL(MX53_PAD_SD1_DATA1__ESDHC1_DAT1, SD_PAD_CTRL), 131 NEW_PAD_CTRL(MX53_PAD_SD1_DATA2__ESDHC1_DAT2, SD_PAD_CTRL), 132 NEW_PAD_CTRL(MX53_PAD_SD1_DATA3__ESDHC1_DAT3, SD_PAD_CTRL), 133 MX53_PAD_EIM_DA13__GPIO3_13, 134 }; 135 136 static const iomux_v3_cfg_t sd2_pads[] = { 137 NEW_PAD_CTRL(MX53_PAD_PATA_RESET_B__ESDHC3_CMD, 138 SD_CMD_PAD_CTRL), 139 NEW_PAD_CTRL(MX53_PAD_PATA_IORDY__ESDHC3_CLK, SD_PAD_CTRL), 140 NEW_PAD_CTRL(MX53_PAD_PATA_DATA8__ESDHC3_DAT0, SD_PAD_CTRL), 141 NEW_PAD_CTRL(MX53_PAD_PATA_DATA9__ESDHC3_DAT1, SD_PAD_CTRL), 142 NEW_PAD_CTRL(MX53_PAD_PATA_DATA10__ESDHC3_DAT2, SD_PAD_CTRL), 143 NEW_PAD_CTRL(MX53_PAD_PATA_DATA11__ESDHC3_DAT3, SD_PAD_CTRL), 144 NEW_PAD_CTRL(MX53_PAD_PATA_DATA0__ESDHC3_DAT4, SD_PAD_CTRL), 145 NEW_PAD_CTRL(MX53_PAD_PATA_DATA1__ESDHC3_DAT5, SD_PAD_CTRL), 146 NEW_PAD_CTRL(MX53_PAD_PATA_DATA2__ESDHC3_DAT6, SD_PAD_CTRL), 147 NEW_PAD_CTRL(MX53_PAD_PATA_DATA3__ESDHC3_DAT7, SD_PAD_CTRL), 148 MX53_PAD_EIM_DA11__GPIO3_11, 149 }; 150 151 u32 index; 152 int ret; 153 154 esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); 155 esdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); 156 157 for (index = 0; index < CONFIG_SYS_FSL_ESDHC_NUM; index++) { 158 switch (index) { 159 case 0: 160 imx_iomux_v3_setup_multiple_pads(sd1_pads, 161 ARRAY_SIZE(sd1_pads)); 162 break; 163 case 1: 164 imx_iomux_v3_setup_multiple_pads(sd2_pads, 165 ARRAY_SIZE(sd2_pads)); 166 break; 167 default: 168 printf("Warning: you configured more ESDHC controller" 169 "(%d) as supported by the board(2)\n", 170 CONFIG_SYS_FSL_ESDHC_NUM); 171 return -EINVAL; 172 } 173 ret = fsl_esdhc_initialize(bis, &esdhc_cfg[index]); 174 if (ret) 175 return ret; 176 } 177 178 return 0; 179 } 180 #endif 181 182 #define I2C_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \ 183 PAD_CTL_PUS_100K_UP | PAD_CTL_ODE) 184 185 static void setup_iomux_i2c(void) 186 { 187 static const iomux_v3_cfg_t i2c1_pads[] = { 188 NEW_PAD_CTRL(MX53_PAD_CSI0_DAT8__I2C1_SDA, I2C_PAD_CTRL), 189 NEW_PAD_CTRL(MX53_PAD_CSI0_DAT9__I2C1_SCL, I2C_PAD_CTRL), 190 }; 191 192 imx_iomux_v3_setup_multiple_pads(i2c1_pads, ARRAY_SIZE(i2c1_pads)); 193 } 194 195 static int power_init(void) 196 { 197 unsigned int val; 198 int ret; 199 struct pmic *p; 200 201 if (!i2c_probe(CONFIG_SYS_DIALOG_PMIC_I2C_ADDR)) { 202 ret = pmic_dialog_init(I2C_PMIC); 203 if (ret) 204 return ret; 205 206 p = pmic_get("DIALOG_PMIC"); 207 if (!p) 208 return -ENODEV; 209 210 env_set("fdt_file", "imx53-qsb.dtb"); 211 212 /* Set VDDA to 1.25V */ 213 val = DA9052_BUCKCORE_BCOREEN | DA_BUCKCORE_VBCORE_1_250V; 214 ret = pmic_reg_write(p, DA9053_BUCKCORE_REG, val); 215 if (ret) { 216 printf("Writing to BUCKCORE_REG failed: %d\n", ret); 217 return ret; 218 } 219 220 pmic_reg_read(p, DA9053_SUPPLY_REG, &val); 221 val |= DA9052_SUPPLY_VBCOREGO; 222 ret = pmic_reg_write(p, DA9053_SUPPLY_REG, val); 223 if (ret) { 224 printf("Writing to SUPPLY_REG failed: %d\n", ret); 225 return ret; 226 } 227 228 /* Set Vcc peripheral to 1.30V */ 229 ret = pmic_reg_write(p, DA9053_BUCKPRO_REG, 0x62); 230 if (ret) { 231 printf("Writing to BUCKPRO_REG failed: %d\n", ret); 232 return ret; 233 } 234 235 ret = pmic_reg_write(p, DA9053_SUPPLY_REG, 0x62); 236 if (ret) { 237 printf("Writing to SUPPLY_REG failed: %d\n", ret); 238 return ret; 239 } 240 241 return ret; 242 } 243 244 if (!i2c_probe(CONFIG_SYS_FSL_PMIC_I2C_ADDR)) { 245 ret = pmic_init(I2C_0); 246 if (ret) 247 return ret; 248 249 p = pmic_get("FSL_PMIC"); 250 if (!p) 251 return -ENODEV; 252 253 env_set("fdt_file", "imx53-qsrb.dtb"); 254 255 /* Set VDDGP to 1.25V for 1GHz on SW1 */ 256 pmic_reg_read(p, REG_SW_0, &val); 257 val = (val & ~SWx_VOLT_MASK_MC34708) | SWx_1_250V_MC34708; 258 ret = pmic_reg_write(p, REG_SW_0, val); 259 if (ret) { 260 printf("Writing to REG_SW_0 failed: %d\n", ret); 261 return ret; 262 } 263 264 /* Set VCC as 1.30V on SW2 */ 265 pmic_reg_read(p, REG_SW_1, &val); 266 val = (val & ~SWx_VOLT_MASK_MC34708) | SWx_1_300V_MC34708; 267 ret = pmic_reg_write(p, REG_SW_1, val); 268 if (ret) { 269 printf("Writing to REG_SW_1 failed: %d\n", ret); 270 return ret; 271 } 272 273 /* Set global reset timer to 4s */ 274 pmic_reg_read(p, REG_POWER_CTL2, &val); 275 val = (val & ~TIMER_MASK_MC34708) | TIMER_4S_MC34708; 276 ret = pmic_reg_write(p, REG_POWER_CTL2, val); 277 if (ret) { 278 printf("Writing to REG_POWER_CTL2 failed: %d\n", ret); 279 return ret; 280 } 281 282 /* Set VUSBSEL and VUSBEN for USB PHY supply*/ 283 pmic_reg_read(p, REG_MODE_0, &val); 284 val |= (VUSBSEL_MC34708 | VUSBEN_MC34708); 285 ret = pmic_reg_write(p, REG_MODE_0, val); 286 if (ret) { 287 printf("Writing to REG_MODE_0 failed: %d\n", ret); 288 return ret; 289 } 290 291 /* Set SWBST to 5V in auto mode */ 292 val = SWBST_AUTO; 293 ret = pmic_reg_write(p, SWBST_CTRL, val); 294 if (ret) { 295 printf("Writing to SWBST_CTRL failed: %d\n", ret); 296 return ret; 297 } 298 299 return ret; 300 } 301 302 return -1; 303 } 304 305 static void clock_1GHz(void) 306 { 307 int ret; 308 u32 ref_clk = MXC_HCLK; 309 /* 310 * After increasing voltage to 1.25V, we can switch 311 * CPU clock to 1GHz and DDR to 400MHz safely 312 */ 313 ret = mxc_set_clock(ref_clk, 1000, MXC_ARM_CLK); 314 if (ret) 315 printf("CPU: Switch CPU clock to 1GHZ failed\n"); 316 317 ret = mxc_set_clock(ref_clk, 400, MXC_PERIPH_CLK); 318 ret |= mxc_set_clock(ref_clk, 400, MXC_DDR_CLK); 319 if (ret) 320 printf("CPU: Switch DDR clock to 400MHz failed\n"); 321 } 322 323 int board_early_init_f(void) 324 { 325 setup_iomux_uart(); 326 setup_iomux_fec(); 327 setup_iomux_lcd(); 328 329 return 0; 330 } 331 332 /* 333 * Do not overwrite the console 334 * Use always serial for U-Boot console 335 */ 336 int overwrite_console(void) 337 { 338 return 1; 339 } 340 341 int board_init(void) 342 { 343 gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; 344 345 mxc_set_sata_internal_clock(); 346 setup_iomux_i2c(); 347 348 return 0; 349 } 350 351 int board_late_init(void) 352 { 353 if (!power_init()) 354 clock_1GHz(); 355 356 return 0; 357 } 358 359 int checkboard(void) 360 { 361 puts("Board: MX53 LOCO\n"); 362 363 return 0; 364 } 365