Skip to content

Commit

Permalink
driver/ddr/fsl: Add general MMDC driver and reuse common MMDC driver …
Browse files Browse the repository at this point in the history
…for ls1012a

This general MMDC driver adds basic support for Freescale MMDC
(Multi Mode DDR Controller). Currently MMDC is integrated on ARMv8
LS1012A SoC for DDR3L, there will be a update to this driver to
support more flexible configuration if new features (DDR4, multiple
controllers/chip selections, etc) are implimented in future.

Meantime, reuse common MMDC driver for LS1012ARDB/LS1012AQDS/
LS1012AFRDM.

Signed-off-by: Shengzhou Liu <[email protected]>
Reviewed-by: York Sun <[email protected]>
  • Loading branch information
shengzhou authored and York Sun committed Sep 14, 2016
1 parent 93a6d32 commit b9e745b
Show file tree
Hide file tree
Showing 11 changed files with 262 additions and 409 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ libs-y += drivers/power/ \
libs-y += drivers/spi/
libs-$(CONFIG_FMAN_ENET) += drivers/net/fm/
libs-$(CONFIG_SYS_FSL_DDR) += drivers/ddr/fsl/
libs-$(CONFIG_SYS_FSL_MMDC) += drivers/ddr/fsl/
libs-$(CONFIG_ALTERA_SDRAM) += drivers/ddr/altera/
libs-y += drivers/serial/
libs-y += drivers/usb/dwc3/
Expand Down
4 changes: 3 additions & 1 deletion arch/arm/include/asm/arch-fsl-layerscape/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
#define CONFIG_SYS_FSL_DDRC_ARM_GEN3 /* Enable Freescale ARM DDR3 driver */
#endif

#ifndef CONFIG_LS1012A
#ifdef CONFIG_LS1012A
#define CONFIG_SYS_FSL_MMDC /* Freescale MMDC driver */
#else
#define CONFIG_SYS_FSL_DDR /* Freescale DDR driver */
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_5_0
#endif
Expand Down
116 changes: 0 additions & 116 deletions board/freescale/ls1012afrdm/ls1012afrdm.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,129 +17,13 @@

DECLARE_GLOBAL_DATA_PTR;

static void set_wait_for_bits_clear(void *ptr, u32 value, u32 bits)
{
int timeout = 1000;

out_be32(ptr, value);

while (in_be32(ptr) & bits) {
udelay(100);
timeout--;
}
if (timeout <= 0)
puts("Error: wait for clear timeout.\n");
}

int checkboard(void)
{
puts("Board: LS1012AFRDM ");

return 0;
}

void mmdc_init(void)
{
struct mmdc_p_regs *mmdc =
(struct mmdc_p_regs *)CONFIG_SYS_FSL_DDR_ADDR;

out_be32(&mmdc->mdscr, CONFIGURATION_REQ);

/* configure timing parms */
out_be32(&mmdc->mdotc, CONFIG_SYS_MMDC_CORE_ODT_TIMING);
out_be32(&mmdc->mdcfg0, CONFIG_SYS_MMDC_CORE_TIMING_CFG_0);
out_be32(&mmdc->mdcfg1, CONFIG_SYS_MMDC_CORE_TIMING_CFG_1);
out_be32(&mmdc->mdcfg2, CONFIG_SYS_MMDC_CORE_TIMING_CFG_2);

/* other parms */
out_be32(&mmdc->mdmisc, CONFIG_SYS_MMDC_CORE_MISC);
out_be32(&mmdc->mpmur0, CONFIG_SYS_MMDC_PHY_MEASURE_UNIT);
out_be32(&mmdc->mdrwd, CONFIG_SYS_MMDC_CORE_RDWR_CMD_DELAY);
out_be32(&mmdc->mpodtctrl, CONFIG_SYS_MMDC_PHY_ODT_CTRL);

/* out of reset delays */
out_be32(&mmdc->mdor, CONFIG_SYS_MMDC_CORE_OUT_OF_RESET_DELAY);

/* physical parms */
out_be32(&mmdc->mdctl, CONFIG_SYS_MMDC_CORE_CONTROL_1);
out_be32(&mmdc->mdasp, CONFIG_SYS_MMDC_CORE_ADDR_PARTITION);

/* Enable MMDC */
out_be32(&mmdc->mdctl, CONFIG_SYS_MMDC_CORE_CONTROL_2);

/* dram init sequence: update MRs */
out_be32(&mmdc->mdscr, (CMD_ADDR_LSB_MR_ADDR(0x8) | CONFIGURATION_REQ |
CMD_LOAD_MODE_REG | CMD_BANK_ADDR_2));
out_be32(&mmdc->mdscr, (CONFIGURATION_REQ | CMD_LOAD_MODE_REG |
CMD_BANK_ADDR_3));
out_be32(&mmdc->mdscr, (CMD_ADDR_LSB_MR_ADDR(0x4) | CONFIGURATION_REQ |
CMD_LOAD_MODE_REG | CMD_BANK_ADDR_1));
out_be32(&mmdc->mdscr, (CMD_ADDR_MSB_MR_OP(0x19) |
CMD_ADDR_LSB_MR_ADDR(0x30) | CONFIGURATION_REQ |
CMD_LOAD_MODE_REG | CMD_BANK_ADDR_0));

/* dram init sequence: ZQCL */
out_be32(&mmdc->mdscr, (CMD_ADDR_MSB_MR_OP(0x4) | CONFIGURATION_REQ |
CMD_ZQ_CALIBRATION | CMD_BANK_ADDR_0));
set_wait_for_bits_clear(&mmdc->mpzqhwctrl,
CONFIG_SYS_MMDC_PHY_ZQ_HW_CTRL,
FORCE_ZQ_AUTO_CALIBRATION);

/* Calibrations now: wr lvl */
out_be32(&mmdc->mdscr, (CMD_ADDR_LSB_MR_ADDR(0x84) |
CONFIGURATION_REQ | CMD_LOAD_MODE_REG |
CMD_BANK_ADDR_1));
out_be32(&mmdc->mdscr, (CONFIGURATION_REQ | WL_EN | CMD_NORMAL));
set_wait_for_bits_clear(&mmdc->mpwlgcr, WR_LVL_HW_EN, WR_LVL_HW_EN);

mdelay(1);

out_be32(&mmdc->mdscr, (CMD_ADDR_LSB_MR_ADDR(0x4) | CONFIGURATION_REQ |
CMD_LOAD_MODE_REG | CMD_BANK_ADDR_1));
out_be32(&mmdc->mdscr, CONFIGURATION_REQ);

mdelay(1);

/* Calibrations now: Read DQS gating calibration */
out_be32(&mmdc->mdscr, (CMD_ADDR_MSB_MR_OP(0x4) | CONFIGURATION_REQ |
CMD_PRECHARGE_BANK_OPEN | CMD_BANK_ADDR_0));
out_be32(&mmdc->mdscr, (CMD_ADDR_LSB_MR_ADDR(0x4) | CONFIGURATION_REQ |
CMD_LOAD_MODE_REG | CMD_BANK_ADDR_3));
out_be32(&mmdc->mppdcmpr2, MPR_COMPARE_EN);
out_be32(&mmdc->mprddlctl, CONFIG_SYS_MMDC_PHY_RD_DLY_LINES_CFG);
set_wait_for_bits_clear(&mmdc->mpdgctrl0,
AUTO_RD_DQS_GATING_CALIBRATION_EN,
AUTO_RD_DQS_GATING_CALIBRATION_EN);

out_be32(&mmdc->mdscr, (CONFIGURATION_REQ | CMD_LOAD_MODE_REG |
CMD_BANK_ADDR_3));

/* Calibrations now: Read calibration */
out_be32(&mmdc->mdscr, (CMD_ADDR_MSB_MR_OP(0x4) | CONFIGURATION_REQ |
CMD_PRECHARGE_BANK_OPEN | CMD_BANK_ADDR_0));
out_be32(&mmdc->mdscr, (CMD_ADDR_LSB_MR_ADDR(0x4) | CONFIGURATION_REQ |
CMD_LOAD_MODE_REG | CMD_BANK_ADDR_3));
out_be32(&mmdc->mppdcmpr2, MPR_COMPARE_EN);
set_wait_for_bits_clear(&mmdc->mprddlhwctl,
AUTO_RD_CALIBRATION_EN,
AUTO_RD_CALIBRATION_EN);

out_be32(&mmdc->mdscr, (CONFIGURATION_REQ | CMD_LOAD_MODE_REG |
CMD_BANK_ADDR_3));

/* PD, SR */
out_be32(&mmdc->mdpdc, CONFIG_SYS_MMDC_CORE_PWR_DOWN_CTRL);
out_be32(&mmdc->mapsr, CONFIG_SYS_MMDC_CORE_PWR_SAV_CTRL_STAT);

/* refresh scheme */
set_wait_for_bits_clear(&mmdc->mdref,
CONFIG_SYS_MMDC_CORE_REFRESH_CTL,
START_REFRESH);

/* disable CON_REQ */
out_be32(&mmdc->mdscr, DISABLE_CFG_REQ);
}

int dram_init(void)
{
mmdc_init();
Expand Down
116 changes: 0 additions & 116 deletions board/freescale/ls1012aqds/ls1012aqds.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,6 @@

DECLARE_GLOBAL_DATA_PTR;

static void set_wait_for_bits_clear(void *ptr, u32 value, u32 bits)
{
int timeout = 1000;

out_be32(ptr, value);

while (in_be32(ptr) & bits) {
udelay(100);
timeout--;
}
if (timeout <= 0)
puts("Error: wait for clear timeout.\n");
}

int checkboard(void)
{
char buf[64];
Expand All @@ -66,108 +52,6 @@ int checkboard(void)
return 0;
}

void mmdc_init(void)
{
struct mmdc_p_regs *mmdc =
(struct mmdc_p_regs *)CONFIG_SYS_FSL_DDR_ADDR;

out_be32(&mmdc->mdscr, CONFIGURATION_REQ);

/* configure timing parms */
out_be32(&mmdc->mdotc, CONFIG_SYS_MMDC_CORE_ODT_TIMING);
out_be32(&mmdc->mdcfg0, CONFIG_SYS_MMDC_CORE_TIMING_CFG_0);
out_be32(&mmdc->mdcfg1, CONFIG_SYS_MMDC_CORE_TIMING_CFG_1);
out_be32(&mmdc->mdcfg2, CONFIG_SYS_MMDC_CORE_TIMING_CFG_2);

/* other parms */
out_be32(&mmdc->mdmisc, CONFIG_SYS_MMDC_CORE_MISC);
out_be32(&mmdc->mpmur0, CONFIG_SYS_MMDC_PHY_MEASURE_UNIT);
out_be32(&mmdc->mdrwd, CONFIG_SYS_MMDC_CORE_RDWR_CMD_DELAY);
out_be32(&mmdc->mpodtctrl, CONFIG_SYS_MMDC_PHY_ODT_CTRL);

/* out of reset delays */
out_be32(&mmdc->mdor, CONFIG_SYS_MMDC_CORE_OUT_OF_RESET_DELAY);

/* physical parms */
out_be32(&mmdc->mdctl, CONFIG_SYS_MMDC_CORE_CONTROL_1);
out_be32(&mmdc->mdasp, CONFIG_SYS_MMDC_CORE_ADDR_PARTITION);

/* Enable MMDC */
out_be32(&mmdc->mdctl, CONFIG_SYS_MMDC_CORE_CONTROL_2);

/* dram init sequence: update MRs */
out_be32(&mmdc->mdscr, (CMD_ADDR_LSB_MR_ADDR(0x8) | CONFIGURATION_REQ |
CMD_LOAD_MODE_REG | CMD_BANK_ADDR_2));
out_be32(&mmdc->mdscr, (CONFIGURATION_REQ | CMD_LOAD_MODE_REG |
CMD_BANK_ADDR_3));
out_be32(&mmdc->mdscr, (CMD_ADDR_LSB_MR_ADDR(0x4) | CONFIGURATION_REQ |
CMD_LOAD_MODE_REG | CMD_BANK_ADDR_1));
out_be32(&mmdc->mdscr, (CMD_ADDR_MSB_MR_OP(0x19) |
CMD_ADDR_LSB_MR_ADDR(0x30) | CONFIGURATION_REQ |
CMD_LOAD_MODE_REG | CMD_BANK_ADDR_0));

/* dram init sequence: ZQCL */
out_be32(&mmdc->mdscr, (CMD_ADDR_MSB_MR_OP(0x4) | CONFIGURATION_REQ |
CMD_ZQ_CALIBRATION | CMD_BANK_ADDR_0));
set_wait_for_bits_clear(&mmdc->mpzqhwctrl,
CONFIG_SYS_MMDC_PHY_ZQ_HW_CTRL,
FORCE_ZQ_AUTO_CALIBRATION);

/* Calibrations now: wr lvl */
out_be32(&mmdc->mdscr, (CMD_ADDR_LSB_MR_ADDR(0x84) |
CONFIGURATION_REQ | CMD_LOAD_MODE_REG |
CMD_BANK_ADDR_1));
out_be32(&mmdc->mdscr, (CONFIGURATION_REQ | WL_EN | CMD_NORMAL));
set_wait_for_bits_clear(&mmdc->mpwlgcr, WR_LVL_HW_EN, WR_LVL_HW_EN);

mdelay(1);

out_be32(&mmdc->mdscr, (CMD_ADDR_LSB_MR_ADDR(0x4) | CONFIGURATION_REQ |
CMD_LOAD_MODE_REG | CMD_BANK_ADDR_1));
out_be32(&mmdc->mdscr, CONFIGURATION_REQ);

mdelay(1);

/* Calibrations now: Read DQS gating calibration */
out_be32(&mmdc->mdscr, (CMD_ADDR_MSB_MR_OP(0x4) | CONFIGURATION_REQ |
CMD_PRECHARGE_BANK_OPEN | CMD_BANK_ADDR_0));
out_be32(&mmdc->mdscr, (CMD_ADDR_LSB_MR_ADDR(0x4) | CONFIGURATION_REQ |
CMD_LOAD_MODE_REG | CMD_BANK_ADDR_3));
out_be32(&mmdc->mppdcmpr2, MPR_COMPARE_EN);
out_be32(&mmdc->mprddlctl, CONFIG_SYS_MMDC_PHY_RD_DLY_LINES_CFG);
set_wait_for_bits_clear(&mmdc->mpdgctrl0,
AUTO_RD_DQS_GATING_CALIBRATION_EN,
AUTO_RD_DQS_GATING_CALIBRATION_EN);

out_be32(&mmdc->mdscr, (CONFIGURATION_REQ | CMD_LOAD_MODE_REG |
CMD_BANK_ADDR_3));

/* Calibrations now: Read calibration */
out_be32(&mmdc->mdscr, (CMD_ADDR_MSB_MR_OP(0x4) | CONFIGURATION_REQ |
CMD_PRECHARGE_BANK_OPEN | CMD_BANK_ADDR_0));
out_be32(&mmdc->mdscr, (CMD_ADDR_LSB_MR_ADDR(0x4) | CONFIGURATION_REQ |
CMD_LOAD_MODE_REG | CMD_BANK_ADDR_3));
out_be32(&mmdc->mppdcmpr2, MPR_COMPARE_EN);
set_wait_for_bits_clear(&mmdc->mprddlhwctl,
AUTO_RD_CALIBRATION_EN,
AUTO_RD_CALIBRATION_EN);

out_be32(&mmdc->mdscr, (CONFIGURATION_REQ | CMD_LOAD_MODE_REG |
CMD_BANK_ADDR_3));

/* PD, SR */
out_be32(&mmdc->mdpdc, CONFIG_SYS_MMDC_CORE_PWR_DOWN_CTRL);
out_be32(&mmdc->mapsr, CONFIG_SYS_MMDC_CORE_PWR_SAV_CTRL_STAT);

/* refresh scheme */
set_wait_for_bits_clear(&mmdc->mdref,
CONFIG_SYS_MMDC_CORE_REFRESH_CTL,
START_REFRESH);

/* disable CON_REQ */
out_be32(&mmdc->mdscr, DISABLE_CFG_REQ);
}

int dram_init(void)
{
mmdc_init();
Expand Down
Loading

0 comments on commit b9e745b

Please sign in to comment.