bdd9e0e3c38126d698207ea1f437b0d183aed640
[platform/kernel/u-boot.git] / board / engicam / icorem6_rqs / icorem6_rqs.c
1 /*
2  * Copyright (C) 2016 Amarula Solutions B.V.
3  * Copyright (C) 2016 Engicam S.r.l.
4  * Author: Jagan Teki <jagan@amarulasolutions.com>
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 #include <common.h>
10 #include <mmc.h>
11
12 #include <asm/io.h>
13 #include <asm/gpio.h>
14 #include <linux/sizes.h>
15
16 #include <asm/arch/clock.h>
17 #include <asm/arch/crm_regs.h>
18 #include <asm/arch/iomux.h>
19 #include <asm/arch/mx6-pins.h>
20 #include <asm/arch/sys_proto.h>
21 #include <asm/imx-common/iomux-v3.h>
22
23 #include "../common/board.h"
24
25 DECLARE_GLOBAL_DATA_PTR;
26
27 #ifdef CONFIG_ENV_IS_IN_MMC
28 int board_mmc_get_env_dev(int devno)
29 {
30         /* dev 0 for SD/eSD, dev 1 for MMC/eMMC */
31         return (devno == 3) ? 1 : 0;
32 }
33 #endif
34
35 int board_late_init(void)
36 {
37         switch ((imx6_src_get_boot_mode() & IMX6_BMODE_MASK) >>
38                         IMX6_BMODE_SHIFT) {
39         case IMX6_BMODE_SD:
40         case IMX6_BMODE_ESD:
41         case IMX6_BMODE_MMC:
42         case IMX6_BMODE_EMMC:
43 #ifdef CONFIG_ENV_IS_IN_MMC
44                 mmc_late_init();
45 #endif
46                 setenv("modeboot", "mmcboot");
47                 break;
48         default:
49                 setenv("modeboot", "");
50                 break;
51         }
52
53         if (is_mx6dq())
54                 setenv("fdt_file", "imx6q-icore-rqs.dtb");
55         else if(is_mx6dl() || is_mx6solo())
56                 setenv("fdt_file", "imx6dl-icore-rqs.dtb");
57
58         return 0;
59 }
60
61 #ifdef CONFIG_SPL_BUILD
62 #include <spl.h>
63
64 /* MMC board initialization is needed till adding DM support in SPL */
65 #if defined(CONFIG_FSL_ESDHC) && !defined(CONFIG_DM_MMC)
66 #include <mmc.h>
67 #include <fsl_esdhc.h>
68
69 #define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |             \
70         PAD_CTL_PUS_47K_UP  | PAD_CTL_SPEED_HIGH |               \
71         PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
72
73 static iomux_v3_cfg_t const usdhc3_pads[] = {
74         IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
75         IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
76         IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
77         IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
78         IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
79         IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
80 };
81
82 static iomux_v3_cfg_t const usdhc4_pads[] = {
83         IOMUX_PADS(PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
84         IOMUX_PADS(PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
85         IOMUX_PADS(PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
86         IOMUX_PADS(PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
87         IOMUX_PADS(PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
88         IOMUX_PADS(PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
89         IOMUX_PADS(PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
90         IOMUX_PADS(PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
91         IOMUX_PADS(PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
92         IOMUX_PADS(PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
93 };
94
95 struct fsl_esdhc_cfg usdhc_cfg[2] = {
96         {USDHC3_BASE_ADDR, 1, 4},
97         {USDHC4_BASE_ADDR, 1, 8},
98 };
99
100 int board_mmc_getcd(struct mmc *mmc)
101 {
102         struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
103         int ret = 0;
104
105         switch (cfg->esdhc_base) {
106         case USDHC3_BASE_ADDR:
107         case USDHC4_BASE_ADDR:
108                 ret = 1;
109                 break;
110         }
111
112         return ret;
113 }
114
115 int board_mmc_init(bd_t *bis)
116 {
117         int i, ret;
118
119         /*
120         * According to the board_mmc_init() the following map is done:
121         * (U-boot device node)    (Physical Port)
122         * mmc0                  USDHC3
123         * mmc1                  USDHC4
124         */
125         for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
126                 switch (i) {
127                 case 0:
128                         SETUP_IOMUX_PADS(usdhc3_pads);
129                         usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
130                         break;
131                 case 1:
132                         SETUP_IOMUX_PADS(usdhc4_pads);
133                         usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
134                         break;
135                 default:
136                         printf("Warning - USDHC%d controller not supporting\n",
137                                i + 1);
138                         return 0;
139                 }
140
141                 ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
142                 if (ret) {
143                         printf("Warning: failed to initialize mmc dev %d\n", i);
144                         return ret;
145                 }
146         }
147
148         return 0;
149 }
150
151 #ifdef CONFIG_ENV_IS_IN_MMC
152 void board_boot_order(u32 *spl_boot_list)
153 {
154         u32 bmode = imx6_src_get_boot_mode();
155         u8 boot_dev = BOOT_DEVICE_MMC1;
156
157         switch ((bmode & IMX6_BMODE_MASK) >> IMX6_BMODE_SHIFT) {
158         case IMX6_BMODE_SD:
159         case IMX6_BMODE_ESD:
160                 /* SD/eSD - BOOT_DEVICE_MMC1 */
161                 break;
162         case IMX6_BMODE_MMC:
163         case IMX6_BMODE_EMMC:
164                 /* MMC/eMMC */
165                 boot_dev = BOOT_DEVICE_MMC2;
166                 break;
167         default:
168                 /* Default - BOOT_DEVICE_MMC1 */
169                 printf("Wrong board boot order\n");
170                 break;
171         }
172
173         spl_boot_list[0] = boot_dev;
174 }
175 #endif
176 #endif
177
178 #ifdef CONFIG_SPL_LOAD_FIT
179 int board_fit_config_name_match(const char *name)
180 {
181         if (is_mx6dq() && !strcmp(name, "imx6q-icore-rqs"))
182                 return 0;
183         else if ((is_mx6dl() || is_mx6solo()) && !strcmp(name, "imx6dl-icore-rqs"))
184                 return 0;
185         else
186                 return -1;
187 }
188 #endif
189 #endif /* CONFIG_SPL_BUILD */