diff options
Diffstat (limited to 'drivers/ddr/altera/sdram_s10.c')
| -rw-r--r-- | drivers/ddr/altera/sdram_s10.c | 320 | 
1 files changed, 19 insertions, 301 deletions
| diff --git a/drivers/ddr/altera/sdram_s10.c b/drivers/ddr/altera/sdram_s10.c index 82d9a13efad..93c15dd18b3 100644 --- a/drivers/ddr/altera/sdram_s10.c +++ b/drivers/ddr/altera/sdram_s10.c @@ -14,32 +14,15 @@  #include <reset.h>  #include "sdram_s10.h"  #include <wait_bit.h> -#include <asm/arch/firewall_s10.h> -#include <asm/arch/system_manager.h> +#include <asm/arch/firewall.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; -static const struct socfpga_system_manager *sysmgr_regs = -		(void *)SOCFPGA_SYSMGR_ADDRESS; -  #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) */ @@ -66,28 +49,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; @@ -99,192 +60,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(&sysmgr_regs->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); @@ -324,6 +105,20 @@ static int sdram_mmr_init_full(struct udevice *dev)  	clrbits_le32(CCU_REG_ADDR(CCU_IOM_MPRT_ADBASE_MEMSPACE1E),  		     CCU_ADBASE_DI_MASK); +	/* Enable access to DDR from TCU */ +	clrbits_le32(CCU_REG_ADDR(CCU_TCU_MPRT_ADBASE_MEMSPACE0), +		     CCU_ADBASE_DI_MASK); +	clrbits_le32(CCU_REG_ADDR(CCU_TCU_MPRT_ADBASE_MEMSPACE1A), +		     CCU_ADBASE_DI_MASK); +	clrbits_le32(CCU_REG_ADDR(CCU_TCU_MPRT_ADBASE_MEMSPACE1B), +		     CCU_ADBASE_DI_MASK); +	clrbits_le32(CCU_REG_ADDR(CCU_TCU_MPRT_ADBASE_MEMSPACE1C), +		     CCU_ADBASE_DI_MASK); +	clrbits_le32(CCU_REG_ADDR(CCU_TCU_MPRT_ADBASE_MEMSPACE1D), +		     CCU_ADBASE_DI_MASK); +	clrbits_le32(CCU_REG_ADDR(CCU_TCU_MPRT_ADBASE_MEMSPACE1E), +		     CCU_ADBASE_DI_MASK); +  	/* this enables nonsecure access to DDR */  	/* mpuregion0addr_limit */  	FW_MPU_DDR_SCR_WRITEL(0xFFFF0000, FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT); @@ -512,9 +307,6 @@ static int sdram_mmr_init_full(struct udevice *dev)  			      DDR_HMC_ECCCTL2_AWB_EN_SET_MSK));  		hmc_ecc_writel(plat, DDR_HMC_ERRINTEN_INTMASK, ERRINTENS); -		/* Enable non-secure writes to HMC Adapter for SDRAM ECC */ -		writel(FW_HMC_ADAPTOR_MPU_MASK, FW_HMC_ADAPTOR_REG_ADDR); -  		/* Initialize memory content if not from warm reset */  		if (!cpu_has_been_warmreset())  			sdram_init_ecc_bits(&bd); @@ -528,6 +320,9 @@ static int sdram_mmr_init_full(struct udevice *dev)  			      DDR_HMC_ECCCTL2_AWB_EN_SET_MSK));  	} +	/* Enable non-secure reads/writes to HMC Adapter for SDRAM ECC */ +	writel(FW_HMC_ADAPTOR_MPU_MASK, FW_HMC_ADAPTOR_REG_ADDR); +  	sdram_size_check(&bd);  	priv->info.base = bd.bi_dram[0].start; @@ -537,80 +332,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), -}; | 
