Merge branch 'master' of git://git.denx.de/u-boot-sunxi
[oweals/u-boot.git] / board / variscite / dart_6ul / spl.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2015-2019 Variscite Ltd.
4  * Copyright (C) 2019 Parthiban Nallathambi <parthitce@gmail.com>
5  */
6
7 #include <common.h>
8 #include <spl.h>
9 #include <asm/arch/clock.h>
10 #include <asm/io.h>
11 #include <asm/arch/mx6-ddr.h>
12 #include <asm/arch/mx6-pins.h>
13 #include <asm/arch/crm_regs.h>
14 #include <fsl_esdhc.h>
15
16 #define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |             \
17         PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
18         PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
19
20 static iomux_v3_cfg_t const uart1_pads[] = {
21         MX6_PAD_UART1_TX_DATA__UART1_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
22         MX6_PAD_UART1_RX_DATA__UART1_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
23 };
24
25 static void setup_iomux_uart(void)
26 {
27         imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
28 }
29
30 static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = {
31         .grp_addds = 0x00000030,
32         .grp_ddrmode_ctl = 0x00020000,
33         .grp_b0ds = 0x00000030,
34         .grp_ctlds = 0x00000030,
35         .grp_b1ds = 0x00000030,
36         .grp_ddrpke = 0x00000000,
37         .grp_ddrmode = 0x00020000,
38         .grp_ddr_type = 0x000c0000,
39 };
40
41 static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = {
42         .dram_dqm0 = 0x00000030,
43         .dram_dqm1 = 0x00000030,
44         .dram_ras = 0x00000030,
45         .dram_cas = 0x00000030,
46         .dram_odt0 = 0x00000030,
47         .dram_odt1 = 0x00000030,
48         .dram_sdba2 = 0x00000000,
49         .dram_sdclk_0 = 0x00000008,
50         .dram_sdqs0 = 0x00000038,
51         .dram_sdqs1 = 0x00000030,
52         .dram_reset = 0x00000030,
53 };
54
55 static struct mx6_mmdc_calibration mx6_mmcd_calib = {
56         .p0_mpwldectrl0 = 0x00000000,
57         .p0_mpdgctrl0   = 0x414C0158,
58         .p0_mprddlctl   = 0x40403A3A,
59         .p0_mpwrdlctl   = 0x40405A56,
60 };
61
62 struct mx6_ddr_sysinfo ddr_sysinfo = {
63         .dsize = 0,
64         .cs_density = 20,
65         .ncs = 1,
66         .cs1_mirror = 0,
67         .rtt_wr = 2,
68         .rtt_nom = 1,           /* RTT_Nom = RZQ/2 */
69         .walat = 1,             /* Write additional latency */
70         .ralat = 5,             /* Read additional latency */
71         .mif3_mode = 3,         /* Command prediction working mode */
72         .bi_on = 1,             /* Bank interleaving enabled */
73         .sde_to_rst = 0x10,     /* 14 cycles, 200us (JEDEC default) */
74         .rst_to_cke = 0x23,     /* 33 cycles, 500us (JEDEC default) */
75 };
76
77 static struct mx6_ddr3_cfg mem_ddr = {
78         .mem_speed = 800,
79         .density = 4,
80         .width = 16,
81         .banks = 8,
82         .rowaddr = 15,
83         .coladdr = 10,
84         .pagesz = 2,
85         .trcd = 1375,
86         .trcmin = 4875,
87         .trasmin = 3500,
88 };
89
90 static void ccgr_init(void)
91 {
92         struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
93
94         writel(0xFFFFFFFF, &ccm->CCGR0);
95         writel(0xFFFFFFFF, &ccm->CCGR1);
96         writel(0xFFFFFFFF, &ccm->CCGR2);
97         writel(0xFFFFFFFF, &ccm->CCGR3);
98         writel(0xFFFFFFFF, &ccm->CCGR4);
99         writel(0xFFFFFFFF, &ccm->CCGR5);
100         writel(0xFFFFFFFF, &ccm->CCGR6);
101         writel(0xFFFFFFFF, &ccm->CCGR7);
102         /* Enable Audio Clock for SOM codec */
103         writel(0x01130100, (long *)CCM_CCOSR);
104 }
105
106 static void spl_dram_init(void)
107 {
108         mx6ul_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
109         mx6_dram_cfg(&ddr_sysinfo, &mx6_mmcd_calib, &mem_ddr);
110 }
111
112 #define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |             \
113         PAD_CTL_PUS_22K_UP  | PAD_CTL_SPEED_LOW |               \
114         PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
115 static iomux_v3_cfg_t const usdhc1_pads[] = {
116         MX6_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
117         MX6_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
118         MX6_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
119         MX6_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
120         MX6_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
121         MX6_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
122 };
123
124 #ifndef CONFIG_NAND_MXS
125 static iomux_v3_cfg_t const usdhc2_pads[] = {
126         MX6_PAD_NAND_RE_B__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
127         MX6_PAD_NAND_WE_B__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
128         MX6_PAD_NAND_DATA00__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
129         MX6_PAD_NAND_DATA01__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
130         MX6_PAD_NAND_DATA02__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
131         MX6_PAD_NAND_DATA03__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
132         MX6_PAD_NAND_DATA04__USDHC2_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
133         MX6_PAD_NAND_DATA05__USDHC2_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
134         MX6_PAD_NAND_DATA06__USDHC2_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
135         MX6_PAD_NAND_DATA07__USDHC2_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
136 };
137 #endif
138
139 static struct fsl_esdhc_cfg usdhc_cfg[] = {
140         {
141                 .esdhc_base = USDHC1_BASE_ADDR,
142                 .max_bus_width = 4,
143         },
144 #ifndef CONFIG_NAND_MXS
145         {
146                 .esdhc_base = USDHC2_BASE_ADDR,
147                 .max_bus_width = 8,
148         },
149 #endif
150 };
151
152 int board_mmc_getcd(struct mmc *mmc)
153 {
154         return 1;
155 }
156
157 int board_mmc_init(bd_t *bis)
158 {
159         int i, ret;
160
161         for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
162                 switch (i) {
163                 case 0:
164                         SETUP_IOMUX_PADS(usdhc1_pads);
165                         usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
166                         break;
167 #ifndef CONFIG_NAND_MXS
168                 case 1:
169                         SETUP_IOMUX_PADS(usdhc2_pads);
170                         usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
171                         break;
172 #endif
173                 default:
174                         printf("Warning - USDHC%d controller not supporting\n",
175                                i + 1);
176                         return 0;
177                 }
178
179                 ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
180                 if (ret) {
181                         printf("Warning: failed to initialize mmc dev %d\n", i);
182                         return ret;
183                 }
184         }
185
186         return 0;
187 }
188
189 void board_init_f(ulong dummy)
190 {
191         /* setup AIPS and disable watchdog */
192         arch_cpu_init();
193
194         ccgr_init();
195
196         /* setup GP timer */
197         timer_init();
198
199         setup_iomux_uart();
200
201         /* iomux and setup of i2c */
202         board_early_init_f();
203
204         /* UART clocks enabled and gd valid - init serial console */
205         preloader_console_init();
206
207         /* DDR initialization */
208         spl_dram_init();
209
210         /* Clear the BSS. */
211         memset(__bss_start, 0, __bss_end - __bss_start);
212
213         /* load/boot image from boot device */
214         board_init_r(NULL, 0);
215 }