All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/5] Add 3GiB DRAM support to 64-bit Allwinner SoCs
@ 2018-02-07 19:35 Icenowy Zheng
  2018-02-07 19:35 ` [U-Boot] [PATCH 1/5] sunxi: map DRAM part with 3G size Icenowy Zheng
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Icenowy Zheng @ 2018-02-07 19:35 UTC (permalink / raw)
  To: u-boot

Allwinner 64-bit SoCs have allocated 3GiB space in the memory map for
DRAM. If memory bigger than 3GiB is installed (as memory usually come as
pow of 2 and they are not known to support 3GiB LPDDR3 modules, it means
4GiB memory is installed), the whole 3GiB space can be all used.

However, in many situations we still only defined 2GiB for the DRAM.

Add support for 3GiB DRAM. Tested on a customized Pine A64-LTS with 4GiB
LPDDR3 memory installed.

Icenowy Zheng (5):
  sunxi: map DRAM part with 3G size
  sunxi: add Kconfig option for the maximum accessible DRAM
  sunxi: add 3GiB DRAM detection support in main U-Boot
  sunxi: let sunxi_dram_init return unsigned long long
  sunxi: restrict the ram_size to the accessible range in SPL

 arch/arm/include/asm/arch-sunxi/dram.h |  2 +-
 arch/arm/mach-sunxi/Kconfig            |  7 +++++++
 arch/arm/mach-sunxi/board.c            |  2 +-
 arch/arm/mach-sunxi/dram_sun6i.c       |  2 +-
 arch/arm/mach-sunxi/dram_sun8i_a23.c   |  2 +-
 arch/arm/mach-sunxi/dram_sun8i_a33.c   |  2 +-
 arch/arm/mach-sunxi/dram_sun8i_a83t.c  |  2 +-
 arch/arm/mach-sunxi/dram_sun9i.c       |  4 ++--
 arch/arm/mach-sunxi/dram_sunxi_dw.c    |  4 ++--
 board/sunxi/board.c                    | 36 ++++++++++++++++++++++++++++++++--
 board/sunxi/dram_sun4i_auto.c          |  2 +-
 board/sunxi/dram_sun5i_auto.c          |  2 +-
 include/configs/sunxi-common.h         |  2 +-
 13 files changed, 54 insertions(+), 15 deletions(-)

-- 
2.15.1

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH 1/5] sunxi: map DRAM part with 3G size
  2018-02-07 19:35 [U-Boot] [PATCH 0/5] Add 3GiB DRAM support to 64-bit Allwinner SoCs Icenowy Zheng
@ 2018-02-07 19:35 ` Icenowy Zheng
  2018-02-08  0:34   ` André Przywara
  2018-02-07 19:35 ` [U-Boot] [PATCH 2/5] sunxi: add Kconfig option for the maximum accessible DRAM Icenowy Zheng
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Icenowy Zheng @ 2018-02-07 19:35 UTC (permalink / raw)
  To: u-boot

All Allwinner 64-bit SoCs now are known to be able to access 3GiB of
external DRAM, however the size of DRAM part in the MMU translation
table is still 2GiB.

Change the size of DRAM part in MMU table to 3GiB.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 arch/arm/mach-sunxi/board.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 0c60ee04da..4ee1040ac9 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -53,7 +53,7 @@ static struct mm_region sunxi_mem_map[] = {
 		/* RAM */
 		.virt = 0x40000000UL,
 		.phys = 0x40000000UL,
-		.size = 0x80000000UL,
+		.size = 0xC0000000UL,
 		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 			 PTE_BLOCK_INNER_SHARE
 	}, {
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH 2/5] sunxi: add Kconfig option for the maximum accessible DRAM
  2018-02-07 19:35 [U-Boot] [PATCH 0/5] Add 3GiB DRAM support to 64-bit Allwinner SoCs Icenowy Zheng
  2018-02-07 19:35 ` [U-Boot] [PATCH 1/5] sunxi: map DRAM part with 3G size Icenowy Zheng
@ 2018-02-07 19:35 ` Icenowy Zheng
  2018-02-08  0:35   ` André Przywara
  2018-02-07 19:35 ` [U-Boot] [PATCH 3/5] sunxi: add 3GiB DRAM detection support in main U-Boot Icenowy Zheng
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Icenowy Zheng @ 2018-02-07 19:35 UTC (permalink / raw)
  To: u-boot

Allwinner 64-bit SoCs can use 4GiB DRAM chip, however their memory map
has only allocated 3GiB for DRAM, so only 3GiB of the DRAM is
accessible.

Add a Kconfig option for the maximum accessible DRAM.

For A80 it should be a much higher value (8GiB), but as I have no A80
device to test and originally U-Boot only supports 2GiB DRAM on A80, it
currently still falls under the 2GiB situation.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 arch/arm/mach-sunxi/Kconfig | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 1fededd0a3..32739e0f33 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -63,6 +63,13 @@ config MACH_SUNXI_H3_H5
 	select SUNXI_GEN_SUN6I
 	select SUPPORT_SPL
 
+# TODO: try out A80's 8GiB DRAM space
+config SUNXI_DRAM_MAX_SIZE
+	hex
+	default 0xC0000000 if MACH_SUN50I
+	default 0xC0000000 if MACH_SUN50I_H5
+	default 0x80000000
+
 choice
 	prompt "Sunxi SoC Variant"
 	optional
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH 3/5] sunxi: add 3GiB DRAM detection support in main U-Boot
  2018-02-07 19:35 [U-Boot] [PATCH 0/5] Add 3GiB DRAM support to 64-bit Allwinner SoCs Icenowy Zheng
  2018-02-07 19:35 ` [U-Boot] [PATCH 1/5] sunxi: map DRAM part with 3G size Icenowy Zheng
  2018-02-07 19:35 ` [U-Boot] [PATCH 2/5] sunxi: add Kconfig option for the maximum accessible DRAM Icenowy Zheng
@ 2018-02-07 19:35 ` Icenowy Zheng
  2018-02-08  0:37   ` André Przywara
  2018-02-07 19:35 ` [U-Boot] [PATCH 4/5] sunxi: let sunxi_dram_init return unsigned long long Icenowy Zheng
  2018-02-07 19:35 ` [U-Boot] [PATCH 5/5] sunxi: restrict the ram_size to the accessible range in SPL Icenowy Zheng
  4 siblings, 1 reply; 15+ messages in thread
From: Icenowy Zheng @ 2018-02-07 19:35 UTC (permalink / raw)
  To: u-boot

Some Allwinner SoCs can use 3GiB DRAM (part of 4GiB or larger module).

As the common get_ram_size function cannot detect non-pow-of-2 memory,
add special detect code into the DRAM size code in main U-Boot.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 board/sunxi/board.c            | 23 +++++++++++++++++++++++
 include/configs/sunxi-common.h |  2 +-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 8891961dcc..8d707cbac2 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -256,7 +256,30 @@ int board_init(void)
 
 int dram_init(void)
 {
+#if PHYS_SDRAM_0_SIZE == (SZ_2G + SZ_1G)
+	/*
+	 * get_ram_size() doesn't support non-pow-of-2 sizes, so the detection
+	 * of 3GiB DRAM is implemented here.
+	 * It just checks whether the DRAM is bigger than 2GiB, as the DRAM
+	 * module is usually 4GiB in this case (and 1GiB is not accessible).
+	 */
+	u32 save_0, save_2g;
+	gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, SZ_2G);
+	if (gd->ram_size == SZ_2G) {
+		save_0 = readl(PHYS_SDRAM_0);
+		save_2g = readl(PHYS_SDRAM_0 + SZ_2G);
+		writel(0, PHYS_SDRAM_0);
+		writel(0xaa55aa55, PHYS_SDRAM_0 + SZ_2G);
+		dsb();
+		if (readl(PHYS_SDRAM_0) != readl(PHYS_SDRAM_0 + SZ_2G)) {
+			gd->ram_size = SZ_2G + SZ_1G;
+			writel(save_2g, PHYS_SDRAM_0 + SZ_2G);
+		}
+		writel(save_0, PHYS_SDRAM_0);
+	}
+#else
 	gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE);
+#endif
 
 	return 0;
 }
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 9b3944ad13..177647e009 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -111,7 +111,7 @@
 
 #define CONFIG_NR_DRAM_BANKS		1
 #define PHYS_SDRAM_0			CONFIG_SYS_SDRAM_BASE
-#define PHYS_SDRAM_0_SIZE		0x80000000 /* 2 GiB */
+#define PHYS_SDRAM_0_SIZE		CONFIG_SUNXI_DRAM_MAX_SIZE
 
 #ifdef CONFIG_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH 4/5] sunxi: let sunxi_dram_init return unsigned long long
  2018-02-07 19:35 [U-Boot] [PATCH 0/5] Add 3GiB DRAM support to 64-bit Allwinner SoCs Icenowy Zheng
                   ` (2 preceding siblings ...)
  2018-02-07 19:35 ` [U-Boot] [PATCH 3/5] sunxi: add 3GiB DRAM detection support in main U-Boot Icenowy Zheng
@ 2018-02-07 19:35 ` Icenowy Zheng
  2018-02-08  0:37   ` André Przywara
  2018-02-07 19:35 ` [U-Boot] [PATCH 5/5] sunxi: restrict the ram_size to the accessible range in SPL Icenowy Zheng
  4 siblings, 1 reply; 15+ messages in thread
From: Icenowy Zheng @ 2018-02-07 19:35 UTC (permalink / raw)
  To: u-boot

As 4GiB capacity is above the range of 32-bit unsigned integer, raise
the return type of sunxi_dram_init() to unsigned long long, thus it can
hold 4GiB capacity (or maybe more on A80).

Some controllers that are possible to use 4GiB+ memory module are
also changed to calculate its memory capacity in unsigned long long.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 arch/arm/include/asm/arch-sunxi/dram.h | 2 +-
 arch/arm/mach-sunxi/dram_sun6i.c       | 2 +-
 arch/arm/mach-sunxi/dram_sun8i_a23.c   | 2 +-
 arch/arm/mach-sunxi/dram_sun8i_a33.c   | 2 +-
 arch/arm/mach-sunxi/dram_sun8i_a83t.c  | 2 +-
 arch/arm/mach-sunxi/dram_sun9i.c       | 4 ++--
 arch/arm/mach-sunxi/dram_sunxi_dw.c    | 4 ++--
 board/sunxi/board.c                    | 2 +-
 board/sunxi/dram_sun4i_auto.c          | 2 +-
 board/sunxi/dram_sun5i_auto.c          | 2 +-
 10 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h
index 80abac95b8..d08b82371d 100644
--- a/arch/arm/include/asm/arch-sunxi/dram.h
+++ b/arch/arm/include/asm/arch-sunxi/dram.h
@@ -32,7 +32,7 @@
 #include <asm/arch/dram_sun4i.h>
 #endif
 
-unsigned long sunxi_dram_init(void);
+unsigned long long sunxi_dram_init(void);
 void mctl_await_completion(u32 *reg, u32 mask, u32 val);
 bool mctl_mem_matches(u32 offset);
 
diff --git a/arch/arm/mach-sunxi/dram_sun6i.c b/arch/arm/mach-sunxi/dram_sun6i.c
index 5dbbf6186f..bdf52a2c38 100644
--- a/arch/arm/mach-sunxi/dram_sun6i.c
+++ b/arch/arm/mach-sunxi/dram_sun6i.c
@@ -326,7 +326,7 @@ static void mctl_port_cfg(void)
 	writel(0x00000307, &mctl_com->mbagcr[5]);
 }
 
-unsigned long sunxi_dram_init(void)
+unsigned long long sunxi_dram_init(void)
 {
 	struct sunxi_mctl_com_reg * const mctl_com =
 		(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
diff --git a/arch/arm/mach-sunxi/dram_sun8i_a23.c b/arch/arm/mach-sunxi/dram_sun8i_a23.c
index c53671a0e9..169ccff41a 100644
--- a/arch/arm/mach-sunxi/dram_sun8i_a23.c
+++ b/arch/arm/mach-sunxi/dram_sun8i_a23.c
@@ -264,7 +264,7 @@ static void mctl_init(u32 *bus_width)
 	writel(0x00000000, &mctl_ctl->rfshctl3);
 }
 
-unsigned long sunxi_dram_init(void)
+unsigned long long sunxi_dram_init(void)
 {
 	struct sunxi_mctl_com_reg * const mctl_com =
 		(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
diff --git a/arch/arm/mach-sunxi/dram_sun8i_a33.c b/arch/arm/mach-sunxi/dram_sun8i_a33.c
index fa1620cb39..dfbbe6f39c 100644
--- a/arch/arm/mach-sunxi/dram_sun8i_a33.c
+++ b/arch/arm/mach-sunxi/dram_sun8i_a33.c
@@ -325,7 +325,7 @@ static void mctl_sys_init(struct dram_para *para)
 	udelay(250);
 }
 
-unsigned long sunxi_dram_init(void)
+unsigned long long sunxi_dram_init(void)
 {
 	struct sunxi_mctl_com_reg * const mctl_com =
 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
diff --git a/arch/arm/mach-sunxi/dram_sun8i_a83t.c b/arch/arm/mach-sunxi/dram_sun8i_a83t.c
index 55df1b9d54..ec4bccd635 100644
--- a/arch/arm/mach-sunxi/dram_sun8i_a83t.c
+++ b/arch/arm/mach-sunxi/dram_sun8i_a83t.c
@@ -423,7 +423,7 @@ static void mctl_sys_init(struct dram_para *para)
 	udelay(250);
 }
 
-unsigned long sunxi_dram_init(void)
+unsigned long long sunxi_dram_init(void)
 {
 	struct sunxi_mctl_com_reg * const mctl_com =
 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
diff --git a/arch/arm/mach-sunxi/dram_sun9i.c b/arch/arm/mach-sunxi/dram_sun9i.c
index 8c681f3541..dcb20f763e 100644
--- a/arch/arm/mach-sunxi/dram_sun9i.c
+++ b/arch/arm/mach-sunxi/dram_sun9i.c
@@ -854,7 +854,7 @@ signed int DRAMC_get_dram_size(void)
 	return 1 << dram_size;
 }
 
-unsigned long sunxi_dram_init(void)
+unsigned long long sunxi_dram_init(void)
 {
 	struct sunxi_mctl_com_reg * const mctl_com =
 		(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
@@ -957,5 +957,5 @@ unsigned long sunxi_dram_init(void)
 	mctl_com_init(&para);
 
 	/* return the proper RAM size */
-	return DRAMC_get_dram_size() << 20;
+	return ((unsigned long long)DRAMC_get_dram_size()) << 20;
 }
diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c
index 78b4ffb9c3..3bff1c46cd 100644
--- a/arch/arm/mach-sunxi/dram_sunxi_dw.c
+++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c
@@ -682,7 +682,7 @@ static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para)
 	   3,  3,  3,  3,  3,  3,  3,  3,			\
 	   3,  3,  3,  3,  2,  0,  0      }
 
-unsigned long sunxi_dram_init(void)
+unsigned long long sunxi_dram_init(void)
 {
 	struct sunxi_mctl_com_reg * const mctl_com =
 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
@@ -763,6 +763,6 @@ unsigned long sunxi_dram_init(void)
 	mctl_auto_detect_dram_size(socid, &para);
 	mctl_set_cr(socid, &para);
 
-	return (1UL << (para.row_bits + para.bank_bits)) * para.page_size *
+	return (1ULL << (para.row_bits + para.bank_bits)) * para.page_size *
 	       (para.dual_rank ? 2 : 1);
 }
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 8d707cbac2..5828d47294 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -601,7 +601,7 @@ void sunxi_board_init(void)
 #endif
 #endif
 	printf("DRAM:");
-	gd->ram_size = sunxi_dram_init();
+	gd->ram_size = (phys_size_t)sunxi_dram_init();
 	printf(" %d MiB\n", (int)(gd->ram_size >> 20));
 	if (!gd->ram_size)
 		hang();
diff --git a/board/sunxi/dram_sun4i_auto.c b/board/sunxi/dram_sun4i_auto.c
index 7d4409b51e..293c968f6b 100644
--- a/board/sunxi/dram_sun4i_auto.c
+++ b/board/sunxi/dram_sun4i_auto.c
@@ -29,7 +29,7 @@ static struct dram_para dram_para = {
 	.dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY,
 };
 
-unsigned long sunxi_dram_init(void)
+unsigned long long sunxi_dram_init(void)
 {
 	return dramc_init(&dram_para);
 }
diff --git a/board/sunxi/dram_sun5i_auto.c b/board/sunxi/dram_sun5i_auto.c
index e3fa243267..02e29b215f 100644
--- a/board/sunxi/dram_sun5i_auto.c
+++ b/board/sunxi/dram_sun5i_auto.c
@@ -32,7 +32,7 @@ static struct dram_para dram_para = {
 	.dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY,
 };
 
-unsigned long sunxi_dram_init(void)
+unsigned long long sunxi_dram_init(void)
 {
 	return dramc_init(&dram_para);
 }
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH 5/5] sunxi: restrict the ram_size to the accessible range in SPL
  2018-02-07 19:35 [U-Boot] [PATCH 0/5] Add 3GiB DRAM support to 64-bit Allwinner SoCs Icenowy Zheng
                   ` (3 preceding siblings ...)
  2018-02-07 19:35 ` [U-Boot] [PATCH 4/5] sunxi: let sunxi_dram_init return unsigned long long Icenowy Zheng
@ 2018-02-07 19:35 ` Icenowy Zheng
  4 siblings, 0 replies; 15+ messages in thread
From: Icenowy Zheng @ 2018-02-07 19:35 UTC (permalink / raw)
  To: u-boot

On newer Allwinner SoCs with the BROM start at 0x0 and the DRAM space at
<0x40000000 0xc0000000>, some parts of DRAM will be inaccessible when
4GiB module is used.

Restrict the ram_size written to global_data in SPL.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 board/sunxi/board.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 5828d47294..a6620f260a 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -541,6 +541,7 @@ int board_mmc_init(bd_t *bis)
 void sunxi_board_init(void)
 {
 	int power_failed = 0;
+	unsigned long long dram_real_size;
 
 #ifdef CONFIG_SY8106A_POWER
 	power_failed = sy8106a_set_vout1(CONFIG_SY8106A_VOUT1_VOLT);
@@ -601,8 +602,16 @@ void sunxi_board_init(void)
 #endif
 #endif
 	printf("DRAM:");
-	gd->ram_size = (phys_size_t)sunxi_dram_init();
-	printf(" %d MiB\n", (int)(gd->ram_size >> 20));
+	dram_real_size = sunxi_dram_init();
+	printf(" %d MiB", (int)(dram_real_size >> 20));
+	if (dram_real_size > CONFIG_SUNXI_DRAM_MAX_SIZE) {
+		gd->ram_size = CONFIG_SUNXI_DRAM_MAX_SIZE;
+		printf(", %d MiB usable\n", (int)(gd->ram_size >> 20));
+	} else {
+		gd->ram_size = (phys_size_t) dram_real_size;
+		printf("\n");
+	}
+
 	if (!gd->ram_size)
 		hang();
 
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH 1/5] sunxi: map DRAM part with 3G size
  2018-02-07 19:35 ` [U-Boot] [PATCH 1/5] sunxi: map DRAM part with 3G size Icenowy Zheng
@ 2018-02-08  0:34   ` André Przywara
  0 siblings, 0 replies; 15+ messages in thread
From: André Przywara @ 2018-02-08  0:34 UTC (permalink / raw)
  To: u-boot

On 07/02/18 19:35, Icenowy Zheng wrote:

Hi,

> All Allwinner 64-bit SoCs now are known to be able to access 3GiB of
> external DRAM, however the size of DRAM part in the MMU translation
> table is still 2GiB.
> 
> Change the size of DRAM part in MMU table to 3GiB.

This is needed for the (new) get_ram_size() to work, isn't it?

I don't like this routine very much, but I guess this change here is
fine anyway:

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre.

> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> ---
>  arch/arm/mach-sunxi/board.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
> index 0c60ee04da..4ee1040ac9 100644
> --- a/arch/arm/mach-sunxi/board.c
> +++ b/arch/arm/mach-sunxi/board.c
> @@ -53,7 +53,7 @@ static struct mm_region sunxi_mem_map[] = {
>  		/* RAM */
>  		.virt = 0x40000000UL,
>  		.phys = 0x40000000UL,
> -		.size = 0x80000000UL,
> +		.size = 0xC0000000UL,
>  		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
>  			 PTE_BLOCK_INNER_SHARE
>  	}, {
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH 2/5] sunxi: add Kconfig option for the maximum accessible DRAM
  2018-02-07 19:35 ` [U-Boot] [PATCH 2/5] sunxi: add Kconfig option for the maximum accessible DRAM Icenowy Zheng
@ 2018-02-08  0:35   ` André Przywara
  2018-02-08  2:14     ` [U-Boot] [linux-sunxi] " Chen-Yu Tsai
  0 siblings, 1 reply; 15+ messages in thread
From: André Przywara @ 2018-02-08  0:35 UTC (permalink / raw)
  To: u-boot

On 07/02/18 19:35, Icenowy Zheng wrote:
> Allwinner 64-bit SoCs can use 4GiB DRAM chip, however their memory map
> has only allocated 3GiB for DRAM, so only 3GiB of the DRAM is
> accessible.
> 
> Add a Kconfig option for the maximum accessible DRAM.

That looks fine to me, but have you checked CONFIG_MAX_MEM_MAPPED?
get_effective_memsize() in common/memsize.c looks like it's solving this
very problem.

> For A80 it should be a much higher value (8GiB), but as I have no A80
> device to test and originally U-Boot only supports 2GiB DRAM on A80, it
> currently still falls under the 2GiB situation.

Well, that depends on how we will use SUNXI_DRAM_SIZE. If that's to
limit the size we eventually report in the DT, that should be indeed 8GB
on the A80. But U-Boot itself can't use more than 3GB on sunxi/ARMv7
(due to the static 1:1 mapping).
I think we should separate those two numbers (actual DRAM size and
U-Boot's own DRAM size), if we really want to support >3GB on the A80.

But maybe we should not get carried away by something that doesn't
really exist.

Thanks,
Andre.

> 
> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> ---
>  arch/arm/mach-sunxi/Kconfig | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index 1fededd0a3..32739e0f33 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -63,6 +63,13 @@ config MACH_SUNXI_H3_H5
>  	select SUNXI_GEN_SUN6I
>  	select SUPPORT_SPL
>  
> +# TODO: try out A80's 8GiB DRAM space
> +config SUNXI_DRAM_MAX_SIZE
> +	hex
> +	default 0xC0000000 if MACH_SUN50I
> +	default 0xC0000000 if MACH_SUN50I_H5
> +	default 0x80000000
> +
>  choice
>  	prompt "Sunxi SoC Variant"
>  	optional
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH 3/5] sunxi: add 3GiB DRAM detection support in main U-Boot
  2018-02-07 19:35 ` [U-Boot] [PATCH 3/5] sunxi: add 3GiB DRAM detection support in main U-Boot Icenowy Zheng
@ 2018-02-08  0:37   ` André Przywara
  2018-02-08  7:03     ` [U-Boot] [linux-sunxi] " Icenowy Zheng
  2018-02-08  8:10     ` Icenowy Zheng
  0 siblings, 2 replies; 15+ messages in thread
From: André Przywara @ 2018-02-08  0:37 UTC (permalink / raw)
  To: u-boot

On 07/02/18 19:35, Icenowy Zheng wrote:

Hi,

> Some Allwinner SoCs can use 3GiB DRAM (part of 4GiB or larger module).
> 
> As the common get_ram_size function cannot detect non-pow-of-2 memory,
> add special detect code into the DRAM size code in main U-Boot.

The original get_ram_size() function is slightly dodgy already (as it
probes memory by writing). And in general we will never be able to cover
ARMv7/LPAE machines easily with our current static identify mapping -
regardless of any probing hacks we pull up.

So I was wondering if we could either:
- somehow pass the result of sunxi_dram_init() to U-Boot proper, or
- call the DRAM size determination routine again

This would give us the definite answer, and would be correct in every
case. We just need to limit it to the memory map limit, if any.

But his function below looks really like a hack. If at all, it should be
part of the get_ram_size() routine itself, as this is not sunxi specific.

Cheers,
Andre.


> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> ---
>  board/sunxi/board.c            | 23 +++++++++++++++++++++++
>  include/configs/sunxi-common.h |  2 +-
>  2 files changed, 24 insertions(+), 1 deletion(-)
> 
> diff --git a/board/sunxi/board.c b/board/sunxi/board.c
> index 8891961dcc..8d707cbac2 100644
> --- a/board/sunxi/board.c
> +++ b/board/sunxi/board.c
> @@ -256,7 +256,30 @@ int board_init(void)
>  
>  int dram_init(void)
>  {
> +#if PHYS_SDRAM_0_SIZE == (SZ_2G + SZ_1G)
> +	/*
> +	 * get_ram_size() doesn't support non-pow-of-2 sizes, so the detection
> +	 * of 3GiB DRAM is implemented here.
> +	 * It just checks whether the DRAM is bigger than 2GiB, as the DRAM
> +	 * module is usually 4GiB in this case (and 1GiB is not accessible).
> +	 */
> +	u32 save_0, save_2g;
> +	gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, SZ_2G);
> +	if (gd->ram_size == SZ_2G) {
> +		save_0 = readl(PHYS_SDRAM_0);
> +		save_2g = readl(PHYS_SDRAM_0 + SZ_2G);
> +		writel(0, PHYS_SDRAM_0);
> +		writel(0xaa55aa55, PHYS_SDRAM_0 + SZ_2G);
> +		dsb();
> +		if (readl(PHYS_SDRAM_0) != readl(PHYS_SDRAM_0 + SZ_2G)) {
> +			gd->ram_size = SZ_2G + SZ_1G;
> +			writel(save_2g, PHYS_SDRAM_0 + SZ_2G);
> +		}
> +		writel(save_0, PHYS_SDRAM_0);
> +	}
> +#else
>  	gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE);
> +#endif
>  
>  	return 0;
>  }
> diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
> index 9b3944ad13..177647e009 100644
> --- a/include/configs/sunxi-common.h
> +++ b/include/configs/sunxi-common.h
> @@ -111,7 +111,7 @@
>  
>  #define CONFIG_NR_DRAM_BANKS		1
>  #define PHYS_SDRAM_0			CONFIG_SYS_SDRAM_BASE
> -#define PHYS_SDRAM_0_SIZE		0x80000000 /* 2 GiB */
> +#define PHYS_SDRAM_0_SIZE		CONFIG_SUNXI_DRAM_MAX_SIZE
>  
>  #ifdef CONFIG_AHCI
>  #define CONFIG_SCSI_AHCI_PLAT
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH 4/5] sunxi: let sunxi_dram_init return unsigned long long
  2018-02-07 19:35 ` [U-Boot] [PATCH 4/5] sunxi: let sunxi_dram_init return unsigned long long Icenowy Zheng
@ 2018-02-08  0:37   ` André Przywara
  2018-02-08  6:56     ` Icenowy Zheng
  0 siblings, 1 reply; 15+ messages in thread
From: André Przywara @ 2018-02-08  0:37 UTC (permalink / raw)
  To: u-boot

On 07/02/18 19:35, Icenowy Zheng wrote:

Hi,

> As 4GiB capacity is above the range of 32-bit unsigned integer, raise
> the return type of sunxi_dram_init() to unsigned long long, thus it can
> hold 4GiB capacity (or maybe more on A80).
> Some controllers that are possible to use 4GiB+ memory module are
> also changed to calculate its memory capacity in unsigned long long.
> 
> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> ---
>  arch/arm/include/asm/arch-sunxi/dram.h | 2 +-
>  arch/arm/mach-sunxi/dram_sun6i.c       | 2 +-
>  arch/arm/mach-sunxi/dram_sun8i_a23.c   | 2 +-
>  arch/arm/mach-sunxi/dram_sun8i_a33.c   | 2 +-
>  arch/arm/mach-sunxi/dram_sun8i_a83t.c  | 2 +-
>  arch/arm/mach-sunxi/dram_sun9i.c       | 4 ++--
>  arch/arm/mach-sunxi/dram_sunxi_dw.c    | 4 ++--
>  board/sunxi/board.c                    | 2 +-
>  board/sunxi/dram_sun4i_auto.c          | 2 +-
>  board/sunxi/dram_sun5i_auto.c          | 2 +-
>  10 files changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h
> index 80abac95b8..d08b82371d 100644
> --- a/arch/arm/include/asm/arch-sunxi/dram.h
> +++ b/arch/arm/include/asm/arch-sunxi/dram.h
> @@ -32,7 +32,7 @@
>  #include <asm/arch/dram_sun4i.h>
>  #endif
>  
> -unsigned long sunxi_dram_init(void);
> +unsigned long long sunxi_dram_init(void);

Since this is explicitly about > 4GB/32 bits, I would suggest we just
use uint64_t here, instead of guessing what long long means.

But can't we just change the semantics of sunxi_dram_init() to return
megabytes instead? sun9i already uses this internally, and just blows it
up in the wrapper. I don't think we have anything with a granularity
smaller than 1MB?
Then we could just leave it at native bit size, and spare poor ARMv7
from struggling with 64 bit arithmetic.

Cheers,
Andre.

>  void mctl_await_completion(u32 *reg, u32 mask, u32 val);
>  bool mctl_mem_matches(u32 offset);
>  
> diff --git a/arch/arm/mach-sunxi/dram_sun6i.c b/arch/arm/mach-sunxi/dram_sun6i.c
> index 5dbbf6186f..bdf52a2c38 100644
> --- a/arch/arm/mach-sunxi/dram_sun6i.c
> +++ b/arch/arm/mach-sunxi/dram_sun6i.c
> @@ -326,7 +326,7 @@ static void mctl_port_cfg(void)
>  	writel(0x00000307, &mctl_com->mbagcr[5]);
>  }
>  
> -unsigned long sunxi_dram_init(void)
> +unsigned long long sunxi_dram_init(void)
>  {
>  	struct sunxi_mctl_com_reg * const mctl_com =
>  		(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
> diff --git a/arch/arm/mach-sunxi/dram_sun8i_a23.c b/arch/arm/mach-sunxi/dram_sun8i_a23.c
> index c53671a0e9..169ccff41a 100644
> --- a/arch/arm/mach-sunxi/dram_sun8i_a23.c
> +++ b/arch/arm/mach-sunxi/dram_sun8i_a23.c
> @@ -264,7 +264,7 @@ static void mctl_init(u32 *bus_width)
>  	writel(0x00000000, &mctl_ctl->rfshctl3);
>  }
>  
> -unsigned long sunxi_dram_init(void)
> +unsigned long long sunxi_dram_init(void)
>  {
>  	struct sunxi_mctl_com_reg * const mctl_com =
>  		(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
> diff --git a/arch/arm/mach-sunxi/dram_sun8i_a33.c b/arch/arm/mach-sunxi/dram_sun8i_a33.c
> index fa1620cb39..dfbbe6f39c 100644
> --- a/arch/arm/mach-sunxi/dram_sun8i_a33.c
> +++ b/arch/arm/mach-sunxi/dram_sun8i_a33.c
> @@ -325,7 +325,7 @@ static void mctl_sys_init(struct dram_para *para)
>  	udelay(250);
>  }
>  
> -unsigned long sunxi_dram_init(void)
> +unsigned long long sunxi_dram_init(void)
>  {
>  	struct sunxi_mctl_com_reg * const mctl_com =
>  			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
> diff --git a/arch/arm/mach-sunxi/dram_sun8i_a83t.c b/arch/arm/mach-sunxi/dram_sun8i_a83t.c
> index 55df1b9d54..ec4bccd635 100644
> --- a/arch/arm/mach-sunxi/dram_sun8i_a83t.c
> +++ b/arch/arm/mach-sunxi/dram_sun8i_a83t.c
> @@ -423,7 +423,7 @@ static void mctl_sys_init(struct dram_para *para)
>  	udelay(250);
>  }
>  
> -unsigned long sunxi_dram_init(void)
> +unsigned long long sunxi_dram_init(void)
>  {
>  	struct sunxi_mctl_com_reg * const mctl_com =
>  			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
> diff --git a/arch/arm/mach-sunxi/dram_sun9i.c b/arch/arm/mach-sunxi/dram_sun9i.c
> index 8c681f3541..dcb20f763e 100644
> --- a/arch/arm/mach-sunxi/dram_sun9i.c
> +++ b/arch/arm/mach-sunxi/dram_sun9i.c
> @@ -854,7 +854,7 @@ signed int DRAMC_get_dram_size(void)
>  	return 1 << dram_size;
>  }
>  
> -unsigned long sunxi_dram_init(void)
> +unsigned long long sunxi_dram_init(void)
>  {
>  	struct sunxi_mctl_com_reg * const mctl_com =
>  		(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
> @@ -957,5 +957,5 @@ unsigned long sunxi_dram_init(void)
>  	mctl_com_init(&para);
>  
>  	/* return the proper RAM size */
> -	return DRAMC_get_dram_size() << 20;
> +	return ((unsigned long long)DRAMC_get_dram_size()) << 20;
>  }
> diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c
> index 78b4ffb9c3..3bff1c46cd 100644
> --- a/arch/arm/mach-sunxi/dram_sunxi_dw.c
> +++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c
> @@ -682,7 +682,7 @@ static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para)
>  	   3,  3,  3,  3,  3,  3,  3,  3,			\
>  	   3,  3,  3,  3,  2,  0,  0      }
>  
> -unsigned long sunxi_dram_init(void)
> +unsigned long long sunxi_dram_init(void)
>  {
>  	struct sunxi_mctl_com_reg * const mctl_com =
>  			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
> @@ -763,6 +763,6 @@ unsigned long sunxi_dram_init(void)
>  	mctl_auto_detect_dram_size(socid, &para);
>  	mctl_set_cr(socid, &para);
>  
> -	return (1UL << (para.row_bits + para.bank_bits)) * para.page_size *
> +	return (1ULL << (para.row_bits + para.bank_bits)) * para.page_size *
>  	       (para.dual_rank ? 2 : 1);
>  }
> diff --git a/board/sunxi/board.c b/board/sunxi/board.c
> index 8d707cbac2..5828d47294 100644
> --- a/board/sunxi/board.c
> +++ b/board/sunxi/board.c
> @@ -601,7 +601,7 @@ void sunxi_board_init(void)
>  #endif
>  #endif
>  	printf("DRAM:");
> -	gd->ram_size = sunxi_dram_init();
> +	gd->ram_size = (phys_size_t)sunxi_dram_init();
>  	printf(" %d MiB\n", (int)(gd->ram_size >> 20));
>  	if (!gd->ram_size)
>  		hang();
> diff --git a/board/sunxi/dram_sun4i_auto.c b/board/sunxi/dram_sun4i_auto.c
> index 7d4409b51e..293c968f6b 100644
> --- a/board/sunxi/dram_sun4i_auto.c
> +++ b/board/sunxi/dram_sun4i_auto.c
> @@ -29,7 +29,7 @@ static struct dram_para dram_para = {
>  	.dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY,
>  };
>  
> -unsigned long sunxi_dram_init(void)
> +unsigned long long sunxi_dram_init(void)
>  {
>  	return dramc_init(&dram_para);
>  }
> diff --git a/board/sunxi/dram_sun5i_auto.c b/board/sunxi/dram_sun5i_auto.c
> index e3fa243267..02e29b215f 100644
> --- a/board/sunxi/dram_sun5i_auto.c
> +++ b/board/sunxi/dram_sun5i_auto.c
> @@ -32,7 +32,7 @@ static struct dram_para dram_para = {
>  	.dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY,
>  };
>  
> -unsigned long sunxi_dram_init(void)
> +unsigned long long sunxi_dram_init(void)
>  {
>  	return dramc_init(&dram_para);
>  }
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [linux-sunxi] Re: [PATCH 2/5] sunxi: add Kconfig option for the maximum accessible DRAM
  2018-02-08  0:35   ` André Przywara
@ 2018-02-08  2:14     ` Chen-Yu Tsai
  2018-02-08  6:43       ` Icenowy Zheng
  0 siblings, 1 reply; 15+ messages in thread
From: Chen-Yu Tsai @ 2018-02-08  2:14 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 8, 2018 at 8:35 AM, André Przywara <andre.przywara@arm.com> wrote:
> On 07/02/18 19:35, Icenowy Zheng wrote:
>> Allwinner 64-bit SoCs can use 4GiB DRAM chip, however their memory map
>> has only allocated 3GiB for DRAM, so only 3GiB of the DRAM is
>> accessible.
>>
>> Add a Kconfig option for the maximum accessible DRAM.
>
> That looks fine to me, but have you checked CONFIG_MAX_MEM_MAPPED?
> get_effective_memsize() in common/memsize.c looks like it's solving this
> very problem.
>
>> For A80 it should be a much higher value (8GiB), but as I have no A80
>> device to test and originally U-Boot only supports 2GiB DRAM on A80, it
>> currently still falls under the 2GiB situation.
>
> Well, that depends on how we will use SUNXI_DRAM_SIZE. If that's to
> limit the size we eventually report in the DT, that should be indeed 8GB
> on the A80. But U-Boot itself can't use more than 3GB on sunxi/ARMv7
> (due to the static 1:1 mapping).
> I think we should separate those two numbers (actual DRAM size and
> U-Boot's own DRAM size), if we really want to support >3GB on the A80.
>
> But maybe we should not get carried away by something that doesn't
> really exist.

That was the first thing that popped up in my mind after seeing this
series. A80 supports LPAE. However, the A80 is out of production, and
no one produced any boards with more than 2GB of RAM. So >3GB on
sunxi is going to go untested for a long time, if not forever.

ChenYu

>
> Thanks,
> Andre.
>
>>
>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>> ---
>>  arch/arm/mach-sunxi/Kconfig | 7 +++++++
>>  1 file changed, 7 insertions(+)
>>
>> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
>> index 1fededd0a3..32739e0f33 100644
>> --- a/arch/arm/mach-sunxi/Kconfig
>> +++ b/arch/arm/mach-sunxi/Kconfig
>> @@ -63,6 +63,13 @@ config MACH_SUNXI_H3_H5
>>       select SUNXI_GEN_SUN6I
>>       select SUPPORT_SPL
>>
>> +# TODO: try out A80's 8GiB DRAM space
>> +config SUNXI_DRAM_MAX_SIZE
>> +     hex
>> +     default 0xC0000000 if MACH_SUN50I
>> +     default 0xC0000000 if MACH_SUN50I_H5
>> +     default 0x80000000
>> +
>>  choice
>>       prompt "Sunxi SoC Variant"
>>       optional
>>
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe at googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [linux-sunxi] Re: [PATCH 2/5] sunxi: add Kconfig option for the maximum accessible DRAM
  2018-02-08  2:14     ` [U-Boot] [linux-sunxi] " Chen-Yu Tsai
@ 2018-02-08  6:43       ` Icenowy Zheng
  0 siblings, 0 replies; 15+ messages in thread
From: Icenowy Zheng @ 2018-02-08  6:43 UTC (permalink / raw)
  To: u-boot

在 2018-02-08 10:14,Chen-Yu Tsai 写道:
> On Thu, Feb 8, 2018 at 8:35 AM, André Przywara <andre.przywara@arm.com> 
> wrote:
>> On 07/02/18 19:35, Icenowy Zheng wrote:
>>> Allwinner 64-bit SoCs can use 4GiB DRAM chip, however their memory 
>>> map
>>> has only allocated 3GiB for DRAM, so only 3GiB of the DRAM is
>>> accessible.
>>> 
>>> Add a Kconfig option for the maximum accessible DRAM.
>> 
>> That looks fine to me, but have you checked CONFIG_MAX_MEM_MAPPED?
>> get_effective_memsize() in common/memsize.c looks like it's solving 
>> this
>> very problem.

get_effective_memsize() restricts memory size from gd->ram_size. 
gd->ram_size
is defined as phys_size_t, which should be 32-bit on Allwinner SoCs 
except
A80. (Although currently CONFIG_ARM64 selects CONFIG_PHYS_64BIT which
makes phys_size_t 64-bit, the high 32-bit doesn't physically exist on
those SoCs, and it's possible for a 32-bit SoC with 3GiB DRAM space to
appear).

A 32-bit data type cannot store a size of 4GiB. This is the first reason
that I doesn't rely on get_effective_memsize().

>> 
>>> For A80 it should be a much higher value (8GiB), but as I have no A80
>>> device to test and originally U-Boot only supports 2GiB DRAM on A80, 
>>> it
>>> currently still falls under the 2GiB situation.
>> 
>> Well, that depends on how we will use SUNXI_DRAM_SIZE. If that's to
>> limit the size we eventually report in the DT, that should be indeed 
>> 8GB
>> on the A80. But U-Boot itself can't use more than 3GB on sunxi/ARMv7
>> (due to the static 1:1 mapping).
>> I think we should separate those two numbers (actual DRAM size and
>> U-Boot's own DRAM size), if we really want to support >3GB on the A80.

Yes, and the CONFIG_MAX_MEM_MAPPED should be used in A80 case, and the
CONFIG_PHYS_64BIT option should be selected, as the internal bus of A80
is bigger than 4GiB.

So that the meaning of CONFIG_MAX_MEM_MAPPED is "maximum memory mapped
in U-Boot", in A80 case only 3.5G is mapped in U-Boot, but Linux can
use the other 4.5G.

(In this case another U-Boot stage code that doesn't scan DRAM size but
calculate it from memory controller is needed.)

In A64/H5/H6 case the whole 3G accessible memory is mapped to U-Boot,
and there's no memory that U-Boot cannot access but some other software
can. So the gd->ram_size should be restricted at 3GiB. (The 1GiB is
installed to the system, but it's not part of the system memory due to
it's totally not accessible.)

>> 
>> But maybe we should not get carried away by something that doesn't
>> really exist.
> 
> That was the first thing that popped up in my mind after seeing this
> series. A80 supports LPAE. However, the A80 is out of production, and
> no one produced any boards with more than 2GB of RAM. So >3GB on
> sunxi is going to go untested for a long time, if not forever.
> 
> ChenYu
> 
>> 
>> Thanks,
>> Andre.
>> 
>>> 
>>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>>> ---
>>>  arch/arm/mach-sunxi/Kconfig | 7 +++++++
>>>  1 file changed, 7 insertions(+)
>>> 
>>> diff --git a/arch/arm/mach-sunxi/Kconfig 
>>> b/arch/arm/mach-sunxi/Kconfig
>>> index 1fededd0a3..32739e0f33 100644
>>> --- a/arch/arm/mach-sunxi/Kconfig
>>> +++ b/arch/arm/mach-sunxi/Kconfig
>>> @@ -63,6 +63,13 @@ config MACH_SUNXI_H3_H5
>>>       select SUNXI_GEN_SUN6I
>>>       select SUPPORT_SPL
>>> 
>>> +# TODO: try out A80's 8GiB DRAM space
>>> +config SUNXI_DRAM_MAX_SIZE
>>> +     hex
>>> +     default 0xC0000000 if MACH_SUN50I
>>> +     default 0xC0000000 if MACH_SUN50I_H5
>>> +     default 0x80000000
>>> +
>>>  choice
>>>       prompt "Sunxi SoC Variant"
>>>       optional
>>> 
>> 
>> --
>> You received this message because you are subscribed to the Google 
>> Groups "linux-sunxi" group.
>> To unsubscribe from this group and stop receiving emails from it, send 
>> an email to linux-sunxi+unsubscribe at googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH 4/5] sunxi: let sunxi_dram_init return unsigned long long
  2018-02-08  0:37   ` André Przywara
@ 2018-02-08  6:56     ` Icenowy Zheng
  0 siblings, 0 replies; 15+ messages in thread
From: Icenowy Zheng @ 2018-02-08  6:56 UTC (permalink / raw)
  To: u-boot

在 2018-02-08 08:37,André Przywara 写道:
> On 07/02/18 19:35, Icenowy Zheng wrote:
> 
> Hi,
> 
>> As 4GiB capacity is above the range of 32-bit unsigned integer, raise
>> the return type of sunxi_dram_init() to unsigned long long, thus it 
>> can
>> hold 4GiB capacity (or maybe more on A80).
>> Some controllers that are possible to use 4GiB+ memory module are
>> also changed to calculate its memory capacity in unsigned long long.
>> 
>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>> ---
>>  arch/arm/include/asm/arch-sunxi/dram.h | 2 +-
>>  arch/arm/mach-sunxi/dram_sun6i.c       | 2 +-
>>  arch/arm/mach-sunxi/dram_sun8i_a23.c   | 2 +-
>>  arch/arm/mach-sunxi/dram_sun8i_a33.c   | 2 +-
>>  arch/arm/mach-sunxi/dram_sun8i_a83t.c  | 2 +-
>>  arch/arm/mach-sunxi/dram_sun9i.c       | 4 ++--
>>  arch/arm/mach-sunxi/dram_sunxi_dw.c    | 4 ++--
>>  board/sunxi/board.c                    | 2 +-
>>  board/sunxi/dram_sun4i_auto.c          | 2 +-
>>  board/sunxi/dram_sun5i_auto.c          | 2 +-
>>  10 files changed, 12 insertions(+), 12 deletions(-)
>> 
>> diff --git a/arch/arm/include/asm/arch-sunxi/dram.h 
>> b/arch/arm/include/asm/arch-sunxi/dram.h
>> index 80abac95b8..d08b82371d 100644
>> --- a/arch/arm/include/asm/arch-sunxi/dram.h
>> +++ b/arch/arm/include/asm/arch-sunxi/dram.h
>> @@ -32,7 +32,7 @@
>>  #include <asm/arch/dram_sun4i.h>
>>  #endif
>> 
>> -unsigned long sunxi_dram_init(void);
>> +unsigned long long sunxi_dram_init(void);
> 
> Since this is explicitly about > 4GB/32 bits, I would suggest we just
> use uint64_t here, instead of guessing what long long means.

Seems OK. But is there any sure suffix for uint64_t? For unsigned long
long we can use ULL.

> 
> But can't we just change the semantics of sunxi_dram_init() to return
> megabytes instead? sun9i already uses this internally, and just blows 
> it
> up in the wrapper. I don't think we have anything with a granularity
> smaller than 1MB?
> Then we could just leave it at native bit size, and spare poor ARMv7
> from struggling with 64 bit arithmetic.

The calculated size is just in byte.

The A80 code first shifted it to MiB in DRAMC_get_dram_size() and then
shifted it back to B in sunxi_dram_init(); however the code that shifts
it to MiB only applies to drivers which have shift operation.

The other target driver, dram_sunxi_dw, uses both bit shifts and 
multiply
when calculating the size, and to have 4096MiB value we still need to
calculate the byte value as uint64_t and then shift it to MiB value.
(The multiply value can get as high as 4096, so it's highly possible
that the shift value could be less than 20.)

I think keeping the return value as byte will make the code more clear.

> 
> Cheers,
> Andre.
> 
>>  void mctl_await_completion(u32 *reg, u32 mask, u32 val);
>>  bool mctl_mem_matches(u32 offset);
>> 
>> diff --git a/arch/arm/mach-sunxi/dram_sun6i.c 
>> b/arch/arm/mach-sunxi/dram_sun6i.c
>> index 5dbbf6186f..bdf52a2c38 100644
>> --- a/arch/arm/mach-sunxi/dram_sun6i.c
>> +++ b/arch/arm/mach-sunxi/dram_sun6i.c
>> @@ -326,7 +326,7 @@ static void mctl_port_cfg(void)
>>  	writel(0x00000307, &mctl_com->mbagcr[5]);
>>  }
>> 
>> -unsigned long sunxi_dram_init(void)
>> +unsigned long long sunxi_dram_init(void)
>>  {
>>  	struct sunxi_mctl_com_reg * const mctl_com =
>>  		(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
>> diff --git a/arch/arm/mach-sunxi/dram_sun8i_a23.c 
>> b/arch/arm/mach-sunxi/dram_sun8i_a23.c
>> index c53671a0e9..169ccff41a 100644
>> --- a/arch/arm/mach-sunxi/dram_sun8i_a23.c
>> +++ b/arch/arm/mach-sunxi/dram_sun8i_a23.c
>> @@ -264,7 +264,7 @@ static void mctl_init(u32 *bus_width)
>>  	writel(0x00000000, &mctl_ctl->rfshctl3);
>>  }
>> 
>> -unsigned long sunxi_dram_init(void)
>> +unsigned long long sunxi_dram_init(void)
>>  {
>>  	struct sunxi_mctl_com_reg * const mctl_com =
>>  		(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
>> diff --git a/arch/arm/mach-sunxi/dram_sun8i_a33.c 
>> b/arch/arm/mach-sunxi/dram_sun8i_a33.c
>> index fa1620cb39..dfbbe6f39c 100644
>> --- a/arch/arm/mach-sunxi/dram_sun8i_a33.c
>> +++ b/arch/arm/mach-sunxi/dram_sun8i_a33.c
>> @@ -325,7 +325,7 @@ static void mctl_sys_init(struct dram_para *para)
>>  	udelay(250);
>>  }
>> 
>> -unsigned long sunxi_dram_init(void)
>> +unsigned long long sunxi_dram_init(void)
>>  {
>>  	struct sunxi_mctl_com_reg * const mctl_com =
>>  			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
>> diff --git a/arch/arm/mach-sunxi/dram_sun8i_a83t.c 
>> b/arch/arm/mach-sunxi/dram_sun8i_a83t.c
>> index 55df1b9d54..ec4bccd635 100644
>> --- a/arch/arm/mach-sunxi/dram_sun8i_a83t.c
>> +++ b/arch/arm/mach-sunxi/dram_sun8i_a83t.c
>> @@ -423,7 +423,7 @@ static void mctl_sys_init(struct dram_para *para)
>>  	udelay(250);
>>  }
>> 
>> -unsigned long sunxi_dram_init(void)
>> +unsigned long long sunxi_dram_init(void)
>>  {
>>  	struct sunxi_mctl_com_reg * const mctl_com =
>>  			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
>> diff --git a/arch/arm/mach-sunxi/dram_sun9i.c 
>> b/arch/arm/mach-sunxi/dram_sun9i.c
>> index 8c681f3541..dcb20f763e 100644
>> --- a/arch/arm/mach-sunxi/dram_sun9i.c
>> +++ b/arch/arm/mach-sunxi/dram_sun9i.c
>> @@ -854,7 +854,7 @@ signed int DRAMC_get_dram_size(void)
>>  	return 1 << dram_size;
>>  }
>> 
>> -unsigned long sunxi_dram_init(void)
>> +unsigned long long sunxi_dram_init(void)
>>  {
>>  	struct sunxi_mctl_com_reg * const mctl_com =
>>  		(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
>> @@ -957,5 +957,5 @@ unsigned long sunxi_dram_init(void)
>>  	mctl_com_init(&para);
>> 
>>  	/* return the proper RAM size */
>> -	return DRAMC_get_dram_size() << 20;
>> +	return ((unsigned long long)DRAMC_get_dram_size()) << 20;
>>  }
>> diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c 
>> b/arch/arm/mach-sunxi/dram_sunxi_dw.c
>> index 78b4ffb9c3..3bff1c46cd 100644
>> --- a/arch/arm/mach-sunxi/dram_sunxi_dw.c
>> +++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c
>> @@ -682,7 +682,7 @@ static void mctl_auto_detect_dram_size(uint16_t 
>> socid, struct dram_para *para)
>>  	   3,  3,  3,  3,  3,  3,  3,  3,			\
>>  	   3,  3,  3,  3,  2,  0,  0      }
>> 
>> -unsigned long sunxi_dram_init(void)
>> +unsigned long long sunxi_dram_init(void)
>>  {
>>  	struct sunxi_mctl_com_reg * const mctl_com =
>>  			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
>> @@ -763,6 +763,6 @@ unsigned long sunxi_dram_init(void)
>>  	mctl_auto_detect_dram_size(socid, &para);
>>  	mctl_set_cr(socid, &para);
>> 
>> -	return (1UL << (para.row_bits + para.bank_bits)) * para.page_size *
>> +	return (1ULL << (para.row_bits + para.bank_bits)) * para.page_size *
>>  	       (para.dual_rank ? 2 : 1);
>>  }
>> diff --git a/board/sunxi/board.c b/board/sunxi/board.c
>> index 8d707cbac2..5828d47294 100644
>> --- a/board/sunxi/board.c
>> +++ b/board/sunxi/board.c
>> @@ -601,7 +601,7 @@ void sunxi_board_init(void)
>>  #endif
>>  #endif
>>  	printf("DRAM:");
>> -	gd->ram_size = sunxi_dram_init();
>> +	gd->ram_size = (phys_size_t)sunxi_dram_init();
>>  	printf(" %d MiB\n", (int)(gd->ram_size >> 20));
>>  	if (!gd->ram_size)
>>  		hang();
>> diff --git a/board/sunxi/dram_sun4i_auto.c 
>> b/board/sunxi/dram_sun4i_auto.c
>> index 7d4409b51e..293c968f6b 100644
>> --- a/board/sunxi/dram_sun4i_auto.c
>> +++ b/board/sunxi/dram_sun4i_auto.c
>> @@ -29,7 +29,7 @@ static struct dram_para dram_para = {
>>  	.dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY,
>>  };
>> 
>> -unsigned long sunxi_dram_init(void)
>> +unsigned long long sunxi_dram_init(void)
>>  {
>>  	return dramc_init(&dram_para);
>>  }
>> diff --git a/board/sunxi/dram_sun5i_auto.c 
>> b/board/sunxi/dram_sun5i_auto.c
>> index e3fa243267..02e29b215f 100644
>> --- a/board/sunxi/dram_sun5i_auto.c
>> +++ b/board/sunxi/dram_sun5i_auto.c
>> @@ -32,7 +32,7 @@ static struct dram_para dram_para = {
>>  	.dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY,
>>  };
>> 
>> -unsigned long sunxi_dram_init(void)
>> +unsigned long long sunxi_dram_init(void)
>>  {
>>  	return dramc_init(&dram_para);
>>  }
>> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [linux-sunxi] Re: [PATCH 3/5] sunxi: add 3GiB DRAM detection support in main U-Boot
  2018-02-08  0:37   ` André Przywara
@ 2018-02-08  7:03     ` Icenowy Zheng
  2018-02-08  8:10     ` Icenowy Zheng
  1 sibling, 0 replies; 15+ messages in thread
From: Icenowy Zheng @ 2018-02-08  7:03 UTC (permalink / raw)
  To: u-boot

在 2018-02-08 08:37,André Przywara 写道:
> On 07/02/18 19:35, Icenowy Zheng wrote:
> 
> Hi,
> 
>> Some Allwinner SoCs can use 3GiB DRAM (part of 4GiB or larger module).
>> 
>> As the common get_ram_size function cannot detect non-pow-of-2 memory,
>> add special detect code into the DRAM size code in main U-Boot.
> 
> The original get_ram_size() function is slightly dodgy already (as it
> probes memory by writing). And in general we will never be able to 
> cover
> ARMv7/LPAE machines easily with our current static identify mapping -
> regardless of any probing hacks we pull up.
> 
> So I was wondering if we could either:
> - somehow pass the result of sunxi_dram_init() to U-Boot proper, or
> - call the DRAM size determination routine again
> 
> This would give us the definite answer, and would be correct in every
> case. We just need to limit it to the memory map limit, if any.

Okay. Let me try.

> 
> But his function below looks really like a hack. If at all, it should 
> be
> part of the get_ram_size() routine itself, as this is not sunxi 
> specific.

This hack is too immature to be a common hack, it just consider 4GiB as 
3GiB,
so it's still a sunxi specific hack.

> 
> Cheers,
> Andre.
> 
> 
>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>> ---
>>  board/sunxi/board.c            | 23 +++++++++++++++++++++++
>>  include/configs/sunxi-common.h |  2 +-
>>  2 files changed, 24 insertions(+), 1 deletion(-)
>> 
>> diff --git a/board/sunxi/board.c b/board/sunxi/board.c
>> index 8891961dcc..8d707cbac2 100644
>> --- a/board/sunxi/board.c
>> +++ b/board/sunxi/board.c
>> @@ -256,7 +256,30 @@ int board_init(void)
>> 
>>  int dram_init(void)
>>  {
>> +#if PHYS_SDRAM_0_SIZE == (SZ_2G + SZ_1G)
>> +	/*
>> +	 * get_ram_size() doesn't support non-pow-of-2 sizes, so the 
>> detection
>> +	 * of 3GiB DRAM is implemented here.
>> +	 * It just checks whether the DRAM is bigger than 2GiB, as the DRAM
>> +	 * module is usually 4GiB in this case (and 1GiB is not accessible).
>> +	 */
>> +	u32 save_0, save_2g;
>> +	gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, SZ_2G);
>> +	if (gd->ram_size == SZ_2G) {
>> +		save_0 = readl(PHYS_SDRAM_0);
>> +		save_2g = readl(PHYS_SDRAM_0 + SZ_2G);
>> +		writel(0, PHYS_SDRAM_0);
>> +		writel(0xaa55aa55, PHYS_SDRAM_0 + SZ_2G);
>> +		dsb();
>> +		if (readl(PHYS_SDRAM_0) != readl(PHYS_SDRAM_0 + SZ_2G)) {
>> +			gd->ram_size = SZ_2G + SZ_1G;
>> +			writel(save_2g, PHYS_SDRAM_0 + SZ_2G);
>> +		}
>> +		writel(save_0, PHYS_SDRAM_0);
>> +	}
>> +#else
>>  	gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, 
>> PHYS_SDRAM_0_SIZE);
>> +#endif
>> 
>>  	return 0;
>>  }
>> diff --git a/include/configs/sunxi-common.h 
>> b/include/configs/sunxi-common.h
>> index 9b3944ad13..177647e009 100644
>> --- a/include/configs/sunxi-common.h
>> +++ b/include/configs/sunxi-common.h
>> @@ -111,7 +111,7 @@
>> 
>>  #define CONFIG_NR_DRAM_BANKS		1
>>  #define PHYS_SDRAM_0			CONFIG_SYS_SDRAM_BASE
>> -#define PHYS_SDRAM_0_SIZE		0x80000000 /* 2 GiB */
>> +#define PHYS_SDRAM_0_SIZE		CONFIG_SUNXI_DRAM_MAX_SIZE
>> 
>>  #ifdef CONFIG_AHCI
>>  #define CONFIG_SCSI_AHCI_PLAT
>> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [linux-sunxi] Re: [PATCH 3/5] sunxi: add 3GiB DRAM detection support in main U-Boot
  2018-02-08  0:37   ` André Przywara
  2018-02-08  7:03     ` [U-Boot] [linux-sunxi] " Icenowy Zheng
@ 2018-02-08  8:10     ` Icenowy Zheng
  1 sibling, 0 replies; 15+ messages in thread
From: Icenowy Zheng @ 2018-02-08  8:10 UTC (permalink / raw)
  To: u-boot

在 2018-02-08 08:37,André Przywara 写道:
> On 07/02/18 19:35, Icenowy Zheng wrote:
> 
> Hi,
> 
>> Some Allwinner SoCs can use 3GiB DRAM (part of 4GiB or larger module).
>> 
>> As the common get_ram_size function cannot detect non-pow-of-2 memory,
>> add special detect code into the DRAM size code in main U-Boot.
> 
> The original get_ram_size() function is slightly dodgy already (as it
> probes memory by writing). And in general we will never be able to 
> cover
> ARMv7/LPAE machines easily with our current static identify mapping -
> regardless of any probing hacks we pull up.
> 
> So I was wondering if we could either:
> - somehow pass the result of sunxi_dram_init() to U-Boot proper, or

Where to pass it?

I don't think currently we pass anything from SPL to U-Boot. And it's
still a bit possible to use BSP boot0 with mainline U-Boot.

> - call the DRAM size determination routine again

I checked the DRAM controller of H6, and it's not easy to re-calc the
DRAM size -- the DRAM size is only considered when constructing ADDRMAP
registers. We may need to emulate part of the DRAM controller to calc
the size ;-)

> 
> This would give us the definite answer, and would be correct in every
> case. We just need to limit it to the memory map limit, if any.
> 
> But his function below looks really like a hack. If at all, it should 
> be
> part of the get_ram_size() routine itself, as this is not sunxi 
> specific.
> 
> Cheers,
> Andre.
> 
> 
>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>> ---
>>  board/sunxi/board.c            | 23 +++++++++++++++++++++++
>>  include/configs/sunxi-common.h |  2 +-
>>  2 files changed, 24 insertions(+), 1 deletion(-)
>> 
>> diff --git a/board/sunxi/board.c b/board/sunxi/board.c
>> index 8891961dcc..8d707cbac2 100644
>> --- a/board/sunxi/board.c
>> +++ b/board/sunxi/board.c
>> @@ -256,7 +256,30 @@ int board_init(void)
>> 
>>  int dram_init(void)
>>  {
>> +#if PHYS_SDRAM_0_SIZE == (SZ_2G + SZ_1G)
>> +	/*
>> +	 * get_ram_size() doesn't support non-pow-of-2 sizes, so the 
>> detection
>> +	 * of 3GiB DRAM is implemented here.
>> +	 * It just checks whether the DRAM is bigger than 2GiB, as the DRAM
>> +	 * module is usually 4GiB in this case (and 1GiB is not accessible).
>> +	 */
>> +	u32 save_0, save_2g;
>> +	gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, SZ_2G);
>> +	if (gd->ram_size == SZ_2G) {
>> +		save_0 = readl(PHYS_SDRAM_0);
>> +		save_2g = readl(PHYS_SDRAM_0 + SZ_2G);
>> +		writel(0, PHYS_SDRAM_0);
>> +		writel(0xaa55aa55, PHYS_SDRAM_0 + SZ_2G);
>> +		dsb();
>> +		if (readl(PHYS_SDRAM_0) != readl(PHYS_SDRAM_0 + SZ_2G)) {
>> +			gd->ram_size = SZ_2G + SZ_1G;
>> +			writel(save_2g, PHYS_SDRAM_0 + SZ_2G);
>> +		}
>> +		writel(save_0, PHYS_SDRAM_0);
>> +	}
>> +#else
>>  	gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, 
>> PHYS_SDRAM_0_SIZE);
>> +#endif
>> 
>>  	return 0;
>>  }
>> diff --git a/include/configs/sunxi-common.h 
>> b/include/configs/sunxi-common.h
>> index 9b3944ad13..177647e009 100644
>> --- a/include/configs/sunxi-common.h
>> +++ b/include/configs/sunxi-common.h
>> @@ -111,7 +111,7 @@
>> 
>>  #define CONFIG_NR_DRAM_BANKS		1
>>  #define PHYS_SDRAM_0			CONFIG_SYS_SDRAM_BASE
>> -#define PHYS_SDRAM_0_SIZE		0x80000000 /* 2 GiB */
>> +#define PHYS_SDRAM_0_SIZE		CONFIG_SUNXI_DRAM_MAX_SIZE
>> 
>>  #ifdef CONFIG_AHCI
>>  #define CONFIG_SCSI_AHCI_PLAT
>> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2018-02-08  8:10 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-07 19:35 [U-Boot] [PATCH 0/5] Add 3GiB DRAM support to 64-bit Allwinner SoCs Icenowy Zheng
2018-02-07 19:35 ` [U-Boot] [PATCH 1/5] sunxi: map DRAM part with 3G size Icenowy Zheng
2018-02-08  0:34   ` André Przywara
2018-02-07 19:35 ` [U-Boot] [PATCH 2/5] sunxi: add Kconfig option for the maximum accessible DRAM Icenowy Zheng
2018-02-08  0:35   ` André Przywara
2018-02-08  2:14     ` [U-Boot] [linux-sunxi] " Chen-Yu Tsai
2018-02-08  6:43       ` Icenowy Zheng
2018-02-07 19:35 ` [U-Boot] [PATCH 3/5] sunxi: add 3GiB DRAM detection support in main U-Boot Icenowy Zheng
2018-02-08  0:37   ` André Przywara
2018-02-08  7:03     ` [U-Boot] [linux-sunxi] " Icenowy Zheng
2018-02-08  8:10     ` Icenowy Zheng
2018-02-07 19:35 ` [U-Boot] [PATCH 4/5] sunxi: let sunxi_dram_init return unsigned long long Icenowy Zheng
2018-02-08  0:37   ` André Przywara
2018-02-08  6:56     ` Icenowy Zheng
2018-02-07 19:35 ` [U-Boot] [PATCH 5/5] sunxi: restrict the ram_size to the accessible range in SPL Icenowy Zheng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.