1 /* 2 * SPL specific code 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 <spl.h> 13 #include <asm/io.h> 14 #include <asm/gpio.h> 15 #include <asm/arch/mx6-ddr.h> 16 #include <asm/arch/clock.h> 17 #include <asm/arch/sys_proto.h> 18 #include <asm/imx-common/iomux-v3.h> 19 #include <fsl_esdhc.h> 20 #include "common.h" 21 22 DECLARE_GLOBAL_DATA_PTR; 23 24 enum ddr_config { 25 DDR_16BIT_256MB, 26 DDR_32BIT_512MB, 27 DDR_32BIT_1GB, 28 DDR_64BIT_1GB, 29 DDR_64BIT_2GB, 30 DDR_64BIT_4GB, 31 DDR_UNKNOWN, 32 }; 33 34 /* 35 * Below DRAM_RESET[DDR_SEL] = 0 which is incorrect according to 36 * Freescale QRM, but this is exactly the value used by the automatic 37 * calibration script and it works also in all our tests, so we leave 38 * it as is at this point. 39 */ 40 #define CM_FX6_DDR_IOMUX_CFG \ 41 .dram_sdqs0 = 0x00000038, \ 42 .dram_sdqs1 = 0x00000038, \ 43 .dram_sdqs2 = 0x00000038, \ 44 .dram_sdqs3 = 0x00000038, \ 45 .dram_sdqs4 = 0x00000038, \ 46 .dram_sdqs5 = 0x00000038, \ 47 .dram_sdqs6 = 0x00000038, \ 48 .dram_sdqs7 = 0x00000038, \ 49 .dram_dqm0 = 0x00000038, \ 50 .dram_dqm1 = 0x00000038, \ 51 .dram_dqm2 = 0x00000038, \ 52 .dram_dqm3 = 0x00000038, \ 53 .dram_dqm4 = 0x00000038, \ 54 .dram_dqm5 = 0x00000038, \ 55 .dram_dqm6 = 0x00000038, \ 56 .dram_dqm7 = 0x00000038, \ 57 .dram_cas = 0x00000038, \ 58 .dram_ras = 0x00000038, \ 59 .dram_sdclk_0 = 0x00000038, \ 60 .dram_sdclk_1 = 0x00000038, \ 61 .dram_sdcke0 = 0x00003000, \ 62 .dram_sdcke1 = 0x00003000, \ 63 .dram_reset = 0x00000038, \ 64 .dram_sdba2 = 0x00000000, \ 65 .dram_sdodt0 = 0x00000038, \ 66 .dram_sdodt1 = 0x00000038, 67 68 #define CM_FX6_GPR_IOMUX_CFG \ 69 .grp_b0ds = 0x00000038, \ 70 .grp_b1ds = 0x00000038, \ 71 .grp_b2ds = 0x00000038, \ 72 .grp_b3ds = 0x00000038, \ 73 .grp_b4ds = 0x00000038, \ 74 .grp_b5ds = 0x00000038, \ 75 .grp_b6ds = 0x00000038, \ 76 .grp_b7ds = 0x00000038, \ 77 .grp_addds = 0x00000038, \ 78 .grp_ddrmode_ctl = 0x00020000, \ 79 .grp_ddrpke = 0x00000000, \ 80 .grp_ddrmode = 0x00020000, \ 81 .grp_ctlds = 0x00000038, \ 82 .grp_ddr_type = 0x000C0000, 83 84 static struct mx6sdl_iomux_ddr_regs ddr_iomux_s = { CM_FX6_DDR_IOMUX_CFG }; 85 static struct mx6sdl_iomux_grp_regs grp_iomux_s = { CM_FX6_GPR_IOMUX_CFG }; 86 static struct mx6dq_iomux_ddr_regs ddr_iomux_q = { CM_FX6_DDR_IOMUX_CFG }; 87 static struct mx6dq_iomux_grp_regs grp_iomux_q = { CM_FX6_GPR_IOMUX_CFG }; 88 89 static struct mx6_mmdc_calibration cm_fx6_calib_s = { 90 .p0_mpwldectrl0 = 0x005B0061, 91 .p0_mpwldectrl1 = 0x004F0055, 92 .p0_mpdgctrl0 = 0x0314030C, 93 .p0_mpdgctrl1 = 0x025C0268, 94 .p0_mprddlctl = 0x42464646, 95 .p0_mpwrdlctl = 0x36322C34, 96 }; 97 98 static struct mx6_ddr_sysinfo cm_fx6_sysinfo_s = { 99 .cs1_mirror = 1, 100 .cs_density = 16, 101 .bi_on = 1, 102 .rtt_nom = 1, 103 .rtt_wr = 0, 104 .ralat = 5, 105 .walat = 1, 106 .mif3_mode = 3, 107 .rst_to_cke = 0x23, 108 .sde_to_rst = 0x10, 109 }; 110 111 static struct mx6_ddr3_cfg cm_fx6_ddr3_cfg_s = { 112 .mem_speed = 800, 113 .density = 4, 114 .rowaddr = 14, 115 .coladdr = 10, 116 .pagesz = 2, 117 .trcd = 1800, 118 .trcmin = 5200, 119 .trasmin = 3600, 120 .SRT = 0, 121 }; 122 123 static void spl_mx6s_dram_init(enum ddr_config dram_config, bool reset) 124 { 125 if (reset) 126 ((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2; 127 128 switch (dram_config) { 129 case DDR_16BIT_256MB: 130 cm_fx6_sysinfo_s.dsize = 0; 131 cm_fx6_sysinfo_s.ncs = 1; 132 break; 133 case DDR_32BIT_512MB: 134 cm_fx6_sysinfo_s.dsize = 1; 135 cm_fx6_sysinfo_s.ncs = 1; 136 break; 137 case DDR_32BIT_1GB: 138 cm_fx6_sysinfo_s.dsize = 1; 139 cm_fx6_sysinfo_s.ncs = 2; 140 break; 141 default: 142 puts("Tried to setup invalid DDR configuration\n"); 143 hang(); 144 } 145 146 mx6_dram_cfg(&cm_fx6_sysinfo_s, &cm_fx6_calib_s, &cm_fx6_ddr3_cfg_s); 147 udelay(100); 148 } 149 150 static struct mx6_mmdc_calibration cm_fx6_calib_q = { 151 .p0_mpwldectrl0 = 0x00630068, 152 .p0_mpwldectrl1 = 0x0068005D, 153 .p0_mpdgctrl0 = 0x04140428, 154 .p0_mpdgctrl1 = 0x037C037C, 155 .p0_mprddlctl = 0x3C30303A, 156 .p0_mpwrdlctl = 0x3A344038, 157 .p1_mpwldectrl0 = 0x0035004C, 158 .p1_mpwldectrl1 = 0x00170026, 159 .p1_mpdgctrl0 = 0x0374037C, 160 .p1_mpdgctrl1 = 0x0350032C, 161 .p1_mprddlctl = 0x30322A3C, 162 .p1_mpwrdlctl = 0x48304A3E, 163 }; 164 165 static struct mx6_ddr_sysinfo cm_fx6_sysinfo_q = { 166 .cs_density = 16, 167 .cs1_mirror = 1, 168 .bi_on = 1, 169 .rtt_nom = 1, 170 .rtt_wr = 0, 171 .ralat = 5, 172 .walat = 1, 173 .mif3_mode = 3, 174 .rst_to_cke = 0x23, 175 .sde_to_rst = 0x10, 176 }; 177 178 static struct mx6_ddr3_cfg cm_fx6_ddr3_cfg_q = { 179 .mem_speed = 1066, 180 .density = 4, 181 .rowaddr = 14, 182 .coladdr = 10, 183 .pagesz = 2, 184 .trcd = 1324, 185 .trcmin = 59500, 186 .trasmin = 9750, 187 .SRT = 0, 188 }; 189 190 static void spl_mx6q_dram_init(enum ddr_config dram_config, bool reset) 191 { 192 if (reset) 193 ((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2; 194 195 cm_fx6_ddr3_cfg_q.rowaddr = 14; 196 switch (dram_config) { 197 case DDR_16BIT_256MB: 198 cm_fx6_sysinfo_q.dsize = 0; 199 cm_fx6_sysinfo_q.ncs = 1; 200 break; 201 case DDR_32BIT_512MB: 202 cm_fx6_sysinfo_q.dsize = 1; 203 cm_fx6_sysinfo_q.ncs = 1; 204 break; 205 case DDR_64BIT_1GB: 206 cm_fx6_sysinfo_q.dsize = 2; 207 cm_fx6_sysinfo_q.ncs = 1; 208 break; 209 case DDR_64BIT_2GB: 210 cm_fx6_sysinfo_q.dsize = 2; 211 cm_fx6_sysinfo_q.ncs = 2; 212 break; 213 case DDR_64BIT_4GB: 214 cm_fx6_sysinfo_q.dsize = 2; 215 cm_fx6_sysinfo_q.ncs = 2; 216 cm_fx6_ddr3_cfg_q.rowaddr = 15; 217 break; 218 default: 219 puts("Tried to setup invalid DDR configuration\n"); 220 hang(); 221 } 222 223 mx6_dram_cfg(&cm_fx6_sysinfo_q, &cm_fx6_calib_q, &cm_fx6_ddr3_cfg_q); 224 udelay(100); 225 } 226 227 static int cm_fx6_spl_dram_init(void) 228 { 229 unsigned long bank1_size, bank2_size; 230 231 switch (get_cpu_type()) { 232 case MXC_CPU_MX6SOLO: 233 mx6sdl_dram_iocfg(64, &ddr_iomux_s, &grp_iomux_s); 234 235 spl_mx6s_dram_init(DDR_32BIT_1GB, false); 236 bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000); 237 if (bank1_size == 0x40000000) 238 return 0; 239 240 if (bank1_size == 0x20000000) { 241 spl_mx6s_dram_init(DDR_32BIT_512MB, true); 242 return 0; 243 } 244 245 spl_mx6s_dram_init(DDR_16BIT_256MB, true); 246 bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000); 247 if (bank1_size == 0x10000000) 248 return 0; 249 250 break; 251 case MXC_CPU_MX6D: 252 case MXC_CPU_MX6Q: 253 mx6dq_dram_iocfg(64, &ddr_iomux_q, &grp_iomux_q); 254 255 spl_mx6q_dram_init(DDR_64BIT_4GB, false); 256 bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000); 257 if (bank1_size == 0x80000000) 258 return 0; 259 260 if (bank1_size == 0x40000000) { 261 bank2_size = get_ram_size((long int *)PHYS_SDRAM_2, 262 0x80000000); 263 if (bank2_size == 0x40000000) { 264 /* Don't do a full reset here */ 265 spl_mx6q_dram_init(DDR_64BIT_2GB, false); 266 } else { 267 spl_mx6q_dram_init(DDR_64BIT_1GB, true); 268 } 269 270 return 0; 271 } 272 273 spl_mx6q_dram_init(DDR_32BIT_512MB, true); 274 bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000); 275 if (bank1_size == 0x20000000) 276 return 0; 277 278 spl_mx6q_dram_init(DDR_16BIT_256MB, true); 279 bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000); 280 if (bank1_size == 0x10000000) 281 return 0; 282 283 break; 284 } 285 286 return -1; 287 } 288 289 static iomux_v3_cfg_t const uart4_pads[] = { 290 IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), 291 IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), 292 }; 293 294 static void cm_fx6_setup_uart(void) 295 { 296 SETUP_IOMUX_PADS(uart4_pads); 297 enable_uart_clk(1); 298 } 299 300 #ifdef CONFIG_SPL_SPI_SUPPORT 301 static void cm_fx6_setup_ecspi(void) 302 { 303 cm_fx6_set_ecspi_iomux(); 304 enable_cspi_clock(1, 0); 305 } 306 #else 307 static void cm_fx6_setup_ecspi(void) { } 308 #endif 309 310 void board_init_f(ulong dummy) 311 { 312 gd = &gdata; 313 arch_cpu_init(); 314 timer_init(); 315 cm_fx6_setup_ecspi(); 316 cm_fx6_setup_uart(); 317 get_clocks(); 318 preloader_console_init(); 319 gpio_direction_output(CM_FX6_GREEN_LED, 1); 320 if (cm_fx6_spl_dram_init()) { 321 puts("!!!ERROR!!! DRAM detection failed!!!\n"); 322 hang(); 323 } 324 325 memset(__bss_start, 0, __bss_end - __bss_start); 326 board_init_r(NULL, 0); 327 } 328 329 void spl_board_init(void) 330 { 331 u32 boot_device = spl_boot_device(); 332 333 if (boot_device == BOOT_DEVICE_SPI) 334 puts("Booting from SPI flash\n"); 335 else if (boot_device == BOOT_DEVICE_MMC1) 336 puts("Booting from MMC\n"); 337 else 338 puts("Unknown boot device\n"); 339 } 340 341 #ifdef CONFIG_SPL_MMC_SUPPORT 342 static struct fsl_esdhc_cfg usdhc_cfg = { 343 .esdhc_base = USDHC3_BASE_ADDR, 344 .max_bus_width = 4, 345 }; 346 347 int board_mmc_init(bd_t *bis) 348 { 349 cm_fx6_set_usdhc_iomux(); 350 351 usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); 352 353 return fsl_esdhc_initialize(bis, &usdhc_cfg); 354 } 355 #endif 356