Message ID | 9356277340f7409b8627c2590377d290@PH1P110MB1393.NAMP110.PROD.OUTLOOK.COM |
---|---|
State | Deferred |
Delegated to: | Tom Rini |
Headers | show |
Series | [1/1] am65x_gp_evm: Support for ECC DDR with DMA priming | expand |
Hello, I am inquiring on the status of this patch. Is it still being held for review? Thanks, Ben Roytburd From: Ben Roytburd Sent: Friday, May 26, 2023 3:39 PM To: u-boot@lists.denx.de Cc: trini@konsulko.com Subject: [PATCH 1/1] am65x_gp_evm: Support for ECC DDR with DMA priming From e019ed98623c8c8388bef3082002d27d5ec9de40 Mon Sep 17 00:00:00 2001 From: broytburd <broytburd@relativityspace.com<mailto:broytburd@relativityspace.com>> Date: Fri, 26 May 2023 09:14:14 -0700 Subject: [PATCH 1/1] am65x_gp_evm: Support for ECC DDR with DMA priming Add support for configuring DDR4 memory on AM65x_GP_EVM SR1.0 with ECC. Add register writes and memory priming function for DDR initialization. Priming done using dma_memcpy from MSMC SRAM, bugfix required for k3 udma driver to prevent dereferencing a null pointer within unprimed DDR space. Signed-off-by: broytburd <broytburd@relativityspace.com<mailto:broytburd@relativityspace.com>> Cc: Tom Rini <trini@konsulko.com<mailto:trini@konsulko.com>> --- arch/arm/dts/k3-am654-base-board.dts | 5 +- drivers/dma/ti/k3-udma.c | 9 +++- drivers/ram/k3-am654-ddrss.c | 74 +++++++++++++++++++++++++++- 3 files changed, 81 insertions(+), 7 deletions(-) diff --git a/arch/arm/dts/k3-am654-base-board.dts b/arch/arm/dts/k3-am654-base-board.dts index cfbcebfa37..bd54c84359 100644 --- a/arch/arm/dts/k3-am654-base-board.dts +++ b/arch/arm/dts/k3-am654-base-board.dts @@ -20,9 +20,8 @@ memory@80000000 { device_type = "memory"; - /* 4G RAM */ - reg = <0x00000000 0x80000000 0x00000000 0x80000000>, - <0x00000008 0x80000000 0x00000000 0x80000000>; + /* 2G RAM */ + reg = <0x00000000 0x80000000 0x00000000 0x80000000>; }; reserved-memory { diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index 05c3a4311c..461162ab6c 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -1044,8 +1044,8 @@ static int udma_alloc_tchan_sci_req(struct udma_chan *uc) static int udma_alloc_rchan_sci_req(struct udma_chan *uc) { struct udma_dev *ud = uc->ud; - int fd_ring = k3_nav_ringacc_get_ring_id(uc->rflow->fd_ring); - int rx_ring = k3_nav_ringacc_get_ring_id(uc->rflow->r_ring); + int fd_ring = 0; + int rx_ring = 0; int tc_ring = k3_nav_ringacc_get_ring_id(uc->tchan->tc_ring); struct ti_sci_msg_rm_udmap_rx_ch_cfg req = { 0 }; struct ti_sci_msg_rm_udmap_flow_cfg flow_req = { 0 }; @@ -1053,6 +1053,11 @@ static int udma_alloc_rchan_sci_req(struct udma_chan *uc) u32 mode; int ret; + if (!uc->rflow) { + fd_ring = k3_nav_ringacc_get_ring_id(uc->rflow->fd_ring); + rx_ring = k3_nav_ringacc_get_ring_id(uc->rflow->r_ring); + } + if (uc->config.pkt_mode) mode = TI_SCI_RM_UDMAP_CHAN_TYPE_PKT_PBRR; else diff --git a/drivers/ram/k3-am654-ddrss.c b/drivers/ram/k3-am654-ddrss.c index b8338f84a3..6f28cb856f 100644 --- a/drivers/ram/k3-am654-ddrss.c +++ b/drivers/ram/k3-am654-ddrss.c @@ -9,6 +9,7 @@ #include <common.h> #include <clk.h> #include <dm.h> +#include <dma.h> #include <log.h> #include <ram.h> #include <asm/io.h> @@ -24,7 +25,20 @@ u32 wait_on_value(u32 read_bit_mask, u32 match_value, void *read_addr, #define LDELAY 10000 /* DDRSS PHY configuration register fixed values */ -#define DDRSS_DDRPHY_RANKIDR_RANK0 0 +#define DDRSS_DDRPHY_RANKIDR_RANK0 0x00000000 +#define DDRSS_DDRPHY_RANKIDR_RANK1 0x00010001 + +/* Amount of DDR we wish to prime */ +#define DATA_BYTES 0x80000000 + +/* Amount of MSMC memory we will use to prime */ +#define MSMC_BYTES 0x20000000 + +/* Base address of DDR */ +static u32 *ddr_ptr = (uint32_t *)0x80000000; + +/* Base address of MSMC */ +static u32 *msmc_ptr = (uint32_t *)0x60000000; /** * struct am654_ddrss_desc - Description of ddrss integration. @@ -49,6 +63,15 @@ struct am654_ddrss_desc { struct ddrss_params params; }; +/** + * am654_prime_ecc(struct am654_ddrss_desc *ddrss) - Prime ECC + * + * Write a specified pattern to our entire DDR so that ECC timing + * parameters can be calibrated + * + */ +static int am654_prime_ecc(struct am654_ddrss_desc *ddrss); + static inline u32 ddrss_readl(void __iomem *addr, unsigned int offset) { return readl(addr + offset); @@ -172,6 +195,11 @@ static void am654_ddrss_ctrl_configuration(struct am654_ddrss_desc *ddrss) ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP10, map->ddrctl_addrmap10); ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP11, map->ddrctl_addrmap11); + ddrss_ctl_writel(DDRSS_DDRCTL_DQMAP0, map->ddrctl_dqmap0); + ddrss_ctl_writel(DDRSS_DDRCTL_DQMAP1, map->ddrctl_dqmap1); + ddrss_ctl_writel(DDRSS_DDRCTL_DQMAP4, map->ddrctl_dqmap4); + ddrss_ctl_writel(DDRSS_DDRCTL_DQMAP5, map->ddrctl_dqmap5); + ddrss_ctl_writel(DDRSS_DDRCTL_ODTCFG, reg->ddrctl_odtcfg); ddrss_ctl_writel(DDRSS_DDRCTL_ODTMAP, reg->ddrctl_odtmap); @@ -287,12 +315,14 @@ static void am654_ddrss_phy_configuration(struct am654_ddrss_desc *ddrss) ddrss_phy_writel(DDRSS_DDRPHY_DX1GCR4, cfg->ddrphy_dx1gcr4); ddrss_phy_writel(DDRSS_DDRPHY_DX2GCR4, cfg->ddrphy_dx2gcr4); ddrss_phy_writel(DDRSS_DDRPHY_DX3GCR4, cfg->ddrphy_dx3gcr4); + ddrss_phy_writel(DDRSS_DDRPHY_DX4GCR4, cfg->ddrphy_dx4gcr4); ddrss_phy_writel(DDRSS_DDRPHY_PGCR5, cfg->ddrphy_pgcr5); ddrss_phy_writel(DDRSS_DDRPHY_DX0GCR5, cfg->ddrphy_dx0gcr5); ddrss_phy_writel(DDRSS_DDRPHY_DX1GCR5, cfg->ddrphy_dx1gcr5); ddrss_phy_writel(DDRSS_DDRPHY_DX2GCR5, cfg->ddrphy_dx2gcr5); ddrss_phy_writel(DDRSS_DDRPHY_DX3GCR5, cfg->ddrphy_dx3gcr5); + ddrss_phy_writel(DDRSS_DDRPHY_DX4GCR5, cfg->ddrphy_dx4gcr5); ddrss_phy_writel(DDRSS_DDRPHY_RANKIDR, DDRSS_DDRPHY_RANKIDR_RANK0); @@ -300,6 +330,16 @@ static void am654_ddrss_phy_configuration(struct am654_ddrss_desc *ddrss) ddrss_phy_writel(DDRSS_DDRPHY_DX1GTR0, cfg->ddrphy_dx1gtr0); ddrss_phy_writel(DDRSS_DDRPHY_DX2GTR0, cfg->ddrphy_dx2gtr0); ddrss_phy_writel(DDRSS_DDRPHY_DX3GTR0, cfg->ddrphy_dx3gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX4GTR0, cfg->ddrphy_dx4gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_ODTCR, cfg->ddrphy_odtcr); + + ddrss_phy_writel(DDRSS_DDRPHY_RANKIDR, DDRSS_DDRPHY_RANKIDR_RANK1); + + ddrss_phy_writel(DDRSS_DDRPHY_DX0GTR0, cfg->ddrphy_dx0gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX1GTR0, cfg->ddrphy_dx1gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX2GTR0, cfg->ddrphy_dx2gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX3GTR0, cfg->ddrphy_dx3gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX4GTR0, cfg->ddrphy_dx4gtr0); ddrss_phy_writel(DDRSS_DDRPHY_ODTCR, cfg->ddrphy_odtcr); ddrss_phy_writel(DDRSS_DDRPHY_DX8SL0IOCR, cfg->ddrphy_dx8sl0iocr); @@ -543,13 +583,14 @@ int disable_dqs_pd(struct am654_ddrss_desc *ddrss) int cleanup_training(struct am654_ddrss_desc *ddrss) { u32 val; - u32 dgsl0, dgsl1, dgsl2, dgsl3, rddly, rd2wr_wr2rd; + u32 dgsl0, dgsl1, dgsl2, dgsl3, dgsl4, rddly, rd2wr_wr2rd; ddrss_phy_writel(DDRSS_DDRPHY_RANKIDR, 0x00000000); dgsl0 = (ddrss_phy_readl(DDRSS_DDRPHY_DX0GTR0) & 0x1F) >> 2; dgsl1 = (ddrss_phy_readl(DDRSS_DDRPHY_DX1GTR0) & 0x1F) >> 2; dgsl2 = (ddrss_phy_readl(DDRSS_DDRPHY_DX2GTR0) & 0x1F) >> 2; dgsl3 = (ddrss_phy_readl(DDRSS_DDRPHY_DX3GTR0) & 0x1F) >> 2; + dgsl4 = (ddrss_phy_readl(DDRSS_DDRPHY_DX4GTR0) & 0x1F) >> 2; rddly = dgsl0; if (dgsl1 < rddly) @@ -558,6 +599,8 @@ int cleanup_training(struct am654_ddrss_desc *ddrss) rddly = dgsl2; if (dgsl3 < rddly) rddly = dgsl3; + if (dgsl4 < rddly) + rddly = dgsl4; rddly += 5; @@ -578,6 +621,10 @@ int cleanup_training(struct am654_ddrss_desc *ddrss) val |= (rddly << 20); ddrss_phy_writel(DDRSS_DDRPHY_DX3GCR0, val); + val = (ddrss_phy_readl(DDRSS_DDRPHY_DX4GCR0) & ~0xF00000); + val |= (rddly << 20); + ddrss_phy_writel(DDRSS_DDRPHY_DX4GCR0, val); + /* * Add system latency derived from training back into rd2wr and wr2rd * rd2wr = RL + BL/2 + 1 + WR_PREAMBLE - WL + max(DXnGTR0.DGSL) / 2 @@ -591,6 +638,7 @@ int cleanup_training(struct am654_ddrss_desc *ddrss) dgsl1 = (ddrss_phy_readl(DDRSS_DDRPHY_DX1GTR0) & 0x1F); dgsl2 = (ddrss_phy_readl(DDRSS_DDRPHY_DX2GTR0) & 0x1F); dgsl3 = (ddrss_phy_readl(DDRSS_DDRPHY_DX3GTR0) & 0x1F); + dgsl4 = (ddrss_phy_readl(DDRSS_DDRPHY_DX4GTR0) & 0x1F); /* Find maximum value across all bytes */ rd2wr_wr2rd = dgsl0; @@ -600,6 +648,8 @@ int cleanup_training(struct am654_ddrss_desc *ddrss) rd2wr_wr2rd = dgsl2; if (dgsl3 > rd2wr_wr2rd) rd2wr_wr2rd = dgsl3; + if (dgsl4 > rd2wr_wr2rd) + rd2wr_wr2rd = dgsl4; rd2wr_wr2rd >>= 1; @@ -1071,6 +1121,10 @@ static int am654_ddrss_probe(struct udevice *dev) ret = am654_ddrss_init(ddrss); + // Only prime ECC if it is enabled + if (ddrss_ctl_readl(DDRSS_DDRCTL_ECCCFG0) & 0x4) + ret = am654_prime_ecc(ddrss); + return ret; } @@ -1096,3 +1150,19 @@ U_BOOT_DRIVER(am654_ddrss) = { .probe = am654_ddrss_probe, .priv_auto = sizeof(struct am654_ddrss_desc), }; + +static int am654_prime_ecc(struct am654_ddrss_desc *ddrss) +{ + int ret; + + // Use MSMC memory to prime DDR memory + for (int i = 0; i < (DATA_BYTES / MSMC_BYTES); i++) { + ret = dma_memcpy(ddr_ptr + ((MSMC_BYTES / 4) * i), msmc_ptr, MSMC_BYTES); + if (ret) { + dev_err(ddrss->dev, "DDR prime DMA Memcpy failed %d\n", ret); + return ret; + } + } + + return ret; +} -- 2.25.1
diff --git a/arch/arm/dts/k3-am654-base-board.dts b/arch/arm/dts/k3-am654-base-board.dts index cfbcebfa37..bd54c84359 100644 --- a/arch/arm/dts/k3-am654-base-board.dts +++ b/arch/arm/dts/k3-am654-base-board.dts @@ -20,9 +20,8 @@ memory@80000000 { device_type = "memory"; - /* 4G RAM */ - reg = <0x00000000 0x80000000 0x00000000 0x80000000>, - <0x00000008 0x80000000 0x00000000 0x80000000>; + /* 2G RAM */ + reg = <0x00000000 0x80000000 0x00000000 0x80000000>; }; reserved-memory { diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index 05c3a4311c..461162ab6c 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -1044,8 +1044,8 @@ static int udma_alloc_tchan_sci_req(struct udma_chan *uc) static int udma_alloc_rchan_sci_req(struct udma_chan *uc) { struct udma_dev *ud = uc->ud; - int fd_ring = k3_nav_ringacc_get_ring_id(uc->rflow->fd_ring); - int rx_ring = k3_nav_ringacc_get_ring_id(uc->rflow->r_ring); + int fd_ring = 0; + int rx_ring = 0; int tc_ring = k3_nav_ringacc_get_ring_id(uc->tchan->tc_ring); struct ti_sci_msg_rm_udmap_rx_ch_cfg req = { 0 }; struct ti_sci_msg_rm_udmap_flow_cfg flow_req = { 0 }; @@ -1053,6 +1053,11 @@ static int udma_alloc_rchan_sci_req(struct udma_chan *uc) u32 mode; int ret; + if (!uc->rflow) { + fd_ring = k3_nav_ringacc_get_ring_id(uc->rflow->fd_ring); + rx_ring = k3_nav_ringacc_get_ring_id(uc->rflow->r_ring); + } + if (uc->config.pkt_mode) mode = TI_SCI_RM_UDMAP_CHAN_TYPE_PKT_PBRR; else diff --git a/drivers/ram/k3-am654-ddrss.c b/drivers/ram/k3-am654-ddrss.c index b8338f84a3..6f28cb856f 100644 --- a/drivers/ram/k3-am654-ddrss.c +++ b/drivers/ram/k3-am654-ddrss.c @@ -9,6 +9,7 @@ #include <common.h> #include <clk.h> #include <dm.h> +#include <dma.h> #include <log.h> #include <ram.h> #include <asm/io.h> @@ -24,7 +25,20 @@ u32 wait_on_value(u32 read_bit_mask, u32 match_value, void *read_addr, #define LDELAY 10000 /* DDRSS PHY configuration register fixed values */ -#define DDRSS_DDRPHY_RANKIDR_RANK0 0 +#define DDRSS_DDRPHY_RANKIDR_RANK0 0x00000000 +#define DDRSS_DDRPHY_RANKIDR_RANK1 0x00010001 + +/* Amount of DDR we wish to prime */ +#define DATA_BYTES 0x80000000 + +/* Amount of MSMC memory we will use to prime */ +#define MSMC_BYTES 0x20000000 + +/* Base address of DDR */ +static u32 *ddr_ptr = (uint32_t *)0x80000000; + +/* Base address of MSMC */ +static u32 *msmc_ptr = (uint32_t *)0x60000000; /** * struct am654_ddrss_desc - Description of ddrss integration. @@ -49,6 +63,15 @@ struct am654_ddrss_desc { struct ddrss_params params; }; +/** + * am654_prime_ecc(struct am654_ddrss_desc *ddrss) - Prime ECC + * + * Write a specified pattern to our entire DDR so that ECC timing + * parameters can be calibrated + * + */ +static int am654_prime_ecc(struct am654_ddrss_desc *ddrss); + static inline u32 ddrss_readl(void __iomem *addr, unsigned int offset) { return readl(addr + offset); @@ -172,6 +195,11 @@ static void am654_ddrss_ctrl_configuration(struct am654_ddrss_desc *ddrss) ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP10, map->ddrctl_addrmap10); ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP11, map->ddrctl_addrmap11); + ddrss_ctl_writel(DDRSS_DDRCTL_DQMAP0, map->ddrctl_dqmap0); + ddrss_ctl_writel(DDRSS_DDRCTL_DQMAP1, map->ddrctl_dqmap1); + ddrss_ctl_writel(DDRSS_DDRCTL_DQMAP4, map->ddrctl_dqmap4); + ddrss_ctl_writel(DDRSS_DDRCTL_DQMAP5, map->ddrctl_dqmap5); + ddrss_ctl_writel(DDRSS_DDRCTL_ODTCFG, reg->ddrctl_odtcfg); ddrss_ctl_writel(DDRSS_DDRCTL_ODTMAP, reg->ddrctl_odtmap); @@ -287,12 +315,14 @@ static void am654_ddrss_phy_configuration(struct am654_ddrss_desc *ddrss) ddrss_phy_writel(DDRSS_DDRPHY_DX1GCR4, cfg->ddrphy_dx1gcr4); ddrss_phy_writel(DDRSS_DDRPHY_DX2GCR4, cfg->ddrphy_dx2gcr4); ddrss_phy_writel(DDRSS_DDRPHY_DX3GCR4, cfg->ddrphy_dx3gcr4); + ddrss_phy_writel(DDRSS_DDRPHY_DX4GCR4, cfg->ddrphy_dx4gcr4); ddrss_phy_writel(DDRSS_DDRPHY_PGCR5, cfg->ddrphy_pgcr5); ddrss_phy_writel(DDRSS_DDRPHY_DX0GCR5, cfg->ddrphy_dx0gcr5); ddrss_phy_writel(DDRSS_DDRPHY_DX1GCR5, cfg->ddrphy_dx1gcr5); ddrss_phy_writel(DDRSS_DDRPHY_DX2GCR5, cfg->ddrphy_dx2gcr5); ddrss_phy_writel(DDRSS_DDRPHY_DX3GCR5, cfg->ddrphy_dx3gcr5); + ddrss_phy_writel(DDRSS_DDRPHY_DX4GCR5, cfg->ddrphy_dx4gcr5); ddrss_phy_writel(DDRSS_DDRPHY_RANKIDR, DDRSS_DDRPHY_RANKIDR_RANK0); @@ -300,6 +330,16 @@ static void am654_ddrss_phy_configuration(struct am654_ddrss_desc *ddrss) ddrss_phy_writel(DDRSS_DDRPHY_DX1GTR0, cfg->ddrphy_dx1gtr0); ddrss_phy_writel(DDRSS_DDRPHY_DX2GTR0, cfg->ddrphy_dx2gtr0); ddrss_phy_writel(DDRSS_DDRPHY_DX3GTR0, cfg->ddrphy_dx3gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX4GTR0, cfg->ddrphy_dx4gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_ODTCR, cfg->ddrphy_odtcr); + + ddrss_phy_writel(DDRSS_DDRPHY_RANKIDR, DDRSS_DDRPHY_RANKIDR_RANK1); + + ddrss_phy_writel(DDRSS_DDRPHY_DX0GTR0, cfg->ddrphy_dx0gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX1GTR0, cfg->ddrphy_dx1gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX2GTR0, cfg->ddrphy_dx2gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX3GTR0, cfg->ddrphy_dx3gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX4GTR0, cfg->ddrphy_dx4gtr0); ddrss_phy_writel(DDRSS_DDRPHY_ODTCR, cfg->ddrphy_odtcr); ddrss_phy_writel(DDRSS_DDRPHY_DX8SL0IOCR, cfg->ddrphy_dx8sl0iocr); @@ -543,13 +583,14 @@ int disable_dqs_pd(struct am654_ddrss_desc *ddrss) int cleanup_training(struct am654_ddrss_desc *ddrss) { u32 val; - u32 dgsl0, dgsl1, dgsl2, dgsl3, rddly, rd2wr_wr2rd; + u32 dgsl0, dgsl1, dgsl2, dgsl3, dgsl4, rddly, rd2wr_wr2rd; ddrss_phy_writel(DDRSS_DDRPHY_RANKIDR, 0x00000000); dgsl0 = (ddrss_phy_readl(DDRSS_DDRPHY_DX0GTR0) & 0x1F) >> 2; dgsl1 = (ddrss_phy_readl(DDRSS_DDRPHY_DX1GTR0) & 0x1F) >> 2; dgsl2 = (ddrss_phy_readl(DDRSS_DDRPHY_DX2GTR0) & 0x1F) >> 2; dgsl3 = (ddrss_phy_readl(DDRSS_DDRPHY_DX3GTR0) & 0x1F) >> 2; + dgsl4 = (ddrss_phy_readl(DDRSS_DDRPHY_DX4GTR0) & 0x1F) >> 2; rddly = dgsl0; if (dgsl1 < rddly) @@ -558,6 +599,8 @@ int cleanup_training(struct am654_ddrss_desc *ddrss) rddly = dgsl2; if (dgsl3 < rddly) rddly = dgsl3; + if (dgsl4 < rddly) + rddly = dgsl4; rddly += 5; @@ -578,6 +621,10 @@ int cleanup_training(struct am654_ddrss_desc *ddrss) val |= (rddly << 20); ddrss_phy_writel(DDRSS_DDRPHY_DX3GCR0, val); + val = (ddrss_phy_readl(DDRSS_DDRPHY_DX4GCR0) & ~0xF00000); + val |= (rddly << 20); + ddrss_phy_writel(DDRSS_DDRPHY_DX4GCR0, val); + /* * Add system latency derived from training back into rd2wr and wr2rd * rd2wr = RL + BL/2 + 1 + WR_PREAMBLE - WL + max(DXnGTR0.DGSL) / 2 @@ -591,6 +638,7 @@ int cleanup_training(struct am654_ddrss_desc *ddrss) dgsl1 = (ddrss_phy_readl(DDRSS_DDRPHY_DX1GTR0) & 0x1F); dgsl2 = (ddrss_phy_readl(DDRSS_DDRPHY_DX2GTR0) & 0x1F); dgsl3 = (ddrss_phy_readl(DDRSS_DDRPHY_DX3GTR0) & 0x1F); + dgsl4 = (ddrss_phy_readl(DDRSS_DDRPHY_DX4GTR0) & 0x1F); /* Find maximum value across all bytes */ rd2wr_wr2rd = dgsl0; @@ -600,6 +648,8 @@ int cleanup_training(struct am654_ddrss_desc *ddrss) rd2wr_wr2rd = dgsl2; if (dgsl3 > rd2wr_wr2rd) rd2wr_wr2rd = dgsl3; + if (dgsl4 > rd2wr_wr2rd) + rd2wr_wr2rd = dgsl4; rd2wr_wr2rd >>= 1; @@ -1071,6 +1121,10 @@ static int am654_ddrss_probe(struct udevice *dev) ret = am654_ddrss_init(ddrss); + // Only prime ECC if it is enabled + if (ddrss_ctl_readl(DDRSS_DDRCTL_ECCCFG0) & 0x4) + ret = am654_prime_ecc(ddrss); + return ret; } @@ -1096,3 +1150,19 @@ U_BOOT_DRIVER(am654_ddrss) = { .probe = am654_ddrss_probe, .priv_auto = sizeof(struct am654_ddrss_desc), }; + +static int am654_prime_ecc(struct am654_ddrss_desc *ddrss) +{ + int ret; + + // Use MSMC memory to prime DDR memory + for (int i = 0; i < (DATA_BYTES / MSMC_BYTES); i++) { + ret = dma_memcpy(ddr_ptr + ((MSMC_BYTES / 4) * i), msmc_ptr, MSMC_BYTES); + if (ret) { + dev_err(ddrss->dev, "DDR prime DMA Memcpy failed %d\n", ret); + return ret; + } + } + + return ret; +}