1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
26963204cSIlya Ledvich /*
36963204cSIlya Ledvich * SPL board functions for CompuLab CL-SOM-iMX7 module
46963204cSIlya Ledvich *
56963204cSIlya Ledvich * (C) Copyright 2017 CompuLab, Ltd. http://www.compulab.com
66963204cSIlya Ledvich *
76963204cSIlya Ledvich * Author: Uri Mashiach <uri.mashiach@compulab.co.il>
86963204cSIlya Ledvich */
96963204cSIlya Ledvich
106963204cSIlya Ledvich #include <common.h>
116963204cSIlya Ledvich #include <spl.h>
126963204cSIlya Ledvich #include <fsl_esdhc.h>
136963204cSIlya Ledvich #include <asm/mach-imx/iomux-v3.h>
146963204cSIlya Ledvich #include <asm/arch-mx7/mx7-pins.h>
156963204cSIlya Ledvich #include <asm/arch-mx7/clock.h>
166963204cSIlya Ledvich #include <asm/arch-mx7/mx7-ddr.h>
176963204cSIlya Ledvich #include "common.h"
186963204cSIlya Ledvich
196963204cSIlya Ledvich #ifdef CONFIG_FSL_ESDHC
206963204cSIlya Ledvich
216963204cSIlya Ledvich static struct fsl_esdhc_cfg cl_som_imx7_spl_usdhc_cfg = {
226963204cSIlya Ledvich USDHC1_BASE_ADDR, 0, 4};
236963204cSIlya Ledvich
board_mmc_init(bd_t * bis)246963204cSIlya Ledvich int board_mmc_init(bd_t *bis)
256963204cSIlya Ledvich {
266963204cSIlya Ledvich cl_som_imx7_usdhc1_pads_set();
276963204cSIlya Ledvich cl_som_imx7_spl_usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
286963204cSIlya Ledvich return fsl_esdhc_initialize(bis, &cl_som_imx7_spl_usdhc_cfg);
296963204cSIlya Ledvich }
306963204cSIlya Ledvich #endif /* CONFIG_FSL_ESDHC */
316963204cSIlya Ledvich
326963204cSIlya Ledvich static iomux_v3_cfg_t const led_pads[] = {
336963204cSIlya Ledvich MX7D_PAD_SAI1_TX_SYNC__GPIO6_IO14 | MUX_PAD_CTRL(PAD_CTL_PUS_PU5KOHM |
346963204cSIlya Ledvich PAD_CTL_PUE | PAD_CTL_SRE_SLOW)
356963204cSIlya Ledvich };
366963204cSIlya Ledvich
376963204cSIlya Ledvich static struct ddrc cl_som_imx7_spl_ddrc_regs_val = {
386963204cSIlya Ledvich .init1 = 0x00690000,
396963204cSIlya Ledvich .init0 = 0x00020083,
406963204cSIlya Ledvich .init3 = 0x09300004,
416963204cSIlya Ledvich .init4 = 0x04080000,
426963204cSIlya Ledvich .init5 = 0x00100004,
436963204cSIlya Ledvich .rankctl = 0x0000033F,
446963204cSIlya Ledvich .dramtmg1 = 0x0007020E,
456963204cSIlya Ledvich .dramtmg2 = 0x03040407,
466963204cSIlya Ledvich .dramtmg3 = 0x00002006,
476963204cSIlya Ledvich .dramtmg4 = 0x04020305,
486963204cSIlya Ledvich .dramtmg5 = 0x03030202,
496963204cSIlya Ledvich .dramtmg8 = 0x00000803,
506963204cSIlya Ledvich .zqctl0 = 0x00810021,
516963204cSIlya Ledvich .dfitmg0 = 0x02098204,
526963204cSIlya Ledvich .dfitmg1 = 0x00030303,
536963204cSIlya Ledvich .dfiupd0 = 0x80400003,
546963204cSIlya Ledvich .dfiupd1 = 0x00100020,
556963204cSIlya Ledvich .dfiupd2 = 0x80100004,
566963204cSIlya Ledvich .addrmap4 = 0x00000F0F,
576963204cSIlya Ledvich .odtcfg = 0x06000604,
586963204cSIlya Ledvich .odtmap = 0x00000001,
596963204cSIlya Ledvich };
606963204cSIlya Ledvich
616963204cSIlya Ledvich static struct ddrc_mp cl_som_imx7_spl_ddrc_mp_val = {
626963204cSIlya Ledvich .pctrl_0 = 0x00000001,
636963204cSIlya Ledvich };
646963204cSIlya Ledvich
656963204cSIlya Ledvich static struct ddr_phy cl_som_imx7_spl_ddr_phy_regs_val = {
666963204cSIlya Ledvich .phy_con0 = 0x17420F40,
676963204cSIlya Ledvich .phy_con1 = 0x10210100,
686963204cSIlya Ledvich .phy_con4 = 0x00060807,
696963204cSIlya Ledvich .mdll_con0 = 0x1010007E,
706963204cSIlya Ledvich .drvds_con0 = 0x00000D6E,
716963204cSIlya Ledvich .cmd_sdll_con0 = 0x00000010,
726963204cSIlya Ledvich .offset_lp_con0 = 0x0000000F,
736963204cSIlya Ledvich };
746963204cSIlya Ledvich
756963204cSIlya Ledvich struct mx7_calibration cl_som_imx7_spl_calib_param = {
766963204cSIlya Ledvich .num_val = 5,
776963204cSIlya Ledvich .values = {
786963204cSIlya Ledvich 0x0E407304,
796963204cSIlya Ledvich 0x0E447304,
806963204cSIlya Ledvich 0x0E447306,
816963204cSIlya Ledvich 0x0E447304,
826963204cSIlya Ledvich 0x0E407304,
836963204cSIlya Ledvich },
846963204cSIlya Ledvich };
856963204cSIlya Ledvich
cl_som_imx7_spl_dram_cfg_size(u32 ram_size)866963204cSIlya Ledvich static void cl_som_imx7_spl_dram_cfg_size(u32 ram_size)
876963204cSIlya Ledvich {
886963204cSIlya Ledvich switch (ram_size) {
896963204cSIlya Ledvich case SZ_256M:
906963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.mstr = 0x01041001;
916963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.rfshtmg = 0x00400046;
926963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.dramtmg0 = 0x090E1109;
936963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap0 = 0x00000014;
946963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap1 = 0x00151515;
956963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap5 = 0x03030303;
966963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap6 = 0x0F0F0303;
976963204cSIlya Ledvich cl_som_imx7_spl_ddr_phy_regs_val.offset_rd_con0 = 0x0C0C0C0C;
986963204cSIlya Ledvich cl_som_imx7_spl_ddr_phy_regs_val.offset_wr_con0 = 0x04040404;
996963204cSIlya Ledvich break;
1006963204cSIlya Ledvich case SZ_512M:
1016963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.mstr = 0x01040001;
1026963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.rfshtmg = 0x00400046;
1036963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.dramtmg0 = 0x090E1109;
1046963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap0 = 0x00000015;
1056963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap1 = 0x00161616;
1066963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap5 = 0x04040404;
1076963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap6 = 0x0F0F0404;
1086963204cSIlya Ledvich cl_som_imx7_spl_ddr_phy_regs_val.offset_rd_con0 = 0x0C0C0C0C;
1096963204cSIlya Ledvich cl_som_imx7_spl_ddr_phy_regs_val.offset_wr_con0 = 0x04040404;
1106963204cSIlya Ledvich break;
1116963204cSIlya Ledvich case SZ_1G:
1126963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.mstr = 0x01040001;
1136963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.rfshtmg = 0x00400046;
1146963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.dramtmg0 = 0x090E1109;
1156963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap0 = 0x00000016;
1166963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap1 = 0x00171717;
1176963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap5 = 0x04040404;
1186963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap6 = 0x0F040404;
1196963204cSIlya Ledvich cl_som_imx7_spl_ddr_phy_regs_val.offset_rd_con0 = 0x0A0A0A0A;
1206963204cSIlya Ledvich cl_som_imx7_spl_ddr_phy_regs_val.offset_wr_con0 = 0x02020202;
1216963204cSIlya Ledvich break;
1226963204cSIlya Ledvich case SZ_2G:
1236963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.mstr = 0x01040001;
1246963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.rfshtmg = 0x0040005E;
1256963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.dramtmg0 = 0x090E110A;
1266963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap0 = 0x00000018;
1276963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap1 = 0x00181818;
1286963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap5 = 0x04040404;
1296963204cSIlya Ledvich cl_som_imx7_spl_ddrc_regs_val.addrmap6 = 0x04040404;
1306963204cSIlya Ledvich cl_som_imx7_spl_ddr_phy_regs_val.offset_rd_con0 = 0x0A0A0A0A;
1316963204cSIlya Ledvich cl_som_imx7_spl_ddr_phy_regs_val.offset_wr_con0 = 0x04040404;
1326963204cSIlya Ledvich break;
1336963204cSIlya Ledvich }
1346963204cSIlya Ledvich
1356963204cSIlya Ledvich mx7_dram_cfg(&cl_som_imx7_spl_ddrc_regs_val,
1366963204cSIlya Ledvich &cl_som_imx7_spl_ddrc_mp_val,
1376963204cSIlya Ledvich &cl_som_imx7_spl_ddr_phy_regs_val,
1386963204cSIlya Ledvich &cl_som_imx7_spl_calib_param);
1396963204cSIlya Ledvich }
1406963204cSIlya Ledvich
cl_som_imx7_spl_dram_cfg(void)1416963204cSIlya Ledvich static void cl_som_imx7_spl_dram_cfg(void)
1426963204cSIlya Ledvich {
1436963204cSIlya Ledvich ulong ram_size_test, ram_size = 0;
1446963204cSIlya Ledvich
1456963204cSIlya Ledvich for (ram_size = SZ_2G; ram_size >= SZ_256M; ram_size >>= 1) {
1466963204cSIlya Ledvich cl_som_imx7_spl_dram_cfg_size(ram_size);
1476963204cSIlya Ledvich ram_size_test = get_ram_size((long int *)PHYS_SDRAM, ram_size);
1486963204cSIlya Ledvich if (ram_size_test == ram_size)
1496963204cSIlya Ledvich break;
1506963204cSIlya Ledvich }
1516963204cSIlya Ledvich
1526963204cSIlya Ledvich if (ram_size < SZ_256M) {
1536963204cSIlya Ledvich puts("!!!ERROR!!! DRAM detection failed!!!\n");
1546963204cSIlya Ledvich hang();
1556963204cSIlya Ledvich }
1566963204cSIlya Ledvich }
1576963204cSIlya Ledvich
1586963204cSIlya Ledvich #ifdef CONFIG_SPL_SPI_SUPPORT
1596963204cSIlya Ledvich
cl_som_imx7_spl_spi_init(void)1606963204cSIlya Ledvich static void cl_som_imx7_spl_spi_init(void)
1616963204cSIlya Ledvich {
1626963204cSIlya Ledvich cl_som_imx7_espi1_pads_set();
1636963204cSIlya Ledvich }
1646963204cSIlya Ledvich #else /* !CONFIG_SPL_SPI_SUPPORT */
cl_som_imx7_spl_spi_init(void)1656963204cSIlya Ledvich static void cl_som_imx7_spl_spi_init(void) {}
1666963204cSIlya Ledvich #endif /* CONFIG_SPL_SPI_SUPPORT */
1676963204cSIlya Ledvich
board_init_f(ulong dummy)1686963204cSIlya Ledvich void board_init_f(ulong dummy)
1696963204cSIlya Ledvich {
1706963204cSIlya Ledvich imx_iomux_v3_setup_multiple_pads(led_pads, 1);
1716963204cSIlya Ledvich /* setup AIPS and disable watchdog */
1726963204cSIlya Ledvich arch_cpu_init();
1736963204cSIlya Ledvich /* setup GP timer */
1746963204cSIlya Ledvich timer_init();
1756963204cSIlya Ledvich cl_som_imx7_spl_spi_init();
1766963204cSIlya Ledvich cl_som_imx7_uart1_pads_set();
1776963204cSIlya Ledvich /* UART clocks enabled and gd valid - init serial console */
1786963204cSIlya Ledvich preloader_console_init();
1796963204cSIlya Ledvich /* DRAM detection */
1806963204cSIlya Ledvich cl_som_imx7_spl_dram_cfg();
1816963204cSIlya Ledvich /* Clear the BSS. */
1826963204cSIlya Ledvich memset(__bss_start, 0, __bss_end - __bss_start);
1836963204cSIlya Ledvich /* load/boot image from boot device */
1846963204cSIlya Ledvich board_init_r(NULL, 0);
1856963204cSIlya Ledvich }
1866963204cSIlya Ledvich
spl_board_init(void)1876963204cSIlya Ledvich void spl_board_init(void)
1886963204cSIlya Ledvich {
1896963204cSIlya Ledvich u32 boot_device = spl_boot_device();
1906963204cSIlya Ledvich
1916963204cSIlya Ledvich if (boot_device == BOOT_DEVICE_SPI)
1926963204cSIlya Ledvich puts("Booting from SPI flash\n");
1936963204cSIlya Ledvich else if (boot_device == BOOT_DEVICE_MMC1)
1946963204cSIlya Ledvich puts("Booting from SD card\n");
1956963204cSIlya Ledvich else
1966963204cSIlya Ledvich puts("Unknown boot device\n");
1976963204cSIlya Ledvich }
1986963204cSIlya Ledvich
board_boot_order(u32 * spl_boot_list)1996963204cSIlya Ledvich void board_boot_order(u32 *spl_boot_list)
2006963204cSIlya Ledvich {
2016963204cSIlya Ledvich spl_boot_list[0] = spl_boot_device();
2026963204cSIlya Ledvich switch (spl_boot_list[0]) {
2036963204cSIlya Ledvich case BOOT_DEVICE_SPI:
2046963204cSIlya Ledvich spl_boot_list[1] = BOOT_DEVICE_MMC1;
2056963204cSIlya Ledvich break;
2066963204cSIlya Ledvich case BOOT_DEVICE_MMC1:
2076963204cSIlya Ledvich spl_boot_list[1] = BOOT_DEVICE_SPI;
2086963204cSIlya Ledvich break;
2096963204cSIlya Ledvich }
2106963204cSIlya Ledvich }
211