15d6050fdSStefan Roese /*
25d6050fdSStefan Roese * Copyright (C) 2014 Stefan Roese <sr@denx.de>
35d6050fdSStefan Roese *
45d6050fdSStefan Roese * Based on: gw_ventana_spl.c which is:
55d6050fdSStefan Roese * Copyright (C) 2014 Gateworks Corporation
65d6050fdSStefan Roese *
75d6050fdSStefan Roese * SPDX-License-Identifier: GPL-2.0+
85d6050fdSStefan Roese */
95d6050fdSStefan Roese
105d6050fdSStefan Roese #include <common.h>
115d6050fdSStefan Roese #include <i2c.h>
125d6050fdSStefan Roese #include <asm/io.h>
135d6050fdSStefan Roese #include <asm/arch/iomux.h>
145d6050fdSStefan Roese #include <asm/arch/mx6-ddr.h>
155d6050fdSStefan Roese #include <asm/arch/mx6-pins.h>
165d6050fdSStefan Roese #include <asm/arch/sys_proto.h>
17*552a848eSStefano Babic #include <asm/mach-imx/boot_mode.h>
18*552a848eSStefano Babic #include <asm/mach-imx/iomux-v3.h>
19*552a848eSStefano Babic #include <asm/mach-imx/mxc_i2c.h>
205d6050fdSStefan Roese #include <spl.h>
215d6050fdSStefan Roese
225d6050fdSStefan Roese #include "platinum.h"
235d6050fdSStefan Roese
245d6050fdSStefan Roese DECLARE_GLOBAL_DATA_PTR;
255d6050fdSStefan Roese
265d6050fdSStefan Roese #undef RTT_NOM_120OHM /* use 120ohm Rtt_nom vs 60ohm (lower power) */
275d6050fdSStefan Roese
285d6050fdSStefan Roese /* Configure MX6Q/DUAL mmdc DDR io registers */
295d6050fdSStefan Roese struct mx6dq_iomux_ddr_regs mx6dq_ddr_ioregs = {
305d6050fdSStefan Roese /* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */
315d6050fdSStefan Roese .dram_sdclk_0 = 0x00020030,
325d6050fdSStefan Roese .dram_sdclk_1 = 0x00020030,
335d6050fdSStefan Roese .dram_cas = 0x00020030,
345d6050fdSStefan Roese .dram_ras = 0x00020030,
355d6050fdSStefan Roese .dram_reset = 0x00020030,
365d6050fdSStefan Roese /* SDCKE[0:1]: 100k pull-up */
375d6050fdSStefan Roese .dram_sdcke0 = 0x00003000,
385d6050fdSStefan Roese .dram_sdcke1 = 0x00003000,
395d6050fdSStefan Roese /* SDBA2: pull-up disabled */
405d6050fdSStefan Roese .dram_sdba2 = 0x00000000,
415d6050fdSStefan Roese /* SDODT[0:1]: 100k pull-up, 40 ohm */
425d6050fdSStefan Roese .dram_sdodt0 = 0x00003030,
435d6050fdSStefan Roese .dram_sdodt1 = 0x00003030,
445d6050fdSStefan Roese /* SDQS[0:7]: Differential input, 40 ohm */
455d6050fdSStefan Roese .dram_sdqs0 = 0x00000030,
465d6050fdSStefan Roese .dram_sdqs1 = 0x00000030,
475d6050fdSStefan Roese .dram_sdqs2 = 0x00000030,
485d6050fdSStefan Roese .dram_sdqs3 = 0x00000030,
495d6050fdSStefan Roese .dram_sdqs4 = 0x00000030,
505d6050fdSStefan Roese .dram_sdqs5 = 0x00000030,
515d6050fdSStefan Roese .dram_sdqs6 = 0x00000030,
525d6050fdSStefan Roese .dram_sdqs7 = 0x00000030,
535d6050fdSStefan Roese /* DQM[0:7]: Differential input, 40 ohm */
545d6050fdSStefan Roese .dram_dqm0 = 0x00020030,
555d6050fdSStefan Roese .dram_dqm1 = 0x00020030,
565d6050fdSStefan Roese .dram_dqm2 = 0x00020030,
575d6050fdSStefan Roese .dram_dqm3 = 0x00020030,
585d6050fdSStefan Roese .dram_dqm4 = 0x00020030,
595d6050fdSStefan Roese .dram_dqm5 = 0x00020030,
605d6050fdSStefan Roese .dram_dqm6 = 0x00020030,
615d6050fdSStefan Roese .dram_dqm7 = 0x00020030,
625d6050fdSStefan Roese };
635d6050fdSStefan Roese
645d6050fdSStefan Roese /* Configure MX6Q/DUAL mmdc GRP io registers */
655d6050fdSStefan Roese struct mx6dq_iomux_grp_regs mx6dq_grp_ioregs = {
665d6050fdSStefan Roese /* DDR3 */
675d6050fdSStefan Roese .grp_ddr_type = 0x000c0000,
685d6050fdSStefan Roese .grp_ddrmode_ctl = 0x00020000,
695d6050fdSStefan Roese /* disable DDR pullups */
705d6050fdSStefan Roese .grp_ddrpke = 0x00000000,
715d6050fdSStefan Roese /* ADDR[00:16], SDBA[0:1]: 40 ohm */
725d6050fdSStefan Roese .grp_addds = 0x00000030,
735d6050fdSStefan Roese /* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */
745d6050fdSStefan Roese .grp_ctlds = 0x00000030,
755d6050fdSStefan Roese /* DATA[00:63]: Differential input, 40 ohm */
765d6050fdSStefan Roese .grp_ddrmode = 0x00020000,
775d6050fdSStefan Roese .grp_b0ds = 0x00000030,
785d6050fdSStefan Roese .grp_b1ds = 0x00000030,
795d6050fdSStefan Roese .grp_b2ds = 0x00000030,
805d6050fdSStefan Roese .grp_b3ds = 0x00000030,
815d6050fdSStefan Roese .grp_b4ds = 0x00000030,
825d6050fdSStefan Roese .grp_b5ds = 0x00000030,
835d6050fdSStefan Roese .grp_b6ds = 0x00000030,
845d6050fdSStefan Roese .grp_b7ds = 0x00000030,
855d6050fdSStefan Roese };
865d6050fdSStefan Roese
875d6050fdSStefan Roese /* MT41J128M16JT-125 */
885d6050fdSStefan Roese static struct mx6_ddr3_cfg mt41j128m16jt_125 = {
895d6050fdSStefan Roese .mem_speed = 1600,
905d6050fdSStefan Roese .density = 2,
915d6050fdSStefan Roese .width = 16,
925d6050fdSStefan Roese .banks = 8,
935d6050fdSStefan Roese .rowaddr = 14,
945d6050fdSStefan Roese .coladdr = 10,
955d6050fdSStefan Roese .pagesz = 2,
965d6050fdSStefan Roese .trcd = 1375,
975d6050fdSStefan Roese .trcmin = 4875,
985d6050fdSStefan Roese .trasmin = 3500,
995d6050fdSStefan Roese };
1005d6050fdSStefan Roese
1015d6050fdSStefan Roese static struct mx6_mmdc_calibration mx6dq_mmdc_calib = {
1025d6050fdSStefan Roese /* Write leveling calibration determine */
1035d6050fdSStefan Roese .p0_mpwldectrl0 = 0x001f001f,
1045d6050fdSStefan Roese .p0_mpwldectrl1 = 0x001f001f,
1055d6050fdSStefan Roese .p1_mpwldectrl0 = 0x00440044,
1065d6050fdSStefan Roese .p1_mpwldectrl1 = 0x00440044,
1075d6050fdSStefan Roese /* Read DQS Gating calibration */
1085d6050fdSStefan Roese .p0_mpdgctrl0 = 0x434b0350,
1095d6050fdSStefan Roese .p0_mpdgctrl1 = 0x034c0359,
1105d6050fdSStefan Roese .p1_mpdgctrl0 = 0x434b0350,
1115d6050fdSStefan Roese .p1_mpdgctrl1 = 0x03650348,
1125d6050fdSStefan Roese /* Read Calibration: DQS delay relative to DQ read access */
1135d6050fdSStefan Roese .p0_mprddlctl = 0x4436383b,
1145d6050fdSStefan Roese .p1_mprddlctl = 0x39393341,
1155d6050fdSStefan Roese /* Write Calibration: DQ/DM delay relative to DQS write access */
1165d6050fdSStefan Roese .p0_mpwrdlctl = 0x35373933,
1175d6050fdSStefan Roese .p1_mpwrdlctl = 0x48254a36,
1185d6050fdSStefan Roese };
1195d6050fdSStefan Roese
spl_dram_init(int width)1205d6050fdSStefan Roese static void spl_dram_init(int width)
1215d6050fdSStefan Roese {
1225d6050fdSStefan Roese struct mx6_ddr3_cfg *mem = &mt41j128m16jt_125;
1235d6050fdSStefan Roese struct mx6_ddr_sysinfo sysinfo = {
1245d6050fdSStefan Roese /* width of data bus:0=16,1=32,2=64 */
1255d6050fdSStefan Roese .dsize = width / 32,
1265d6050fdSStefan Roese /* config for full 4GB range so that get_mem_size() works */
1275d6050fdSStefan Roese .cs_density = 32, /* 32Gb per CS */
1285d6050fdSStefan Roese /* single chip select */
1295d6050fdSStefan Roese .ncs = 1,
1305d6050fdSStefan Roese .cs1_mirror = 1,
1315d6050fdSStefan Roese .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */
1325d6050fdSStefan Roese #ifdef RTT_NOM_120OHM
1335d6050fdSStefan Roese .rtt_nom = 2 /*DDR3_RTT_120_OHM*/, /* RTT_Nom = RZQ/2 */
1345d6050fdSStefan Roese #else
1355d6050fdSStefan Roese .rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */
1365d6050fdSStefan Roese #endif
1375d6050fdSStefan Roese .walat = 0, /* Write additional latency */
1385d6050fdSStefan Roese .ralat = 5, /* Read additional latency */
1395d6050fdSStefan Roese .mif3_mode = 3, /* Command prediction working mode */
1405d6050fdSStefan Roese .bi_on = 1, /* Bank interleaving enabled */
1415d6050fdSStefan Roese .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */
1425d6050fdSStefan Roese .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */
143f2ff8343SPeng Fan .ddr_type = DDR_TYPE_DDR3,
144edf00937SFabio Estevam .refsel = 1, /* Refresh cycles at 32KHz */
145edf00937SFabio Estevam .refr = 7, /* 8 refresh commands per refresh cycle */
1465d6050fdSStefan Roese };
1475d6050fdSStefan Roese
1485d6050fdSStefan Roese mx6dq_dram_iocfg(width, &mx6dq_ddr_ioregs, &mx6dq_grp_ioregs);
1495d6050fdSStefan Roese mx6_dram_cfg(&sysinfo, &mx6dq_mmdc_calib, mem);
1505d6050fdSStefan Roese }
1515d6050fdSStefan Roese
1525d6050fdSStefan Roese /*
1535d6050fdSStefan Roese * Called from C runtime startup code (arch/arm/lib/crt0.S:_main)
1545d6050fdSStefan Roese * - we have a stack and a place to store GD, both in SRAM
1555d6050fdSStefan Roese * - no variable global data is available
1565d6050fdSStefan Roese */
board_init_f(ulong dummy)1575d6050fdSStefan Roese void board_init_f(ulong dummy)
1585d6050fdSStefan Roese {
1595d6050fdSStefan Roese /* Setup AIPS and disable watchdog */
1605d6050fdSStefan Roese arch_cpu_init();
1615d6050fdSStefan Roese
1625d6050fdSStefan Roese ccgr_init();
1635d6050fdSStefan Roese gpr_init();
1645d6050fdSStefan Roese
1655d6050fdSStefan Roese /* UART iomux */
1665d6050fdSStefan Roese board_early_init_f();
1675d6050fdSStefan Roese
1685d6050fdSStefan Roese /* Setup GP timer */
1695d6050fdSStefan Roese timer_init();
1705d6050fdSStefan Roese
1715d6050fdSStefan Roese /* UART clocks enabled and gd valid - init serial console */
1725d6050fdSStefan Roese preloader_console_init();
1735d6050fdSStefan Roese
1745d6050fdSStefan Roese /* Init DDR with 32bit width */
1755d6050fdSStefan Roese spl_dram_init(32);
1765d6050fdSStefan Roese
1775d6050fdSStefan Roese /* Clear the BSS */
1785d6050fdSStefan Roese memset(__bss_start, 0, __bss_end - __bss_start);
1795d6050fdSStefan Roese
1805d6050fdSStefan Roese /*
1815d6050fdSStefan Roese * Setup enet related MUXing early to give the PHY
1825d6050fdSStefan Roese * some time to wake-up from reset
1835d6050fdSStefan Roese */
1845d6050fdSStefan Roese platinum_setup_enet();
1855d6050fdSStefan Roese
1865d6050fdSStefan Roese /* load/boot image from boot device */
1875d6050fdSStefan Roese board_init_r(NULL, 0);
1885d6050fdSStefan Roese }
189