183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2552a848eSStefano Babic /*
330754ef7SSébastien Szymanski * Copyright (C) 2018 Armadeus Systems
4552a848eSStefano Babic */
5552a848eSStefano Babic
6552a848eSStefano Babic #include <asm/arch/clock.h>
7552a848eSStefano Babic #include <asm/arch/crm_regs.h>
8552a848eSStefano Babic #include <asm/arch/imx-regs.h>
9552a848eSStefano Babic #include <asm/arch/iomux.h>
10552a848eSStefano Babic #include <asm/arch/mx6-pins.h>
11552a848eSStefano Babic #include <asm/arch/sys_proto.h>
12552a848eSStefano Babic #include <asm/gpio.h>
13552a848eSStefano Babic #include <asm/mach-imx/iomux-v3.h>
14552a848eSStefano Babic #include <asm/io.h>
15552a848eSStefano Babic #include <common.h>
16552a848eSStefano Babic #include <environment.h>
17552a848eSStefano Babic
18552a848eSStefano Babic DECLARE_GLOBAL_DATA_PTR;
19552a848eSStefano Babic
20552a848eSStefano Babic #ifdef CONFIG_FEC_MXC
21552a848eSStefano Babic #include <miiphy.h>
22552a848eSStefano Babic
23552a848eSStefano Babic #define MDIO_PAD_CTRL ( \
24552a848eSStefano Babic PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
25552a848eSStefano Babic PAD_CTL_DSE_40ohm \
26552a848eSStefano Babic )
27552a848eSStefano Babic
28552a848eSStefano Babic #define ENET_PAD_CTRL_PU ( \
29552a848eSStefano Babic PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
30552a848eSStefano Babic PAD_CTL_DSE_40ohm \
31552a848eSStefano Babic )
32552a848eSStefano Babic
33552a848eSStefano Babic #define ENET_PAD_CTRL_PD ( \
34552a848eSStefano Babic PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED | \
35552a848eSStefano Babic PAD_CTL_DSE_40ohm \
36552a848eSStefano Babic )
37552a848eSStefano Babic
38552a848eSStefano Babic #define ENET_CLK_PAD_CTRL ( \
39552a848eSStefano Babic PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \
40552a848eSStefano Babic PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST \
41552a848eSStefano Babic )
42552a848eSStefano Babic
43552a848eSStefano Babic static iomux_v3_cfg_t const fec1_pads[] = {
44552a848eSStefano Babic MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),
45552a848eSStefano Babic MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(MDIO_PAD_CTRL),
46552a848eSStefano Babic MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
47552a848eSStefano Babic MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
48552a848eSStefano Babic MX6_PAD_ENET1_RX_DATA1__ENET1_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
49552a848eSStefano Babic MX6_PAD_ENET1_RX_DATA0__ENET1_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
50552a848eSStefano Babic MX6_PAD_ENET1_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL_PU),
51552a848eSStefano Babic MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL_PU),
52552a848eSStefano Babic MX6_PAD_ENET1_TX_EN__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL_PU),
53552a848eSStefano Babic /* PHY Int */
54552a848eSStefano Babic MX6_PAD_NAND_DQS__GPIO4_IO16 | MUX_PAD_CTRL(ENET_PAD_CTRL_PU),
55552a848eSStefano Babic /* PHY Reset */
56552a848eSStefano Babic MX6_PAD_NAND_DATA00__GPIO4_IO02 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
57552a848eSStefano Babic MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),
58552a848eSStefano Babic };
59552a848eSStefano Babic
board_phy_config(struct phy_device * phydev)60552a848eSStefano Babic int board_phy_config(struct phy_device *phydev)
61552a848eSStefano Babic {
62552a848eSStefano Babic phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x8190);
63552a848eSStefano Babic
64552a848eSStefano Babic if (phydev->drv->config)
65552a848eSStefano Babic phydev->drv->config(phydev);
66552a848eSStefano Babic
67552a848eSStefano Babic return 0;
68552a848eSStefano Babic }
69552a848eSStefano Babic
board_eth_init(bd_t * bis)70552a848eSStefano Babic int board_eth_init(bd_t *bis)
71552a848eSStefano Babic {
72552a848eSStefano Babic struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
73552a848eSStefano Babic struct gpio_desc rst;
74552a848eSStefano Babic int ret;
75552a848eSStefano Babic
76552a848eSStefano Babic /* Use 50M anatop loopback REF_CLK1 for ENET1,
77552a848eSStefano Babic * clear gpr1[13], set gpr1[17] */
78552a848eSStefano Babic clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK,
79552a848eSStefano Babic IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK);
80552a848eSStefano Babic
81552a848eSStefano Babic ret = enable_fec_anatop_clock(0, ENET_50MHZ);
82552a848eSStefano Babic if (ret)
83552a848eSStefano Babic return ret;
84552a848eSStefano Babic
85552a848eSStefano Babic enable_enet_clk(1);
86552a848eSStefano Babic
87552a848eSStefano Babic imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads));
88552a848eSStefano Babic
89552a848eSStefano Babic ret = dm_gpio_lookup_name("GPIO4_2", &rst);
90552a848eSStefano Babic if (ret) {
91552a848eSStefano Babic printf("Cannot get GPIO4_2\n");
92552a848eSStefano Babic return ret;
93552a848eSStefano Babic }
94552a848eSStefano Babic
95552a848eSStefano Babic ret = dm_gpio_request(&rst, "phy-rst");
96552a848eSStefano Babic if (ret) {
97552a848eSStefano Babic printf("Cannot request GPIO4_2\n");
98552a848eSStefano Babic return ret;
99552a848eSStefano Babic }
100552a848eSStefano Babic
101552a848eSStefano Babic dm_gpio_set_dir_flags(&rst, GPIOD_IS_OUT);
102552a848eSStefano Babic dm_gpio_set_value(&rst, 0);
103552a848eSStefano Babic udelay(1000);
104552a848eSStefano Babic dm_gpio_set_value(&rst, 1);
105552a848eSStefano Babic
106552a848eSStefano Babic return fecmxc_initialize(bis);
107552a848eSStefano Babic }
108552a848eSStefano Babic #endif /* CONFIG_FEC_MXC */
109552a848eSStefano Babic
board_init(void)110552a848eSStefano Babic int board_init(void)
111552a848eSStefano Babic {
112552a848eSStefano Babic /* Address of boot parameters */
113552a848eSStefano Babic gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
114552a848eSStefano Babic
115552a848eSStefano Babic return 0;
116552a848eSStefano Babic }
117552a848eSStefano Babic
opos6ul_board_late_init(void)118552a848eSStefano Babic int __weak opos6ul_board_late_init(void)
119552a848eSStefano Babic {
120552a848eSStefano Babic return 0;
121552a848eSStefano Babic }
122552a848eSStefano Babic
board_late_init(void)123552a848eSStefano Babic int board_late_init(void)
124552a848eSStefano Babic {
125552a848eSStefano Babic struct src *psrc = (struct src *)SRC_BASE_ADDR;
126552a848eSStefano Babic unsigned reg = readl(&psrc->sbmr2);
127552a848eSStefano Babic
128552a848eSStefano Babic /* In bootstrap don't use the env vars */
129552a848eSStefano Babic if (((reg & 0x3000000) >> 24) == 0x1) {
130*c5d548a9SYaniv Levinsky set_default_env(NULL, 0);
131382bee57SSimon Glass env_set("preboot", "");
132552a848eSStefano Babic }
133552a848eSStefano Babic
134552a848eSStefano Babic return opos6ul_board_late_init();
135552a848eSStefano Babic }
136552a848eSStefano Babic
dram_init(void)137552a848eSStefano Babic int dram_init(void)
138552a848eSStefano Babic {
139552a848eSStefano Babic gd->ram_size = imx_ddr_size();
140552a848eSStefano Babic
141552a848eSStefano Babic return 0;
142552a848eSStefano Babic }
143552a848eSStefano Babic
144552a848eSStefano Babic #ifdef CONFIG_SPL_BUILD
145552a848eSStefano Babic #include <asm/arch/mx6-ddr.h>
146b08c8c48SMasahiro Yamada #include <linux/libfdt.h>
147552a848eSStefano Babic #include <spl.h>
148552a848eSStefano Babic
149552a848eSStefano Babic static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = {
150552a848eSStefano Babic .grp_addds = 0x00000030,
151552a848eSStefano Babic .grp_ddrmode_ctl = 0x00020000,
152552a848eSStefano Babic .grp_b0ds = 0x00000030,
153552a848eSStefano Babic .grp_ctlds = 0x00000030,
154552a848eSStefano Babic .grp_b1ds = 0x00000030,
155552a848eSStefano Babic .grp_ddrpke = 0x00000000,
156552a848eSStefano Babic .grp_ddrmode = 0x00020000,
157552a848eSStefano Babic .grp_ddr_type = 0x000c0000,
158552a848eSStefano Babic };
159552a848eSStefano Babic
160552a848eSStefano Babic static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = {
161552a848eSStefano Babic .dram_dqm0 = 0x00000030,
162552a848eSStefano Babic .dram_dqm1 = 0x00000030,
163552a848eSStefano Babic .dram_ras = 0x00000030,
164552a848eSStefano Babic .dram_cas = 0x00000030,
165552a848eSStefano Babic .dram_odt0 = 0x00000030,
166552a848eSStefano Babic .dram_odt1 = 0x00000030,
167552a848eSStefano Babic .dram_sdba2 = 0x00000000,
168552a848eSStefano Babic .dram_sdclk_0 = 0x00000008,
169552a848eSStefano Babic .dram_sdqs0 = 0x00000038,
170552a848eSStefano Babic .dram_sdqs1 = 0x00000030,
171552a848eSStefano Babic .dram_reset = 0x00000030,
172552a848eSStefano Babic };
173552a848eSStefano Babic
174552a848eSStefano Babic static struct mx6_mmdc_calibration mx6_mmcd_calib = {
175552a848eSStefano Babic .p0_mpwldectrl0 = 0x00070007,
176552a848eSStefano Babic .p0_mpdgctrl0 = 0x41490145,
177552a848eSStefano Babic .p0_mprddlctl = 0x40404546,
178552a848eSStefano Babic .p0_mpwrdlctl = 0x4040524D,
179552a848eSStefano Babic };
180552a848eSStefano Babic
181552a848eSStefano Babic struct mx6_ddr_sysinfo ddr_sysinfo = {
182552a848eSStefano Babic .dsize = 0,
183552a848eSStefano Babic .cs_density = 20,
184552a848eSStefano Babic .ncs = 1,
185552a848eSStefano Babic .cs1_mirror = 0,
186552a848eSStefano Babic .rtt_wr = 2,
187552a848eSStefano Babic .rtt_nom = 1, /* RTT_Nom = RZQ/2 */
188552a848eSStefano Babic .walat = 1, /* Write additional latency */
189552a848eSStefano Babic .ralat = 5, /* Read additional latency */
190552a848eSStefano Babic .mif3_mode = 3, /* Command prediction working mode */
191552a848eSStefano Babic .bi_on = 1, /* Bank interleaving enabled */
192552a848eSStefano Babic .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */
193552a848eSStefano Babic .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */
194552a848eSStefano Babic .ddr_type = DDR_TYPE_DDR3,
195552a848eSStefano Babic };
196552a848eSStefano Babic
197552a848eSStefano Babic static struct mx6_ddr3_cfg mem_ddr = {
198552a848eSStefano Babic .mem_speed = 800,
199552a848eSStefano Babic .density = 2,
200552a848eSStefano Babic .width = 16,
201552a848eSStefano Babic .banks = 8,
202552a848eSStefano Babic .rowaddr = 14,
203552a848eSStefano Babic .coladdr = 10,
204552a848eSStefano Babic .pagesz = 2,
205552a848eSStefano Babic .trcd = 1500,
206552a848eSStefano Babic .trcmin = 5250,
207552a848eSStefano Babic .trasmin = 3750,
208552a848eSStefano Babic };
209552a848eSStefano Babic
board_boot_order(u32 * spl_boot_list)210ea772178SSébastien Szymanski void board_boot_order(u32 *spl_boot_list)
211ea772178SSébastien Szymanski {
212ea772178SSébastien Szymanski unsigned int bmode = readl(&src_base->sbmr2);
213ea772178SSébastien Szymanski
214ea772178SSébastien Szymanski if (((bmode >> 24) & 0x03) == 0x01) /* Serial Downloader */
215ea772178SSébastien Szymanski spl_boot_list[0] = BOOT_DEVICE_UART;
216ea772178SSébastien Szymanski else
217ea772178SSébastien Szymanski spl_boot_list[0] = spl_boot_device();
218ea772178SSébastien Szymanski }
219ea772178SSébastien Szymanski
ccgr_init(void)220552a848eSStefano Babic static void ccgr_init(void)
221552a848eSStefano Babic {
222552a848eSStefano Babic struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
223552a848eSStefano Babic
224552a848eSStefano Babic writel(0xFFFFFFFF, &ccm->CCGR0);
225552a848eSStefano Babic writel(0xFFFFFFFF, &ccm->CCGR1);
226552a848eSStefano Babic writel(0xFFFFFFFF, &ccm->CCGR2);
227552a848eSStefano Babic writel(0xFFFFFFFF, &ccm->CCGR3);
228552a848eSStefano Babic writel(0xFFFFFFFF, &ccm->CCGR4);
229552a848eSStefano Babic writel(0xFFFFFFFF, &ccm->CCGR5);
230552a848eSStefano Babic writel(0xFFFFFFFF, &ccm->CCGR6);
231552a848eSStefano Babic writel(0xFFFFFFFF, &ccm->CCGR7);
232552a848eSStefano Babic }
233552a848eSStefano Babic
spl_dram_init(void)234552a848eSStefano Babic static void spl_dram_init(void)
235552a848eSStefano Babic {
236552a848eSStefano Babic struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
237552a848eSStefano Babic struct fuse_bank *bank = &ocotp->bank[4];
238552a848eSStefano Babic struct fuse_bank4_regs *fuse =
239552a848eSStefano Babic (struct fuse_bank4_regs *)bank->fuse_regs;
240552a848eSStefano Babic int reg = readl(&fuse->gp1);
241552a848eSStefano Babic
242552a848eSStefano Babic /* 512MB of RAM */
243552a848eSStefano Babic if (reg & 0x1) {
244552a848eSStefano Babic mem_ddr.density = 4;
245552a848eSStefano Babic mem_ddr.rowaddr = 15;
246552a848eSStefano Babic mem_ddr.trcd = 1375;
247552a848eSStefano Babic mem_ddr.trcmin = 4875;
248552a848eSStefano Babic mem_ddr.trasmin = 3500;
249552a848eSStefano Babic }
250552a848eSStefano Babic
251552a848eSStefano Babic mx6ul_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
252552a848eSStefano Babic mx6_dram_cfg(&ddr_sysinfo, &mx6_mmcd_calib, &mem_ddr);
253552a848eSStefano Babic }
254552a848eSStefano Babic
spl_board_init(void)25530754ef7SSébastien Szymanski void spl_board_init(void)
25630754ef7SSébastien Szymanski {
25730754ef7SSébastien Szymanski preloader_console_init();
25830754ef7SSébastien Szymanski }
25930754ef7SSébastien Szymanski
board_init_f(ulong dummy)260552a848eSStefano Babic void board_init_f(ulong dummy)
261552a848eSStefano Babic {
262552a848eSStefano Babic ccgr_init();
263552a848eSStefano Babic
264552a848eSStefano Babic /* setup AIPS and disable watchdog */
265552a848eSStefano Babic arch_cpu_init();
266552a848eSStefano Babic
267552a848eSStefano Babic /* setup GP timer */
268552a848eSStefano Babic timer_init();
269552a848eSStefano Babic
270552a848eSStefano Babic /* DDR initialization */
271552a848eSStefano Babic spl_dram_init();
272552a848eSStefano Babic }
273552a848eSStefano Babic #endif /* CONFIG_SPL_BUILD */
274