summaryrefslogtreecommitdiff
path: root/drivers/ram/renesas/dbsc5/dram.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ram/renesas/dbsc5/dram.c')
-rw-r--r--drivers/ram/renesas/dbsc5/dram.c92
1 files changed, 66 insertions, 26 deletions
diff --git a/drivers/ram/renesas/dbsc5/dram.c b/drivers/ram/renesas/dbsc5/dram.c
index 6f78afb0ab5..ca8a7fb4783 100644
--- a/drivers/ram/renesas/dbsc5/dram.c
+++ b/drivers/ram/renesas/dbsc5/dram.c
@@ -1325,6 +1325,11 @@ static const u32 PI_DARRAY3_1_CSx_Fx[CS_CNT][3] = {
#define DBSC_DBACEN 0x200
#define DBSC_DBRFEN 0x204
#define DBSC_DBCMD 0x208
+#define DBSC_DBCMD_CMD_OPCODE_PD 0x8
+#define DBSC_DBCMD_CMD_OPCODE_MRW 0xe
+#define DBSC_DBCMD_CMD_OPCODE_MRR 0xf
+#define DBSC_DBCMD_CMD_CHANNEL_ALL 0x8
+#define DBSC_DBCMD_CMD_RANK_ALL 0x4
#define DBSC_DBWAIT 0x210
#define DBSC_DBBL 0x400
#define DBSC_DBBLA 0x400
@@ -1736,24 +1741,20 @@ static void dbsc5_reg_write(void __iomem *addr, u32 data)
}
/**
- * dbsc5_reg_write() - DRAM Command Write Access
+ * dbsc5_wait_dbwait() - DRAM Command Wait Access Completion
* @dev: DBSC5 device
- * @cmd DRAM command.
*
- * First, execute the dummy read to DBSC_DBCMD.
- * Confirm that no DBSC command operation is in progress 0.
- * Write the contents of the command to be sent to DRAM.
+ * Wait for DRAM access completion. This is used before sending a command
+ * to the DRAM to assure no other command is in flight already, or while
+ * waiting for MRR command to complete.
*/
-static void dbsc5_send_dbcmd2(struct udevice *dev, u32 cmd)
+static void dbsc5_wait_dbwait(struct udevice *dev)
{
struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
u32 val;
int ret;
- /* dummy read */
- readl(regs_dbsc_d + DBSC_DBCMD);
-
ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBWAIT, val, ((val & BIT(0)) == 0), 1000000);
if (ret < 0) {
printf("%s DBWAIT bit 0 timeout\n", __func__);
@@ -1765,6 +1766,32 @@ static void dbsc5_send_dbcmd2(struct udevice *dev, u32 cmd)
printf("%s DBWAIT + 0x4000 bit 0 timeout\n", __func__);
hang();
}
+}
+
+/**
+ * dbsc5_send_dbcmd2() - DRAM Command Write Access
+ * @dev: DBSC5 device
+ * @opcode DRAM controller opcode
+ * @channel DRAM controller channel (0..3)
+ * @rank DRAM controller rank (0..1)
+ * @arg Command and argument bits (command specific encoding)
+ *
+ * First, execute the dummy read to DBSC_DBCMD.
+ * Confirm that no DBSC command operation is in progress 0.
+ * Write the contents of the command to be sent to DRAM.
+ */
+static void dbsc5_send_dbcmd2(struct udevice *dev, const u8 opcode,
+ const u8 channel, const u8 rank,
+ const u16 arg)
+{
+ const u32 cmd = (opcode << 24) | (channel << 20) | (rank << 16) | arg;
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+
+ /* dummy read */
+ readl(regs_dbsc_d + DBSC_DBCMD);
+
+ dbsc5_wait_dbwait(dev);
dbsc5_reg_write(regs_dbsc_d + DBSC_DBCMD, cmd);
}
@@ -2950,10 +2977,14 @@ static u32 dbsc5_pi_training(struct udevice *dev)
writel(0x21, regs_dbsc_d + DBSC_DBDFICNT(ch));
/* Dummy PDE */
- dbsc5_send_dbcmd2(dev, 0x8840000);
+ dbsc5_send_dbcmd2(dev, DBSC_DBCMD_CMD_OPCODE_PD,
+ DBSC_DBCMD_CMD_CHANNEL_ALL,
+ DBSC_DBCMD_CMD_RANK_ALL, 0);
/* PDX */
- dbsc5_send_dbcmd2(dev, 0x8840001);
+ dbsc5_send_dbcmd2(dev, DBSC_DBCMD_CMD_OPCODE_PD,
+ DBSC_DBCMD_CMD_CHANNEL_ALL,
+ DBSC_DBCMD_CMD_RANK_ALL, 1);
/* Wait init_complete */
for (retry = 0; retry < retry_max; retry++) {
@@ -4085,25 +4116,27 @@ static u32 dbsc5_read_training(struct udevice *dev)
}
/**
- * dbsc5_ddr_register_set() - DDR mode register setting
+ * dbsc5_ddr_register_mr28_set() - DDR mode register MR28 set
* @dev: DBSC5 device
*
* Set the mode register 28 of the SDRAM.
* ZQ Mode: Command-Based ZQ Calibration
* ZQ interval: Background Cal Interval < 64ms
*/
-static void dbsc5_ddr_register_set(struct udevice *dev)
+static void dbsc5_ddr_register_mr28_set(struct udevice *dev)
{
- dbsc5_send_dbcmd2(dev, 0xE841C24);
+ dbsc5_send_dbcmd2(dev, DBSC_DBCMD_CMD_OPCODE_MRW,
+ DBSC_DBCMD_CMD_CHANNEL_ALL,
+ DBSC_DBCMD_CMD_RANK_ALL, (28 << 8) | 0x24);
}
/**
- * dbsc5_ddr_register_read() - DDR mode register read
+ * dbsc5_ddr_register_mr27_mr57_read() - DDR mode register MR27/MR57 read
* @dev: DBSC5 device
*
* Set the mode register 27 and 57 of the SDRAM.
*/
-static void dbsc5_ddr_register_read(struct udevice *dev)
+static void dbsc5_ddr_register_mr27_mr57_read(struct udevice *dev)
{
struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
@@ -4111,17 +4144,21 @@ static void dbsc5_ddr_register_read(struct udevice *dev)
return;
/* MR27 rank0 */
- dbsc5_send_dbcmd2(dev, 0xF801B00);
+ dbsc5_send_dbcmd2(dev, DBSC_DBCMD_CMD_OPCODE_MRR,
+ DBSC_DBCMD_CMD_CHANNEL_ALL, 0, 27 << 8);
/* MR57 rank0 */
- dbsc5_send_dbcmd2(dev, 0xF803900);
+ dbsc5_send_dbcmd2(dev, DBSC_DBCMD_CMD_OPCODE_MRR,
+ DBSC_DBCMD_CMD_CHANNEL_ALL, 0, 57 << 8);
if (!priv->ch_have_this_cs[1])
return;
/* MR27 rank1 */
- dbsc5_send_dbcmd2(dev, 0xF811B00);
+ dbsc5_send_dbcmd2(dev, DBSC_DBCMD_CMD_OPCODE_MRR,
+ DBSC_DBCMD_CMD_CHANNEL_ALL, 1, 27 << 8);
/* MR57 rank1 */
- dbsc5_send_dbcmd2(dev, 0xF813900);
+ dbsc5_send_dbcmd2(dev, DBSC_DBCMD_CMD_OPCODE_MRR,
+ DBSC_DBCMD_CMD_CHANNEL_ALL, 1, 57 << 8);
}
/**
@@ -4200,8 +4237,8 @@ static u32 dbsc5_init_ddr(struct udevice *dev)
dbsc5_dbsc_regset(dev);
/* Frequency selection change (F1->F2) */
- dbsc5_ddr_setval_all_ch(dev, PHY_FREQ_SEL_INDEX, 0x1);
- dbsc5_ddr_setval_all_ch(dev, PHY_FREQ_SEL_MULTICAST_EN, 0x0);
+ dbsc5_ddr_setval_all_ch(dev, PHY_FREQ_SEL_INDEX, 0x1);
+ dbsc5_ddr_setval_all_ch(dev, PHY_FREQ_SEL_MULTICAST_EN, 0x0);
/* dfi_init_start (start ddrphy) & execute pi_training */
phytrainingok = dbsc5_pi_training(dev);
@@ -4278,10 +4315,10 @@ static u32 dbsc5_init_ddr(struct udevice *dev)
/* setup DDR mode registers */
/* MRS */
- dbsc5_ddr_register_set(dev);
+ dbsc5_ddr_register_mr28_set(dev);
/* MRR */
- dbsc5_ddr_register_read(dev);
+ dbsc5_ddr_register_mr27_mr57_read(dev);
/* training complete, setup DBSC */
dbsc5_dbsc_regset_post(dev);
@@ -4296,10 +4333,13 @@ static u32 dbsc5_init_ddr(struct udevice *dev)
/**
* dbsc5_get_board_data() - Obtain board specific DRAM configuration
+ * @dev: DBSC5 device
+ * @modemr0: MODEMR0 register content
*
* Return board specific DRAM configuration structure pointer.
*/
-__weak const struct renesas_dbsc5_board_config *dbsc5_get_board_data(void)
+__weak const struct renesas_dbsc5_board_config *
+dbsc5_get_board_data(struct udevice *dev, const u32 modemr0)
{
return &renesas_v4h_dbsc5_board_config;
}
@@ -4335,7 +4375,7 @@ static int renesas_dbsc5_dram_probe(struct udevice *dev)
u32 ch, cs;
/* Get board data */
- priv->dbsc5_board_config = dbsc5_get_board_data();
+ priv->dbsc5_board_config = dbsc5_get_board_data(dev, modemr0);
priv->ddr_phyvalid = (u32)(priv->dbsc5_board_config->bdcfg_phyvalid);
priv->max_density = 0;
priv->cpg_regs = (void __iomem *)ofnode_get_addr(cnode);