From 0481bef035f5281d075549eb18cc6949dfbc42ff Mon Sep 17 00:00:00 2001 From: Ludwig Zenz Date: Thu, 5 Jul 2018 09:23:48 +0200 Subject: [PATCH] ARM: imx6: DHCOM i.MX6 PDK: ddr init for 32bit bus and 4GBit chips Support 1GIB + 2GIB DDR3 with 64bit bus width and 512MIB + 1GIB with 32bit bus width Signed-off-by: Ludwig Zenz --- board/dhelectronics/dh_imx6/dh_imx6_spl.c | 191 ++++++++++++++++++++-- 1 file changed, 173 insertions(+), 18 deletions(-) diff --git a/board/dhelectronics/dh_imx6/dh_imx6_spl.c b/board/dhelectronics/dh_imx6/dh_imx6_spl.c index eafb86d84f..04e9eab272 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6_spl.c +++ b/board/dhelectronics/dh_imx6/dh_imx6_spl.c @@ -136,7 +136,31 @@ static const struct mx6sdl_iomux_grp_regs dhcom6sdl_grp_ioregs = { .grp_b7ds = 0x00000030, }; -static const struct mx6_mmdc_calibration dhcom_mmdc_calib = { +static const struct mx6_mmdc_calibration dhcom_mmdc_calib_4x4g_1066 = { + .p0_mpwldectrl0 = 0x00150019, + .p0_mpwldectrl1 = 0x001C000B, + .p1_mpwldectrl0 = 0x00020018, + .p1_mpwldectrl1 = 0x0002000C, + .p0_mpdgctrl0 = 0x43140320, + .p0_mpdgctrl1 = 0x03080304, + .p1_mpdgctrl0 = 0x43180320, + .p1_mpdgctrl1 = 0x03100254, + .p0_mprddlctl = 0x4830383C, + .p1_mprddlctl = 0x3836323E, + .p0_mpwrdlctl = 0x3E444642, + .p1_mpwrdlctl = 0x42344442, +}; + +static const struct mx6_mmdc_calibration dhcom_mmdc_calib_2x4g_800 = { + .p0_mpwldectrl0 = 0x0040003C, + .p0_mpwldectrl1 = 0x0032003E, + .p0_mpdgctrl0 = 0x42350231, + .p0_mpdgctrl1 = 0x021A0218, + .p0_mprddlctl = 0x4B4B4E49, + .p0_mpwrdlctl = 0x3F3F3035, +}; + +static const struct mx6_mmdc_calibration dhcom_mmdc_calib_4x2g_1066 = { .p0_mpwldectrl0 = 0x0011000E, .p0_mpwldectrl1 = 0x000E001B, .p1_mpwldectrl0 = 0x00190015, @@ -151,23 +175,89 @@ static const struct mx6_mmdc_calibration dhcom_mmdc_calib = { .p1_mpwrdlctl = 0x473E4A3B, }; -static const struct mx6_ddr3_cfg dhcom_mem_ddr = { +static const struct mx6_mmdc_calibration dhcom_mmdc_calib_4x2g_800 = { + .p0_mpwldectrl0 = 0x003A003A, + .p0_mpwldectrl1 = 0x0030002F, + .p1_mpwldectrl0 = 0x002F0038, + .p1_mpwldectrl1 = 0x00270039, + .p0_mpdgctrl0 = 0x420F020F, + .p0_mpdgctrl1 = 0x01760175, + .p1_mpdgctrl0 = 0x41640171, + .p1_mpdgctrl1 = 0x015E0160, + .p0_mprddlctl = 0x45464B4A, + .p1_mprddlctl = 0x49484A46, + .p0_mpwrdlctl = 0x40402E32, + .p1_mpwrdlctl = 0x3A3A3231, +}; + +static const struct mx6_mmdc_calibration dhcom_mmdc_calib_2x2g_800 = { + .p0_mpwldectrl0 = 0x0040003C, + .p0_mpwldectrl1 = 0x0032003E, + .p0_mpdgctrl0 = 0x42350231, + .p0_mpdgctrl1 = 0x021A0218, + .p0_mprddlctl = 0x4B4B4E49, + .p0_mpwrdlctl = 0x3F3F3035, +}; + +/* + * 2 Gbit DDR3 memory + * - NANYA #NT5CC128M16IP-DII + * - NANYA #NT5CB128M16FP-DII + */ +static const struct mx6_ddr3_cfg dhcom_mem_ddr_2g = { .mem_speed = 1600, .density = 2, - .width = 64, + .width = 16, .banks = 8, .rowaddr = 14, .coladdr = 10, .pagesz = 2, - .trcd = 1312, + .trcd = 1375, .trcmin = 5863, .trasmin = 3750, }; -static const struct mx6_ddr_sysinfo dhcom_ddr_info = { +/* + * 4 Gbit DDR3 memory + * - Intelligent Memory #IM4G16D3EABG-125I + */ +static const struct mx6_ddr3_cfg dhcom_mem_ddr_4g = { + .mem_speed = 1600, + .density = 4, + .width = 16, + .banks = 8, + .rowaddr = 15, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, +}; + +/* DDR3 64bit */ +static const struct mx6_ddr_sysinfo dhcom_ddr_64bit = { /* width of data bus:0=16,1=32,2=64 */ .dsize = 2, - .cs_density = 16, + .cs_density = 32, + .ncs = 1, /* single chip select */ + .cs1_mirror = 1, + .rtt_wr = 1, /* DDR3_RTT_60_OHM, RTT_Wr = RZQ/4 */ + .rtt_nom = 1, /* DDR3_RTT_60_OHM, RTT_Nom = RZQ/4 */ + .walat = 1, /* Write additional latency */ + .ralat = 5, /* Read additional latency */ + .mif3_mode = 3, /* Command prediction working mode */ + .bi_on = 1, /* Bank interleaving enabled */ + .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ + .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ + .refsel = 1, /* Refresh cycles at 32KHz */ + .refr = 3, /* 4 refresh commands per refresh cycle */ +}; + +/* DDR3 32bit */ +static const struct mx6_ddr_sysinfo dhcom_ddr_32bit = { + /* width of data bus:0=16,1=32,2=64 */ + .dsize = 1, + .cs_density = 32, .ncs = 1, /* single chip select */ .cs1_mirror = 1, .rtt_wr = 1, /* DDR3_RTT_60_OHM, RTT_Wr = RZQ/4 */ @@ -392,6 +482,81 @@ static void setup_iomux_usb(void) SETUP_IOMUX_PADS(usb_pads); } + +/* DRAM */ +static void dhcom_spl_dram_init(void) +{ + enum dhcom_ddr3_code ddr3_code = dhcom_get_ddr3_code(); + + if (is_mx6dq()) { + mx6dq_dram_iocfg(64, &dhcom6dq_ddr_ioregs, + &dhcom6dq_grp_ioregs); + switch (ddr3_code) { + default: + printf("imx6qd: unsupported ddr3 code %d\n", ddr3_code); + printf(" choosing 1024 MB\n"); + /* fall through */ + case DH_DDR3_SIZE_1GIB: + mx6_dram_cfg(&dhcom_ddr_64bit, + &dhcom_mmdc_calib_4x2g_1066, + &dhcom_mem_ddr_2g); + break; + case DH_DDR3_SIZE_2GIB: + mx6_dram_cfg(&dhcom_ddr_64bit, + &dhcom_mmdc_calib_4x4g_1066, + &dhcom_mem_ddr_4g); + break; + } + + /* Perform DDR DRAM calibration */ + udelay(100); + mmdc_do_dqs_calibration(&dhcom_ddr_64bit); + + } else if (is_cpu_type(MXC_CPU_MX6DL)) { + mx6sdl_dram_iocfg(64, &dhcom6sdl_ddr_ioregs, + &dhcom6sdl_grp_ioregs); + switch (ddr3_code) { + default: + printf("imx6dl: unsupported ddr3 code %d\n", ddr3_code); + printf(" choosing 1024 MB\n"); + /* fall through */ + case DH_DDR3_SIZE_1GIB: + mx6_dram_cfg(&dhcom_ddr_64bit, + &dhcom_mmdc_calib_4x2g_800, + &dhcom_mem_ddr_2g); + break; + } + + /* Perform DDR DRAM calibration */ + udelay(100); + mmdc_do_dqs_calibration(&dhcom_ddr_64bit); + + } else if (is_cpu_type(MXC_CPU_MX6SOLO)) { + mx6sdl_dram_iocfg(32, &dhcom6sdl_ddr_ioregs, + &dhcom6sdl_grp_ioregs); + switch (ddr3_code) { + default: + printf("imx6s: unsupported ddr3 code %d\n", ddr3_code); + printf(" choosing 512 MB\n"); + /* fall through */ + case DH_DDR3_SIZE_512MIB: + mx6_dram_cfg(&dhcom_ddr_32bit, + &dhcom_mmdc_calib_2x2g_800, + &dhcom_mem_ddr_2g); + break; + case DH_DDR3_SIZE_1GIB: + mx6_dram_cfg(&dhcom_ddr_32bit, + &dhcom_mmdc_calib_2x4g_800, + &dhcom_mem_ddr_4g); + break; + } + + /* Perform DDR DRAM calibration */ + udelay(100); + mmdc_do_dqs_calibration(&dhcom_ddr_32bit); + } +} + void board_init_f(ulong dummy) { /* setup AIPS and disable watchdog */ @@ -415,18 +580,8 @@ void board_init_f(ulong dummy) /* UART clocks enabled and gd valid - init serial console */ preloader_console_init(); - /* Start the DDR DRAM */ - if (is_mx6dq()) - mx6dq_dram_iocfg(dhcom_mem_ddr.width, &dhcom6dq_ddr_ioregs, - &dhcom6dq_grp_ioregs); - else - mx6sdl_dram_iocfg(dhcom_mem_ddr.width, &dhcom6sdl_ddr_ioregs, - &dhcom6sdl_grp_ioregs); - mx6_dram_cfg(&dhcom_ddr_info, &dhcom_mmdc_calib, &dhcom_mem_ddr); - - /* Perform DDR DRAM calibration */ - udelay(100); - mmdc_do_dqs_calibration(&dhcom_ddr_info); + /* DDR3 initialization */ + dhcom_spl_dram_init(); /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start);