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