1 /* 2 * SPL board functions for CompuLab CL-SOM-iMX7 module 3 * 4 * (C) Copyright 2017 CompuLab, Ltd. http://www.compulab.com 5 * 6 * Author: Uri Mashiach <uri.mashiach@compulab.co.il> 7 * 8 * SPDX-License-Identifier: GPL-2.0+ 9 */ 10 11 #include <common.h> 12 #include <spl.h> 13 #include <fsl_esdhc.h> 14 #include <asm/mach-imx/iomux-v3.h> 15 #include <asm/arch-mx7/mx7-pins.h> 16 #include <asm/arch-mx7/clock.h> 17 #include <asm/arch-mx7/mx7-ddr.h> 18 #include "common.h" 19 20 #ifdef CONFIG_FSL_ESDHC 21 22 static struct fsl_esdhc_cfg cl_som_imx7_spl_usdhc_cfg = { 23 USDHC1_BASE_ADDR, 0, 4}; 24 25 int board_mmc_init(bd_t *bis) 26 { 27 cl_som_imx7_usdhc1_pads_set(); 28 cl_som_imx7_spl_usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); 29 return fsl_esdhc_initialize(bis, &cl_som_imx7_spl_usdhc_cfg); 30 } 31 #endif /* CONFIG_FSL_ESDHC */ 32 33 static iomux_v3_cfg_t const led_pads[] = { 34 MX7D_PAD_SAI1_TX_SYNC__GPIO6_IO14 | MUX_PAD_CTRL(PAD_CTL_PUS_PU5KOHM | 35 PAD_CTL_PUE | PAD_CTL_SRE_SLOW) 36 }; 37 38 static struct ddrc cl_som_imx7_spl_ddrc_regs_val = { 39 .init1 = 0x00690000, 40 .init0 = 0x00020083, 41 .init3 = 0x09300004, 42 .init4 = 0x04080000, 43 .init5 = 0x00100004, 44 .rankctl = 0x0000033F, 45 .dramtmg1 = 0x0007020E, 46 .dramtmg2 = 0x03040407, 47 .dramtmg3 = 0x00002006, 48 .dramtmg4 = 0x04020305, 49 .dramtmg5 = 0x03030202, 50 .dramtmg8 = 0x00000803, 51 .zqctl0 = 0x00810021, 52 .dfitmg0 = 0x02098204, 53 .dfitmg1 = 0x00030303, 54 .dfiupd0 = 0x80400003, 55 .dfiupd1 = 0x00100020, 56 .dfiupd2 = 0x80100004, 57 .addrmap4 = 0x00000F0F, 58 .odtcfg = 0x06000604, 59 .odtmap = 0x00000001, 60 }; 61 62 static struct ddrc_mp cl_som_imx7_spl_ddrc_mp_val = { 63 .pctrl_0 = 0x00000001, 64 }; 65 66 static struct ddr_phy cl_som_imx7_spl_ddr_phy_regs_val = { 67 .phy_con0 = 0x17420F40, 68 .phy_con1 = 0x10210100, 69 .phy_con4 = 0x00060807, 70 .mdll_con0 = 0x1010007E, 71 .drvds_con0 = 0x00000D6E, 72 .cmd_sdll_con0 = 0x00000010, 73 .offset_lp_con0 = 0x0000000F, 74 }; 75 76 struct mx7_calibration cl_som_imx7_spl_calib_param = { 77 .num_val = 5, 78 .values = { 79 0x0E407304, 80 0x0E447304, 81 0x0E447306, 82 0x0E447304, 83 0x0E407304, 84 }, 85 }; 86 87 static void cl_som_imx7_spl_dram_cfg_size(u32 ram_size) 88 { 89 switch (ram_size) { 90 case SZ_256M: 91 cl_som_imx7_spl_ddrc_regs_val.mstr = 0x01041001; 92 cl_som_imx7_spl_ddrc_regs_val.rfshtmg = 0x00400046; 93 cl_som_imx7_spl_ddrc_regs_val.dramtmg0 = 0x090E1109; 94 cl_som_imx7_spl_ddrc_regs_val.addrmap0 = 0x00000014; 95 cl_som_imx7_spl_ddrc_regs_val.addrmap1 = 0x00151515; 96 cl_som_imx7_spl_ddrc_regs_val.addrmap5 = 0x03030303; 97 cl_som_imx7_spl_ddrc_regs_val.addrmap6 = 0x0F0F0303; 98 cl_som_imx7_spl_ddr_phy_regs_val.offset_rd_con0 = 0x0C0C0C0C; 99 cl_som_imx7_spl_ddr_phy_regs_val.offset_wr_con0 = 0x04040404; 100 break; 101 case SZ_512M: 102 cl_som_imx7_spl_ddrc_regs_val.mstr = 0x01040001; 103 cl_som_imx7_spl_ddrc_regs_val.rfshtmg = 0x00400046; 104 cl_som_imx7_spl_ddrc_regs_val.dramtmg0 = 0x090E1109; 105 cl_som_imx7_spl_ddrc_regs_val.addrmap0 = 0x00000015; 106 cl_som_imx7_spl_ddrc_regs_val.addrmap1 = 0x00161616; 107 cl_som_imx7_spl_ddrc_regs_val.addrmap5 = 0x04040404; 108 cl_som_imx7_spl_ddrc_regs_val.addrmap6 = 0x0F0F0404; 109 cl_som_imx7_spl_ddr_phy_regs_val.offset_rd_con0 = 0x0C0C0C0C; 110 cl_som_imx7_spl_ddr_phy_regs_val.offset_wr_con0 = 0x04040404; 111 break; 112 case SZ_1G: 113 cl_som_imx7_spl_ddrc_regs_val.mstr = 0x01040001; 114 cl_som_imx7_spl_ddrc_regs_val.rfshtmg = 0x00400046; 115 cl_som_imx7_spl_ddrc_regs_val.dramtmg0 = 0x090E1109; 116 cl_som_imx7_spl_ddrc_regs_val.addrmap0 = 0x00000016; 117 cl_som_imx7_spl_ddrc_regs_val.addrmap1 = 0x00171717; 118 cl_som_imx7_spl_ddrc_regs_val.addrmap5 = 0x04040404; 119 cl_som_imx7_spl_ddrc_regs_val.addrmap6 = 0x0F040404; 120 cl_som_imx7_spl_ddr_phy_regs_val.offset_rd_con0 = 0x0A0A0A0A; 121 cl_som_imx7_spl_ddr_phy_regs_val.offset_wr_con0 = 0x02020202; 122 break; 123 case SZ_2G: 124 cl_som_imx7_spl_ddrc_regs_val.mstr = 0x01040001; 125 cl_som_imx7_spl_ddrc_regs_val.rfshtmg = 0x0040005E; 126 cl_som_imx7_spl_ddrc_regs_val.dramtmg0 = 0x090E110A; 127 cl_som_imx7_spl_ddrc_regs_val.addrmap0 = 0x00000018; 128 cl_som_imx7_spl_ddrc_regs_val.addrmap1 = 0x00181818; 129 cl_som_imx7_spl_ddrc_regs_val.addrmap5 = 0x04040404; 130 cl_som_imx7_spl_ddrc_regs_val.addrmap6 = 0x04040404; 131 cl_som_imx7_spl_ddr_phy_regs_val.offset_rd_con0 = 0x0A0A0A0A; 132 cl_som_imx7_spl_ddr_phy_regs_val.offset_wr_con0 = 0x04040404; 133 break; 134 } 135 136 mx7_dram_cfg(&cl_som_imx7_spl_ddrc_regs_val, 137 &cl_som_imx7_spl_ddrc_mp_val, 138 &cl_som_imx7_spl_ddr_phy_regs_val, 139 &cl_som_imx7_spl_calib_param); 140 } 141 142 static void cl_som_imx7_spl_dram_cfg(void) 143 { 144 ulong ram_size_test, ram_size = 0; 145 146 for (ram_size = SZ_2G; ram_size >= SZ_256M; ram_size >>= 1) { 147 cl_som_imx7_spl_dram_cfg_size(ram_size); 148 ram_size_test = get_ram_size((long int *)PHYS_SDRAM, ram_size); 149 if (ram_size_test == ram_size) 150 break; 151 } 152 153 if (ram_size < SZ_256M) { 154 puts("!!!ERROR!!! DRAM detection failed!!!\n"); 155 hang(); 156 } 157 } 158 159 #ifdef CONFIG_SPL_SPI_SUPPORT 160 161 static void cl_som_imx7_spl_spi_init(void) 162 { 163 cl_som_imx7_espi1_pads_set(); 164 } 165 #else /* !CONFIG_SPL_SPI_SUPPORT */ 166 static void cl_som_imx7_spl_spi_init(void) {} 167 #endif /* CONFIG_SPL_SPI_SUPPORT */ 168 169 void board_init_f(ulong dummy) 170 { 171 imx_iomux_v3_setup_multiple_pads(led_pads, 1); 172 /* setup AIPS and disable watchdog */ 173 arch_cpu_init(); 174 /* setup GP timer */ 175 timer_init(); 176 cl_som_imx7_spl_spi_init(); 177 cl_som_imx7_uart1_pads_set(); 178 /* UART clocks enabled and gd valid - init serial console */ 179 preloader_console_init(); 180 /* DRAM detection */ 181 cl_som_imx7_spl_dram_cfg(); 182 /* Clear the BSS. */ 183 memset(__bss_start, 0, __bss_end - __bss_start); 184 /* load/boot image from boot device */ 185 board_init_r(NULL, 0); 186 } 187 188 void spl_board_init(void) 189 { 190 u32 boot_device = spl_boot_device(); 191 192 if (boot_device == BOOT_DEVICE_SPI) 193 puts("Booting from SPI flash\n"); 194 else if (boot_device == BOOT_DEVICE_MMC1) 195 puts("Booting from SD card\n"); 196 else 197 puts("Unknown boot device\n"); 198 } 199 200 void board_boot_order(u32 *spl_boot_list) 201 { 202 spl_boot_list[0] = spl_boot_device(); 203 switch (spl_boot_list[0]) { 204 case BOOT_DEVICE_SPI: 205 spl_boot_list[1] = BOOT_DEVICE_MMC1; 206 break; 207 case BOOT_DEVICE_MMC1: 208 spl_boot_list[1] = BOOT_DEVICE_SPI; 209 break; 210 } 211 } 212