ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/marvell/uboot/drivers/ddr/mck/Makefile b/marvell/uboot/drivers/ddr/mck/Makefile
new file mode 100644
index 0000000..ccf17b2
--- /dev/null
+++ b/marvell/uboot/drivers/ddr/mck/Makefile
@@ -0,0 +1,11 @@
+#
+# Copyright 2008-2011 Marvell Semiconductor, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# Version 2 as published by the Free Software Foundation.
+#
+
+obj-$(CONFIG_SYS_DMCU_DDR)	+= dmcu.o
+obj-$(CONFIG_SYS_MCK5_DDR)	+= mck5.o
+obj-$(CONFIG_SYS_MCK4_DDR)	+= mck4.o
diff --git a/marvell/uboot/drivers/ddr/mck/dmcu.c b/marvell/uboot/drivers/ddr/mck/dmcu.c
new file mode 100644
index 0000000..cbea880
--- /dev/null
+++ b/marvell/uboot/drivers/ddr/mck/dmcu.c
@@ -0,0 +1,172 @@
+/*
+ *(C) Copyright 2018 ASR Microelectronics (Shanghai) Co., Ltd.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <pxa_amp.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_ASR1901
+#define DMCU_ADDR_BASE	0xC0000000
+#else
+#define DMCU_ADDR_BASE	0xC0100000
+#endif
+
+#define DMCU_CH0_MMAP0	(DMCU_ADDR_BASE + 0x200)
+#define DMCU_CH0_MMAP1	(DMCU_ADDR_BASE + 0x208)
+
+#define DMCU_CH0_PMAP0	(DMCU_ADDR_BASE + 0x220)
+#define DMCU_CH0_PMAP1	(DMCU_ADDR_BASE + 0x224)
+#define DMCU_CH0_DRAM_CFG_0	(DMCU_ADDR_BASE + 0x44)
+
+extern int get_ramdump_flag_f(void);
+
+int DMCU_sdram_base(int cs, ulong *base)
+{
+	u32 mmap;
+
+	switch (cs) {
+	case 0:
+		mmap = readl(DMCU_CH0_MMAP0);
+		break;
+	case 1:
+		mmap = readl(DMCU_CH0_MMAP1);
+		break;
+	default:
+		return -1;
+	}
+
+	if (!(0x1 & mmap))
+		return -1;
+	else
+		*base = 0xFF800000 & mmap;
+	return 0;
+}
+
+int DMCU_sdram_size(int cs, ulong *size)
+{
+	u32 mmap, _size, pmap, dram_cfg_0;
+	u32 bank_bits, row_bits, col_bits, width_bits;
+
+	switch (cs) {
+	case 0:
+		mmap = readl(DMCU_CH0_MMAP0);
+		pmap = readl(DMCU_CH0_PMAP0);
+		break;
+	case 1:
+		mmap = readl(DMCU_CH0_MMAP1);
+		pmap = readl(DMCU_CH0_PMAP1);
+		break;
+	default:
+		return -1;
+	}
+
+	if (!(0x1 & mmap))
+		return -1;
+
+	dram_cfg_0 = readl(DMCU_CH0_DRAM_CFG_0);
+
+	_size = (mmap >> 16) & 0x1F;
+	if (_size < 0x7) {
+		printf("Unknown dram size!\n");
+		return -1;
+	} else {
+		width_bits = ((dram_cfg_0 & (0x7 << 8)) >> 8) - 1;
+		bank_bits = ((pmap & 0x3) >> 0) + 1;
+		row_bits = ((pmap & (0xf << 8)) >> 8) + 10;
+		col_bits = ((pmap & (0xf << 4)) >> 4) + 7;
+
+		*size = (0x1 << (width_bits + bank_bits + row_bits + col_bits));
+	}
+
+	return 0;
+}
+
+#ifndef CONFIG_SYS_BOARD_DRAM_INIT
+/* dram init when bd not avaliable */
+int dram_init(void)
+{
+	int i;
+	unsigned int reloc_end;
+	ulong start, size, ddr_st_offset = 0x0;
+	
+	gd->ram_size = 0;
+
+	/* find ddr map start address */
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (!DMCU_sdram_base(i, &ddr_st_offset))
+			break;
+	}
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (DMCU_sdram_base(i, &start))
+			continue;	
+		if (start != (gd->ram_size + ddr_st_offset)) {
+			printf("error: unspported not-continous ram\n");
+			hang();
+		}
+		if (DMCU_sdram_size(i, &size)) {
+			printf("Read dram size error for chip %d.\n", i);
+			hang();
+		}
+		gd->ram_size += size;
+	}
+
+	/* extend 64MB ddr space to 128MB in ap ramdump mode */
+	if (get_ramdump_flag_f() && (gd->ram_size == (64 * 1024 * 1024)))
+		gd->ram_size = (128 * 1024 * 1024);
+
+	/*
+	 * limit the uboot ddr usage between CONFIG_SYS_TEXT_BASE and
+	 * CONFIG_SYS_RELOC_END, which reside in ion range
+	 * and won't impact emmddump.
+	 */
+	debug("gd->ram_size = 0x%lx\n\n",gd->ram_size);
+	reloc_end = pxa_amp_reloc_end();
+	if ((gd->ram_size + ddr_st_offset) < reloc_end)
+		hang();
+	else
+		gd->ram_size = (reloc_end - ddr_st_offset);
+
+	return 0;
+}
+
+/*
+ * If this function is not defined here,
+ * board.c alters dram bank zero configuration defined above.
+ * read from mck register again and skip error as already
+ * checked before
+ */
+void dram_init_banksize(void)
+{
+	int i, b = 0;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (!DMCU_sdram_base(i, &gd->bd->bi_dram[b].start))
+			DMCU_sdram_size(i, &gd->bd->bi_dram[b++].size);
+	}
+
+	/*
+	 * If there are banks that are not valid, we need to set
+	 * their start address and size to 0. Otherwise other
+	 * u-boot functions and Linux kernel gets wrong values which
+	 * could result in crash.
+	 */
+	for (; b < CONFIG_NR_DRAM_BANKS; b++) {
+		gd->bd->bi_dram[b].start = 0;
+		gd->bd->bi_dram[b].size = 0;
+	}
+
+	if (gd->bd->bi_dram[0].size < CONFIG_TZ_HYPERVISOR_SIZE) {
+		printf("Cannot meet requirement for TrustZone!\n");
+	} else {
+		gd->bd->bi_dram[0].start += CONFIG_TZ_HYPERVISOR_SIZE;
+		gd->bd->bi_dram[0].size  -= CONFIG_TZ_HYPERVISOR_SIZE;
+		gd->ram_size -= CONFIG_TZ_HYPERVISOR_SIZE;
+	}
+}
+#endif /* CONFIG_SYS_BOARD_DRAM_INIT */
diff --git a/marvell/uboot/drivers/ddr/mck/mck4.c b/marvell/uboot/drivers/ddr/mck/mck4.c
new file mode 100644
index 0000000..b95745d
--- /dev/null
+++ b/marvell/uboot/drivers/ddr/mck/mck4.c
@@ -0,0 +1,161 @@
+/*
+ * (C) Copyright 2012
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Neil Zhang <zhangwm@marvell.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <pxa_amp.h>
+#include <asm/io.h>
+#include <asm/arch/pxa988.h>
+#include <asm/arch/cpu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Pantheon DRAM controller supports upto 8 banks
+ * for chip select 0 and 1
+ */
+
+/*
+ * DDR Memory Control Registers
+ * Refer Datasheet 4.4
+ */
+struct pxa988ddr_map_registers {
+	u32	cs;	/* Memory Address Map Register -CS */
+};
+
+struct pxa988ddr_registers {
+	u8	pad[0x10];
+	struct pxa988ddr_map_registers mmap[2];
+};
+
+/*
+ * pxa988_sdram_base - reads SDRAM Base Address Register
+ */
+u32 pxa988_sdram_base(int chip_sel, u32 base)
+{
+	struct pxa988ddr_registers *ddr_regs;
+	u32 cs_valid = 0;
+	u32 result = 0;
+
+	ddr_regs = (struct pxa988ddr_registers *)base;
+	cs_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs);
+	if (!cs_valid)
+		return 0;
+
+	result = readl(&ddr_regs->mmap[chip_sel].cs) & 0xFF800000;
+	return result;
+}
+
+/*
+ * pxa988_sdram_size - reads SDRAM size
+ */
+static u32 pxa988_sdram_size(int chip_sel, u32 base)
+{
+	struct pxa988ddr_registers *ddr_regs;
+	u32 cs_valid = 0;
+	u32 result = 0;
+
+	ddr_regs = (struct pxa988ddr_registers *)base;
+	cs_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs);
+	if (!cs_valid)
+		return 0;
+
+	result = readl(&ddr_regs->mmap[chip_sel].cs);
+	result = (result >> 16) & 0xF;
+	if (result < 0x7) {
+		printf("Unknown DRAM Size\n");
+		return -1;
+	} else {
+		return (0x8 << (result - 0x7)) * 1024 * 1024;
+	}
+}
+
+#ifndef CONFIG_SYS_BOARD_DRAM_INIT
+int dram_init(void)
+{
+	u32 base = PXA988_DRAM_BASE;
+	int i, mcb_conf0;
+	ulong dram_start, dram_size;
+	unsigned int reloc_end;
+
+	gd->ram_size = 0;
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		dram_start = pxa988_sdram_base(i, base);
+		dram_size = pxa988_sdram_size(i, base);
+
+		if (gd->bd) {
+			gd->bd->bi_dram[i].start = dram_start;
+			gd->bd->bi_dram[i].size = dram_size;
+		}
+		/*
+		 * It is assumed that all memory banks are consecutive
+		 * and without gaps.
+		 * If the gap is found, ram_size will be reported for
+		 * consecutive memory only
+		 */
+		if (dram_start != gd->ram_size)
+			break;
+
+		gd->ram_size += dram_size;
+	}
+
+	/*
+	 * limit the uboot ddr usage between CONFIG_SYS_TEXT_BASE and
+	 * CONFIG_SYS_RELOC_END.
+	 */
+	reloc_end = pxa_amp_reloc_end();
+	if (gd->ram_size < reloc_end)
+		hang();
+	else
+		gd->ram_size = reloc_end;
+
+	for (; i < CONFIG_NR_DRAM_BANKS; i++) {
+		/*
+		 * If above loop terminated prematurely, we need to set
+		 * remaining banks' start address & size as 0. Otherwise other
+		 * u-boot functions and Linux kernel gets wrong values which
+		 * could result in crash
+		 */
+		if (gd->bd) {
+			gd->bd->bi_dram[i].start = 0;
+			gd->bd->bi_dram[i].size = 0;
+		}
+	}
+
+	/*
+	 * Set MSA as critical priority for DDR access.
+	 * And set LCD as high priority for DDR access, which is helpful to fix
+	 * the flicker issue.
+	 * Set CP as high priority for LTE, which is helpful for performance.
+	 */
+	if (cpu_is_pxa1L88())
+		writel(0xF7402008, base + 0x140);
+	else
+		writel(0xF7402000, base + 0x140);
+	mcb_conf0 = readl(PXA988_CIU_BASE + 0x1C);
+	writel(mcb_conf0 | 0x3, PXA988_CIU_BASE + 0x1C);
+
+	return 0;
+}
+
+/*
+ * If this function is not defined here,
+ * board.c alters dram bank zero configuration defined above.
+ */
+void dram_init_banksize(void)
+{
+	dram_init();
+
+	if (gd->bd->bi_dram[0].size < CONFIG_TZ_HYPERVISOR_SIZE) {
+		printf("Cannot meet requirement for TrustZone!\n");
+	} else {
+		gd->bd->bi_dram[0].start += CONFIG_TZ_HYPERVISOR_SIZE;
+		gd->bd->bi_dram[0].size  -= CONFIG_TZ_HYPERVISOR_SIZE;
+		gd->ram_size -= CONFIG_TZ_HYPERVISOR_SIZE;
+	}
+}
+#endif /* CONFIG_SYS_BOARD_DRAM_INIT */
diff --git a/marvell/uboot/drivers/ddr/mck/mck5.c b/marvell/uboot/drivers/ddr/mck/mck5.c
new file mode 100644
index 0000000..62ded54
--- /dev/null
+++ b/marvell/uboot/drivers/ddr/mck/mck5.c
@@ -0,0 +1,167 @@
+/*
+ * (C) Copyright 2011
+ * Marvell Semiconductor <www.marvell.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <pxa_amp.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined (CONFIG_PXA1U88) || defined (CONFIG_PXA182X)
+#define MCK5_ADDR_BASE	0xC0100000
+#else
+#define MCK5_ADDR_BASE	0xD0000000
+#endif
+
+/* PXA1928 and PXA1826 only use CH0. So ignore CH1 here */
+#define MCK5_CH0_MMAP0	(MCK5_ADDR_BASE + 0x200)
+#define MCK5_CH0_MMAP1	(MCK5_ADDR_BASE + 0x204)
+#define MCK5_CH0_PMAP0	(MCK5_ADDR_BASE + 0x210)
+#define MCK5_CH0_PMAP1	(MCK5_ADDR_BASE + 0x214)
+#define MCK5_CH0_DRAM_CFG_1	(MCK5_ADDR_BASE + 0x300)
+
+int MCK5_sdram_base(int cs, ulong *base)
+{
+	u32 mmap;
+
+	switch (cs) {
+	case 0:
+		mmap = readl(MCK5_CH0_MMAP0);
+		break;
+	case 1:
+		mmap = readl(MCK5_CH0_MMAP1);
+		break;
+	default:
+		return -1;
+	}
+
+	if (!(0x1 & mmap))
+		return -1;
+	else
+		*base = 0xFF800000 & mmap;
+	return 0;
+}
+
+int MCK5_sdram_size(int cs, ulong *size)
+{
+	u32 mmap, _size, pmap, dram_cfg_1;
+	u32 bank_bits, row_bits, col_bits, width_bits;
+
+	switch (cs) {
+	case 0:
+		mmap = readl(MCK5_CH0_MMAP0);
+		pmap = readl(MCK5_CH0_PMAP0);
+		break;
+	case 1:
+		mmap = readl(MCK5_CH0_MMAP1);
+		pmap = readl(MCK5_CH0_PMAP1);
+		break;
+	default:
+		return -1;
+	}
+
+	if (!(0x1 & mmap))
+		return -1;
+
+	dram_cfg_1 = readl(MCK5_CH0_DRAM_CFG_1);
+
+	_size = (mmap >> 16) & 0x1F;
+	if (_size < 0x7) {
+		printf("Unknown dram size!\n");
+		return -1;
+	} else {
+		/* *size = (0x8 << (_size - 0x7)) * 1024 * 1024; */
+		width_bits = (dram_cfg_1 & 0x7) - 1;
+		bank_bits = (pmap & 0x3) + 1;
+		/* row is 1~6, column is 1~5 */
+		row_bits = ((pmap >> 8) & 0x7) + 10;
+		col_bits = ((pmap >> 4) & 0x7) + 7;
+		*size = 0x1 << (width_bits + bank_bits + row_bits + col_bits);
+	}
+	return 0;
+}
+
+#ifndef CONFIG_SYS_BOARD_DRAM_INIT
+/* dram init when bd not avaliable */
+int dram_init(void)
+{
+	int i;
+	unsigned int reloc_end;
+	ulong start, size, ddr_st_offset = 0x0;
+	
+	gd->ram_size = 0;
+
+	/* find ddr map start address */
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (!MCK5_sdram_base(i, &ddr_st_offset))
+			break;
+	}
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (MCK5_sdram_base(i, &start))
+			continue;	
+		if (start != (gd->ram_size + ddr_st_offset)) {
+			printf("error: unspported not-continous ram\n");
+			hang();
+		}
+		if (MCK5_sdram_size(i, &size)) {
+			printf("Read dram size error for chip %d.\n", i);
+			hang();
+		}
+		gd->ram_size += size;
+	}
+
+	/*
+	 * limit the uboot ddr usage between CONFIG_SYS_TEXT_BASE and
+	 * CONFIG_SYS_RELOC_END, which reside in ion range
+	 * and won't impact emmddump.
+	 */
+	debug("gd->ram_size = 0x%lx\n\n",gd->ram_size);
+	reloc_end = pxa_amp_reloc_end();
+	if ((gd->ram_size + ddr_st_offset) < reloc_end)
+		hang();
+	else
+		gd->ram_size = (reloc_end - ddr_st_offset);
+
+	return 0;
+}
+
+/*
+ * If this function is not defined here,
+ * board.c alters dram bank zero configuration defined above.
+ * read from mck register again and skip error as already
+ * checked before
+ */
+void dram_init_banksize(void)
+{
+	int i, b = 0;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (!MCK5_sdram_base(i, &gd->bd->bi_dram[b].start))
+			MCK5_sdram_size(i, &gd->bd->bi_dram[b++].size);
+	}
+
+	/*
+	 * If there are banks that are not valid, we need to set
+	 * their start address and size to 0. Otherwise other
+	 * u-boot functions and Linux kernel gets wrong values which
+	 * could result in crash.
+	 */
+	for (; b < CONFIG_NR_DRAM_BANKS; b++) {
+		gd->bd->bi_dram[b].start = 0;
+		gd->bd->bi_dram[b].size = 0;
+	}
+
+	if (gd->bd->bi_dram[0].size < CONFIG_TZ_HYPERVISOR_SIZE) {
+		printf("Cannot meet requirement for TrustZone!\n");
+	} else {
+		gd->bd->bi_dram[0].start += CONFIG_TZ_HYPERVISOR_SIZE;
+		gd->bd->bi_dram[0].size  -= CONFIG_TZ_HYPERVISOR_SIZE;
+		gd->ram_size -= CONFIG_TZ_HYPERVISOR_SIZE;
+	}
+}
+#endif /* CONFIG_SYS_BOARD_DRAM_INIT */