From 8fbf39698cbe972ddbef8084c1e1cc5ff4239d63 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 25 Mar 2025 23:43:29 +0100 Subject: ram: renesas: dbsc5: Clarify MR27/MR28/MR57 register operations Rename dbsc5_ddr_register_read() to dbsc5_ddr_register_mr27_mr57_read() and dbsc5_ddr_register_set() to dbsc5_ddr_register_mr28_set() to make it clear what those functions really do. No functional change. Signed-off-by: Marek Vasut --- drivers/ram/renesas/dbsc5/dram.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/ram/renesas/dbsc5/dram.c b/drivers/ram/renesas/dbsc5/dram.c index 6f78afb0ab5..e0c4e5fe6c0 100644 --- a/drivers/ram/renesas/dbsc5/dram.c +++ b/drivers/ram/renesas/dbsc5/dram.c @@ -4085,25 +4085,25 @@ 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_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); @@ -4278,10 +4278,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); -- cgit v1.3.1 From 34cf3a269c269241de46ea4c04aa3ec750da4ea5 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 25 Mar 2025 23:43:30 +0100 Subject: ram: renesas: dbsc5: Drop space before dbsc5_ddr_setval_all_ch() Remove leading space before dbsc5_ddr_setval_all_ch() , no functional change. Signed-off-by: Marek Vasut --- drivers/ram/renesas/dbsc5/dram.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ram/renesas/dbsc5/dram.c b/drivers/ram/renesas/dbsc5/dram.c index e0c4e5fe6c0..730ce79605b 100644 --- a/drivers/ram/renesas/dbsc5/dram.c +++ b/drivers/ram/renesas/dbsc5/dram.c @@ -4200,8 +4200,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); -- cgit v1.3.1 From c238bc3b0fd2ef25368f8ce886a17f9f4e0b43cc Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 25 Mar 2025 23:43:31 +0100 Subject: ram: renesas: dbsc5: Improve dbsc5_send_dbcmd2() signature Update dbsc5_send_dbcmd2() such that it takes multiple parameters instead of one magic register content value. These parameters are used to form the same resulting register value internally in the dbsc5_send_dbcmd2() function, but from well defined input constants. The new input constants are the operation code, channel, rank, and operation argument. The argument is operation code specific, therefore it is still a 16-bit magic number, but the rest of the arguments are now split up. No functional change. Signed-off-by: Marek Vasut --- drivers/ram/renesas/dbsc5/dram.c | 41 ++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/drivers/ram/renesas/dbsc5/dram.c b/drivers/ram/renesas/dbsc5/dram.c index 730ce79605b..461c862ea27 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,16 +1741,22 @@ static void dbsc5_reg_write(void __iomem *addr, u32 data) } /** - * dbsc5_reg_write() - DRAM Command Write Access + * dbsc5_send_dbcmd2() - DRAM Command Write Access * @dev: DBSC5 device - * @cmd DRAM command. + * @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, u32 cmd) +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; u32 val; @@ -2950,10 +2961,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++) { @@ -4094,7 +4109,9 @@ static u32 dbsc5_read_training(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); } /** @@ -4111,17 +4128,21 @@ static void dbsc5_ddr_register_mr27_mr57_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); } /** -- cgit v1.3.1 From 401c268e1d295983eb4830f539bf2ad04dfaa2ad Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 25 Mar 2025 23:43:32 +0100 Subject: ram: renesas: dbsc5: Factor out dbsc5_wait_dbwait() Extract wait for completion code from dbsc5_send_dbcmd2() into new separate function dbsc5_wait_dbwait(). This extracted code can be used to implement MR register read in the future. Signed-off-by: Marek Vasut --- drivers/ram/renesas/dbsc5/dram.c | 42 +++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/drivers/ram/renesas/dbsc5/dram.c b/drivers/ram/renesas/dbsc5/dram.c index 461c862ea27..ce04dd58180 100644 --- a/drivers/ram/renesas/dbsc5/dram.c +++ b/drivers/ram/renesas/dbsc5/dram.c @@ -1740,6 +1740,34 @@ static void dbsc5_reg_write(void __iomem *addr, u32 data) writel(data, addr + 0x8000); } +/** + * dbsc5_wait_dbwait() - DRAM Command Wait Access Completion + * @dev: DBSC5 device + * + * 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_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; + + 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__); + hang(); + } + + ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBWAIT + 0x4000, val, ((val & BIT(0)) == 0), 1000000); + if (ret < 0) { + printf("%s DBWAIT + 0x4000 bit 0 timeout\n", __func__); + hang(); + } +} + /** * dbsc5_send_dbcmd2() - DRAM Command Write Access * @dev: DBSC5 device @@ -1759,23 +1787,11 @@ static void dbsc5_send_dbcmd2(struct udevice *dev, const u8 opcode, 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; - 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__); - hang(); - } - - ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBWAIT + 0x4000, val, ((val & BIT(0)) == 0), 1000000); - if (ret < 0) { - printf("%s DBWAIT + 0x4000 bit 0 timeout\n", __func__); - hang(); - } + dbsc5_wait_dbwait(dev); dbsc5_reg_write(regs_dbsc_d + DBSC_DBCMD, cmd); } -- cgit v1.3.1 From 47dad5cc61dd955cca342bbda8c146548ef3409c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 25 Mar 2025 23:43:33 +0100 Subject: ram: renesas: dbsc5: Pass udevice and MODEMR0 to dbsc5_get_board_data() Pass DBSC5 udevice and MODEMR0 register values to board specific function dbsc5_get_board_data(). The board specific implementation of dbsc5_get_board_data() can return struct renesas_dbsc5_board_config which matches the board based on the content of MODEMR0 or content of DT accessible via the udevice. Signed-off-by: Marek Vasut --- drivers/ram/renesas/dbsc5/dram.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/ram/renesas/dbsc5/dram.c b/drivers/ram/renesas/dbsc5/dram.c index ce04dd58180..ca8a7fb4783 100644 --- a/drivers/ram/renesas/dbsc5/dram.c +++ b/drivers/ram/renesas/dbsc5/dram.c @@ -4333,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; } @@ -4372,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); -- cgit v1.3.1