blob: 0c640e2e33c3a41cb8f10a17364335bf42117e33 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Sébastien Szymanskia7762e42017-03-07 14:33:25 +01002/*
Sébastien Szymanski1f29ce52018-04-17 17:29:31 +02003 * Copyright (C) 2018 Armadeus Systems
Sébastien Szymanskia7762e42017-03-07 14:33:25 +01004 */
5
6#include <asm/arch/clock.h>
7#include <asm/arch/crm_regs.h>
8#include <asm/arch/imx-regs.h>
Sébastien Szymanskia7762e42017-03-07 14:33:25 +01009#include <asm/arch/sys_proto.h>
Sébastien Szymanskia7762e42017-03-07 14:33:25 +010010#include <asm/io.h>
11#include <common.h>
Simon Glass5e6201b2019-08-01 09:46:51 -060012#include <env.h>
Sébastien Szymanskia7762e42017-03-07 14:33:25 +010013
14DECLARE_GLOBAL_DATA_PTR;
15
16#ifdef CONFIG_FEC_MXC
17#include <miiphy.h>
18
Sébastien Szymanskia7762e42017-03-07 14:33:25 +010019int board_phy_config(struct phy_device *phydev)
20{
21 phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x8190);
22
23 if (phydev->drv->config)
24 phydev->drv->config(phydev);
25
26 return 0;
27}
28
Sébastien Szymanski5444fdf2019-10-21 15:33:02 +020029static int setup_fec(void)
Sébastien Szymanskia7762e42017-03-07 14:33:25 +010030{
31 struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
Sébastien Szymanskia7762e42017-03-07 14:33:25 +010032
33 /* Use 50M anatop loopback REF_CLK1 for ENET1,
34 * clear gpr1[13], set gpr1[17] */
35 clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK,
36 IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK);
37
Sébastien Szymanski5444fdf2019-10-21 15:33:02 +020038 return enable_fec_anatop_clock(0, ENET_50MHZ);
Sébastien Szymanskia7762e42017-03-07 14:33:25 +010039}
40#endif /* CONFIG_FEC_MXC */
41
42int board_init(void)
43{
44 /* Address of boot parameters */
45 gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
46
Sébastien Szymanski5444fdf2019-10-21 15:33:02 +020047#ifdef CONFIG_FEC_MXC
48 setup_fec();
49#endif
50
Sébastien Szymanskia7762e42017-03-07 14:33:25 +010051 return 0;
52}
53
54int __weak opos6ul_board_late_init(void)
55{
56 return 0;
57}
58
59int board_late_init(void)
60{
61 struct src *psrc = (struct src *)SRC_BASE_ADDR;
62 unsigned reg = readl(&psrc->sbmr2);
63
64 /* In bootstrap don't use the env vars */
65 if (((reg & 0x3000000) >> 24) == 0x1) {
Simon Glass97385862019-08-01 09:47:00 -060066 env_set_default(NULL, 0);
Simon Glass6a38e412017-08-03 12:22:09 -060067 env_set("preboot", "");
Sébastien Szymanskia7762e42017-03-07 14:33:25 +010068 }
69
70 return opos6ul_board_late_init();
71}
72
Sébastien Szymanskia7762e42017-03-07 14:33:25 +010073int dram_init(void)
74{
75 gd->ram_size = imx_ddr_size();
76
77 return 0;
78}
79
80#ifdef CONFIG_SPL_BUILD
81#include <asm/arch/mx6-ddr.h>
Masahiro Yamada75f82d02018-03-05 01:20:11 +090082#include <linux/libfdt.h>
Sébastien Szymanskia7762e42017-03-07 14:33:25 +010083#include <spl.h>
84
Sébastien Szymanskia7762e42017-03-07 14:33:25 +010085static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = {
86 .grp_addds = 0x00000030,
87 .grp_ddrmode_ctl = 0x00020000,
88 .grp_b0ds = 0x00000030,
89 .grp_ctlds = 0x00000030,
90 .grp_b1ds = 0x00000030,
91 .grp_ddrpke = 0x00000000,
92 .grp_ddrmode = 0x00020000,
93 .grp_ddr_type = 0x000c0000,
94};
95
96static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = {
97 .dram_dqm0 = 0x00000030,
98 .dram_dqm1 = 0x00000030,
99 .dram_ras = 0x00000030,
100 .dram_cas = 0x00000030,
101 .dram_odt0 = 0x00000030,
102 .dram_odt1 = 0x00000030,
103 .dram_sdba2 = 0x00000000,
104 .dram_sdclk_0 = 0x00000008,
105 .dram_sdqs0 = 0x00000038,
106 .dram_sdqs1 = 0x00000030,
107 .dram_reset = 0x00000030,
108};
109
110static struct mx6_mmdc_calibration mx6_mmcd_calib = {
111 .p0_mpwldectrl0 = 0x00070007,
112 .p0_mpdgctrl0 = 0x41490145,
113 .p0_mprddlctl = 0x40404546,
114 .p0_mpwrdlctl = 0x4040524D,
115};
116
117struct mx6_ddr_sysinfo ddr_sysinfo = {
118 .dsize = 0,
119 .cs_density = 20,
120 .ncs = 1,
121 .cs1_mirror = 0,
122 .rtt_wr = 2,
123 .rtt_nom = 1, /* RTT_Nom = RZQ/2 */
124 .walat = 1, /* Write additional latency */
125 .ralat = 5, /* Read additional latency */
126 .mif3_mode = 3, /* Command prediction working mode */
127 .bi_on = 1, /* Bank interleaving enabled */
128 .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */
129 .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */
130 .ddr_type = DDR_TYPE_DDR3,
Sébastien Szymanski943d8b52019-05-14 13:33:46 +0200131 .refsel = 1, /* Refresh cycles at 32KHz */
132 .refr = 7, /* 8 refreshes commands per refresh cycle */
Sébastien Szymanskia7762e42017-03-07 14:33:25 +0100133};
134
135static struct mx6_ddr3_cfg mem_ddr = {
136 .mem_speed = 800,
137 .density = 2,
138 .width = 16,
139 .banks = 8,
140 .rowaddr = 14,
141 .coladdr = 10,
142 .pagesz = 2,
143 .trcd = 1500,
144 .trcmin = 5250,
145 .trasmin = 3750,
146};
147
Sébastien Szymanski016f0052018-04-17 17:29:32 +0200148void board_boot_order(u32 *spl_boot_list)
149{
150 unsigned int bmode = readl(&src_base->sbmr2);
151
152 if (((bmode >> 24) & 0x03) == 0x01) /* Serial Downloader */
153 spl_boot_list[0] = BOOT_DEVICE_UART;
154 else
155 spl_boot_list[0] = spl_boot_device();
156}
157
Sébastien Szymanskia7762e42017-03-07 14:33:25 +0100158static void ccgr_init(void)
159{
160 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
161
162 writel(0xFFFFFFFF, &ccm->CCGR0);
163 writel(0xFFFFFFFF, &ccm->CCGR1);
164 writel(0xFFFFFFFF, &ccm->CCGR2);
165 writel(0xFFFFFFFF, &ccm->CCGR3);
166 writel(0xFFFFFFFF, &ccm->CCGR4);
167 writel(0xFFFFFFFF, &ccm->CCGR5);
168 writel(0xFFFFFFFF, &ccm->CCGR6);
169 writel(0xFFFFFFFF, &ccm->CCGR7);
170}
171
172static void spl_dram_init(void)
173{
174 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
175 struct fuse_bank *bank = &ocotp->bank[4];
176 struct fuse_bank4_regs *fuse =
177 (struct fuse_bank4_regs *)bank->fuse_regs;
178 int reg = readl(&fuse->gp1);
179
180 /* 512MB of RAM */
181 if (reg & 0x1) {
182 mem_ddr.density = 4;
183 mem_ddr.rowaddr = 15;
184 mem_ddr.trcd = 1375;
185 mem_ddr.trcmin = 4875;
186 mem_ddr.trasmin = 3500;
187 }
188
189 mx6ul_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
190 mx6_dram_cfg(&ddr_sysinfo, &mx6_mmcd_calib, &mem_ddr);
191}
192
Sébastien Szymanski1f29ce52018-04-17 17:29:31 +0200193void spl_board_init(void)
194{
195 preloader_console_init();
196}
197
Sébastien Szymanskia7762e42017-03-07 14:33:25 +0100198void board_init_f(ulong dummy)
199{
200 ccgr_init();
201
202 /* setup AIPS and disable watchdog */
203 arch_cpu_init();
204
205 /* setup GP timer */
206 timer_init();
207
Sébastien Szymanskia7762e42017-03-07 14:33:25 +0100208 /* DDR initialization */
209 spl_dram_init();
210}
211#endif /* CONFIG_SPL_BUILD */