[U-Boot] [PATCH v5 14/19] ddr: altera: Restructure Stratix 10 SDRAM driver
Simon Goldschmidt
simon.k.r.goldschmidt at gmail.com
Tue Oct 22 18:40:47 UTC 2019
Am 11.10.2019 um 11:52 schrieb Ley Foon Tan:
> Restructure Stratix 10 SDRAM driver. Move common code to separate
> file, in preparation to support SDRAM driver for Agilex.
>
> Signed-off-by: Ley Foon Tan <ley.foon.tan at intel.com>
>
> ---
> v3:
> - Change sdram_common.* to sdram_soc64.*
> ---
> drivers/ddr/altera/Makefile | 2 +-
> drivers/ddr/altera/sdram_s10.c | 296 +----------------
> drivers/ddr/altera/sdram_s10.h | 148 +--------
> drivers/ddr/altera/sdram_soc64.c | 304 ++++++++++++++++++
> .../ddr/altera/{sdram_s10.h => sdram_soc64.h} | 70 ++--
> 5 files changed, 341 insertions(+), 479 deletions(-)
> create mode 100644 drivers/ddr/altera/sdram_soc64.c
> copy drivers/ddr/altera/{sdram_s10.h => sdram_soc64.h} (79%)
>
> diff --git a/drivers/ddr/altera/Makefile b/drivers/ddr/altera/Makefile
> index 341ac0d73b..eb8da13b7d 100644
> --- a/drivers/ddr/altera/Makefile
> +++ b/drivers/ddr/altera/Makefile
> @@ -9,5 +9,5 @@
> ifdef CONFIG_$(SPL_)ALTERA_SDRAM
> obj-$(CONFIG_TARGET_SOCFPGA_GEN5) += sdram_gen5.o sequencer.o
> obj-$(CONFIG_TARGET_SOCFPGA_ARRIA10) += sdram_arria10.o
> -obj-$(CONFIG_TARGET_SOCFPGA_STRATIX10) += sdram_s10.o
> +obj-$(CONFIG_TARGET_SOCFPGA_STRATIX10) += sdram_soc64.o sdram_s10.o
> endif
> diff --git a/drivers/ddr/altera/sdram_s10.c b/drivers/ddr/altera/sdram_s10.c
> index 9578aa743d..fcab3ae3e4 100644
> --- a/drivers/ddr/altera/sdram_s10.c
> +++ b/drivers/ddr/altera/sdram_s10.c
> @@ -14,28 +14,14 @@
> #include "sdram_s10.h"
> #include <wait_bit.h>
> #include <asm/arch/firewall.h>
> -#include <asm/arch/system_manager.h>
> #include <asm/arch/reset_manager.h>
> #include <asm/io.h>
> #include <linux/sizes.h>
>
> -struct altera_sdram_priv {
> - struct ram_info info;
> - struct reset_ctl_bulk resets;
> -};
> -
> -struct altera_sdram_platdata {
> - void __iomem *hmc;
> - void __iomem *ddr_sch;
> - void __iomem *iomhc;
> -};
> -
> DECLARE_GLOBAL_DATA_PTR;
>
> #define DDR_CONFIG(A, B, C, R) (((A) << 24) | ((B) << 16) | ((C) << 8) | (R))
>
> -#define PGTABLE_OFF 0x4000
> -
> /* The followring are the supported configurations */
> u32 ddr_config[] = {
> /* DDR_CONFIG(Address order,Bank,Column,Row) */
> @@ -62,28 +48,6 @@ u32 ddr_config[] = {
> DDR_CONFIG(1, 4, 10, 17),
> };
>
> -static u32 hmc_readl(struct altera_sdram_platdata *plat, u32 reg)
> -{
> - return readl(plat->iomhc + reg);
> -}
> -
> -static u32 hmc_ecc_readl(struct altera_sdram_platdata *plat, u32 reg)
> -{
> - return readl(plat->hmc + reg);
> -}
> -
> -static u32 hmc_ecc_writel(struct altera_sdram_platdata *plat,
> - u32 data, u32 reg)
> -{
> - return writel(data, plat->hmc + reg);
> -}
> -
> -static u32 ddr_sch_writel(struct altera_sdram_platdata *plat, u32 data,
> - u32 reg)
> -{
> - return writel(data, plat->ddr_sch + reg);
> -}
> -
> int match_ddr_conf(u32 ddr_conf)
> {
> int i;
> @@ -95,193 +59,12 @@ int match_ddr_conf(u32 ddr_conf)
> return 0;
> }
>
> -static int emif_clear(struct altera_sdram_platdata *plat)
> -{
> - hmc_ecc_writel(plat, 0, RSTHANDSHAKECTRL);
> -
> - return wait_for_bit_le32((const void *)(plat->hmc +
> - RSTHANDSHAKESTAT),
> - DDR_HMC_RSTHANDSHAKE_MASK,
> - false, 1000, false);
> -}
> -
> -static int emif_reset(struct altera_sdram_platdata *plat)
> -{
> - u32 c2s, s2c, ret;
> -
> - c2s = hmc_ecc_readl(plat, RSTHANDSHAKECTRL) & DDR_HMC_RSTHANDSHAKE_MASK;
> - s2c = hmc_ecc_readl(plat, RSTHANDSHAKESTAT) & DDR_HMC_RSTHANDSHAKE_MASK;
> -
> - debug("DDR: c2s=%08x s2c=%08x nr0=%08x nr1=%08x nr2=%08x dst=%08x\n",
> - c2s, s2c, hmc_readl(plat, NIOSRESERVED0),
> - hmc_readl(plat, NIOSRESERVED1), hmc_readl(plat, NIOSRESERVED2),
> - hmc_readl(plat, DRAMSTS));
> -
> - if (s2c && emif_clear(plat)) {
> - printf("DDR: emif_clear() failed\n");
> - return -1;
> - }
> -
> - debug("DDR: Triggerring emif reset\n");
> - hmc_ecc_writel(plat, DDR_HMC_CORE2SEQ_INT_REQ, RSTHANDSHAKECTRL);
> -
> - /* if seq2core[3] = 0, we are good */
> - ret = wait_for_bit_le32((const void *)(plat->hmc +
> - RSTHANDSHAKESTAT),
> - DDR_HMC_SEQ2CORE_INT_RESP_MASK,
> - false, 1000, false);
> - if (ret) {
> - printf("DDR: failed to get ack from EMIF\n");
> - return ret;
> - }
> -
> - ret = emif_clear(plat);
> - if (ret) {
> - printf("DDR: emif_clear() failed\n");
> - return ret;
> - }
> -
> - debug("DDR: %s triggered successly\n", __func__);
> - return 0;
> -}
> -
> -static int poll_hmc_clock_status(void)
> -{
> - return wait_for_bit_le32((const void *)(socfpga_sysmgr_base +
> - SYSMGR_SOC64_HMC_CLK),
> - SYSMGR_HMC_CLK_STATUS_MSK, true, 1000, false);
> -}
> -
> -static void sdram_clear_mem(phys_addr_t addr, phys_size_t size)
> -{
> - phys_size_t i;
> -
> - if (addr % CONFIG_SYS_CACHELINE_SIZE) {
> - printf("DDR: address 0x%llx is not cacheline size aligned.\n",
> - addr);
> - hang();
> - }
> -
> - if (size % CONFIG_SYS_CACHELINE_SIZE) {
> - printf("DDR: size 0x%llx is not multiple of cacheline size\n",
> - size);
> - hang();
> - }
> -
> - /* Use DC ZVA instruction to clear memory to zeros by a cache line */
> - for (i = 0; i < size; i = i + CONFIG_SYS_CACHELINE_SIZE) {
> - asm volatile("dc zva, %0"
> - :
> - : "r"(addr)
> - : "memory");
> - addr += CONFIG_SYS_CACHELINE_SIZE;
> - }
> -}
> -
> -static void sdram_init_ecc_bits(bd_t *bd)
> -{
> - phys_size_t size, size_init;
> - phys_addr_t start_addr;
> - int bank = 0;
> - unsigned int start = get_timer(0);
> -
> - icache_enable();
> -
> - start_addr = bd->bi_dram[0].start;
> - size = bd->bi_dram[0].size;
> -
> - /* Initialize small block for page table */
> - memset((void *)start_addr, 0, PGTABLE_SIZE + PGTABLE_OFF);
> - gd->arch.tlb_addr = start_addr + PGTABLE_OFF;
> - gd->arch.tlb_size = PGTABLE_SIZE;
> - start_addr += PGTABLE_SIZE + PGTABLE_OFF;
> - size -= (PGTABLE_OFF + PGTABLE_SIZE);
> - dcache_enable();
> -
> - while (1) {
> - while (size) {
> - size_init = min((phys_addr_t)SZ_1G, (phys_addr_t)size);
> - sdram_clear_mem(start_addr, size_init);
> - size -= size_init;
> - start_addr += size_init;
> - WATCHDOG_RESET();
> - }
> -
> - bank++;
> - if (bank >= CONFIG_NR_DRAM_BANKS)
> - break;
> -
> - start_addr = bd->bi_dram[bank].start;
> - size = bd->bi_dram[bank].size;
> - }
> -
> - dcache_disable();
> - icache_disable();
> -
> - printf("SDRAM-ECC: Initialized success with %d ms\n",
> - (unsigned int)get_timer(start));
> -}
> -
> -static void sdram_size_check(bd_t *bd)
> -{
> - phys_size_t total_ram_check = 0;
> - phys_size_t ram_check = 0;
> - phys_addr_t start = 0;
> - int bank;
> -
> - /* Sanity check ensure correct SDRAM size specified */
> - debug("DDR: Running SDRAM size sanity check\n");
> -
> - for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
> - start = bd->bi_dram[bank].start;
> - while (ram_check < bd->bi_dram[bank].size) {
> - ram_check += get_ram_size((void *)(start + ram_check),
> - (phys_size_t)SZ_1G);
> - }
> - total_ram_check += ram_check;
> - ram_check = 0;
> - }
> -
> - /* If the ram_size is 2GB smaller, we can assume the IO space is
> - * not mapped in. gd->ram_size is the actual size of the dram
> - * not the accessible size.
> - */
> - if (total_ram_check != gd->ram_size) {
> - puts("DDR: SDRAM size check failed!\n");
> - hang();
> - }
> -
> - debug("DDR: SDRAM size check passed!\n");
> -}
> -
> -/**
> - * sdram_calculate_size() - Calculate SDRAM size
> - *
> - * Calculate SDRAM device size based on SDRAM controller parameters.
> - * Size is specified in bytes.
> - */
> -static phys_size_t sdram_calculate_size(struct altera_sdram_platdata *plat)
> -{
> - u32 dramaddrw = hmc_readl(plat, DRAMADDRW);
> -
> - phys_size_t size = 1 << (DRAMADDRW_CFG_CS_ADDR_WIDTH(dramaddrw) +
> - DRAMADDRW_CFG_BANK_GRP_ADDR_WIDTH(dramaddrw) +
> - DRAMADDRW_CFG_BANK_ADDR_WIDTH(dramaddrw) +
> - DRAMADDRW_CFG_ROW_ADDR_WIDTH(dramaddrw) +
> - DRAMADDRW_CFG_COL_ADDR_WIDTH(dramaddrw));
> -
> - size *= (2 << (hmc_ecc_readl(plat, DDRIOCTRL) &
> - DDR_HMC_DDRIOCTRL_IOSIZE_MSK));
> -
> - return size;
> -}
> -
> /**
> * sdram_mmr_init_full() - Function to initialize SDRAM MMR
> *
> * Initialize the SDRAM MMR.
> */
> -static int sdram_mmr_init_full(struct udevice *dev)
> +int sdram_mmr_init_full(struct udevice *dev)
> {
> struct altera_sdram_platdata *plat = dev->platdata;
> struct altera_sdram_priv *priv = dev_get_priv(dev);
> @@ -534,80 +317,3 @@ static int sdram_mmr_init_full(struct udevice *dev)
> return 0;
> }
>
> -static int altera_sdram_ofdata_to_platdata(struct udevice *dev)
> -{
> - struct altera_sdram_platdata *plat = dev->platdata;
> - fdt_addr_t addr;
> -
> - addr = dev_read_addr_index(dev, 0);
> - if (addr == FDT_ADDR_T_NONE)
> - return -EINVAL;
> - plat->ddr_sch = (void __iomem *)addr;
> -
> - addr = dev_read_addr_index(dev, 1);
> - if (addr == FDT_ADDR_T_NONE)
> - return -EINVAL;
> - plat->iomhc = (void __iomem *)addr;
> -
> - addr = dev_read_addr_index(dev, 2);
> - if (addr == FDT_ADDR_T_NONE)
> - return -EINVAL;
> - plat->hmc = (void __iomem *)addr;
> -
> - return 0;
> -}
> -
> -static int altera_sdram_probe(struct udevice *dev)
> -{
> - int ret;
> - struct altera_sdram_priv *priv = dev_get_priv(dev);
> -
> - ret = reset_get_bulk(dev, &priv->resets);
> - if (ret) {
> - dev_err(dev, "Can't get reset: %d\n", ret);
> - return -ENODEV;
> - }
> - reset_deassert_bulk(&priv->resets);
> -
> - if (sdram_mmr_init_full(dev) != 0) {
> - puts("SDRAM init failed.\n");
> - goto failed;
> - }
> -
> - return 0;
> -
> -failed:
> - reset_release_bulk(&priv->resets);
> - return -ENODEV;
> -}
> -
> -static int altera_sdram_get_info(struct udevice *dev,
> - struct ram_info *info)
> -{
> - struct altera_sdram_priv *priv = dev_get_priv(dev);
> -
> - info->base = priv->info.base;
> - info->size = priv->info.size;
> -
> - return 0;
> -}
> -
> -static struct ram_ops altera_sdram_ops = {
> - .get_info = altera_sdram_get_info,
> -};
> -
> -static const struct udevice_id altera_sdram_ids[] = {
> - { .compatible = "altr,sdr-ctl-s10" },
> - { /* sentinel */ }
> -};
> -
> -U_BOOT_DRIVER(altera_sdram) = {
> - .name = "altr_sdr_ctl",
> - .id = UCLASS_RAM,
> - .of_match = altera_sdram_ids,
> - .ops = &altera_sdram_ops,
> - .ofdata_to_platdata = altera_sdram_ofdata_to_platdata,
> - .platdata_auto_alloc_size = sizeof(struct altera_sdram_platdata),
> - .probe = altera_sdram_probe,
> - .priv_auto_alloc_size = sizeof(struct altera_sdram_priv),
> -};
> diff --git a/drivers/ddr/altera/sdram_s10.h b/drivers/ddr/altera/sdram_s10.h
> index 096c06cba2..cca4cb35ec 100644
> --- a/drivers/ddr/altera/sdram_s10.h
> +++ b/drivers/ddr/altera/sdram_s10.h
> @@ -11,48 +11,6 @@
> #define DDR_READ_LATENCY_DELAY 40
> #define DDR_ACTIVATE_FAWBANK 0x1
>
> -/* ECC HMC registers */
> -#define DDRIOCTRL 0x8
> -#define DDRCALSTAT 0xc
> -#define DRAMADDRWIDTH 0xe0
> -#define ECCCTRL1 0x100
> -#define ECCCTRL2 0x104
> -#define ERRINTEN 0x110
> -#define ERRINTENS 0x114
> -#define INTMODE 0x11c
> -#define INTSTAT 0x120
> -#define AUTOWB_CORRADDR 0x138
> -#define ECC_REG2WRECCDATABUS 0x144
> -#define ECC_DIAGON 0x150
> -#define ECC_DECSTAT 0x154
> -#define HPSINTFCSEL 0x210
> -#define RSTHANDSHAKECTRL 0x214
> -#define RSTHANDSHAKESTAT 0x218
> -
> -#define DDR_HMC_DDRIOCTRL_IOSIZE_MSK 0x00000003
> -#define DDR_HMC_DDRCALSTAT_CAL_MSK BIT(0)
> -#define DDR_HMC_ECCCTL_AWB_CNT_RST_SET_MSK BIT(16)
> -#define DDR_HMC_ECCCTL_CNT_RST_SET_MSK BIT(8)
> -#define DDR_HMC_ECCCTL_ECC_EN_SET_MSK BIT(0)
> -#define DDR_HMC_ECCCTL2_RMW_EN_SET_MSK BIT(8)
> -#define DDR_HMC_ECCCTL2_AWB_EN_SET_MSK BIT(0)
> -#define DDR_HMC_ECC_DIAGON_ECCDIAGON_EN_SET_MSK BIT(16)
> -#define DDR_HMC_ECC_DIAGON_WRDIAGON_EN_SET_MSK BIT(0)
> -#define DDR_HMC_ERRINTEN_SERRINTEN_EN_SET_MSK BIT(0)
> -#define DDR_HMC_ERRINTEN_DERRINTEN_EN_SET_MSK BIT(1)
> -#define DDR_HMC_INTSTAT_SERRPENA_SET_MSK BIT(0)
> -#define DDR_HMC_INTSTAT_DERRPENA_SET_MSK BIT(1)
> -#define DDR_HMC_INTSTAT_ADDRMTCFLG_SET_MSK BIT(16)
> -#define DDR_HMC_INTMODE_INTMODE_SET_MSK BIT(0)
> -#define DDR_HMC_RSTHANDSHAKE_MASK 0x000000ff
> -#define DDR_HMC_CORE2SEQ_INT_REQ 0xF
> -#define DDR_HMC_SEQ2CORE_INT_RESP_MASK BIT(3)
> -#define DDR_HMC_HPSINTFCSEL_ENABLE_MASK 0x001f1f1f
> -
> -#define DDR_HMC_ERRINTEN_INTMASK \
> - (DDR_HMC_ERRINTEN_SERRINTEN_EN_SET_MSK | \
> - DDR_HMC_ERRINTEN_DERRINTEN_EN_SET_MSK)
> -
> /* NOC DDR scheduler */
> #define DDR_SCH_ID_COREID 0
> #define DDR_SCH_ID_REVID 0x4
> @@ -79,110 +37,6 @@
> #define DDR_SCH_DEVTODEV_BUSRDTOWR_OFF 2
> #define DDR_SCH_DEVTODEV_BUSWRTORD_OFF 4
>
> -/* HMC MMR IO48 registers */
> -#define CTRLCFG0 0x28
> -#define CTRLCFG1 0x2c
> -#define DRAMTIMING0 0x50
> -#define CALTIMING0 0x7c
> -#define CALTIMING1 0x80
> -#define CALTIMING2 0x84
> -#define CALTIMING3 0x88
> -#define CALTIMING4 0x8c
> -#define CALTIMING9 0xa0
> -#define DRAMADDRW 0xa8
> -#define DRAMSTS 0xec
> -#define NIOSRESERVED0 0x110
> -#define NIOSRESERVED1 0x114
> -#define NIOSRESERVED2 0x118
> -
> -#define DRAMADDRW_CFG_COL_ADDR_WIDTH(x) \
> - (((x) >> 0) & 0x1F)
> -#define DRAMADDRW_CFG_ROW_ADDR_WIDTH(x) \
> - (((x) >> 5) & 0x1F)
> -#define DRAMADDRW_CFG_BANK_ADDR_WIDTH(x) \
> - (((x) >> 10) & 0xF)
> -#define DRAMADDRW_CFG_BANK_GRP_ADDR_WIDTH(x) \
> - (((x) >> 14) & 0x3)
> -#define DRAMADDRW_CFG_CS_ADDR_WIDTH(x) \
> - (((x) >> 16) & 0x7)
> -
> -#define CTRLCFG0_CFG_MEMTYPE(x) \
> - (((x) >> 0) & 0xF)
> -#define CTRLCFG0_CFG_DIMM_TYPE(x) \
> - (((x) >> 4) & 0x7)
> -#define CTRLCFG0_CFG_AC_POS(x) \
> - (((x) >> 7) & 0x3)
> -#define CTRLCFG0_CFG_CTRL_BURST_LEN(x) \
> - (((x) >> 9) & 0x1F)
> -
> -#define CTRLCFG1_CFG_DBC3_BURST_LEN(x) \
> - (((x) >> 0) & 0x1F)
> -#define CTRLCFG1_CFG_ADDR_ORDER(x) \
> - (((x) >> 5) & 0x3)
> -#define CTRLCFG1_CFG_CTRL_EN_ECC(x) \
> - (((x) >> 7) & 0x1)
> -
> -#define DRAMTIMING0_CFG_TCL(x) \
> - (((x) >> 0) & 0x7F)
> -
> -#define CALTIMING0_CFG_ACT_TO_RDWR(x) \
> - (((x) >> 0) & 0x3F)
> -#define CALTIMING0_CFG_ACT_TO_PCH(x) \
> - (((x) >> 6) & 0x3F)
> -#define CALTIMING0_CFG_ACT_TO_ACT(x) \
> - (((x) >> 12) & 0x3F)
> -#define CALTIMING0_CFG_ACT_TO_ACT_DB(x) \
> - (((x) >> 18) & 0x3F)
> -
> -#define CALTIMING1_CFG_RD_TO_RD(x) \
> - (((x) >> 0) & 0x3F)
> -#define CALTIMING1_CFG_RD_TO_RD_DC(x) \
> - (((x) >> 6) & 0x3F)
> -#define CALTIMING1_CFG_RD_TO_RD_DB(x) \
> - (((x) >> 12) & 0x3F)
> -#define CALTIMING1_CFG_RD_TO_WR(x) \
> - (((x) >> 18) & 0x3F)
> -#define CALTIMING1_CFG_RD_TO_WR_DC(x) \
> - (((x) >> 24) & 0x3F)
> -
> -#define CALTIMING2_CFG_RD_TO_WR_DB(x) \
> - (((x) >> 0) & 0x3F)
> -#define CALTIMING2_CFG_RD_TO_WR_PCH(x) \
> - (((x) >> 6) & 0x3F)
> -#define CALTIMING2_CFG_RD_AP_TO_VALID(x) \
> - (((x) >> 12) & 0x3F)
> -#define CALTIMING2_CFG_WR_TO_WR(x) \
> - (((x) >> 18) & 0x3F)
> -#define CALTIMING2_CFG_WR_TO_WR_DC(x) \
> - (((x) >> 24) & 0x3F)
> -
> -#define CALTIMING3_CFG_WR_TO_WR_DB(x) \
> - (((x) >> 0) & 0x3F)
> -#define CALTIMING3_CFG_WR_TO_RD(x) \
> - (((x) >> 6) & 0x3F)
> -#define CALTIMING3_CFG_WR_TO_RD_DC(x) \
> - (((x) >> 12) & 0x3F)
> -#define CALTIMING3_CFG_WR_TO_RD_DB(x) \
> - (((x) >> 18) & 0x3F)
> -#define CALTIMING3_CFG_WR_TO_PCH(x) \
> - (((x) >> 24) & 0x3F)
> -
> -#define CALTIMING4_CFG_WR_AP_TO_VALID(x) \
> - (((x) >> 0) & 0x3F)
> -#define CALTIMING4_CFG_PCH_TO_VALID(x) \
> - (((x) >> 6) & 0x3F)
> -#define CALTIMING4_CFG_PCH_ALL_TO_VALID(x) \
> - (((x) >> 12) & 0x3F)
> -#define CALTIMING4_CFG_ARF_TO_VALID(x) \
> - (((x) >> 18) & 0xFF)
> -#define CALTIMING4_CFG_PDN_TO_VALID(x) \
> - (((x) >> 26) & 0x3F)
> -
> -#define CALTIMING9_CFG_4_ACT_TO_ACT(x) \
> - (((x) >> 0) & 0xFF)
> -
> -/* Firewall DDR scheduler MPFE */
> -#define FW_HMC_ADAPTOR_REG_ADDR 0xf8020004
> -#define FW_HMC_ADAPTOR_MPU_MASK BIT(0)
> +#include "sdram_soc64.h"
>
> #endif /* _SDRAM_S10_H_ */
> diff --git a/drivers/ddr/altera/sdram_soc64.c b/drivers/ddr/altera/sdram_soc64.c
> new file mode 100644
> index 0000000000..3097e0671c
> --- /dev/null
> +++ b/drivers/ddr/altera/sdram_soc64.c
> @@ -0,0 +1,304 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2016-2019 Intel Corporation <www.intel.com>
> + *
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <div64.h>
> +#include <fdtdec.h>
> +#include <ram.h>
> +#include <reset.h>
> +#include "sdram_soc64.h"
> +#include <wait_bit.h>
> +#include <asm/arch/firewall.h>
> +#include <asm/arch/system_manager.h>
> +#include <asm/arch/reset_manager.h>
> +#include <asm/io.h>
> +#include <linux/sizes.h>
> +
> +#define PGTABLE_OFF 0x4000
> +
> +u32 hmc_readl(struct altera_sdram_platdata *plat, u32 reg)
> +{
> + return readl(plat->iomhc + reg);
> +}
> +
> +u32 hmc_ecc_readl(struct altera_sdram_platdata *plat, u32 reg)
> +{
> + return readl(plat->hmc + reg);
> +}
> +
> +u32 hmc_ecc_writel(struct altera_sdram_platdata *plat,
> + u32 data, u32 reg)
> +{
> + return writel(data, plat->hmc + reg);
> +}
> +
> +u32 ddr_sch_writel(struct altera_sdram_platdata *plat, u32 data,
> + u32 reg)
> +{
> + return writel(data, plat->ddr_sch + reg);
> +}
> +
> +int emif_clear(struct altera_sdram_platdata *plat)
> +{
> + hmc_ecc_writel(plat, 0, RSTHANDSHAKECTRL);
> +
> + return wait_for_bit_le32((const void *)(plat->hmc +
> + RSTHANDSHAKESTAT),
> + DDR_HMC_RSTHANDSHAKE_MASK,
> + false, 1000, false);
> +}
> +
> +int emif_reset(struct altera_sdram_platdata *plat)
> +{
> + u32 c2s, s2c, ret;
> +
> + c2s = hmc_ecc_readl(plat, RSTHANDSHAKECTRL) & DDR_HMC_RSTHANDSHAKE_MASK;
> + s2c = hmc_ecc_readl(plat, RSTHANDSHAKESTAT) & DDR_HMC_RSTHANDSHAKE_MASK;
> +
> + debug("DDR: c2s=%08x s2c=%08x nr0=%08x nr1=%08x nr2=%08x dst=%08x\n",
> + c2s, s2c, hmc_readl(plat, NIOSRESERVED0),
> + hmc_readl(plat, NIOSRESERVED1), hmc_readl(plat, NIOSRESERVED2),
> + hmc_readl(plat, DRAMSTS));
> +
> + if (s2c && emif_clear(plat)) {
> + printf("DDR: emif_clear() failed\n");
> + return -1;
> + }
> +
> + debug("DDR: Triggerring emif reset\n");
> + hmc_ecc_writel(plat, DDR_HMC_CORE2SEQ_INT_REQ, RSTHANDSHAKECTRL);
> +
> + /* if seq2core[3] = 0, we are good */
> + ret = wait_for_bit_le32((const void *)(plat->hmc +
> + RSTHANDSHAKESTAT),
> + DDR_HMC_SEQ2CORE_INT_RESP_MASK,
> + false, 1000, false);
> + if (ret) {
> + printf("DDR: failed to get ack from EMIF\n");
> + return ret;
> + }
> +
> + ret = emif_clear(plat);
> + if (ret) {
> + printf("DDR: emif_clear() failed\n");
> + return ret;
> + }
> +
> + debug("DDR: %s triggered successly\n", __func__);
> + return 0;
> +}
> +
> +int poll_hmc_clock_status(void)
> +{
> + return wait_for_bit_le32((const void *)(socfpga_sysmgr_base +
> + SYSMGR_SOC64_HMC_CLK),
> + SYSMGR_HMC_CLK_STATUS_MSK, true, 1000, false);
> +}
> +
> +void sdram_clear_mem(phys_addr_t addr, phys_size_t size)
> +{
> + phys_size_t i;
> +
> + if (addr % CONFIG_SYS_CACHELINE_SIZE) {
> + printf("DDR: address 0x%llx is not cacheline size aligned.\n",
> + addr);
> + hang();
> + }
> +
> + if (size % CONFIG_SYS_CACHELINE_SIZE) {
> + printf("DDR: size 0x%llx is not multiple of cacheline size\n",
> + size);
> + hang();
> + }
> +
> + /* Use DC ZVA instruction to clear memory to zeros by a cache line */
> + for (i = 0; i < size; i = i + CONFIG_SYS_CACHELINE_SIZE) {
> + asm volatile("dc zva, %0"
> + :
> + : "r"(addr)
> + : "memory");
> + addr += CONFIG_SYS_CACHELINE_SIZE;
> + }
> +}
> +
> +void sdram_init_ecc_bits(bd_t *bd)
> +{
> + phys_size_t size, size_init;
> + phys_addr_t start_addr;
> + int bank = 0;
> + unsigned int start = get_timer(0);
> +
> + icache_enable();
> +
> + start_addr = bd->bi_dram[0].start;
> + size = bd->bi_dram[0].size;
> +
> + /* Initialize small block for page table */
> + memset((void *)start_addr, 0, PGTABLE_SIZE + PGTABLE_OFF);
> + gd->arch.tlb_addr = start_addr + PGTABLE_OFF;
> + gd->arch.tlb_size = PGTABLE_SIZE;
> + start_addr += PGTABLE_SIZE + PGTABLE_OFF;
> + size -= (PGTABLE_OFF + PGTABLE_SIZE);
> + dcache_enable();
> +
> + while (1) {
> + while (size) {
> + size_init = min((phys_addr_t)SZ_1G, (phys_addr_t)size);
> + sdram_clear_mem(start_addr, size_init);
> + size -= size_init;
> + start_addr += size_init;
> + WATCHDOG_RESET();
> + }
> +
> + bank++;
> + if (bank >= CONFIG_NR_DRAM_BANKS)
> + break;
> +
> + start_addr = bd->bi_dram[bank].start;
> + size = bd->bi_dram[bank].size;
> + }
> +
> + dcache_disable();
> + icache_disable();
> +
> + printf("SDRAM-ECC: Initialized success with %d ms\n",
> + (unsigned int)get_timer(start));
> +}
> +
> +void sdram_size_check(bd_t *bd)
> +{
> + phys_size_t total_ram_check = 0;
> + phys_size_t ram_check = 0;
> + phys_addr_t start = 0;
> + int bank;
> +
> + /* Sanity check ensure correct SDRAM size specified */
> + debug("DDR: Running SDRAM size sanity check\n");
> +
> + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
> + start = bd->bi_dram[bank].start;
> + while (ram_check < bd->bi_dram[bank].size) {
> + ram_check += get_ram_size((void *)(start + ram_check),
> + (phys_size_t)SZ_1G);
> + }
> + total_ram_check += ram_check;
> + ram_check = 0;
> + }
> +
> + /* If the ram_size is 2GB smaller, we can assume the IO space is
> + * not mapped in. gd->ram_size is the actual size of the dram
> + * not the accessible size.
> + */
> + if (total_ram_check != gd->ram_size) {
> + puts("DDR: SDRAM size check failed!\n");
> + hang();
> + }
> +
> + debug("DDR: SDRAM size check passed!\n");
> +}
> +
> +/**
> + * sdram_calculate_size() - Calculate SDRAM size
> + *
> + * Calculate SDRAM device size based on SDRAM controller parameters.
> + * Size is specified in bytes.
> + */
> +phys_size_t sdram_calculate_size(struct altera_sdram_platdata *plat)
> +{
> + u32 dramaddrw = hmc_readl(plat, DRAMADDRW);
> +
> + phys_size_t size = 1 << (DRAMADDRW_CFG_CS_ADDR_WIDTH(dramaddrw) +
> + DRAMADDRW_CFG_BANK_GRP_ADDR_WIDTH(dramaddrw) +
> + DRAMADDRW_CFG_BANK_ADDR_WIDTH(dramaddrw) +
> + DRAMADDRW_CFG_ROW_ADDR_WIDTH(dramaddrw) +
> + DRAMADDRW_CFG_COL_ADDR_WIDTH(dramaddrw));
> +
> + size *= (2 << (hmc_ecc_readl(plat, DDRIOCTRL) &
> + DDR_HMC_DDRIOCTRL_IOSIZE_MSK));
> +
> + return size;
> +}
> +
> +static int altera_sdram_ofdata_to_platdata(struct udevice *dev)
> +{
> + struct altera_sdram_platdata *plat = dev->platdata;
> + fdt_addr_t addr;
> +
> + addr = dev_read_addr_index(dev, 0);
> + if (addr == FDT_ADDR_T_NONE)
> + return -EINVAL;
> + plat->ddr_sch = (void __iomem *)addr;
> +
> + addr = dev_read_addr_index(dev, 1);
> + if (addr == FDT_ADDR_T_NONE)
> + return -EINVAL;
> + plat->iomhc = (void __iomem *)addr;
> +
> + addr = dev_read_addr_index(dev, 2);
> + if (addr == FDT_ADDR_T_NONE)
> + return -EINVAL;
> + plat->hmc = (void __iomem *)addr;
> +
> + return 0;
> +}
> +
> +static int altera_sdram_probe(struct udevice *dev)
> +{
> + int ret;
> + struct altera_sdram_priv *priv = dev_get_priv(dev);
> +
> + ret = reset_get_bulk(dev, &priv->resets);
> + if (ret) {
> + dev_err(dev, "Can't get reset: %d\n", ret);
> + return -ENODEV;
> + }
> + reset_deassert_bulk(&priv->resets);
> +
> + if (sdram_mmr_init_full(dev) != 0) {
> + puts("SDRAM init failed.\n");
> + goto failed;
> + }
> +
> + return 0;
> +
> +failed:
> + reset_release_bulk(&priv->resets);
> + return -ENODEV;
> +}
> +
> +static int altera_sdram_get_info(struct udevice *dev,
> + struct ram_info *info)
> +{
> + struct altera_sdram_priv *priv = dev_get_priv(dev);
> +
> + info->base = priv->info.base;
> + info->size = priv->info.size;
> +
> + return 0;
> +}
> +
> +static struct ram_ops altera_sdram_ops = {
> + .get_info = altera_sdram_get_info,
> +};
> +
> +static const struct udevice_id altera_sdram_ids[] = {
> + { .compatible = "altr,sdr-ctl-s10" },
> + { .compatible = "intel,sdr-ctl-agilex" },
Sigh, so this is *not* what the commit message says. Please keep changes
separate. This patch should merely move code (like the commit message
says) but otherwise leave the code unchanged.
In contrast, here, you at least add a new compatible string. And the
diff is so big it gets easily lost - e.g. while reviewing. That makes
reviewing patches rather annoying: I cannot trust this patch only does
what the commit message says :-(
Regards,
Simon
> + { /* sentinel */ }
> +};
> +
> +U_BOOT_DRIVER(altera_sdram) = {
> + .name = "altr_sdr_ctl",
> + .id = UCLASS_RAM,
> + .of_match = altera_sdram_ids,
> + .ops = &altera_sdram_ops,
> + .ofdata_to_platdata = altera_sdram_ofdata_to_platdata,
> + .platdata_auto_alloc_size = sizeof(struct altera_sdram_platdata),
> + .probe = altera_sdram_probe,
> + .priv_auto_alloc_size = sizeof(struct altera_sdram_priv),
> +};
> diff --git a/drivers/ddr/altera/sdram_s10.h b/drivers/ddr/altera/sdram_soc64.h
> similarity index 79%
> copy from drivers/ddr/altera/sdram_s10.h
> copy to drivers/ddr/altera/sdram_soc64.h
> index 096c06cba2..7d018e76d8 100644
> --- a/drivers/ddr/altera/sdram_s10.h
> +++ b/drivers/ddr/altera/sdram_soc64.h
> @@ -1,15 +1,24 @@
> -/* SPDX-License-Identifier: GPL-2.0
> - *
> - * Copyright (C) 2017-2018 Intel Corporation <www.intel.com>
> - *
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2017-2019 Intel Corporation <www.intel.com>
> */
>
> -#ifndef _SDRAM_S10_H_
> -#define _SDRAM_S10_H_
> +#ifndef _SDRAM_SOC64_H_
> +#define _SDRAM_SOC64_H_
>
> -#define DDR_TWR 15
> -#define DDR_READ_LATENCY_DELAY 40
> -#define DDR_ACTIVATE_FAWBANK 0x1
> +#include <common.h>
> +#include <linux/sizes.h>
> +
> +struct altera_sdram_priv {
> + struct ram_info info;
> + struct reset_ctl_bulk resets;
> +};
> +
> +struct altera_sdram_platdata {
> + void __iomem *hmc;
> + void __iomem *ddr_sch;
> + void __iomem *iomhc;
> +};
>
> /* ECC HMC registers */
> #define DDRIOCTRL 0x8
> @@ -53,32 +62,6 @@
> (DDR_HMC_ERRINTEN_SERRINTEN_EN_SET_MSK | \
> DDR_HMC_ERRINTEN_DERRINTEN_EN_SET_MSK)
>
> -/* NOC DDR scheduler */
> -#define DDR_SCH_ID_COREID 0
> -#define DDR_SCH_ID_REVID 0x4
> -#define DDR_SCH_DDRCONF 0x8
> -#define DDR_SCH_DDRTIMING 0xc
> -#define DDR_SCH_DDRMODE 0x10
> -#define DDR_SCH_READ_LATENCY 0x14
> -#define DDR_SCH_ACTIVATE 0x38
> -#define DDR_SCH_DEVTODEV 0x3c
> -#define DDR_SCH_DDR4TIMING 0x40
> -
> -#define DDR_SCH_DDRTIMING_ACTTOACT_OFF 0
> -#define DDR_SCH_DDRTIMING_RDTOMISS_OFF 6
> -#define DDR_SCH_DDRTIMING_WRTOMISS_OFF 12
> -#define DDR_SCH_DDRTIMING_BURSTLEN_OFF 18
> -#define DDR_SCH_DDRTIMING_RDTOWR_OFF 21
> -#define DDR_SCH_DDRTIMING_WRTORD_OFF 26
> -#define DDR_SCH_DDRTIMING_BWRATIO_OFF 31
> -#define DDR_SCH_DDRMOD_BWRATIOEXTENDED_OFF 1
> -#define DDR_SCH_ACTIVATE_RRD_OFF 0
> -#define DDR_SCH_ACTIVATE_FAW_OFF 4
> -#define DDR_SCH_ACTIVATE_FAWBANK_OFF 10
> -#define DDR_SCH_DEVTODEV_BUSRDTORD_OFF 0
> -#define DDR_SCH_DEVTODEV_BUSRDTOWR_OFF 2
> -#define DDR_SCH_DEVTODEV_BUSWRTORD_OFF 4
> -
> /* HMC MMR IO48 registers */
> #define CTRLCFG0 0x28
> #define CTRLCFG1 0x2c
> @@ -185,4 +168,19 @@
> #define FW_HMC_ADAPTOR_REG_ADDR 0xf8020004
> #define FW_HMC_ADAPTOR_MPU_MASK BIT(0)
>
> -#endif /* _SDRAM_S10_H_ */
> +u32 hmc_readl(struct altera_sdram_platdata *plat, u32 reg);
> +u32 hmc_ecc_readl(struct altera_sdram_platdata *plat, u32 reg);
> +u32 hmc_ecc_writel(struct altera_sdram_platdata *plat,
> + u32 data, u32 reg);
> +u32 ddr_sch_writel(struct altera_sdram_platdata *plat, u32 data,
> + u32 reg);
> +int emif_clear(struct altera_sdram_platdata *plat);
> +int emif_reset(struct altera_sdram_platdata *plat);
> +int poll_hmc_clock_status(void);
> +void sdram_clear_mem(phys_addr_t addr, phys_size_t size);
> +void sdram_init_ecc_bits(bd_t *bd);
> +void sdram_size_check(bd_t *bd);
> +phys_size_t sdram_calculate_size(struct altera_sdram_platdata *plat);
> +int sdram_mmr_init_full(struct udevice *dev);
> +
> +#endif /* _SDRAM_SOC64_H_ */
>
More information about the U-Boot
mailing list