]> Git Repo - u-boot.git/blob - board/technexion/pico-imx7d/spl.c
Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-sh
[u-boot.git] / board / technexion / pico-imx7d / spl.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2018 Technexion Ltd.
4  *
5  * Author: Richard Hu <[email protected]>
6  */
7
8 #include <config.h>
9 #include <cpu_func.h>
10 #include <init.h>
11 #include <asm/arch/clock.h>
12 #include <asm/arch/imx-regs.h>
13 #include <asm/arch/crm_regs.h>
14 #include <asm/arch/mx7-pins.h>
15 #include <asm/arch/sys_proto.h>
16 #include <asm/arch-mx7/mx7-ddr.h>
17 #include <asm/mach-imx/iomux-v3.h>
18 #include <asm/mach-imx/boot_mode.h>
19 #include <asm/gpio.h>
20 #include <asm/sections.h>
21 #include <fsl_esdhc_imx.h>
22 #include <spl.h>
23
24 #if defined(CONFIG_XPL_BUILD)
25
26 #ifdef CONFIG_SPL_OS_BOOT
27 int spl_start_uboot(void)
28 {
29         /* Break into full U-Boot on 'c' */
30         if (serial_tstc() && serial_getc() == 'c')
31                 return 1;
32
33         return 0;
34 }
35 #endif
36
37 static struct ddrc ddrc_regs_val = {
38         .mstr           = 0x01040001,
39         .rfshtmg        = 0x00400046,
40         .init1          = 0x00690000,
41         .init0          = 0x00020083,
42         .init3          = 0x09300004,
43         .init4          = 0x04080000,
44         .init5          = 0x00100004,
45         .rankctl        = 0x0000033F,
46         .dramtmg0       = 0x09081109,
47         .dramtmg1       = 0x0007020d,
48         .dramtmg2       = 0x03040407,
49         .dramtmg3       = 0x00002006,
50         .dramtmg4       = 0x04020205,
51         .dramtmg5       = 0x03030202,
52         .dramtmg8       = 0x00000803,
53         .zqctl0         = 0x00800020,
54         .dfitmg0        = 0x02098204,
55         .dfitmg1        = 0x00030303,
56         .dfiupd0        = 0x80400003,
57         .dfiupd1        = 0x00100020,
58         .dfiupd2        = 0x80100004,
59         .addrmap4       = 0x00000F0F,
60         .odtcfg         = 0x06000604,
61         .odtmap         = 0x00000001,
62         .rfshtmg        = 0x00400046,
63         .dramtmg0       = 0x09081109,
64         .addrmap0       = 0x0000001f,
65         .addrmap1       = 0x00080808,
66         .addrmap2       = 0x00000000,
67         .addrmap3       = 0x00000000,
68         .addrmap4       = 0x00000f0f,
69         .addrmap5       = 0x07070707,
70         .addrmap6       = 0x0f0f0707,
71 };
72
73 static struct ddrc_mp ddrc_mp_val = {
74         .pctrl_0        = 0x00000001,
75 };
76
77 static struct ddr_phy ddr_phy_regs_val = {
78         .phy_con0       = 0x17420f40,
79         .phy_con1       = 0x10210100,
80         .phy_con4       = 0x00060807,
81         .mdll_con0      = 0x1010007e,
82         .drvds_con0     = 0x00000d6e,
83         .cmd_sdll_con0  = 0x00000010,
84         .offset_lp_con0 = 0x0000000f,
85         .offset_rd_con0 = 0x08080808,
86         .offset_wr_con0 = 0x08080808,
87 };
88
89 static struct mx7_calibration calib_param = {
90         .num_val        = 5,
91         .values         = {
92                 0x0E407304,
93                 0x0E447304,
94                 0x0E447306,
95                 0x0E447304,
96                 0x0E447304,
97         },
98 };
99
100 static void gpr_init(void)
101 {
102         struct iomuxc_gpr_base_regs *gpr_regs =
103                 (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
104         writel(0x4F400005, &gpr_regs->gpr[1]);
105 }
106
107 /*
108  * Revision Detection
109  *
110  *   GPIO1_12           GPIO1_13
111  *     0                0           1GB DDR3
112  *     0                1           2GB DDR3
113  *     1                0           512MB DDR3
114  */
115
116 static int imx7d_pico_detect_board(void)
117 {
118         gpio_direction_input(IMX_GPIO_NR(1, 12));
119         gpio_direction_input(IMX_GPIO_NR(1, 13));
120
121         return gpio_get_value(IMX_GPIO_NR(1, 12)) << 1 |
122                gpio_get_value(IMX_GPIO_NR(1, 13));
123 }
124
125 static void ddr_init(void)
126 {
127         switch (imx7d_pico_detect_board()) {
128         case 0:
129                 ddrc_regs_val.addrmap6  = 0x0f070707;
130                 break;
131         case 1:
132                 ddrc_regs_val.addrmap0  = 0x0000001f;
133                 ddrc_regs_val.addrmap1  = 0x00181818;
134                 ddrc_regs_val.addrmap4  = 0x00000f0f;
135                 ddrc_regs_val.addrmap5  = 0x04040404;
136                 ddrc_regs_val.addrmap6  = 0x04040404;
137                 break;
138         }
139
140         mx7_dram_cfg(&ddrc_regs_val, &ddrc_mp_val, &ddr_phy_regs_val,
141                      &calib_param);
142 }
143
144 void board_init_f(ulong dummy)
145 {
146         arch_cpu_init();
147         gpr_init();
148         board_early_init_f();
149         timer_init();
150         preloader_console_init();
151         ddr_init();
152         memset(__bss_start, 0, __bss_end - __bss_start);
153         board_init_r(NULL, 0);
154 }
155
156 void reset_cpu(void)
157 {
158 }
159
160 #define USDHC_PAD_CTRL (PAD_CTL_DSE_3P3V_32OHM | PAD_CTL_SRE_SLOW | \
161         PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PUS_PU47KOHM)
162
163 #define USDHC1_CD_GPIO  IMX_GPIO_NR(5, 0)
164 /* EMMC/SD */
165 static const iomux_v3_cfg_t usdhc1_pads[] = {
166         MX7D_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
167         MX7D_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
168         MX7D_PAD_SD1_DATA0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
169         MX7D_PAD_SD1_DATA1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
170         MX7D_PAD_SD1_DATA2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
171         MX7D_PAD_SD1_DATA3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
172         MX7D_PAD_SD1_CD_B__GPIO5_IO0  | MUX_PAD_CTRL(USDHC_PAD_CTRL),
173 };
174
175 #define USDHC3_CD_GPIO IMX_GPIO_NR(1, 14)
176 static const iomux_v3_cfg_t usdhc3_emmc_pads[] = {
177         MX7D_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
178         MX7D_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
179         MX7D_PAD_SD3_DATA0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
180         MX7D_PAD_SD3_DATA1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
181         MX7D_PAD_SD3_DATA2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
182         MX7D_PAD_SD3_DATA3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
183         MX7D_PAD_SD3_DATA4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
184         MX7D_PAD_SD3_DATA5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
185         MX7D_PAD_SD3_DATA6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
186         MX7D_PAD_SD3_DATA7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
187         MX7D_PAD_GPIO1_IO14__GPIO1_IO14 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
188 };
189
190 static struct fsl_esdhc_cfg usdhc_cfg[2] = {
191         {USDHC3_BASE_ADDR},
192         {USDHC1_BASE_ADDR},
193 };
194
195 int board_mmc_getcd(struct mmc *mmc)
196 {
197         struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
198         int ret = 0;
199
200         switch (cfg->esdhc_base) {
201         case USDHC1_BASE_ADDR:
202                 ret = !gpio_get_value(USDHC1_CD_GPIO);
203                 break;
204         case USDHC3_BASE_ADDR:
205                 ret = !gpio_get_value(USDHC3_CD_GPIO);
206                 break;
207         }
208
209         return ret;
210 }
211
212 int board_mmc_init(struct bd_info *bis)
213 {
214         int ret;
215         u32 index;
216
217         /*
218          * Following map is done:
219          * (USDHC)      (Physical Port)
220          * usdhc3       SOM MicroSD/MMC
221          * usdhc1       Carrier board MicroSD
222          * Always set boot USDHC as mmc0
223          */
224
225         imx_iomux_v3_setup_multiple_pads(usdhc3_emmc_pads,
226                                          ARRAY_SIZE(usdhc3_emmc_pads));
227         gpio_direction_input(USDHC3_CD_GPIO);
228
229         imx_iomux_v3_setup_multiple_pads(usdhc1_pads,
230                                          ARRAY_SIZE(usdhc1_pads));
231         gpio_direction_input(USDHC1_CD_GPIO);
232
233         switch (get_boot_device()) {
234         case SD1_BOOT:
235                 usdhc_cfg[0].esdhc_base = USDHC1_BASE_ADDR;
236                 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
237                 usdhc_cfg[0].max_bus_width = 4;
238                 usdhc_cfg[1].esdhc_base = USDHC3_BASE_ADDR;
239                 usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
240                 usdhc_cfg[1].max_bus_width = 4;
241                 break;
242         case MMC3_BOOT:
243                 usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
244                 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
245                 usdhc_cfg[0].max_bus_width = 8;
246                 usdhc_cfg[1].esdhc_base = USDHC1_BASE_ADDR;
247                 usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
248                 usdhc_cfg[1].max_bus_width = 4;
249                 break;
250         case SD3_BOOT:
251         default:
252                 usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
253                 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
254                 usdhc_cfg[0].max_bus_width = 4;
255                 usdhc_cfg[1].esdhc_base = USDHC1_BASE_ADDR;
256                 usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
257                 usdhc_cfg[1].max_bus_width = 4;
258                 break;
259         }
260
261         for (index = 0; index < CFG_SYS_FSL_USDHC_NUM; ++index) {
262                 ret = fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
263                 if (ret)
264                         return ret;
265         }
266
267         return 0;
268 }
269 #endif
This page took 0.045281 seconds and 4 git commands to generate.