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