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