u-boot.lists.denx.de archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] sunxi: Update H616 DRAM driver
@ 2022-12-11 16:32 Jernej Skrabec
  2022-12-11 16:32 ` [PATCH 1/8] sunxi: Fix write to H616 DRAM CR register Jernej Skrabec
                   ` (9 more replies)
  0 siblings, 10 replies; 29+ messages in thread
From: Jernej Skrabec @ 2022-12-11 16:32 UTC (permalink / raw)
  To: andre.przywara, jagan; +Cc: u-boot, Jernej Skrabec

Current H616 DRAM driver is completely customized to Orange Pi Zero2
board, which is currently the only H616 board supported by U-Boot.
Needless to say, this is not ideal for adding new boards. With changes
in this series, all DDR3 boards are supported and all that is needed is
just vendor DRAM values extracted from Android image. New DRAM types
should also be easier to support, since a lot of constants used before
are not really DRAM type dependent.

Changes were verified by decompiling driver and generated values were
compared to previous, hard coded ones. This was done without dram_para
structures, so compiler was able to heavily optimize code and produce
constants.

Please take a look.

Best regards,
Jernej

Jernej Skrabec (8):
  sunxi: Fix write to H616 DRAM CR register
  sunxi: cosmetic: Fix H616 DRAM driver code style
  sunxi: parameterize H616 DRAM ODT values
  sunxi: Convert H616 DRAM options to single setting
  sunxi: Always configure ODT on H616 DRAM
  sunxi: Make bit delay function in H616 DRAM code void
  sunxi: Parameterize bit delay code in H616 DRAM driver
  sunxi: Parameterize H616 DRAM code some more

 .../include/asm/arch-sunxi/dram_sun50i_h616.h |  18 +
 arch/arm/mach-sunxi/Kconfig                   |  67 +--
 arch/arm/mach-sunxi/dram_sun50i_h616.c        | 445 +++++++++++-------
 configs/orangepi_zero2_defconfig              |   8 +-
 4 files changed, 348 insertions(+), 190 deletions(-)

-- 
2.38.1


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

* [PATCH 1/8] sunxi: Fix write to H616 DRAM CR register
  2022-12-11 16:32 [PATCH 0/8] sunxi: Update H616 DRAM driver Jernej Skrabec
@ 2022-12-11 16:32 ` Jernej Skrabec
  2023-01-04  0:35   ` Andre Przywara
  2022-12-11 16:32 ` [PATCH 2/8] sunxi: cosmetic: Fix H616 DRAM driver code style Jernej Skrabec
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 29+ messages in thread
From: Jernej Skrabec @ 2022-12-11 16:32 UTC (permalink / raw)
  To: andre.przywara, jagan; +Cc: u-boot, Jernej Skrabec

Vendor DRAM code actually writes to whole CR register and not just sets
bit 31 in mctl_ctrl_init().

Just to be safe, do that here too.

Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 arch/arm/mach-sunxi/dram_sun50i_h616.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
index 454c845a0010..039e76224367 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
@@ -873,7 +873,7 @@ static bool mctl_ctrl_init(struct dram_para *para)
 	writel(0x06000400, &mctl_ctl->unk_0x3240);
 	writel(0x06000400, &mctl_ctl->unk_0x4240);
 
-	setbits_le32(&mctl_com->cr, BIT(31));
+	writel(BIT(31), &mctl_com->cr);
 
 	mctl_set_addrmap(para);
 
-- 
2.38.1


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

* [PATCH 2/8] sunxi: cosmetic: Fix H616 DRAM driver code style
  2022-12-11 16:32 [PATCH 0/8] sunxi: Update H616 DRAM driver Jernej Skrabec
  2022-12-11 16:32 ` [PATCH 1/8] sunxi: Fix write to H616 DRAM CR register Jernej Skrabec
@ 2022-12-11 16:32 ` Jernej Skrabec
  2023-01-04  0:36   ` Andre Przywara
  2022-12-11 16:32 ` [PATCH 3/8] sunxi: parameterize H616 DRAM ODT values Jernej Skrabec
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 29+ messages in thread
From: Jernej Skrabec @ 2022-12-11 16:32 UTC (permalink / raw)
  To: andre.przywara, jagan; +Cc: u-boot, Jernej Skrabec

Fix code style for pointer declaration. This is just cosmetic change to
avoid checkpatch errors in later commits.

Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 arch/arm/mach-sunxi/dram_sun50i_h616.c | 74 +++++++++++++-------------
 1 file changed, 37 insertions(+), 37 deletions(-)

diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
index 039e76224367..49983bf7a1b8 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
@@ -285,7 +285,7 @@ static bool mctl_phy_write_leveling(struct dram_para *para)
 	else
 		val = 3;
 
-	mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x188), val, val);
+	mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x188), val, val);
 
 	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 4);
 
@@ -314,7 +314,7 @@ static bool mctl_phy_write_leveling(struct dram_para *para)
 		else
 			val = 3;
 
-		mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x188), val, val);
+		mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x188), val, val);
 
 		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 4);
 	}
@@ -398,26 +398,26 @@ static bool mctl_phy_read_training(struct dram_para *para)
 	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 6);
 	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 1);
 
-	mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc);
+	mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc);
 	if (readl(SUNXI_DRAM_PHY0_BASE + 0x840) & 3)
 		result = false;
 
 	if (para->bus_full_width) {
-		mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc);
+		mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc);
 		if (readl(SUNXI_DRAM_PHY0_BASE + 0xa40) & 3)
 			result = false;
 	}
 
-	ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x898);
-	ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x850);
+	ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x898);
+	ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x850);
 	for (i = 0; i < 9; i++) {
 		val1 = readl(&ptr1[i]);
 		val2 = readl(&ptr2[i]);
 		if (val1 - val2 <= 6)
 			result = false;
 	}
-	ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x8bc);
-	ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x874);
+	ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8bc);
+	ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x874);
 	for (i = 0; i < 9; i++) {
 		val1 = readl(&ptr1[i]);
 		val2 = readl(&ptr2[i]);
@@ -426,8 +426,8 @@ static bool mctl_phy_read_training(struct dram_para *para)
 	}
 
 	if (para->bus_full_width) {
-		ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xa98);
-		ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xa50);
+		ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa98);
+		ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa50);
 		for (i = 0; i < 9; i++) {
 			val1 = readl(&ptr1[i]);
 			val2 = readl(&ptr2[i]);
@@ -435,8 +435,8 @@ static bool mctl_phy_read_training(struct dram_para *para)
 				result = false;
 		}
 
-		ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xabc);
-		ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xa74);
+		ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xabc);
+		ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa74);
 		for (i = 0; i < 9; i++) {
 			val1 = readl(&ptr1[i]);
 			val2 = readl(&ptr2[i]);
@@ -454,12 +454,12 @@ static bool mctl_phy_read_training(struct dram_para *para)
 		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 6);
 		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 1);
 
-		mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc);
+		mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc);
 		if (readl(SUNXI_DRAM_PHY0_BASE + 0x840) & 3)
 			result = false;
 
 		if (para->bus_full_width) {
-			mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc);
+			mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc);
 			if (readl(SUNXI_DRAM_PHY0_BASE + 0xa40) & 3)
 				result = false;
 		}
@@ -488,26 +488,26 @@ static bool mctl_phy_write_training(struct dram_para *para)
 	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
 	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x20);
 
-	mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3);
+	mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3);
 	if (readl(SUNXI_DRAM_PHY0_BASE + 0x8e0) & 0xc)
 		result = false;
 
 	if (para->bus_full_width) {
-		mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3);
+		mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3);
 		if (readl(SUNXI_DRAM_PHY0_BASE + 0xae0) & 0xc)
 			result = false;
 	}
 
-	ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x938);
-	ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x8f0);
+	ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x938);
+	ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8f0);
 	for (i = 0; i < 9; i++) {
 		val1 = readl(&ptr1[i]);
 		val2 = readl(&ptr2[i]);
 		if (val1 - val2 <= 6)
 			result = false;
 	}
-	ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x95c);
-	ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x914);
+	ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x95c);
+	ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x914);
 	for (i = 0; i < 9; i++) {
 		val1 = readl(&ptr1[i]);
 		val2 = readl(&ptr2[i]);
@@ -516,16 +516,16 @@ static bool mctl_phy_write_training(struct dram_para *para)
 	}
 
 	if (para->bus_full_width) {
-		ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xb38);
-		ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xaf0);
+		ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb38);
+		ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xaf0);
 		for (i = 0; i < 9; i++) {
 			val1 = readl(&ptr1[i]);
 			val2 = readl(&ptr2[i]);
 			if (val1 - val2 <= 6)
 				result = false;
 		}
-		ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xb5c);
-		ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xb14);
+		ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb5c);
+		ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb14);
 		for (i = 0; i < 9; i++) {
 			val1 = readl(&ptr1[i]);
 			val2 = readl(&ptr2[i]);
@@ -542,12 +542,12 @@ static bool mctl_phy_write_training(struct dram_para *para)
 		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
 		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x20);
 
-		mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3);
+		mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3);
 		if (readl(SUNXI_DRAM_PHY0_BASE + 0x8e0) & 0xc)
 			result = false;
 
 		if (para->bus_full_width) {
-			mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3);
+			mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3);
 			if (readl(SUNXI_DRAM_PHY0_BASE + 0xae0) & 0xc)
 				result = false;
 		}
@@ -569,7 +569,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
 	setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
 	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
 
-	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x484);
+	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
 	for (i = 0; i < 9; i++) {
 		writel_relaxed(0x16, ptr);
 		writel_relaxed(0x16, ptr + 0x30);
@@ -580,7 +580,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
 	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
 	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
 
-	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
+	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
 	for (i = 0; i < 9; i++) {
 		writel_relaxed(0x1a, ptr);
 		writel_relaxed(0x1a, ptr + 0x30);
@@ -591,7 +591,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
 	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
 	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
 
-	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x604);
+	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
 	for (i = 0; i < 9; i++) {
 		writel_relaxed(0x1a, ptr);
 		writel_relaxed(0x1a, ptr + 0x30);
@@ -602,7 +602,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
 	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
 	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
 
-	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x658);
+	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
 	for (i = 0; i < 9; i++) {
 		writel_relaxed(0x1a, ptr);
 		writel_relaxed(0x1a, ptr + 0x30);
@@ -621,7 +621,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
 	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
 	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
 
-	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x480);
+	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
 	for (i = 0; i < 9; i++) {
 		writel_relaxed(0x10, ptr);
 		writel_relaxed(0x10, ptr + 0x30);
@@ -632,7 +632,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
 	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
 	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
 
-	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
+	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
 	for (i = 0; i < 9; i++) {
 		writel_relaxed(0x12, ptr);
 		writel_relaxed(0x12, ptr + 0x30);
@@ -643,7 +643,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
 	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
 	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
 
-	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x600);
+	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
 	for (i = 0; i < 9; i++) {
 		writel_relaxed(0x12, ptr);
 		writel_relaxed(0x12, ptr + 0x30);
@@ -654,7 +654,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
 	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
 	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
 
-	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x654);
+	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
 	for (i = 0; i < 9; i++) {
 		writel_relaxed(0x14, ptr);
 		writel_relaxed(0x14, ptr + 0x30);
@@ -702,12 +702,12 @@ static bool mctl_phy_init(struct dram_para *para)
 	writel(9, SUNXI_DRAM_PHY0_BASE + 0x370);
 	writel(9, SUNXI_DRAM_PHY0_BASE + 0x37c);
 
-	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xc0);
+	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xc0);
 	for (i = 0; i < ARRAY_SIZE(phy_init); i++)
 		writel(phy_init[i], &ptr[i]);
 
 	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_UNKNOWN_FEATURE)) {
-		ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x780);
+		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780);
 		for (i = 0; i < 32; i++)
 			writel(0x16, &ptr[i]);
 		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x78c);
@@ -738,7 +738,7 @@ static bool mctl_phy_init(struct dram_para *para)
 
 	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x14c, 8);
 
-	mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x180), 4, 4);
+	mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x180), 4, 4);
 
 	writel(0x37, SUNXI_DRAM_PHY0_BASE + 0x58);
 	clrbits_le32(&mctl_com->unk_0x500, 0x200);
-- 
2.38.1


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

* [PATCH 3/8] sunxi: parameterize H616 DRAM ODT values
  2022-12-11 16:32 [PATCH 0/8] sunxi: Update H616 DRAM driver Jernej Skrabec
  2022-12-11 16:32 ` [PATCH 1/8] sunxi: Fix write to H616 DRAM CR register Jernej Skrabec
  2022-12-11 16:32 ` [PATCH 2/8] sunxi: cosmetic: Fix H616 DRAM driver code style Jernej Skrabec
@ 2022-12-11 16:32 ` Jernej Skrabec
  2023-01-04  0:36   ` Andre Przywara
  2022-12-11 16:32 ` [PATCH 4/8] sunxi: Convert H616 DRAM options to single setting Jernej Skrabec
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 29+ messages in thread
From: Jernej Skrabec @ 2022-12-11 16:32 UTC (permalink / raw)
  To: andre.przywara, jagan; +Cc: u-boot, Jernej Skrabec

While ODT values for same memory type are similar, they are not
necessary the same. Let's parameterize them and make parameter same as
in vendor DRAM settings. That way it will be easy to introduce new board
support.

Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 .../include/asm/arch-sunxi/dram_sun50i_h616.h |  3 +
 arch/arm/mach-sunxi/Kconfig                   | 15 +++++
 arch/arm/mach-sunxi/dram_sun50i_h616.c        | 59 ++++++++++++-------
 configs/orangepi_zero2_defconfig              |  3 +
 4 files changed, 58 insertions(+), 22 deletions(-)

diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
index 134679d55205..c9e1f84bfcdd 100644
--- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
+++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
@@ -144,6 +144,9 @@ struct dram_para {
 	u8 rows;
 	u8 ranks;
 	u8 bus_full_width;
+	u32 dx_odt;
+	u32 dx_dri;
+	u32 ca_dri;
 };
 
 
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index dbe6005daab1..cad53f19912c 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -83,6 +83,21 @@ config DRAM_SUN50I_H616_UNKNOWN_FEATURE
 	---help---
 	  Select this when DRAM on your H616 board needs this unknown
 	  feature.
+
+config DRAM_SUN50I_H616_DX_ODT
+	hex "H616 DRAM DX ODT parameter"
+	help
+	  DX ODT value from vendor DRAM settings.
+
+config DRAM_SUN50I_H616_DX_DRI
+	hex "H616 DRAM DX DRI parameter"
+	help
+	  DX DRI value from vendor DRAM settings.
+
+config DRAM_SUN50I_H616_CA_DRI
+	hex "H616 DRAM CA DRI parameter"
+	help
+	  CA DRI value from vendor DRAM settings.
 endif
 
 config SUN6I_PRCM
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
index 49983bf7a1b8..06a07dfbf9cc 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
@@ -234,37 +234,49 @@ static const u8 phy_init[] = {
 	0x09, 0x05, 0x18
 };
 
-static void mctl_phy_configure_odt(void)
+static void mctl_phy_configure_odt(struct dram_para *para)
 {
-	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x388);
-	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x38c);
+	unsigned int val;
 
-	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x3c8);
-	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x3cc);
+	val = para->dx_dri & 0x1f;
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x388);
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x38c);
 
-	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x408);
-	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x40c);
+	val = (para->dx_dri >> 8) & 0x1f;
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3c8);
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3cc);
 
-	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x448);
-	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x44c);
+	val = (para->dx_dri >> 16) & 0x1f;
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x408);
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x40c);
 
-	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x340);
-	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x344);
+	val = (para->dx_dri >> 24) & 0x1f;
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x448);
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x44c);
 
-	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x348);
-	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x34c);
+	val = para->ca_dri & 0x1f;
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x340);
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x344);
 
-	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x380);
-	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x384);
+	val = (para->ca_dri >> 8) & 0x1f;
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x348);
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x34c);
 
-	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x3c0);
-	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x3c4);
+	val = para->dx_odt & 0x1f;
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x380);
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x384);
 
-	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x400);
-	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x404);
+	val = (para->dx_odt >> 8) & 0x1f;
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3c0);
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3c4);
 
-	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x440);
-	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x444);
+	val = (para->dx_odt >> 16) & 0x1f;
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x400);
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x404);
+
+	val = (para->dx_odt >> 24) & 0x1f;
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x440);
+	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x444);
 
 	dmb();
 }
@@ -722,7 +734,7 @@ static bool mctl_phy_init(struct dram_para *para)
 	writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x45c);
 
 	if (IS_ENABLED(CONFIG_DRAM_ODT_EN))
-		mctl_phy_configure_odt();
+		mctl_phy_configure_odt(para);
 
 	clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 7, 0xa);
 
@@ -1007,6 +1019,9 @@ unsigned long sunxi_dram_init(void)
 	struct dram_para para = {
 		.clk = CONFIG_DRAM_CLK,
 		.type = SUNXI_DRAM_TYPE_DDR3,
+		.dx_odt = CONFIG_DRAM_SUN50I_H616_DX_ODT,
+		.dx_dri = CONFIG_DRAM_SUN50I_H616_DX_DRI,
+		.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
 	};
 	unsigned long size;
 
diff --git a/configs/orangepi_zero2_defconfig b/configs/orangepi_zero2_defconfig
index 877eccf31bd6..ca398faef1d3 100644
--- a/configs/orangepi_zero2_defconfig
+++ b/configs/orangepi_zero2_defconfig
@@ -6,6 +6,9 @@ CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING=y
 CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
 CONFIG_DRAM_SUN50I_H616_READ_TRAINING=y
 CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING=y
+CONFIG_DRAM_SUN50I_H616_DX_ODT=0x8080808
+CONFIG_DRAM_SUN50I_H616_DX_DRI=0xe0e0e0e
+CONFIG_DRAM_SUN50I_H616_CA_DRI=0xe0e
 CONFIG_MACH_SUN50I_H616=y
 CONFIG_MMC0_CD_PIN="PF6"
 CONFIG_R_I2C_ENABLE=y
-- 
2.38.1


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

* [PATCH 4/8] sunxi: Convert H616 DRAM options to single setting
  2022-12-11 16:32 [PATCH 0/8] sunxi: Update H616 DRAM driver Jernej Skrabec
                   ` (2 preceding siblings ...)
  2022-12-11 16:32 ` [PATCH 3/8] sunxi: parameterize H616 DRAM ODT values Jernej Skrabec
@ 2022-12-11 16:32 ` Jernej Skrabec
  2022-12-12 17:50   ` Andre Przywara
  2022-12-11 16:32 ` [PATCH 5/8] sunxi: Always configure ODT on H616 DRAM Jernej Skrabec
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 29+ messages in thread
From: Jernej Skrabec @ 2022-12-11 16:32 UTC (permalink / raw)
  To: andre.przywara, jagan; +Cc: u-boot, Jernej Skrabec

Vendor DRAM settings use TPR10 parameter to enable various features.
There are many mores features that just those that are currently
mentioned. Since new will be added later and most are not known, let's
reuse value from vendor DRAM driver as-is. This will also help adding
support for new boards.

Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 .../include/asm/arch-sunxi/dram_sun50i_h616.h |  10 +
 arch/arm/mach-sunxi/Kconfig                   |  38 +---
 arch/arm/mach-sunxi/dram_sun50i_h616.c        | 197 +++++++++---------
 configs/orangepi_zero2_defconfig              |   5 +-
 4 files changed, 117 insertions(+), 133 deletions(-)

diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
index c9e1f84bfcdd..b5140c79b70e 100644
--- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
+++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
@@ -137,6 +137,15 @@ check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240);
 #define MSTR_ACTIVE_RANKS(x)	(((x == 2) ? 3 : 1) << 24)
 #define MSTR_BURST_LENGTH(x)	(((x) >> 1) << 16)
 
+/* TODO: figure out what unknown features do */
+#define TPR10_UNKNOWN_FEAT0	BIT(16)
+#define TPR10_UNKNOWN_FEAT1	BIT(17)
+#define TPR10_UNKNOWN_FEAT2	BIT(18)
+#define TPR10_WRITE_LEVELING	BIT(20)
+#define TPR10_READ_CALIBRATION	BIT(21)
+#define TPR10_READ_TRAINING	BIT(22)
+#define TPR10_WRITE_TRAINING	BIT(23)
+
 struct dram_para {
 	u32 clk;
 	enum sunxi_dram_type type;
@@ -147,6 +156,7 @@ struct dram_para {
 	u32 dx_odt;
 	u32 dx_dri;
 	u32 ca_dri;
+	u32 tpr10;
 };
 
 
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index cad53f19912c..abcbd0fb9061 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -52,38 +52,6 @@ config DRAM_SUN50I_H616
 	  like H616.
 
 if DRAM_SUN50I_H616
-config DRAM_SUN50I_H616_WRITE_LEVELING
-	bool "H616 DRAM write leveling"
-	---help---
-	  Select this when DRAM on your H616 board needs write leveling.
-
-config DRAM_SUN50I_H616_READ_CALIBRATION
-	bool "H616 DRAM read calibration"
-	---help---
-	  Select this when DRAM on your H616 board needs read calibration.
-
-config DRAM_SUN50I_H616_READ_TRAINING
-	bool "H616 DRAM read training"
-	---help---
-	  Select this when DRAM on your H616 board needs read training.
-
-config DRAM_SUN50I_H616_WRITE_TRAINING
-	bool "H616 DRAM write training"
-	---help---
-	  Select this when DRAM on your H616 board needs write training.
-
-config DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION
-	bool "H616 DRAM bit delay compensation"
-	---help---
-	  Select this when DRAM on your H616 board needs bit delay
-	  compensation.
-
-config DRAM_SUN50I_H616_UNKNOWN_FEATURE
-	bool "H616 DRAM unknown feature"
-	---help---
-	  Select this when DRAM on your H616 board needs this unknown
-	  feature.
-
 config DRAM_SUN50I_H616_DX_ODT
 	hex "H616 DRAM DX ODT parameter"
 	help
@@ -98,6 +66,12 @@ config DRAM_SUN50I_H616_CA_DRI
 	hex "H616 DRAM CA DRI parameter"
 	help
 	  CA DRI value from vendor DRAM settings.
+
+config DRAM_SUN50I_H616_TPR10
+	hex "H616 DRAM TPR10 parameter"
+	help
+	  TPR10 value from vendor DRAM settings. It tells which features
+	  should be configured, like write leveling, read calibration, etc.
 endif
 
 config SUN6I_PRCM
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
index 06a07dfbf9cc..14a01a3c4e54 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
@@ -577,109 +577,112 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
 	u32 *ptr;
 	int i;
 
-	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
-	setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
-	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
+	if (para->tpr10 & TPR10_UNKNOWN_FEAT2) {
+		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
+		setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
+		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
 
-	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
-	for (i = 0; i < 9; i++) {
-		writel_relaxed(0x16, ptr);
-		writel_relaxed(0x16, ptr + 0x30);
-		ptr += 2;
-	}
-	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4d0);
-	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x590);
-	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
-	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
+		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
+		for (i = 0; i < 9; i++) {
+			writel_relaxed(0x16, ptr);
+			writel_relaxed(0x16, ptr + 0x30);
+			ptr += 2;
+		}
+		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4d0);
+		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x590);
+		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
+		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
 
-	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
-	for (i = 0; i < 9; i++) {
-		writel_relaxed(0x1a, ptr);
-		writel_relaxed(0x1a, ptr + 0x30);
-		ptr += 2;
-	}
-	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x524);
-	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e4);
-	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
-	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
+		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
+		for (i = 0; i < 9; i++) {
+			writel_relaxed(0x1a, ptr);
+			writel_relaxed(0x1a, ptr + 0x30);
+			ptr += 2;
+		}
+		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x524);
+		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e4);
+		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
+		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
 
-	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
-	for (i = 0; i < 9; i++) {
-		writel_relaxed(0x1a, ptr);
-		writel_relaxed(0x1a, ptr + 0x30);
-		ptr += 2;
-	}
-	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x650);
-	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x710);
-	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
-	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
+		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
+		for (i = 0; i < 9; i++) {
+			writel_relaxed(0x1a, ptr);
+			writel_relaxed(0x1a, ptr + 0x30);
+			ptr += 2;
+		}
+		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x650);
+		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x710);
+		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
+		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
 
-	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
-	for (i = 0; i < 9; i++) {
-		writel_relaxed(0x1a, ptr);
-		writel_relaxed(0x1a, ptr + 0x30);
-		ptr += 2;
-	}
-	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a4);
-	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x764);
-	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a0);
-	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x760);
+		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
+		for (i = 0; i < 9; i++) {
+			writel_relaxed(0x1a, ptr);
+			writel_relaxed(0x1a, ptr + 0x30);
+			ptr += 2;
+		}
+		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a4);
+		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x764);
+		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a0);
+		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x760);
 
-	dmb();
+		dmb();
 
-	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
+		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
+	}
 
-	/* second part */
-	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
-	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
+	if (para->tpr10 & TPR10_UNKNOWN_FEAT1) {
+		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
+		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
 
-	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
-	for (i = 0; i < 9; i++) {
-		writel_relaxed(0x10, ptr);
-		writel_relaxed(0x10, ptr + 0x30);
-		ptr += 2;
-	}
-	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x528);
-	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x5e8);
-	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
-	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
+		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
+		for (i = 0; i < 9; i++) {
+			writel_relaxed(0x10, ptr);
+			writel_relaxed(0x10, ptr + 0x30);
+			ptr += 2;
+		}
+		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x528);
+		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x5e8);
+		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
+		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
 
-	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
-	for (i = 0; i < 9; i++) {
-		writel_relaxed(0x12, ptr);
-		writel_relaxed(0x12, ptr + 0x30);
-		ptr += 2;
-	}
-	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x52c);
-	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5ec);
-	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
-	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
+		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
+		for (i = 0; i < 9; i++) {
+			writel_relaxed(0x12, ptr);
+			writel_relaxed(0x12, ptr + 0x30);
+			ptr += 2;
+		}
+		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x52c);
+		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5ec);
+		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
+		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
 
-	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
-	for (i = 0; i < 9; i++) {
-		writel_relaxed(0x12, ptr);
-		writel_relaxed(0x12, ptr + 0x30);
-		ptr += 2;
-	}
-	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x6a8);
-	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x768);
-	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
-	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
+		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
+		for (i = 0; i < 9; i++) {
+			writel_relaxed(0x12, ptr);
+			writel_relaxed(0x12, ptr + 0x30);
+			ptr += 2;
+		}
+		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x6a8);
+		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x768);
+		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
+		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
 
-	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
-	for (i = 0; i < 9; i++) {
-		writel_relaxed(0x14, ptr);
-		writel_relaxed(0x14, ptr + 0x30);
-		ptr += 2;
-	}
-	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x6ac);
-	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x76c);
-	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x69c);
-	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x75c);
+		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
+		for (i = 0; i < 9; i++) {
+			writel_relaxed(0x14, ptr);
+			writel_relaxed(0x14, ptr + 0x30);
+			ptr += 2;
+		}
+		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x6ac);
+		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x76c);
+		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x69c);
+		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x75c);
 
-	dmb();
+		dmb();
 
-	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
+		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
+	}
 
 	return true;
 }
@@ -718,7 +721,7 @@ static bool mctl_phy_init(struct dram_para *para)
 	for (i = 0; i < ARRAY_SIZE(phy_init); i++)
 		writel(phy_init[i], &ptr[i]);
 
-	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_UNKNOWN_FEATURE)) {
+	if (para->tpr10 & TPR10_UNKNOWN_FEAT0) {
 		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780);
 		for (i = 0; i < 32; i++)
 			writel(0x16, &ptr[i]);
@@ -800,7 +803,7 @@ static bool mctl_phy_init(struct dram_para *para)
 	clrbits_le32(&mctl_ctl->rfshctl3, 1);
 	writel(1, &mctl_ctl->swctl);
 
-	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING)) {
+	if (para->tpr10 & TPR10_WRITE_LEVELING) {
 		for (i = 0; i < 5; i++)
 			if (mctl_phy_write_leveling(para))
 				break;
@@ -810,7 +813,7 @@ static bool mctl_phy_init(struct dram_para *para)
 		}
 	}
 
-	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION)) {
+	if (para->tpr10 & TPR10_READ_CALIBRATION) {
 		for (i = 0; i < 5; i++)
 			if (mctl_phy_read_calibration(para))
 				break;
@@ -820,7 +823,7 @@ static bool mctl_phy_init(struct dram_para *para)
 		}
 	}
 
-	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_READ_TRAINING)) {
+	if (para->tpr10 & TPR10_READ_TRAINING) {
 		for (i = 0; i < 5; i++)
 			if (mctl_phy_read_training(para))
 				break;
@@ -830,7 +833,7 @@ static bool mctl_phy_init(struct dram_para *para)
 		}
 	}
 
-	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING)) {
+	if (para->tpr10 & TPR10_WRITE_TRAINING) {
 		for (i = 0; i < 5; i++)
 			if (mctl_phy_write_training(para))
 				break;
@@ -840,8 +843,7 @@ static bool mctl_phy_init(struct dram_para *para)
 		}
 	}
 
-	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION))
-		mctl_phy_bit_delay_compensation(para);
+	mctl_phy_bit_delay_compensation(para);
 
 	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 4);
 
@@ -1022,6 +1024,7 @@ unsigned long sunxi_dram_init(void)
 		.dx_odt = CONFIG_DRAM_SUN50I_H616_DX_ODT,
 		.dx_dri = CONFIG_DRAM_SUN50I_H616_DX_DRI,
 		.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
+		.tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
 	};
 	unsigned long size;
 
diff --git a/configs/orangepi_zero2_defconfig b/configs/orangepi_zero2_defconfig
index ca398faef1d3..f2024a2502c7 100644
--- a/configs/orangepi_zero2_defconfig
+++ b/configs/orangepi_zero2_defconfig
@@ -2,13 +2,10 @@ CONFIG_ARM=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-h616-orangepi-zero2"
 CONFIG_SPL=y
-CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING=y
-CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
-CONFIG_DRAM_SUN50I_H616_READ_TRAINING=y
-CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING=y
 CONFIG_DRAM_SUN50I_H616_DX_ODT=0x8080808
 CONFIG_DRAM_SUN50I_H616_DX_DRI=0xe0e0e0e
 CONFIG_DRAM_SUN50I_H616_CA_DRI=0xe0e
+CONFIG_DRAM_SUN50I_H616_TPR10=0xf83438
 CONFIG_MACH_SUN50I_H616=y
 CONFIG_MMC0_CD_PIN="PF6"
 CONFIG_R_I2C_ENABLE=y
-- 
2.38.1


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

* [PATCH 5/8] sunxi: Always configure ODT on H616 DRAM
  2022-12-11 16:32 [PATCH 0/8] sunxi: Update H616 DRAM driver Jernej Skrabec
                   ` (3 preceding siblings ...)
  2022-12-11 16:32 ` [PATCH 4/8] sunxi: Convert H616 DRAM options to single setting Jernej Skrabec
@ 2022-12-11 16:32 ` Jernej Skrabec
  2023-01-04  0:37   ` Andre Przywara
  2022-12-11 16:32 ` [PATCH 6/8] sunxi: Make bit delay function in H616 DRAM code void Jernej Skrabec
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 29+ messages in thread
From: Jernej Skrabec @ 2022-12-11 16:32 UTC (permalink / raw)
  To: andre.przywara, jagan; +Cc: u-boot, Jernej Skrabec

Vendor H616 DRAM code always configure part which we call ODT
configuration. Let's reflect that here too.

Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 arch/arm/mach-sunxi/Kconfig            | 2 +-
 arch/arm/mach-sunxi/dram_sun50i_h616.c | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index abcbd0fb9061..778304b77e26 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -488,12 +488,12 @@ config DRAM_ZQ
 
 config DRAM_ODT_EN
 	bool "sunxi dram odt enable"
+	depends on !MACH_SUN50I_H616
 	default y if MACH_SUN8I_A23
 	default y if MACH_SUNXI_H3_H5
 	default y if MACH_SUN8I_R40
 	default y if MACH_SUN50I
 	default y if MACH_SUN50I_H6
-	default y if MACH_SUN50I_H616
 	---help---
 	Select this to enable dram odt (on die termination).
 
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
index 14a01a3c4e54..bf5b4ddfb5c2 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
@@ -736,8 +736,7 @@ static bool mctl_phy_init(struct dram_para *para)
 	writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x3dc);
 	writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x45c);
 
-	if (IS_ENABLED(CONFIG_DRAM_ODT_EN))
-		mctl_phy_configure_odt(para);
+	mctl_phy_configure_odt(para);
 
 	clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 7, 0xa);
 
-- 
2.38.1


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

* [PATCH 6/8] sunxi: Make bit delay function in H616 DRAM code void
  2022-12-11 16:32 [PATCH 0/8] sunxi: Update H616 DRAM driver Jernej Skrabec
                   ` (4 preceding siblings ...)
  2022-12-11 16:32 ` [PATCH 5/8] sunxi: Always configure ODT on H616 DRAM Jernej Skrabec
@ 2022-12-11 16:32 ` Jernej Skrabec
  2023-01-04  0:37   ` Andre Przywara
  2022-12-11 16:32 ` [PATCH 7/8] sunxi: Parameterize bit delay code in H616 DRAM driver Jernej Skrabec
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 29+ messages in thread
From: Jernej Skrabec @ 2022-12-11 16:32 UTC (permalink / raw)
  To: andre.przywara, jagan; +Cc: u-boot, Jernej Skrabec

Mentioned function result is always true and result isn't checked
anyway. Let's make it void.

Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 arch/arm/mach-sunxi/dram_sun50i_h616.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
index bf5b4ddfb5c2..3b2ba168498c 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
@@ -572,7 +572,7 @@ static bool mctl_phy_write_training(struct dram_para *para)
 	return result;
 }
 
-static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
+static void mctl_phy_bit_delay_compensation(struct dram_para *para)
 {
 	u32 *ptr;
 	int i;
@@ -683,8 +683,6 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
 
 		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
 	}
-
-	return true;
 }
 
 static bool mctl_phy_init(struct dram_para *para)
-- 
2.38.1


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

* [PATCH 7/8] sunxi: Parameterize bit delay code in H616 DRAM driver
  2022-12-11 16:32 [PATCH 0/8] sunxi: Update H616 DRAM driver Jernej Skrabec
                   ` (5 preceding siblings ...)
  2022-12-11 16:32 ` [PATCH 6/8] sunxi: Make bit delay function in H616 DRAM code void Jernej Skrabec
@ 2022-12-11 16:32 ` Jernej Skrabec
  2023-01-04  0:37   ` Andre Przywara
  2022-12-11 16:32 ` [PATCH 8/8] sunxi: Parameterize H616 DRAM code some more Jernej Skrabec
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 29+ messages in thread
From: Jernej Skrabec @ 2022-12-11 16:32 UTC (permalink / raw)
  To: andre.przywara, jagan; +Cc: u-boot, Jernej Skrabec

These values are highly board specific and thus make sense to add
parameter for them. To ease adding support for new boards, let's make
them same as in vendor DRAM settings.

Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 .../include/asm/arch-sunxi/dram_sun50i_h616.h |   4 +
 arch/arm/mach-sunxi/Kconfig                   |  18 ++
 arch/arm/mach-sunxi/dram_sun50i_h616.c        | 189 +++++++++++++-----
 3 files changed, 162 insertions(+), 49 deletions(-)

diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
index b5140c79b70e..c7890c83391f 100644
--- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
+++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
@@ -145,6 +145,7 @@ check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240);
 #define TPR10_READ_CALIBRATION	BIT(21)
 #define TPR10_READ_TRAINING	BIT(22)
 #define TPR10_WRITE_TRAINING	BIT(23)
+#define TPR10_UNKNOWN_FEAT3	BIT(30)
 
 struct dram_para {
 	u32 clk;
@@ -156,7 +157,10 @@ struct dram_para {
 	u32 dx_odt;
 	u32 dx_dri;
 	u32 ca_dri;
+	u32 odt_en;
 	u32 tpr10;
+	u32 tpr11;
+	u32 tpr12;
 };
 
 
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 778304b77e26..b050f0a56971 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -67,11 +67,29 @@ config DRAM_SUN50I_H616_CA_DRI
 	help
 	  CA DRI value from vendor DRAM settings.
 
+config DRAM_SUN50I_H616_ODT_EN
+	hex "H616 DRAM ODT EN parameter"
+	default 0x1
+	help
+	  ODT EN value from vendor DRAM settings.
+
 config DRAM_SUN50I_H616_TPR10
 	hex "H616 DRAM TPR10 parameter"
 	help
 	  TPR10 value from vendor DRAM settings. It tells which features
 	  should be configured, like write leveling, read calibration, etc.
+
+config DRAM_SUN50I_H616_TPR11
+	hex "H616 DRAM TPR11 parameter"
+	default 0x0
+	help
+	  TPR11 value from vendor DRAM settings.
+
+config DRAM_SUN50I_H616_TPR12
+	hex "H616 DRAM TPR12 parameter"
+	default 0x0
+	help
+	  TPR12 value from vendor DRAM settings.
 endif
 
 config SUN6I_PRCM
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
index 3b2ba168498c..df06cea42464 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
@@ -574,7 +574,7 @@ static bool mctl_phy_write_training(struct dram_para *para)
 
 static void mctl_phy_bit_delay_compensation(struct dram_para *para)
 {
-	u32 *ptr;
+	u32 *ptr, val;
 	int i;
 
 	if (para->tpr10 & TPR10_UNKNOWN_FEAT2) {
@@ -582,49 +582,93 @@ static void mctl_phy_bit_delay_compensation(struct dram_para *para)
 		setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
 		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
 
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = para->tpr11 & 0x3f;
+		else
+			val = (para->tpr11 & 0xf) << 1;
+
 		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
 		for (i = 0; i < 9; i++) {
-			writel_relaxed(0x16, ptr);
-			writel_relaxed(0x16, ptr + 0x30);
+			writel_relaxed(val, ptr);
+			writel_relaxed(val, ptr + 0x30);
 			ptr += 2;
 		}
-		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4d0);
-		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x590);
-		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
-		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
+
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = (para->odt_en >> 15) & 0x1e;
+		else
+			val = (para->tpr11 >> 15) & 0x1e;
+
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x4d0);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x590);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x4cc);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x58c);
+
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = (para->tpr11 >> 8) & 0x3f;
+		else
+			val = (para->tpr11 >> 3) & 0x1e;
 
 		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
 		for (i = 0; i < 9; i++) {
-			writel_relaxed(0x1a, ptr);
-			writel_relaxed(0x1a, ptr + 0x30);
+			writel_relaxed(val, ptr);
+			writel_relaxed(val, ptr + 0x30);
 			ptr += 2;
 		}
-		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x524);
-		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e4);
-		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
-		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
+
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = (para->odt_en >> 19) & 0x1e;
+		else
+			val = (para->tpr11 >> 19) & 0x1e;
+
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x524);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5e4);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x520);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5e0);
+
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = (para->tpr11 >> 16) & 0x3f;
+		else
+			val = (para->tpr11 >> 7) & 0x1e;
 
 		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
 		for (i = 0; i < 9; i++) {
-			writel_relaxed(0x1a, ptr);
-			writel_relaxed(0x1a, ptr + 0x30);
+			writel_relaxed(val, ptr);
+			writel_relaxed(val, ptr + 0x30);
 			ptr += 2;
 		}
-		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x650);
-		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x710);
-		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
-		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
+
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = (para->odt_en >> 23) & 0x1e;
+		else
+			val = (para->tpr11 >> 23) & 0x1e;
+
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x650);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x710);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x64c);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x70c);
+
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = (para->tpr11 >> 24) & 0x3f;
+		else
+			val = (para->tpr11 >> 11) & 0x1e;
 
 		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
 		for (i = 0; i < 9; i++) {
-			writel_relaxed(0x1a, ptr);
-			writel_relaxed(0x1a, ptr + 0x30);
+			writel_relaxed(val, ptr);
+			writel_relaxed(val, ptr + 0x30);
 			ptr += 2;
 		}
-		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a4);
-		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x764);
-		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a0);
-		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x760);
+
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = (para->odt_en >> 27) & 0x1e;
+		else
+			val = (para->tpr11 >> 27) & 0x1e;
+
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6a4);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x764);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6a0);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x760);
 
 		dmb();
 
@@ -635,49 +679,93 @@ static void mctl_phy_bit_delay_compensation(struct dram_para *para)
 		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
 		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
 
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = para->tpr12 & 0x3f;
+		else
+			val = (para->tpr12 & 0xf) << 1;
+
 		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
 		for (i = 0; i < 9; i++) {
-			writel_relaxed(0x10, ptr);
-			writel_relaxed(0x10, ptr + 0x30);
+			writel_relaxed(val, ptr);
+			writel_relaxed(val, ptr + 0x30);
 			ptr += 2;
 		}
-		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x528);
-		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x5e8);
-		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
-		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
+
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = (para->odt_en << 1) & 0x1e;
+		else
+			val = (para->tpr12 >> 15) & 0x1e;
+
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x528);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5e8);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x4c8);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x588);
+
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = (para->tpr12 >> 8) & 0x3f;
+		else
+			val = (para->tpr12 >> 3) & 0x1e;
 
 		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
 		for (i = 0; i < 9; i++) {
-			writel_relaxed(0x12, ptr);
-			writel_relaxed(0x12, ptr + 0x30);
+			writel_relaxed(val, ptr);
+			writel_relaxed(val, ptr + 0x30);
 			ptr += 2;
 		}
-		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x52c);
-		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5ec);
-		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
-		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
+
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = (para->odt_en >> 3) & 0x1e;
+		else
+			val = (para->tpr12 >> 19) & 0x1e;
+
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x52c);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5ec);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x51c);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5dc);
+
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = (para->tpr12 >> 16) & 0x3f;
+		else
+			val = (para->tpr12 >> 7) & 0x1e;
 
 		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
 		for (i = 0; i < 9; i++) {
-			writel_relaxed(0x12, ptr);
-			writel_relaxed(0x12, ptr + 0x30);
+			writel_relaxed(val, ptr);
+			writel_relaxed(val, ptr + 0x30);
 			ptr += 2;
 		}
-		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x6a8);
-		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x768);
-		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
-		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
+
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = (para->odt_en >> 7) & 0x1e;
+		else
+			val = (para->tpr12 >> 23) & 0x1e;
+
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6a8);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x768);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x648);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x708);
+
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = (para->tpr12 >> 24) & 0x3f;
+		else
+			val = (para->tpr12 >> 11) & 0x1e;
 
 		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
 		for (i = 0; i < 9; i++) {
-			writel_relaxed(0x14, ptr);
-			writel_relaxed(0x14, ptr + 0x30);
+			writel_relaxed(val, ptr);
+			writel_relaxed(val, ptr + 0x30);
 			ptr += 2;
 		}
-		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x6ac);
-		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x76c);
-		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x69c);
-		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x75c);
+
+		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
+			val = (para->odt_en >> 11) & 0x1e;
+		else
+			val = (para->tpr12 >> 27) & 0x1e;
+
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6ac);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x76c);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x69c);
+		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x75c);
 
 		dmb();
 
@@ -1021,7 +1109,10 @@ unsigned long sunxi_dram_init(void)
 		.dx_odt = CONFIG_DRAM_SUN50I_H616_DX_ODT,
 		.dx_dri = CONFIG_DRAM_SUN50I_H616_DX_DRI,
 		.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
+		.odt_en = CONFIG_DRAM_SUN50I_H616_ODT_EN,
 		.tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
+		.tpr11 = CONFIG_DRAM_SUN50I_H616_TPR11,
+		.tpr12 = CONFIG_DRAM_SUN50I_H616_TPR12,
 	};
 	unsigned long size;
 
-- 
2.38.1


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

* [PATCH 8/8] sunxi: Parameterize H616 DRAM code some more
  2022-12-11 16:32 [PATCH 0/8] sunxi: Update H616 DRAM driver Jernej Skrabec
                   ` (6 preceding siblings ...)
  2022-12-11 16:32 ` [PATCH 7/8] sunxi: Parameterize bit delay code in H616 DRAM driver Jernej Skrabec
@ 2022-12-11 16:32 ` Jernej Skrabec
  2022-12-11 18:33   ` Jernej Škrabec
  2023-01-04  0:38   ` Andre Przywara
  2022-12-12  1:04 ` [PATCH 0/8] sunxi: Update H616 DRAM driver Andre Przywara
  2023-01-04  0:47 ` Andre Przywara
  9 siblings, 2 replies; 29+ messages in thread
From: Jernej Skrabec @ 2022-12-11 16:32 UTC (permalink / raw)
  To: andre.przywara, jagan; +Cc: u-boot, Jernej Skrabec

Part of the code, previously known as "unknown feature" also doesn't
have constant values. They are derived from TPR0 parameter in vendor
DRAM code. Introduce that parameter here too, to ease adding new boards.

Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 .../include/asm/arch-sunxi/dram_sun50i_h616.h |  1 +
 arch/arm/mach-sunxi/Kconfig                   |  6 ++++
 arch/arm/mach-sunxi/dram_sun50i_h616.c        | 35 +++++++++++++++----
 3 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
index c7890c83391f..ff736bd88d10 100644
--- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
+++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
@@ -158,6 +158,7 @@ struct dram_para {
 	u32 dx_dri;
 	u32 ca_dri;
 	u32 odt_en;
+	u32 tpr0;
 	u32 tpr10;
 	u32 tpr11;
 	u32 tpr12;
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index b050f0a56971..7858a7045f7e 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -73,6 +73,12 @@ config DRAM_SUN50I_H616_ODT_EN
 	help
 	  ODT EN value from vendor DRAM settings.
 
+config DRAM_SUN50I_H616_TPR0
+	hex "H616 DRAM TPR0 parameter"
+	default 0x0
+	help
+	  TPR0 value from vendor DRAM settings.
+
 config DRAM_SUN50I_H616_TPR10
 	hex "H616 DRAM TPR10 parameter"
 	help
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
index df06cea42464..6d8f8d371bfe 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
@@ -808,15 +808,35 @@ static bool mctl_phy_init(struct dram_para *para)
 		writel(phy_init[i], &ptr[i]);
 
 	if (para->tpr10 & TPR10_UNKNOWN_FEAT0) {
+		if (para->tpr0 & BIT(30))
+			val = (para->tpr0 >> 7) & 0x3e;
+		else
+			val = (para->tpr10 >> 3) & 0x1e;
+
 		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780);
 		for (i = 0; i < 32; i++)
-			writel(0x16, &ptr[i]);
-		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x78c);
-		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7a4);
-		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7b8);
-		writel(0x8, SUNXI_DRAM_PHY0_BASE + 0x7d4);
-		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7dc);
-		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7e0);
+			writel(val, &ptr[i]);
+
+		val = (para->tpr10 << 1) & 0x1e;
+		writel(val, SUNXI_DRAM_PHY0_BASE + 0x7dc);
+		writel(val, SUNXI_DRAM_PHY0_BASE + 0x7e0);
+
+		/* following configuration is DDR3 specific */
+		val = (para->tpr10 >> 7) & 0x1e;
+		writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d4);
+		/*
+		 * TODO: Offsets 0x79c, 0x794 and 0x7e4 may need
+		 * to be set here. However, this doesn't seem to
+		 * be needed by any board seen in the wild for now.
+		 * It's not implemented because it would unnecessarily
+		 * introduce PARA2 and TPR2 options.
+		 */
+		if (para->tpr0 & BIT(31)) {
+			val = (para->tpr0 << 1) & 0x3e;
+			writel(val, SUNXI_DRAM_PHY0_BASE + 0x78c);
+			writel(val, SUNXI_DRAM_PHY0_BASE + 0x7a4);
+			writel(val, SUNXI_DRAM_PHY0_BASE + 0x7b8);
+		}
 	}
 
 	writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x3dc);
@@ -1110,6 +1130,7 @@ unsigned long sunxi_dram_init(void)
 		.dx_dri = CONFIG_DRAM_SUN50I_H616_DX_DRI,
 		.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
 		.odt_en = CONFIG_DRAM_SUN50I_H616_ODT_EN,
+		.tpr0 = CONFIG_DRAM_SUN50I_H616_TPR0,
 		.tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
 		.tpr11 = CONFIG_DRAM_SUN50I_H616_TPR11,
 		.tpr12 = CONFIG_DRAM_SUN50I_H616_TPR12,
-- 
2.38.1


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

* Re: [PATCH 8/8] sunxi: Parameterize H616 DRAM code some more
  2022-12-11 16:32 ` [PATCH 8/8] sunxi: Parameterize H616 DRAM code some more Jernej Skrabec
@ 2022-12-11 18:33   ` Jernej Škrabec
  2023-01-04  0:38   ` Andre Przywara
  1 sibling, 0 replies; 29+ messages in thread
From: Jernej Škrabec @ 2022-12-11 18:33 UTC (permalink / raw)
  To: andre.przywara, jagan; +Cc: u-boot

Dne nedelja, 11. december 2022 ob 17:32:13 CET je Jernej Skrabec napisal(a):
> Part of the code, previously known as "unknown feature" also doesn't
> have constant values. They are derived from TPR0 parameter in vendor
> DRAM code. Introduce that parameter here too, to ease adding new boards.
> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
> ---
>  .../include/asm/arch-sunxi/dram_sun50i_h616.h |  1 +
>  arch/arm/mach-sunxi/Kconfig                   |  6 ++++
>  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 35 +++++++++++++++----
>  3 files changed, 35 insertions(+), 7 deletions(-)

<snip>

> diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> b/arch/arm/mach-sunxi/dram_sun50i_h616.c index df06cea42464..6d8f8d371bfe
> 100644
> --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> @@ -808,15 +808,35 @@ static bool mctl_phy_init(struct dram_para *para)
>  		writel(phy_init[i], &ptr[i]);
> 
>  	if (para->tpr10 & TPR10_UNKNOWN_FEAT0) {
> +		if (para->tpr0 & BIT(30))
> +			val = (para->tpr0 >> 7) & 0x3e;
> +		else
> +			val = (para->tpr10 >> 3) & 0x1e;
> +
>  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780);
>  		for (i = 0; i < 32; i++)
> -			writel(0x16, &ptr[i]);
> -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x78c);
> -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7a4);
> -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7b8);
> -		writel(0x8, SUNXI_DRAM_PHY0_BASE + 0x7d4);
> -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7dc);
> -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7e0);
> +			writel(val, &ptr[i]);
> +
> +		val = (para->tpr10 << 1) & 0x1e;
> +		writel(val, SUNXI_DRAM_PHY0_BASE + 0x7dc);
> +		writel(val, SUNXI_DRAM_PHY0_BASE + 0x7e0);
> +
> +		/* following configuration is DDR3 specific */
> +		val = (para->tpr10 >> 7) & 0x1e;
> +		writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d4);
> +		/*
> +		 * TODO: Offsets 0x79c, 0x794 and 0x7e4 may need
> +		 * to be set here. However, this doesn't seem to
> +		 * be needed by any board seen in the wild for now.
> +		 * It's not implemented because it would unnecessarily
> +		 * introduce PARA2 and TPR2 options.
> +		 */

I just noticed that PARA2 check actually checks rank. I think it's important 
to implement it (register 0x79c) and uses only TPR10 value, which is already 
present.

Best regards,
Jernej

> +		if (para->tpr0 & BIT(31)) {
> +			val = (para->tpr0 << 1) & 0x3e;
> +			writel(val, SUNXI_DRAM_PHY0_BASE + 0x78c);
> +			writel(val, SUNXI_DRAM_PHY0_BASE + 0x7a4);
> +			writel(val, SUNXI_DRAM_PHY0_BASE + 0x7b8);
> +		}
>  	}
> 
>  	writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x3dc);




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

* Re: [PATCH 0/8] sunxi: Update H616 DRAM driver
  2022-12-11 16:32 [PATCH 0/8] sunxi: Update H616 DRAM driver Jernej Skrabec
                   ` (7 preceding siblings ...)
  2022-12-11 16:32 ` [PATCH 8/8] sunxi: Parameterize H616 DRAM code some more Jernej Skrabec
@ 2022-12-12  1:04 ` Andre Przywara
  2022-12-12 16:14   ` Jernej Škrabec
  2023-01-04  0:47 ` Andre Przywara
  9 siblings, 1 reply; 29+ messages in thread
From: Andre Przywara @ 2022-12-12  1:04 UTC (permalink / raw)
  To: Jernej Skrabec; +Cc: jagan, u-boot, linux-sunxi

On Sun, 11 Dec 2022 17:32:05 +0100
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:

Hi Jernej,

many thanks for putting this together!
I will have a more elaborate look at each patch later.

> Current H616 DRAM driver is completely customized to Orange Pi Zero2
> board, which is currently the only H616 board supported by U-Boot.

Not anymore, I merged the X96 Mate support lately, after the DT got
merged into the Linux tree.

Those are the values for the box I came up with:
CONFIG_DRAM_SUN50I_H616_DX_ODT=0x03030303
CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e
CONFIG_DRAM_SUN50I_H616_CA_DRI=0x1c12
CONFIG_DRAM_SUN50I_H616_TPR0=0xc0000c05
CONFIG_DRAM_SUN50I_H616_TPR10=0x2f0007
CONFIG_DRAM_SUN50I_H616_TPR11=0xffffdddd
CONFIG_DRAM_SUN50I_H616_TPR12=0xfedf7557

based on this boot0 found in some firmware update image:
00045400  be 02 00 ea 65 47 4f 4e  2e 42 54 30 cc ba f3 80  |....eGON.BT0....|
00045410  00 c0 00 00 30 00 00 00  00 00 00 00 00 00 02 00  |....0...........|
00045420  00 00 02 00 00 00 00 00  00 00 00 00 34 2e 30 00  |............4.0.|
00045430  00 00 00 00 03 00 00 00  88 02 00 00 03 00 00 00  |................|
00045440  03 03 03 03 0e 0e 0e 0e  12 1c 00 00 01 00 00 00  |................|
00045450  fb 30 00 00 00 00 00 00  40 08 00 00 04 00 00 00  |.0......@.......|
00045460  08 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00045470  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00045480  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00045490  05 0c 00 c0 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000454a0  80 80 80 33 07 00 2f 00  dd dd ff ff 57 75 df fe  |...3../.....Wu..|
000454b0  40 00 00 00 00 00 00 00  00 00 00 00 08 00 02 01  |@...............|

I would be grateful if you could verify this.

I built it, and it reported the 4GB correctly, also managed to boot into
Linux just fine. No extensive testing, nor didn't I compare register
dumps or disassembly (yet).

Cheers,
Andre

P.S. Any plans on upstreaming support for your T95 <whatever> H616 TV
box? That would probably help the case here.


> Needless to say, this is not ideal for adding new boards. With changes
> in this series, all DDR3 boards are supported and all that is needed is
> just vendor DRAM values extracted from Android image. New DRAM types
> should also be easier to support, since a lot of constants used before
> are not really DRAM type dependent.
> 
> Changes were verified by decompiling driver and generated values were
> compared to previous, hard coded ones. This was done without dram_para
> structures, so compiler was able to heavily optimize code and produce
> constants.
> 
> Please take a look.
> 
> Best regards,
> Jernej
> 
> Jernej Skrabec (8):
>   sunxi: Fix write to H616 DRAM CR register
>   sunxi: cosmetic: Fix H616 DRAM driver code style
>   sunxi: parameterize H616 DRAM ODT values
>   sunxi: Convert H616 DRAM options to single setting
>   sunxi: Always configure ODT on H616 DRAM
>   sunxi: Make bit delay function in H616 DRAM code void
>   sunxi: Parameterize bit delay code in H616 DRAM driver
>   sunxi: Parameterize H616 DRAM code some more
> 
>  .../include/asm/arch-sunxi/dram_sun50i_h616.h |  18 +
>  arch/arm/mach-sunxi/Kconfig                   |  67 +--
>  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 445 +++++++++++-------
>  configs/orangepi_zero2_defconfig              |   8 +-
>  4 files changed, 348 insertions(+), 190 deletions(-)
> 


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

* Re: [PATCH 0/8] sunxi: Update H616 DRAM driver
  2022-12-12  1:04 ` [PATCH 0/8] sunxi: Update H616 DRAM driver Andre Przywara
@ 2022-12-12 16:14   ` Jernej Škrabec
  0 siblings, 0 replies; 29+ messages in thread
From: Jernej Škrabec @ 2022-12-12 16:14 UTC (permalink / raw)
  To: Andre Przywara; +Cc: jagan, u-boot, linux-sunxi

Hi Andre,

Dne ponedeljek, 12. december 2022 ob 02:04:51 CET je Andre Przywara 
napisal(a):
> On Sun, 11 Dec 2022 17:32:05 +0100
> Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
> 
> Hi Jernej,
> 
> many thanks for putting this together!
> I will have a more elaborate look at each patch later.
> 
> > Current H616 DRAM driver is completely customized to Orange Pi Zero2
> > board, which is currently the only H616 board supported by U-Boot.
> 
> Not anymore, I merged the X96 Mate support lately, after the DT got
> merged into the Linux tree.

Right. First part of sentence is still true, although I later remembered that 
some values are based on T95 values, those that are not used by Orange Pi 
Zero2.

> 
> Those are the values for the box I came up with:
> CONFIG_DRAM_SUN50I_H616_DX_ODT=0x03030303
> CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e
> CONFIG_DRAM_SUN50I_H616_CA_DRI=0x1c12
> CONFIG_DRAM_SUN50I_H616_TPR0=0xc0000c05
> CONFIG_DRAM_SUN50I_H616_TPR10=0x2f0007
> CONFIG_DRAM_SUN50I_H616_TPR11=0xffffdddd
> CONFIG_DRAM_SUN50I_H616_TPR12=0xfedf7557
> 
> based on this boot0 found in some firmware update image:
> 00045400  be 02 00 ea 65 47 4f 4e  2e 42 54 30 cc ba f3 80 
> |....eGON.BT0....| 00045410  00 c0 00 00 30 00 00 00  00 00 00 00 00 00 02
> 00  |....0...........| 00045420  00 00 02 00 00 00 00 00  00 00 00 00 34 2e
> 30 00  |............4.0.| 00045430  00 00 00 00 03 00 00 00  88 02 00 00 03
> 00 00 00  |................| 00045440  03 03 03 03 0e 0e 0e 0e  12 1c 00 00
> 01 00 00 00  |................| 00045450  fb 30 00 00 00 00 00 00  40 08 00
> 00 04 00 00 00  |.0......@.......| 00045460  08 00 00 00 00 00 00 00  00 00
> 00 00 00 00 00 00  |................| 00045470  00 00 00 00 00 00 00 00  00
> 00 00 00 00 00 00 00  |................| 00045480  00 00 00 00 00 00 00 00 
> 00 00 00 00 00 00 00 00  |................| 00045490  05 0c 00 c0 00 00 00
> 00  00 00 00 00 00 00 00 00  |................| 000454a0  80 80 80 33 07 00
> 2f 00  dd dd ff ff 57 75 df fe  |...3../.....Wu..| 000454b0  40 00 00 00 00
> 00 00 00  00 00 00 00 08 00 02 01  |@...............|
> 
> I would be grateful if you could verify this.

Looks correct. I'll use them in my v2 patches.

> 
> I built it, and it reported the 4GB correctly, also managed to boot into
> Linux just fine. No extensive testing, nor didn't I compare register
> dumps or disassembly (yet).
> 
> Cheers,
> Andre
> 
> P.S. Any plans on upstreaming support for your T95 <whatever> H616 TV
> box? That would probably help the case here.

Not really, X96 Mate is basically the same as T95, except DRAM configuration. 
As I said, I verified that these patches provide same register values as 
before. This includes those which were modeled after T95 DRAM values.

Best regards,
Jernej

> 
> > Needless to say, this is not ideal for adding new boards. With changes
> > in this series, all DDR3 boards are supported and all that is needed is
> > just vendor DRAM values extracted from Android image. New DRAM types
> > should also be easier to support, since a lot of constants used before
> > are not really DRAM type dependent.
> > 
> > Changes were verified by decompiling driver and generated values were
> > compared to previous, hard coded ones. This was done without dram_para
> > structures, so compiler was able to heavily optimize code and produce
> > constants.
> > 
> > Please take a look.
> > 
> > Best regards,
> > Jernej
> > 
> > Jernej Skrabec (8):
> >   sunxi: Fix write to H616 DRAM CR register
> >   sunxi: cosmetic: Fix H616 DRAM driver code style
> >   sunxi: parameterize H616 DRAM ODT values
> >   sunxi: Convert H616 DRAM options to single setting
> >   sunxi: Always configure ODT on H616 DRAM
> >   sunxi: Make bit delay function in H616 DRAM code void
> >   sunxi: Parameterize bit delay code in H616 DRAM driver
> >   sunxi: Parameterize H616 DRAM code some more
> >  
> >  .../include/asm/arch-sunxi/dram_sun50i_h616.h |  18 +
> >  arch/arm/mach-sunxi/Kconfig                   |  67 +--
> >  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 445 +++++++++++-------
> >  configs/orangepi_zero2_defconfig              |   8 +-
> >  4 files changed, 348 insertions(+), 190 deletions(-)





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

* Re: [PATCH 4/8] sunxi: Convert H616 DRAM options to single setting
  2022-12-11 16:32 ` [PATCH 4/8] sunxi: Convert H616 DRAM options to single setting Jernej Skrabec
@ 2022-12-12 17:50   ` Andre Przywara
  2022-12-13 16:23     ` Jernej Škrabec
  0 siblings, 1 reply; 29+ messages in thread
From: Andre Przywara @ 2022-12-12 17:50 UTC (permalink / raw)
  To: Jernej Skrabec; +Cc: jagan, u-boot

On Sun, 11 Dec 2022 17:32:09 +0100
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:

Hi,

> Vendor DRAM settings use TPR10 parameter to enable various features.
> There are many mores features that just those that are currently
> mentioned. Since new will be added later and most are not known, let's
> reuse value from vendor DRAM driver as-is. This will also help adding
> support for new boards.

Looks good. I checked that the actual code in
mctl_phy_bit_delay_compensation() just gets indented (no real changes), and
is now guarded by the new checks.
The values in the _defconfig still result in the same decisions, though
many are blocked anyway by no one actually calling that bit_delay function
at all. (I wonder what happens when we enable it?)
One small thing below.

> Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
> ---
>  .../include/asm/arch-sunxi/dram_sun50i_h616.h |  10 +
>  arch/arm/mach-sunxi/Kconfig                   |  38 +---
>  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 197 +++++++++---------
>  configs/orangepi_zero2_defconfig              |   5 +-
>  4 files changed, 117 insertions(+), 133 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> index c9e1f84bfcdd..b5140c79b70e 100644
> --- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> @@ -137,6 +137,15 @@ check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240);
>  #define MSTR_ACTIVE_RANKS(x)	(((x == 2) ? 3 : 1) << 24)
>  #define MSTR_BURST_LENGTH(x)	(((x) >> 1) << 16)
>  
> +/* TODO: figure out what unknown features do */
> +#define TPR10_UNKNOWN_FEAT0	BIT(16)
> +#define TPR10_UNKNOWN_FEAT1	BIT(17)
> +#define TPR10_UNKNOWN_FEAT2	BIT(18)

Could you just put the bit number in the macro? Like TPR10_BIT16? That
both avoids inventing meaningless names, and helps readers to correlate
code more easily. Or skip the symbol altogether for those and use just
"BIT(16)" in the code.

Cheers,
Andre

> +#define TPR10_WRITE_LEVELING	BIT(20)
> +#define TPR10_READ_CALIBRATION	BIT(21)
> +#define TPR10_READ_TRAINING	BIT(22)
> +#define TPR10_WRITE_TRAINING	BIT(23)
> +
>  struct dram_para {
>  	u32 clk;
>  	enum sunxi_dram_type type;
> @@ -147,6 +156,7 @@ struct dram_para {
>  	u32 dx_odt;
>  	u32 dx_dri;
>  	u32 ca_dri;
> +	u32 tpr10;
>  };
>  
>  
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index cad53f19912c..abcbd0fb9061 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -52,38 +52,6 @@ config DRAM_SUN50I_H616
>  	  like H616.
>  
>  if DRAM_SUN50I_H616
> -config DRAM_SUN50I_H616_WRITE_LEVELING
> -	bool "H616 DRAM write leveling"
> -	---help---
> -	  Select this when DRAM on your H616 board needs write leveling.
> -
> -config DRAM_SUN50I_H616_READ_CALIBRATION
> -	bool "H616 DRAM read calibration"
> -	---help---
> -	  Select this when DRAM on your H616 board needs read calibration.
> -
> -config DRAM_SUN50I_H616_READ_TRAINING
> -	bool "H616 DRAM read training"
> -	---help---
> -	  Select this when DRAM on your H616 board needs read training.
> -
> -config DRAM_SUN50I_H616_WRITE_TRAINING
> -	bool "H616 DRAM write training"
> -	---help---
> -	  Select this when DRAM on your H616 board needs write training.
> -
> -config DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION
> -	bool "H616 DRAM bit delay compensation"
> -	---help---
> -	  Select this when DRAM on your H616 board needs bit delay
> -	  compensation.
> -
> -config DRAM_SUN50I_H616_UNKNOWN_FEATURE
> -	bool "H616 DRAM unknown feature"
> -	---help---
> -	  Select this when DRAM on your H616 board needs this unknown
> -	  feature.
> -
>  config DRAM_SUN50I_H616_DX_ODT
>  	hex "H616 DRAM DX ODT parameter"
>  	help
> @@ -98,6 +66,12 @@ config DRAM_SUN50I_H616_CA_DRI
>  	hex "H616 DRAM CA DRI parameter"
>  	help
>  	  CA DRI value from vendor DRAM settings.
> +
> +config DRAM_SUN50I_H616_TPR10
> +	hex "H616 DRAM TPR10 parameter"
> +	help
> +	  TPR10 value from vendor DRAM settings. It tells which features
> +	  should be configured, like write leveling, read calibration, etc.
>  endif
>  
>  config SUN6I_PRCM
> diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> index 06a07dfbf9cc..14a01a3c4e54 100644
> --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> @@ -577,109 +577,112 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
>  	u32 *ptr;
>  	int i;
>  
> -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> -	setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
> -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
> +	if (para->tpr10 & TPR10_UNKNOWN_FEAT2) {
> +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> +		setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
> +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
>  
> -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
> -	for (i = 0; i < 9; i++) {
> -		writel_relaxed(0x16, ptr);
> -		writel_relaxed(0x16, ptr + 0x30);
> -		ptr += 2;
> -	}
> -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4d0);
> -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x590);
> -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
> -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
> +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
> +		for (i = 0; i < 9; i++) {
> +			writel_relaxed(0x16, ptr);
> +			writel_relaxed(0x16, ptr + 0x30);
> +			ptr += 2;
> +		}
> +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4d0);
> +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x590);
> +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
> +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
>  
> -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
> -	for (i = 0; i < 9; i++) {
> -		writel_relaxed(0x1a, ptr);
> -		writel_relaxed(0x1a, ptr + 0x30);
> -		ptr += 2;
> -	}
> -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x524);
> -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e4);
> -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
> -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
> +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
> +		for (i = 0; i < 9; i++) {
> +			writel_relaxed(0x1a, ptr);
> +			writel_relaxed(0x1a, ptr + 0x30);
> +			ptr += 2;
> +		}
> +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x524);
> +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e4);
> +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
> +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
>  
> -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
> -	for (i = 0; i < 9; i++) {
> -		writel_relaxed(0x1a, ptr);
> -		writel_relaxed(0x1a, ptr + 0x30);
> -		ptr += 2;
> -	}
> -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x650);
> -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x710);
> -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
> -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
> +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
> +		for (i = 0; i < 9; i++) {
> +			writel_relaxed(0x1a, ptr);
> +			writel_relaxed(0x1a, ptr + 0x30);
> +			ptr += 2;
> +		}
> +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x650);
> +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x710);
> +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
> +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
>  
> -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
> -	for (i = 0; i < 9; i++) {
> -		writel_relaxed(0x1a, ptr);
> -		writel_relaxed(0x1a, ptr + 0x30);
> -		ptr += 2;
> -	}
> -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a4);
> -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x764);
> -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a0);
> -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x760);
> +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
> +		for (i = 0; i < 9; i++) {
> +			writel_relaxed(0x1a, ptr);
> +			writel_relaxed(0x1a, ptr + 0x30);
> +			ptr += 2;
> +		}
> +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a4);
> +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x764);
> +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a0);
> +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x760);
>  
> -	dmb();
> +		dmb();
>  
> -	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> +		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> +	}
>  
> -	/* second part */
> -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
> +	if (para->tpr10 & TPR10_UNKNOWN_FEAT1) {
> +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
>  
> -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
> -	for (i = 0; i < 9; i++) {
> -		writel_relaxed(0x10, ptr);
> -		writel_relaxed(0x10, ptr + 0x30);
> -		ptr += 2;
> -	}
> -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x528);
> -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x5e8);
> -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
> -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
> +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
> +		for (i = 0; i < 9; i++) {
> +			writel_relaxed(0x10, ptr);
> +			writel_relaxed(0x10, ptr + 0x30);
> +			ptr += 2;
> +		}
> +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x528);
> +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x5e8);
> +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
> +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
>  
> -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
> -	for (i = 0; i < 9; i++) {
> -		writel_relaxed(0x12, ptr);
> -		writel_relaxed(0x12, ptr + 0x30);
> -		ptr += 2;
> -	}
> -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x52c);
> -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5ec);
> -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
> -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
> +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
> +		for (i = 0; i < 9; i++) {
> +			writel_relaxed(0x12, ptr);
> +			writel_relaxed(0x12, ptr + 0x30);
> +			ptr += 2;
> +		}
> +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x52c);
> +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5ec);
> +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
> +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
>  
> -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
> -	for (i = 0; i < 9; i++) {
> -		writel_relaxed(0x12, ptr);
> -		writel_relaxed(0x12, ptr + 0x30);
> -		ptr += 2;
> -	}
> -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x6a8);
> -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x768);
> -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
> -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
> +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
> +		for (i = 0; i < 9; i++) {
> +			writel_relaxed(0x12, ptr);
> +			writel_relaxed(0x12, ptr + 0x30);
> +			ptr += 2;
> +		}
> +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x6a8);
> +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x768);
> +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
> +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
>  
> -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
> -	for (i = 0; i < 9; i++) {
> -		writel_relaxed(0x14, ptr);
> -		writel_relaxed(0x14, ptr + 0x30);
> -		ptr += 2;
> -	}
> -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x6ac);
> -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x76c);
> -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x69c);
> -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x75c);
> +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
> +		for (i = 0; i < 9; i++) {
> +			writel_relaxed(0x14, ptr);
> +			writel_relaxed(0x14, ptr + 0x30);
> +			ptr += 2;
> +		}
> +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x6ac);
> +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x76c);
> +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x69c);
> +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x75c);
>  
> -	dmb();
> +		dmb();
>  
> -	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> +		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> +	}
>  
>  	return true;
>  }
> @@ -718,7 +721,7 @@ static bool mctl_phy_init(struct dram_para *para)
>  	for (i = 0; i < ARRAY_SIZE(phy_init); i++)
>  		writel(phy_init[i], &ptr[i]);
>  
> -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_UNKNOWN_FEATURE)) {
> +	if (para->tpr10 & TPR10_UNKNOWN_FEAT0) {
>  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780);
>  		for (i = 0; i < 32; i++)
>  			writel(0x16, &ptr[i]);
> @@ -800,7 +803,7 @@ static bool mctl_phy_init(struct dram_para *para)
>  	clrbits_le32(&mctl_ctl->rfshctl3, 1);
>  	writel(1, &mctl_ctl->swctl);
>  
> -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING)) {
> +	if (para->tpr10 & TPR10_WRITE_LEVELING) {
>  		for (i = 0; i < 5; i++)
>  			if (mctl_phy_write_leveling(para))
>  				break;
> @@ -810,7 +813,7 @@ static bool mctl_phy_init(struct dram_para *para)
>  		}
>  	}
>  
> -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION)) {
> +	if (para->tpr10 & TPR10_READ_CALIBRATION) {
>  		for (i = 0; i < 5; i++)
B>  			if (mctl_phy_read_calibration(para))
>  				break;
> @@ -820,7 +823,7 @@ static bool mctl_phy_init(struct dram_para *para)
>  		}
>  	}
>  
> -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_READ_TRAINING)) {
> +	if (para->tpr10 & TPR10_READ_TRAINING) {
>  		for (i = 0; i < 5; i++)
>  			if (mctl_phy_read_training(para))
>  				break;
> @@ -830,7 +833,7 @@ static bool mctl_phy_init(struct dram_para *para)
>  		}
>  	}
>  
> -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING)) {
> +	if (para->tpr10 & TPR10_WRITE_TRAINING) {
>  		for (i = 0; i < 5; i++)
>  			if (mctl_phy_write_training(para))
>  				break;
> @@ -840,8 +843,7 @@ static bool mctl_phy_init(struct dram_para *para)
>  		}
>  	}
>  
> -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION))
> -		mctl_phy_bit_delay_compensation(para);
> +	mctl_phy_bit_delay_compensation(para);
>  
>  	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 4);
>  
> @@ -1022,6 +1024,7 @@ unsigned long sunxi_dram_init(void)
>  		.dx_odt = CONFIG_DRAM_SUN50I_H616_DX_ODT,
>  		.dx_dri = CONFIG_DRAM_SUN50I_H616_DX_DRI,
>  		.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
> +		.tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
>  	};
>  	unsigned long size;
>  
> diff --git a/configs/orangepi_zero2_defconfig b/configs/orangepi_zero2_defconfig
> index ca398faef1d3..f2024a2502c7 100644
> --- a/configs/orangepi_zero2_defconfig
> +++ b/configs/orangepi_zero2_defconfig
> @@ -2,13 +2,10 @@ CONFIG_ARM=y
>  CONFIG_ARCH_SUNXI=y
>  CONFIG_DEFAULT_DEVICE_TREE="sun50i-h616-orangepi-zero2"
>  CONFIG_SPL=y
> -CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING=y
> -CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
> -CONFIG_DRAM_SUN50I_H616_READ_TRAINING=y
> -CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING=y
>  CONFIG_DRAM_SUN50I_H616_DX_ODT=0x8080808
>  CONFIG_DRAM_SUN50I_H616_DX_DRI=0xe0e0e0e
>  CONFIG_DRAM_SUN50I_H616_CA_DRI=0xe0e
> +CONFIG_DRAM_SUN50I_H616_TPR10=0xf83438
>  CONFIG_MACH_SUN50I_H616=y
>  CONFIG_MMC0_CD_PIN="PF6"
>  CONFIG_R_I2C_ENABLE=y


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

* Re: [PATCH 4/8] sunxi: Convert H616 DRAM options to single setting
  2022-12-12 17:50   ` Andre Przywara
@ 2022-12-13 16:23     ` Jernej Škrabec
  2022-12-13 16:51       ` Andre Przywara
  0 siblings, 1 reply; 29+ messages in thread
From: Jernej Škrabec @ 2022-12-13 16:23 UTC (permalink / raw)
  To: Andre Przywara; +Cc: jagan, u-boot

Hi,

Dne ponedeljek, 12. december 2022 ob 18:50:44 CET je Andre Przywara 
napisal(a):
> On Sun, 11 Dec 2022 17:32:09 +0100
> Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
> 
> Hi,
> 
> > Vendor DRAM settings use TPR10 parameter to enable various features.
> > There are many mores features that just those that are currently
> > mentioned. Since new will be added later and most are not known, let's
> > reuse value from vendor DRAM driver as-is. This will also help adding
> > support for new boards.
> 
> Looks good. I checked that the actual code in
> mctl_phy_bit_delay_compensation() just gets indented (no real changes), and
> is now guarded by the new checks.
> The values in the _defconfig still result in the same decisions, though
> many are blocked anyway by no one actually calling that bit_delay function
> at all. (I wonder what happens when we enable it?)

I'm not sure I understand. Bit delay compensation should be enabled for X96 
Mate, according to values you send in previous e-mail. In any case, DRAM 
configuration looks like a black magic at times, so I would rather stick to 
vendor procedure, especially due to missing register documentation, and not 
just randomly enable things which sounds nice. I tried enabling unused 
procedures for T95 and either they didn't went through or amount of detected 
RAM was lower than presetn.

> One small thing below.
> 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
> > ---
> > 
> >  .../include/asm/arch-sunxi/dram_sun50i_h616.h |  10 +
> >  arch/arm/mach-sunxi/Kconfig                   |  38 +---
> >  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 197 +++++++++---------
> >  configs/orangepi_zero2_defconfig              |   5 +-
> >  4 files changed, 117 insertions(+), 133 deletions(-)
> > 
> > diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h index
> > c9e1f84bfcdd..b5140c79b70e 100644
> > --- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > @@ -137,6 +137,15 @@ check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240);
> > 
> >  #define MSTR_ACTIVE_RANKS(x)	(((x == 2) ? 3 : 1) << 24)
> >  #define MSTR_BURST_LENGTH(x)	(((x) >> 1) << 16)
> > 
> > +/* TODO: figure out what unknown features do */
> > +#define TPR10_UNKNOWN_FEAT0	BIT(16)
> > +#define TPR10_UNKNOWN_FEAT1	BIT(17)
> > +#define TPR10_UNKNOWN_FEAT2	BIT(18)
> 
> Could you just put the bit number in the macro? Like TPR10_BIT16? That
> both avoids inventing meaningless names, and helps readers to correlate
> code more easily. Or skip the symbol altogether for those and use just
> "BIT(16)" in the code.

I actually know what these are for now, so I can give much better names. 
However, I still don't know what TPR10_UNKNOWN_FEAT3 does, which is in the 
last commit, so I'll rework that one to use BIT(30) directly.

Best regards,
Jernej

> 
> Cheers,
> Andre
> 
> > +#define TPR10_WRITE_LEVELING	BIT(20)
> > +#define TPR10_READ_CALIBRATION	BIT(21)
> > +#define TPR10_READ_TRAINING	BIT(22)
> > +#define TPR10_WRITE_TRAINING	BIT(23)
> > +
> > 
> >  struct dram_para {
> >  
> >  	u32 clk;
> >  	enum sunxi_dram_type type;
> > 
> > @@ -147,6 +156,7 @@ struct dram_para {
> > 
> >  	u32 dx_odt;
> >  	u32 dx_dri;
> >  	u32 ca_dri;
> > 
> > +	u32 tpr10;
> > 
> >  };
> > 
> > diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> > index cad53f19912c..abcbd0fb9061 100644
> > --- a/arch/arm/mach-sunxi/Kconfig
> > +++ b/arch/arm/mach-sunxi/Kconfig
> > @@ -52,38 +52,6 @@ config DRAM_SUN50I_H616
> > 
> >  	  like H616.
> >  
> >  if DRAM_SUN50I_H616
> > 
> > -config DRAM_SUN50I_H616_WRITE_LEVELING
> > -	bool "H616 DRAM write leveling"
> > -	---help---
> > -	  Select this when DRAM on your H616 board needs write leveling.
> > -
> > -config DRAM_SUN50I_H616_READ_CALIBRATION
> > -	bool "H616 DRAM read calibration"
> > -	---help---
> > -	  Select this when DRAM on your H616 board needs read 
calibration.
> > -
> > -config DRAM_SUN50I_H616_READ_TRAINING
> > -	bool "H616 DRAM read training"
> > -	---help---
> > -	  Select this when DRAM on your H616 board needs read training.
> > -
> > -config DRAM_SUN50I_H616_WRITE_TRAINING
> > -	bool "H616 DRAM write training"
> > -	---help---
> > -	  Select this when DRAM on your H616 board needs write training.
> > -
> > -config DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION
> > -	bool "H616 DRAM bit delay compensation"
> > -	---help---
> > -	  Select this when DRAM on your H616 board needs bit delay
> > -	  compensation.
> > -
> > -config DRAM_SUN50I_H616_UNKNOWN_FEATURE
> > -	bool "H616 DRAM unknown feature"
> > -	---help---
> > -	  Select this when DRAM on your H616 board needs this unknown
> > -	  feature.
> > -
> > 
> >  config DRAM_SUN50I_H616_DX_ODT
> >  
> >  	hex "H616 DRAM DX ODT parameter"
> >  	help
> > 
> > @@ -98,6 +66,12 @@ config DRAM_SUN50I_H616_CA_DRI
> > 
> >  	hex "H616 DRAM CA DRI parameter"
> >  	help
> >  	
> >  	  CA DRI value from vendor DRAM settings.
> > 
> > +
> > +config DRAM_SUN50I_H616_TPR10
> > +	hex "H616 DRAM TPR10 parameter"
> > +	help
> > +	  TPR10 value from vendor DRAM settings. It tells which features
> > +	  should be configured, like write leveling, read calibration, etc.
> > 
> >  endif
> >  
> >  config SUN6I_PRCM
> > 
> > diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > b/arch/arm/mach-sunxi/dram_sun50i_h616.c index 06a07dfbf9cc..14a01a3c4e54
> > 100644
> > --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > @@ -577,109 +577,112 @@ static bool mctl_phy_bit_delay_compensation(struct
> > dram_para *para)> 
> >  	u32 *ptr;
> >  	int i;
> > 
> > -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> > -	setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
> > -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
> > +	if (para->tpr10 & TPR10_UNKNOWN_FEAT2) {
> > +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> > +		setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
> > +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
> > 
> > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
> > -	for (i = 0; i < 9; i++) {
> > -		writel_relaxed(0x16, ptr);
> > -		writel_relaxed(0x16, ptr + 0x30);
> > -		ptr += 2;
> > -	}
> > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4d0);
> > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x590);
> > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
> > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
> > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
> > +		for (i = 0; i < 9; i++) {
> > +			writel_relaxed(0x16, ptr);
> > +			writel_relaxed(0x16, ptr + 0x30);
> > +			ptr += 2;
> > +		}
> > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4d0);
> > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x590);
> > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
> > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
> > 
> > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
> > -	for (i = 0; i < 9; i++) {
> > -		writel_relaxed(0x1a, ptr);
> > -		writel_relaxed(0x1a, ptr + 0x30);
> > -		ptr += 2;
> > -	}
> > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x524);
> > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e4);
> > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
> > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
> > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
> > +		for (i = 0; i < 9; i++) {
> > +			writel_relaxed(0x1a, ptr);
> > +			writel_relaxed(0x1a, ptr + 0x30);
> > +			ptr += 2;
> > +		}
> > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x524);
> > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e4);
> > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
> > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
> > 
> > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
> > -	for (i = 0; i < 9; i++) {
> > -		writel_relaxed(0x1a, ptr);
> > -		writel_relaxed(0x1a, ptr + 0x30);
> > -		ptr += 2;
> > -	}
> > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x650);
> > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x710);
> > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
> > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
> > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
> > +		for (i = 0; i < 9; i++) {
> > +			writel_relaxed(0x1a, ptr);
> > +			writel_relaxed(0x1a, ptr + 0x30);
> > +			ptr += 2;
> > +		}
> > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x650);
> > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x710);
> > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
> > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
> > 
> > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
> > -	for (i = 0; i < 9; i++) {
> > -		writel_relaxed(0x1a, ptr);
> > -		writel_relaxed(0x1a, ptr + 0x30);
> > -		ptr += 2;
> > -	}
> > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a4);
> > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x764);
> > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a0);
> > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x760);
> > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
> > +		for (i = 0; i < 9; i++) {
> > +			writel_relaxed(0x1a, ptr);
> > +			writel_relaxed(0x1a, ptr + 0x30);
> > +			ptr += 2;
> > +		}
> > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a4);
> > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x764);
> > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a0);
> > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x760);
> > 
> > -	dmb();
> > +		dmb();
> > 
> > -	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> > +		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> > +	}
> > 
> > -	/* second part */
> > -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> > -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
> > +	if (para->tpr10 & TPR10_UNKNOWN_FEAT1) {
> > +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> > +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
> > 
> > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
> > -	for (i = 0; i < 9; i++) {
> > -		writel_relaxed(0x10, ptr);
> > -		writel_relaxed(0x10, ptr + 0x30);
> > -		ptr += 2;
> > -	}
> > -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x528);
> > -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x5e8);
> > -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
> > -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
> > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
> > +		for (i = 0; i < 9; i++) {
> > +			writel_relaxed(0x10, ptr);
> > +			writel_relaxed(0x10, ptr + 0x30);
> > +			ptr += 2;
> > +		}
> > +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x528);
> > +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x5e8);
> > +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
> > +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
> > 
> > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
> > -	for (i = 0; i < 9; i++) {
> > -		writel_relaxed(0x12, ptr);
> > -		writel_relaxed(0x12, ptr + 0x30);
> > -		ptr += 2;
> > -	}
> > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x52c);
> > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5ec);
> > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
> > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
> > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
> > +		for (i = 0; i < 9; i++) {
> > +			writel_relaxed(0x12, ptr);
> > +			writel_relaxed(0x12, ptr + 0x30);
> > +			ptr += 2;
> > +		}
> > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x52c);
> > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5ec);
> > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
> > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
> > 
> > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
> > -	for (i = 0; i < 9; i++) {
> > -		writel_relaxed(0x12, ptr);
> > -		writel_relaxed(0x12, ptr + 0x30);
> > -		ptr += 2;
> > -	}
> > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x6a8);
> > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x768);
> > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
> > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
> > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
> > +		for (i = 0; i < 9; i++) {
> > +			writel_relaxed(0x12, ptr);
> > +			writel_relaxed(0x12, ptr + 0x30);
> > +			ptr += 2;
> > +		}
> > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x6a8);
> > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x768);
> > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
> > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
> > 
> > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
> > -	for (i = 0; i < 9; i++) {
> > -		writel_relaxed(0x14, ptr);
> > -		writel_relaxed(0x14, ptr + 0x30);
> > -		ptr += 2;
> > -	}
> > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x6ac);
> > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x76c);
> > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x69c);
> > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x75c);
> > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
> > +		for (i = 0; i < 9; i++) {
> > +			writel_relaxed(0x14, ptr);
> > +			writel_relaxed(0x14, ptr + 0x30);
> > +			ptr += 2;
> > +		}
> > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x6ac);
> > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x76c);
> > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x69c);
> > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x75c);
> > 
> > -	dmb();
> > +		dmb();
> > 
> > -	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> > +		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> > +	}
> > 
> >  	return true;
> >  
> >  }
> > 
> > @@ -718,7 +721,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > 
> >  	for (i = 0; i < ARRAY_SIZE(phy_init); i++)
> >  	
> >  		writel(phy_init[i], &ptr[i]);
> > 
> > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_UNKNOWN_FEATURE)) {
> > +	if (para->tpr10 & TPR10_UNKNOWN_FEAT0) {
> > 
> >  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780);
> >  		for (i = 0; i < 32; i++)
> >  		
> >  			writel(0x16, &ptr[i]);
> > 
> > @@ -800,7 +803,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > 
> >  	clrbits_le32(&mctl_ctl->rfshctl3, 1);
> >  	writel(1, &mctl_ctl->swctl);
> > 
> > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING)) {
> > +	if (para->tpr10 & TPR10_WRITE_LEVELING) {
> > 
> >  		for (i = 0; i < 5; i++)
> >  		
> >  			if (mctl_phy_write_leveling(para))
> >  			
> >  				break;
> > 
> > @@ -810,7 +813,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > 
> >  		}
> >  	
> >  	}
> > 
> > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION)) {
> > +	if (para->tpr10 & TPR10_READ_CALIBRATION) {
> > 
> >  		for (i = 0; i < 5; i++)
> 
> B>  			if (mctl_phy_read_calibration(para))
> 
> >  				break;
> > 
> > @@ -820,7 +823,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > 
> >  		}
> >  	
> >  	}
> > 
> > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_READ_TRAINING)) {
> > +	if (para->tpr10 & TPR10_READ_TRAINING) {
> > 
> >  		for (i = 0; i < 5; i++)
> >  		
> >  			if (mctl_phy_read_training(para))
> >  			
> >  				break;
> > 
> > @@ -830,7 +833,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > 
> >  		}
> >  	
> >  	}
> > 
> > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING)) {
> > +	if (para->tpr10 & TPR10_WRITE_TRAINING) {
> > 
> >  		for (i = 0; i < 5; i++)
> >  		
> >  			if (mctl_phy_write_training(para))
> >  			
> >  				break;
> > 
> > @@ -840,8 +843,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > 
> >  		}
> >  	
> >  	}
> > 
> > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION))
> > -		mctl_phy_bit_delay_compensation(para);
> > +	mctl_phy_bit_delay_compensation(para);
> > 
> >  	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 4);
> > 
> > @@ -1022,6 +1024,7 @@ unsigned long sunxi_dram_init(void)
> > 
> >  		.dx_odt = CONFIG_DRAM_SUN50I_H616_DX_ODT,
> >  		.dx_dri = CONFIG_DRAM_SUN50I_H616_DX_DRI,
> >  		.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
> > 
> > +		.tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
> > 
> >  	};
> >  	unsigned long size;
> > 
> > diff --git a/configs/orangepi_zero2_defconfig
> > b/configs/orangepi_zero2_defconfig index ca398faef1d3..f2024a2502c7
> > 100644
> > --- a/configs/orangepi_zero2_defconfig
> > +++ b/configs/orangepi_zero2_defconfig
> > @@ -2,13 +2,10 @@ CONFIG_ARM=y
> > 
> >  CONFIG_ARCH_SUNXI=y
> >  CONFIG_DEFAULT_DEVICE_TREE="sun50i-h616-orangepi-zero2"
> >  CONFIG_SPL=y
> > 
> > -CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING=y
> > -CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
> > -CONFIG_DRAM_SUN50I_H616_READ_TRAINING=y
> > -CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING=y
> > 
> >  CONFIG_DRAM_SUN50I_H616_DX_ODT=0x8080808
> >  CONFIG_DRAM_SUN50I_H616_DX_DRI=0xe0e0e0e
> >  CONFIG_DRAM_SUN50I_H616_CA_DRI=0xe0e
> > 
> > +CONFIG_DRAM_SUN50I_H616_TPR10=0xf83438
> > 
> >  CONFIG_MACH_SUN50I_H616=y
> >  CONFIG_MMC0_CD_PIN="PF6"
> >  CONFIG_R_I2C_ENABLE=y





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

* Re: [PATCH 4/8] sunxi: Convert H616 DRAM options to single setting
  2022-12-13 16:23     ` Jernej Škrabec
@ 2022-12-13 16:51       ` Andre Przywara
  2022-12-13 17:08         ` Jernej Škrabec
  0 siblings, 1 reply; 29+ messages in thread
From: Andre Przywara @ 2022-12-13 16:51 UTC (permalink / raw)
  To: Jernej Škrabec; +Cc: jagan, u-boot

On Tue, 13 Dec 2022 17:23:12 +0100
Jernej Škrabec <jernej.skrabec@gmail.com> wrote:

> Hi,
> 
> Dne ponedeljek, 12. december 2022 ob 18:50:44 CET je Andre Przywara 
> napisal(a):
> > On Sun, 11 Dec 2022 17:32:09 +0100
> > Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
> > 
> > Hi,
> >   
> > > Vendor DRAM settings use TPR10 parameter to enable various features.
> > > There are many mores features that just those that are currently
> > > mentioned. Since new will be added later and most are not known, let's
> > > reuse value from vendor DRAM driver as-is. This will also help adding
> > > support for new boards.  
> > 
> > Looks good. I checked that the actual code in
> > mctl_phy_bit_delay_compensation() just gets indented (no real changes), and
> > is now guarded by the new checks.
> > The values in the _defconfig still result in the same decisions, though
> > many are blocked anyway by no one actually calling that bit_delay function
> > at all. (I wonder what happens when we enable it?)  
> 
> I'm not sure I understand. Bit delay compensation should be enabled for X96 
> Mate, according to values you send in previous e-mail.

But DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION is not set by any (of the two)
defconfigs atm, and I don't see this in your t95 (WIP?) branch on github
either. So that whole code was completely unused (until now).

> In any case, DRAM 
> configuration looks like a black magic at times, so I would rather stick to 
> vendor procedure, especially due to missing register documentation, and not 
> just randomly enable things which sounds nice. I tried enabling unused 
> procedures for T95 and either they didn't went through or amount of detected 
> RAM was lower than presetn.

Sure, I was just confused that we have some elaborate code, with values
backed by the vendor BSP, but then don't use that. But if it gets used
now, it's all fine, I guess.

> > One small thing below.
> >   
> > > Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
> > > ---
> > > 
> > >  .../include/asm/arch-sunxi/dram_sun50i_h616.h |  10 +
> > >  arch/arm/mach-sunxi/Kconfig                   |  38 +---
> > >  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 197 +++++++++---------
> > >  configs/orangepi_zero2_defconfig              |   5 +-
> > >  4 files changed, 117 insertions(+), 133 deletions(-)
> > > 
> > > diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > > b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h index
> > > c9e1f84bfcdd..b5140c79b70e 100644
> > > --- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > > +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > > @@ -137,6 +137,15 @@ check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240);
> > > 
> > >  #define MSTR_ACTIVE_RANKS(x)	(((x == 2) ? 3 : 1) << 24)
> > >  #define MSTR_BURST_LENGTH(x)	(((x) >> 1) << 16)
> > > 
> > > +/* TODO: figure out what unknown features do */
> > > +#define TPR10_UNKNOWN_FEAT0	BIT(16)
> > > +#define TPR10_UNKNOWN_FEAT1	BIT(17)
> > > +#define TPR10_UNKNOWN_FEAT2	BIT(18)  
> > 
> > Could you just put the bit number in the macro? Like TPR10_BIT16? That
> > both avoids inventing meaningless names, and helps readers to correlate
> > code more easily. Or skip the symbol altogether for those and use just
> > "BIT(16)" in the code.  
> 
> I actually know what these are for now, so I can give much better names. 
> However, I still don't know what TPR10_UNKNOWN_FEAT3 does, which is in the 
> last commit, so I'll rework that one to use BIT(30) directly.

Great, thanks!

Cheers,
Andre

> 
> Best regards,
> Jernej
> 
> > 
> > Cheers,
> > Andre
> >   
> > > +#define TPR10_WRITE_LEVELING	BIT(20)
> > > +#define TPR10_READ_CALIBRATION	BIT(21)
> > > +#define TPR10_READ_TRAINING	BIT(22)
> > > +#define TPR10_WRITE_TRAINING	BIT(23)
> > > +
> > > 
> > >  struct dram_para {
> > >  
> > >  	u32 clk;
> > >  	enum sunxi_dram_type type;
> > > 
> > > @@ -147,6 +156,7 @@ struct dram_para {
> > > 
> > >  	u32 dx_odt;
> > >  	u32 dx_dri;
> > >  	u32 ca_dri;
> > > 
> > > +	u32 tpr10;
> > > 
> > >  };
> > > 
> > > diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> > > index cad53f19912c..abcbd0fb9061 100644
> > > --- a/arch/arm/mach-sunxi/Kconfig
> > > +++ b/arch/arm/mach-sunxi/Kconfig
> > > @@ -52,38 +52,6 @@ config DRAM_SUN50I_H616
> > > 
> > >  	  like H616.
> > >  
> > >  if DRAM_SUN50I_H616
> > > 
> > > -config DRAM_SUN50I_H616_WRITE_LEVELING
> > > -	bool "H616 DRAM write leveling"
> > > -	---help---
> > > -	  Select this when DRAM on your H616 board needs write leveling.
> > > -
> > > -config DRAM_SUN50I_H616_READ_CALIBRATION
> > > -	bool "H616 DRAM read calibration"
> > > -	---help---
> > > -	  Select this when DRAM on your H616 board needs read   
> calibration.
> > > -
> > > -config DRAM_SUN50I_H616_READ_TRAINING
> > > -	bool "H616 DRAM read training"
> > > -	---help---
> > > -	  Select this when DRAM on your H616 board needs read training.
> > > -
> > > -config DRAM_SUN50I_H616_WRITE_TRAINING
> > > -	bool "H616 DRAM write training"
> > > -	---help---
> > > -	  Select this when DRAM on your H616 board needs write training.
> > > -
> > > -config DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION
> > > -	bool "H616 DRAM bit delay compensation"
> > > -	---help---
> > > -	  Select this when DRAM on your H616 board needs bit delay
> > > -	  compensation.
> > > -
> > > -config DRAM_SUN50I_H616_UNKNOWN_FEATURE
> > > -	bool "H616 DRAM unknown feature"
> > > -	---help---
> > > -	  Select this when DRAM on your H616 board needs this unknown
> > > -	  feature.
> > > -
> > > 
> > >  config DRAM_SUN50I_H616_DX_ODT
> > >  
> > >  	hex "H616 DRAM DX ODT parameter"
> > >  	help
> > > 
> > > @@ -98,6 +66,12 @@ config DRAM_SUN50I_H616_CA_DRI
> > > 
> > >  	hex "H616 DRAM CA DRI parameter"
> > >  	help
> > >  	
> > >  	  CA DRI value from vendor DRAM settings.
> > > 
> > > +
> > > +config DRAM_SUN50I_H616_TPR10
> > > +	hex "H616 DRAM TPR10 parameter"
> > > +	help
> > > +	  TPR10 value from vendor DRAM settings. It tells which features
> > > +	  should be configured, like write leveling, read calibration, etc.
> > > 
> > >  endif
> > >  
> > >  config SUN6I_PRCM
> > > 
> > > diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > > b/arch/arm/mach-sunxi/dram_sun50i_h616.c index 06a07dfbf9cc..14a01a3c4e54
> > > 100644
> > > --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > > +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > > @@ -577,109 +577,112 @@ static bool mctl_phy_bit_delay_compensation(struct
> > > dram_para *para)> 
> > >  	u32 *ptr;
> > >  	int i;
> > > 
> > > -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> > > -	setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
> > > -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
> > > +	if (para->tpr10 & TPR10_UNKNOWN_FEAT2) {
> > > +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> > > +		setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
> > > +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
> > > 
> > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
> > > -	for (i = 0; i < 9; i++) {
> > > -		writel_relaxed(0x16, ptr);
> > > -		writel_relaxed(0x16, ptr + 0x30);
> > > -		ptr += 2;
> > > -	}
> > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4d0);
> > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x590);
> > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
> > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
> > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
> > > +		for (i = 0; i < 9; i++) {
> > > +			writel_relaxed(0x16, ptr);
> > > +			writel_relaxed(0x16, ptr + 0x30);
> > > +			ptr += 2;
> > > +		}
> > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4d0);
> > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x590);
> > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
> > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
> > > 
> > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
> > > -	for (i = 0; i < 9; i++) {
> > > -		writel_relaxed(0x1a, ptr);
> > > -		writel_relaxed(0x1a, ptr + 0x30);
> > > -		ptr += 2;
> > > -	}
> > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x524);
> > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e4);
> > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
> > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
> > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
> > > +		for (i = 0; i < 9; i++) {
> > > +			writel_relaxed(0x1a, ptr);
> > > +			writel_relaxed(0x1a, ptr + 0x30);
> > > +			ptr += 2;
> > > +		}
> > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x524);
> > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e4);
> > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
> > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
> > > 
> > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
> > > -	for (i = 0; i < 9; i++) {
> > > -		writel_relaxed(0x1a, ptr);
> > > -		writel_relaxed(0x1a, ptr + 0x30);
> > > -		ptr += 2;
> > > -	}
> > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x650);
> > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x710);
> > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
> > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
> > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
> > > +		for (i = 0; i < 9; i++) {
> > > +			writel_relaxed(0x1a, ptr);
> > > +			writel_relaxed(0x1a, ptr + 0x30);
> > > +			ptr += 2;
> > > +		}
> > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x650);
> > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x710);
> > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
> > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
> > > 
> > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
> > > -	for (i = 0; i < 9; i++) {
> > > -		writel_relaxed(0x1a, ptr);
> > > -		writel_relaxed(0x1a, ptr + 0x30);
> > > -		ptr += 2;
> > > -	}
> > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a4);
> > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x764);
> > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a0);
> > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x760);
> > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
> > > +		for (i = 0; i < 9; i++) {
> > > +			writel_relaxed(0x1a, ptr);
> > > +			writel_relaxed(0x1a, ptr + 0x30);
> > > +			ptr += 2;
> > > +		}
> > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a4);
> > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x764);
> > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a0);
> > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x760);
> > > 
> > > -	dmb();
> > > +		dmb();
> > > 
> > > -	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> > > +		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> > > +	}
> > > 
> > > -	/* second part */
> > > -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> > > -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
> > > +	if (para->tpr10 & TPR10_UNKNOWN_FEAT1) {
> > > +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> > > +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
> > > 
> > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
> > > -	for (i = 0; i < 9; i++) {
> > > -		writel_relaxed(0x10, ptr);
> > > -		writel_relaxed(0x10, ptr + 0x30);
> > > -		ptr += 2;
> > > -	}
> > > -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x528);
> > > -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x5e8);
> > > -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
> > > -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
> > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
> > > +		for (i = 0; i < 9; i++) {
> > > +			writel_relaxed(0x10, ptr);
> > > +			writel_relaxed(0x10, ptr + 0x30);
> > > +			ptr += 2;
> > > +		}
> > > +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x528);
> > > +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x5e8);
> > > +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
> > > +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
> > > 
> > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
> > > -	for (i = 0; i < 9; i++) {
> > > -		writel_relaxed(0x12, ptr);
> > > -		writel_relaxed(0x12, ptr + 0x30);
> > > -		ptr += 2;
> > > -	}
> > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x52c);
> > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5ec);
> > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
> > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
> > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
> > > +		for (i = 0; i < 9; i++) {
> > > +			writel_relaxed(0x12, ptr);
> > > +			writel_relaxed(0x12, ptr + 0x30);
> > > +			ptr += 2;
> > > +		}
> > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x52c);
> > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5ec);
> > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
> > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
> > > 
> > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
> > > -	for (i = 0; i < 9; i++) {
> > > -		writel_relaxed(0x12, ptr);
> > > -		writel_relaxed(0x12, ptr + 0x30);
> > > -		ptr += 2;
> > > -	}
> > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x6a8);
> > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x768);
> > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
> > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
> > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
> > > +		for (i = 0; i < 9; i++) {
> > > +			writel_relaxed(0x12, ptr);
> > > +			writel_relaxed(0x12, ptr + 0x30);
> > > +			ptr += 2;
> > > +		}
> > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x6a8);
> > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x768);
> > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
> > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
> > > 
> > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
> > > -	for (i = 0; i < 9; i++) {
> > > -		writel_relaxed(0x14, ptr);
> > > -		writel_relaxed(0x14, ptr + 0x30);
> > > -		ptr += 2;
> > > -	}
> > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x6ac);
> > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x76c);
> > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x69c);
> > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x75c);
> > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
> > > +		for (i = 0; i < 9; i++) {
> > > +			writel_relaxed(0x14, ptr);
> > > +			writel_relaxed(0x14, ptr + 0x30);
> > > +			ptr += 2;
> > > +		}
> > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x6ac);
> > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x76c);
> > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x69c);
> > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x75c);
> > > 
> > > -	dmb();
> > > +		dmb();
> > > 
> > > -	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> > > +		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> > > +	}
> > > 
> > >  	return true;
> > >  
> > >  }
> > > 
> > > @@ -718,7 +721,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > > 
> > >  	for (i = 0; i < ARRAY_SIZE(phy_init); i++)
> > >  	
> > >  		writel(phy_init[i], &ptr[i]);
> > > 
> > > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_UNKNOWN_FEATURE)) {
> > > +	if (para->tpr10 & TPR10_UNKNOWN_FEAT0) {
> > > 
> > >  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780);
> > >  		for (i = 0; i < 32; i++)
> > >  		
> > >  			writel(0x16, &ptr[i]);
> > > 
> > > @@ -800,7 +803,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > > 
> > >  	clrbits_le32(&mctl_ctl->rfshctl3, 1);
> > >  	writel(1, &mctl_ctl->swctl);
> > > 
> > > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING)) {
> > > +	if (para->tpr10 & TPR10_WRITE_LEVELING) {
> > > 
> > >  		for (i = 0; i < 5; i++)
> > >  		
> > >  			if (mctl_phy_write_leveling(para))
> > >  			
> > >  				break;
> > > 
> > > @@ -810,7 +813,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > > 
> > >  		}
> > >  	
> > >  	}
> > > 
> > > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION)) {
> > > +	if (para->tpr10 & TPR10_READ_CALIBRATION) {
> > > 
> > >  		for (i = 0; i < 5; i++)  
> >   
> > B>  			if (mctl_phy_read_calibration(para))  
> >   
> > >  				break;
> > > 
> > > @@ -820,7 +823,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > > 
> > >  		}
> > >  	
> > >  	}
> > > 
> > > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_READ_TRAINING)) {
> > > +	if (para->tpr10 & TPR10_READ_TRAINING) {
> > > 
> > >  		for (i = 0; i < 5; i++)
> > >  		
> > >  			if (mctl_phy_read_training(para))
> > >  			
> > >  				break;
> > > 
> > > @@ -830,7 +833,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > > 
> > >  		}
> > >  	
> > >  	}
> > > 
> > > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING)) {
> > > +	if (para->tpr10 & TPR10_WRITE_TRAINING) {
> > > 
> > >  		for (i = 0; i < 5; i++)
> > >  		
> > >  			if (mctl_phy_write_training(para))
> > >  			
> > >  				break;
> > > 
> > > @@ -840,8 +843,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > > 
> > >  		}
> > >  	
> > >  	}
> > > 
> > > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION))
> > > -		mctl_phy_bit_delay_compensation(para);
> > > +	mctl_phy_bit_delay_compensation(para);
> > > 
> > >  	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 4);
> > > 
> > > @@ -1022,6 +1024,7 @@ unsigned long sunxi_dram_init(void)
> > > 
> > >  		.dx_odt = CONFIG_DRAM_SUN50I_H616_DX_ODT,
> > >  		.dx_dri = CONFIG_DRAM_SUN50I_H616_DX_DRI,
> > >  		.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
> > > 
> > > +		.tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
> > > 
> > >  	};
> > >  	unsigned long size;
> > > 
> > > diff --git a/configs/orangepi_zero2_defconfig
> > > b/configs/orangepi_zero2_defconfig index ca398faef1d3..f2024a2502c7
> > > 100644
> > > --- a/configs/orangepi_zero2_defconfig
> > > +++ b/configs/orangepi_zero2_defconfig
> > > @@ -2,13 +2,10 @@ CONFIG_ARM=y
> > > 
> > >  CONFIG_ARCH_SUNXI=y
> > >  CONFIG_DEFAULT_DEVICE_TREE="sun50i-h616-orangepi-zero2"
> > >  CONFIG_SPL=y
> > > 
> > > -CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING=y
> > > -CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
> > > -CONFIG_DRAM_SUN50I_H616_READ_TRAINING=y
> > > -CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING=y
> > > 
> > >  CONFIG_DRAM_SUN50I_H616_DX_ODT=0x8080808
> > >  CONFIG_DRAM_SUN50I_H616_DX_DRI=0xe0e0e0e
> > >  CONFIG_DRAM_SUN50I_H616_CA_DRI=0xe0e
> > > 
> > > +CONFIG_DRAM_SUN50I_H616_TPR10=0xf83438
> > > 
> > >  CONFIG_MACH_SUN50I_H616=y
> > >  CONFIG_MMC0_CD_PIN="PF6"
> > >  CONFIG_R_I2C_ENABLE=y  
> 
> 
> 
> 


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

* Re: [PATCH 4/8] sunxi: Convert H616 DRAM options to single setting
  2022-12-13 16:51       ` Andre Przywara
@ 2022-12-13 17:08         ` Jernej Škrabec
  0 siblings, 0 replies; 29+ messages in thread
From: Jernej Škrabec @ 2022-12-13 17:08 UTC (permalink / raw)
  To: Andre Przywara; +Cc: jagan, u-boot

Dne torek, 13. december 2022 ob 17:51:35 CET je Andre Przywara napisal(a):
> On Tue, 13 Dec 2022 17:23:12 +0100
> 
> Jernej Škrabec <jernej.skrabec@gmail.com> wrote:
> > Hi,
> > 
> > Dne ponedeljek, 12. december 2022 ob 18:50:44 CET je Andre Przywara
> > 
> > napisal(a):
> > > On Sun, 11 Dec 2022 17:32:09 +0100
> > > Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
> > > 
> > > Hi,
> > > 
> > > > Vendor DRAM settings use TPR10 parameter to enable various features.
> > > > There are many mores features that just those that are currently
> > > > mentioned. Since new will be added later and most are not known, let's
> > > > reuse value from vendor DRAM driver as-is. This will also help adding
> > > > support for new boards.
> > > 
> > > Looks good. I checked that the actual code in
> > > mctl_phy_bit_delay_compensation() just gets indented (no real changes),
> > > and
> > > is now guarded by the new checks.
> > > The values in the _defconfig still result in the same decisions, though
> > > many are blocked anyway by no one actually calling that bit_delay
> > > function
> > > at all. (I wonder what happens when we enable it?)
> > 
> > I'm not sure I understand. Bit delay compensation should be enabled for
> > X96
> > Mate, according to values you send in previous e-mail.
> 
> But DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION is not set by any (of the two)
> defconfigs atm, and I don't see this in your t95 (WIP?) branch on github
> either. So that whole code was completely unused (until now).

Hm, I remember writing this code for T95, but I'm not sure why it's not 
enabled in defconfig. I'm sure values are ok and match vendor driver.

It's interesting to see how some parts of initialization procedure have some 
wiggle room and still appear to be stable.

> 
> > In any case, DRAM
> > configuration looks like a black magic at times, so I would rather stick
> > to
> > vendor procedure, especially due to missing register documentation, and
> > not
> > just randomly enable things which sounds nice. I tried enabling unused
> > procedures for T95 and either they didn't went through or amount of
> > detected RAM was lower than presetn.
> 
> Sure, I was just confused that we have some elaborate code, with values
> backed by the vendor BSP, but then don't use that. But if it gets used
> now, it's all fine, I guess.

Great!

Best regards,
Jernej

> 
> > > One small thing below.
> > > 
> > > > Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
> > > > ---
> > > > 
> > > >  .../include/asm/arch-sunxi/dram_sun50i_h616.h |  10 +
> > > >  arch/arm/mach-sunxi/Kconfig                   |  38 +---
> > > >  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 197
> > > >  +++++++++---------
> > > >  configs/orangepi_zero2_defconfig              |   5 +-
> > > >  4 files changed, 117 insertions(+), 133 deletions(-)
> > > > 
> > > > diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > > > b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h index
> > > > c9e1f84bfcdd..b5140c79b70e 100644
> > > > --- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > > > +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > > > @@ -137,6 +137,15 @@ check_member(sunxi_mctl_ctl_reg, unk_0x4240,
> > > > 0x4240);
> > > > 
> > > >  #define MSTR_ACTIVE_RANKS(x)	(((x == 2) ? 3 : 1) << 24)
> > > >  #define MSTR_BURST_LENGTH(x)	(((x) >> 1) << 16)
> > > > 
> > > > +/* TODO: figure out what unknown features do */
> > > > +#define TPR10_UNKNOWN_FEAT0	BIT(16)
> > > > +#define TPR10_UNKNOWN_FEAT1	BIT(17)
> > > > +#define TPR10_UNKNOWN_FEAT2	BIT(18)
> > > 
> > > Could you just put the bit number in the macro? Like TPR10_BIT16? That
> > > both avoids inventing meaningless names, and helps readers to correlate
> > > code more easily. Or skip the symbol altogether for those and use just
> > > "BIT(16)" in the code.
> > 
> > I actually know what these are for now, so I can give much better names.
> > However, I still don't know what TPR10_UNKNOWN_FEAT3 does, which is in the
> > last commit, so I'll rework that one to use BIT(30) directly.
> 
> Great, thanks!
> 
> Cheers,
> Andre
> 
> > Best regards,
> > Jernej
> > 
> > > Cheers,
> > > Andre
> > > 
> > > > +#define TPR10_WRITE_LEVELING	BIT(20)
> > > > +#define TPR10_READ_CALIBRATION	BIT(21)
> > > > +#define TPR10_READ_TRAINING	BIT(22)
> > > > +#define TPR10_WRITE_TRAINING	BIT(23)
> > > > +
> > > > 
> > > >  struct dram_para {
> > > >  
> > > >  	u32 clk;
> > > >  	enum sunxi_dram_type type;
> > > > 
> > > > @@ -147,6 +156,7 @@ struct dram_para {
> > > > 
> > > >  	u32 dx_odt;
> > > >  	u32 dx_dri;
> > > >  	u32 ca_dri;
> > > > 
> > > > +	u32 tpr10;
> > > > 
> > > >  };
> > > > 
> > > > diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> > > > index cad53f19912c..abcbd0fb9061 100644
> > > > --- a/arch/arm/mach-sunxi/Kconfig
> > > > +++ b/arch/arm/mach-sunxi/Kconfig
> > > > @@ -52,38 +52,6 @@ config DRAM_SUN50I_H616
> > > > 
> > > >  	  like H616.
> > > >  
> > > >  if DRAM_SUN50I_H616
> > > > 
> > > > -config DRAM_SUN50I_H616_WRITE_LEVELING
> > > > -	bool "H616 DRAM write leveling"
> > > > -	---help---
> > > > -	  Select this when DRAM on your H616 board needs write leveling.
> > > > -
> > > > -config DRAM_SUN50I_H616_READ_CALIBRATION
> > > > -	bool "H616 DRAM read calibration"
> > > > -	---help---
> > > > -	  Select this when DRAM on your H616 board needs read
> > 
> > calibration.
> > 
> > > > -
> > > > -config DRAM_SUN50I_H616_READ_TRAINING
> > > > -	bool "H616 DRAM read training"
> > > > -	---help---
> > > > -	  Select this when DRAM on your H616 board needs read training.
> > > > -
> > > > -config DRAM_SUN50I_H616_WRITE_TRAINING
> > > > -	bool "H616 DRAM write training"
> > > > -	---help---
> > > > -	  Select this when DRAM on your H616 board needs write training.
> > > > -
> > > > -config DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION
> > > > -	bool "H616 DRAM bit delay compensation"
> > > > -	---help---
> > > > -	  Select this when DRAM on your H616 board needs bit delay
> > > > -	  compensation.
> > > > -
> > > > -config DRAM_SUN50I_H616_UNKNOWN_FEATURE
> > > > -	bool "H616 DRAM unknown feature"
> > > > -	---help---
> > > > -	  Select this when DRAM on your H616 board needs this unknown
> > > > -	  feature.
> > > > -
> > > > 
> > > >  config DRAM_SUN50I_H616_DX_ODT
> > > >  
> > > >  	hex "H616 DRAM DX ODT parameter"
> > > >  	help
> > > > 
> > > > @@ -98,6 +66,12 @@ config DRAM_SUN50I_H616_CA_DRI
> > > > 
> > > >  	hex "H616 DRAM CA DRI parameter"
> > > >  	help
> > > >  	
> > > >  	  CA DRI value from vendor DRAM settings.
> > > > 
> > > > +
> > > > +config DRAM_SUN50I_H616_TPR10
> > > > +	hex "H616 DRAM TPR10 parameter"
> > > > +	help
> > > > +	  TPR10 value from vendor DRAM settings. It tells which features
> > > > +	  should be configured, like write leveling, read calibration, 
etc.
> > > > 
> > > >  endif
> > > >  
> > > >  config SUN6I_PRCM
> > > > 
> > > > diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > > > b/arch/arm/mach-sunxi/dram_sun50i_h616.c index
> > > > 06a07dfbf9cc..14a01a3c4e54
> > > > 100644
> > > > --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > > > +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > > > @@ -577,109 +577,112 @@ static bool
> > > > mctl_phy_bit_delay_compensation(struct
> > > > dram_para *para)>
> > > > 
> > > >  	u32 *ptr;
> > > >  	int i;
> > > > 
> > > > -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> > > > -	setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
> > > > -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
> > > > +	if (para->tpr10 & TPR10_UNKNOWN_FEAT2) {
> > > > +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> > > > +		setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
> > > > +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
> > > > 
> > > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
> > > > -	for (i = 0; i < 9; i++) {
> > > > -		writel_relaxed(0x16, ptr);
> > > > -		writel_relaxed(0x16, ptr + 0x30);
> > > > -		ptr += 2;
> > > > -	}
> > > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4d0);
> > > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x590);
> > > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
> > > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
> > > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
> > > > +		for (i = 0; i < 9; i++) {
> > > > +			writel_relaxed(0x16, ptr);
> > > > +			writel_relaxed(0x16, ptr + 0x30);
> > > > +			ptr += 2;
> > > > +		}
> > > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4d0);
> > > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x590);
> > > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
> > > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
> > > > 
> > > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
> > > > -	for (i = 0; i < 9; i++) {
> > > > -		writel_relaxed(0x1a, ptr);
> > > > -		writel_relaxed(0x1a, ptr + 0x30);
> > > > -		ptr += 2;
> > > > -	}
> > > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x524);
> > > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e4);
> > > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
> > > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
> > > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
> > > > +		for (i = 0; i < 9; i++) {
> > > > +			writel_relaxed(0x1a, ptr);
> > > > +			writel_relaxed(0x1a, ptr + 0x30);
> > > > +			ptr += 2;
> > > > +		}
> > > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x524);
> > > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e4);
> > > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
> > > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
> > > > 
> > > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
> > > > -	for (i = 0; i < 9; i++) {
> > > > -		writel_relaxed(0x1a, ptr);
> > > > -		writel_relaxed(0x1a, ptr + 0x30);
> > > > -		ptr += 2;
> > > > -	}
> > > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x650);
> > > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x710);
> > > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
> > > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
> > > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
> > > > +		for (i = 0; i < 9; i++) {
> > > > +			writel_relaxed(0x1a, ptr);
> > > > +			writel_relaxed(0x1a, ptr + 0x30);
> > > > +			ptr += 2;
> > > > +		}
> > > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x650);
> > > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x710);
> > > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
> > > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
> > > > 
> > > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
> > > > -	for (i = 0; i < 9; i++) {
> > > > -		writel_relaxed(0x1a, ptr);
> > > > -		writel_relaxed(0x1a, ptr + 0x30);
> > > > -		ptr += 2;
> > > > -	}
> > > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a4);
> > > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x764);
> > > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a0);
> > > > -	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x760);
> > > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
> > > > +		for (i = 0; i < 9; i++) {
> > > > +			writel_relaxed(0x1a, ptr);
> > > > +			writel_relaxed(0x1a, ptr + 0x30);
> > > > +			ptr += 2;
> > > > +		}
> > > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a4);
> > > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x764);
> > > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a0);
> > > > +		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x760);
> > > > 
> > > > -	dmb();
> > > > +		dmb();
> > > > 
> > > > -	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> > > > +		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
> > > > +	}
> > > > 
> > > > -	/* second part */
> > > > -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> > > > -	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
> > > > +	if (para->tpr10 & TPR10_UNKNOWN_FEAT1) {
> > > > +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> > > > +		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
> > > > 
> > > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
> > > > -	for (i = 0; i < 9; i++) {
> > > > -		writel_relaxed(0x10, ptr);
> > > > -		writel_relaxed(0x10, ptr + 0x30);
> > > > -		ptr += 2;
> > > > -	}
> > > > -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x528);
> > > > -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x5e8);
> > > > -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
> > > > -	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
> > > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
> > > > +		for (i = 0; i < 9; i++) {
> > > > +			writel_relaxed(0x10, ptr);
> > > > +			writel_relaxed(0x10, ptr + 0x30);
> > > > +			ptr += 2;
> > > > +		}
> > > > +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x528);
> > > > +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x5e8);
> > > > +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
> > > > +		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
> > > > 
> > > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
> > > > -	for (i = 0; i < 9; i++) {
> > > > -		writel_relaxed(0x12, ptr);
> > > > -		writel_relaxed(0x12, ptr + 0x30);
> > > > -		ptr += 2;
> > > > -	}
> > > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x52c);
> > > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5ec);
> > > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
> > > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
> > > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
> > > > +		for (i = 0; i < 9; i++) {
> > > > +			writel_relaxed(0x12, ptr);
> > > > +			writel_relaxed(0x12, ptr + 0x30);
> > > > +			ptr += 2;
> > > > +		}
> > > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x52c);
> > > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5ec);
> > > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
> > > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
> > > > 
> > > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
> > > > -	for (i = 0; i < 9; i++) {
> > > > -		writel_relaxed(0x12, ptr);
> > > > -		writel_relaxed(0x12, ptr + 0x30);
> > > > -		ptr += 2;
> > > > -	}
> > > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x6a8);
> > > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x768);
> > > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
> > > > -	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
> > > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
> > > > +		for (i = 0; i < 9; i++) {
> > > > +			writel_relaxed(0x12, ptr);
> > > > +			writel_relaxed(0x12, ptr + 0x30);
> > > > +			ptr += 2;
> > > > +		}
> > > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x6a8);
> > > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x768);
> > > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
> > > > +		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
> > > > 
> > > > -	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
> > > > -	for (i = 0; i < 9; i++) {
> > > > -		writel_relaxed(0x14, ptr);
> > > > -		writel_relaxed(0x14, ptr + 0x30);
> > > > -		ptr += 2;
> > > > -	}
> > > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x6ac);
> > > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x76c);
> > > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x69c);
> > > > -	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x75c);
> > > > +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
> > > > +		for (i = 0; i < 9; i++) {
> > > > +			writel_relaxed(0x14, ptr);
> > > > +			writel_relaxed(0x14, ptr + 0x30);
> > > > +			ptr += 2;
> > > > +		}
> > > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x6ac);
> > > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x76c);
> > > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x69c);
> > > > +		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x75c);
> > > > 
> > > > -	dmb();
> > > > +		dmb();
> > > > 
> > > > -	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> > > > +		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> > > > +	}
> > > > 
> > > >  	return true;
> > > >  
> > > >  }
> > > > 
> > > > @@ -718,7 +721,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > > > 
> > > >  	for (i = 0; i < ARRAY_SIZE(phy_init); i++)
> > > >  	
> > > >  		writel(phy_init[i], &ptr[i]);
> > > > 
> > > > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_UNKNOWN_FEATURE)) {
> > > > +	if (para->tpr10 & TPR10_UNKNOWN_FEAT0) {
> > > > 
> > > >  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780);
> > > >  		for (i = 0; i < 32; i++)
> > > >  		
> > > >  			writel(0x16, &ptr[i]);
> > > > 
> > > > @@ -800,7 +803,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > > > 
> > > >  	clrbits_le32(&mctl_ctl->rfshctl3, 1);
> > > >  	writel(1, &mctl_ctl->swctl);
> > > > 
> > > > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING)) {
> > > > +	if (para->tpr10 & TPR10_WRITE_LEVELING) {
> > > > 
> > > >  		for (i = 0; i < 5; i++)
> > > >  		
> > > >  			if (mctl_phy_write_leveling(para))
> > > >  			
> > > >  				break;
> > > > 
> > > > @@ -810,7 +813,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > > > 
> > > >  		}
> > > >  	
> > > >  	}
> > > > 
> > > > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION)) {
> > > > +	if (para->tpr10 & TPR10_READ_CALIBRATION) {
> > > > 
> > > >  		for (i = 0; i < 5; i++)
> > > 
> > > B>  			if (mctl_phy_read_calibration(para))
> > > 
> > > >  				break;
> > > > 
> > > > @@ -820,7 +823,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > > > 
> > > >  		}
> > > >  	
> > > >  	}
> > > > 
> > > > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_READ_TRAINING)) {
> > > > +	if (para->tpr10 & TPR10_READ_TRAINING) {
> > > > 
> > > >  		for (i = 0; i < 5; i++)
> > > >  		
> > > >  			if (mctl_phy_read_training(para))
> > > >  			
> > > >  				break;
> > > > 
> > > > @@ -830,7 +833,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > > > 
> > > >  		}
> > > >  	
> > > >  	}
> > > > 
> > > > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING)) {
> > > > +	if (para->tpr10 & TPR10_WRITE_TRAINING) {
> > > > 
> > > >  		for (i = 0; i < 5; i++)
> > > >  		
> > > >  			if (mctl_phy_write_training(para))
> > > >  			
> > > >  				break;
> > > > 
> > > > @@ -840,8 +843,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > > > 
> > > >  		}
> > > >  	
> > > >  	}
> > > > 
> > > > -	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION))
> > > > -		mctl_phy_bit_delay_compensation(para);
> > > > +	mctl_phy_bit_delay_compensation(para);
> > > > 
> > > >  	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 4);
> > > > 
> > > > @@ -1022,6 +1024,7 @@ unsigned long sunxi_dram_init(void)
> > > > 
> > > >  		.dx_odt = CONFIG_DRAM_SUN50I_H616_DX_ODT,
> > > >  		.dx_dri = CONFIG_DRAM_SUN50I_H616_DX_DRI,
> > > >  		.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
> > > > 
> > > > +		.tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
> > > > 
> > > >  	};
> > > >  	unsigned long size;
> > > > 
> > > > diff --git a/configs/orangepi_zero2_defconfig
> > > > b/configs/orangepi_zero2_defconfig index ca398faef1d3..f2024a2502c7
> > > > 100644
> > > > --- a/configs/orangepi_zero2_defconfig
> > > > +++ b/configs/orangepi_zero2_defconfig
> > > > @@ -2,13 +2,10 @@ CONFIG_ARM=y
> > > > 
> > > >  CONFIG_ARCH_SUNXI=y
> > > >  CONFIG_DEFAULT_DEVICE_TREE="sun50i-h616-orangepi-zero2"
> > > >  CONFIG_SPL=y
> > > > 
> > > > -CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING=y
> > > > -CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
> > > > -CONFIG_DRAM_SUN50I_H616_READ_TRAINING=y
> > > > -CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING=y
> > > > 
> > > >  CONFIG_DRAM_SUN50I_H616_DX_ODT=0x8080808
> > > >  CONFIG_DRAM_SUN50I_H616_DX_DRI=0xe0e0e0e
> > > >  CONFIG_DRAM_SUN50I_H616_CA_DRI=0xe0e
> > > > 
> > > > +CONFIG_DRAM_SUN50I_H616_TPR10=0xf83438
> > > > 
> > > >  CONFIG_MACH_SUN50I_H616=y
> > > >  CONFIG_MMC0_CD_PIN="PF6"
> > > >  CONFIG_R_I2C_ENABLE=y





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

* Re: [PATCH 1/8] sunxi: Fix write to H616 DRAM CR register
  2022-12-11 16:32 ` [PATCH 1/8] sunxi: Fix write to H616 DRAM CR register Jernej Skrabec
@ 2023-01-04  0:35   ` Andre Przywara
  0 siblings, 0 replies; 29+ messages in thread
From: Andre Przywara @ 2023-01-04  0:35 UTC (permalink / raw)
  To: Jernej Skrabec; +Cc: jagan, u-boot

On Sun, 11 Dec 2022 17:32:06 +0100
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:

> Vendor DRAM code actually writes to whole CR register and not just sets
> bit 31 in mctl_ctrl_init().
> 
> Just to be safe, do that here too.
> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>

Can't really verify this, but it seems to work (TM):

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

Cheers,
Andre

> ---
>  arch/arm/mach-sunxi/dram_sun50i_h616.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> index 454c845a0010..039e76224367 100644
> --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> @@ -873,7 +873,7 @@ static bool mctl_ctrl_init(struct dram_para *para)
>  	writel(0x06000400, &mctl_ctl->unk_0x3240);
>  	writel(0x06000400, &mctl_ctl->unk_0x4240);
>  
> -	setbits_le32(&mctl_com->cr, BIT(31));
> +	writel(BIT(31), &mctl_com->cr);
>  
>  	mctl_set_addrmap(para);
>  


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

* Re: [PATCH 2/8] sunxi: cosmetic: Fix H616 DRAM driver code style
  2022-12-11 16:32 ` [PATCH 2/8] sunxi: cosmetic: Fix H616 DRAM driver code style Jernej Skrabec
@ 2023-01-04  0:36   ` Andre Przywara
  0 siblings, 0 replies; 29+ messages in thread
From: Andre Przywara @ 2023-01-04  0:36 UTC (permalink / raw)
  To: Jernej Skrabec; +Cc: jagan, u-boot

On Sun, 11 Dec 2022 17:32:07 +0100
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:

Hi,

> Fix code style for pointer declaration. This is just cosmetic change to
> avoid checkpatch errors in later commits.
> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>

confirmed to be just s/(u32\*)/(u32 *)/:

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

Cheers,
Andre

> ---
>  arch/arm/mach-sunxi/dram_sun50i_h616.c | 74 +++++++++++++-------------
>  1 file changed, 37 insertions(+), 37 deletions(-)
> 
> diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> index 039e76224367..49983bf7a1b8 100644
> --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> @@ -285,7 +285,7 @@ static bool mctl_phy_write_leveling(struct dram_para *para)
>  	else
>  		val = 3;
>  
> -	mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x188), val, val);
> +	mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x188), val, val);
>  
>  	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 4);
>  
> @@ -314,7 +314,7 @@ static bool mctl_phy_write_leveling(struct dram_para *para)
>  		else
>  			val = 3;
>  
> -		mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x188), val, val);
> +		mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x188), val, val);
>  
>  		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 4);
>  	}
> @@ -398,26 +398,26 @@ static bool mctl_phy_read_training(struct dram_para *para)
>  	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 6);
>  	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 1);
>  
> -	mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc);
> +	mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc);
>  	if (readl(SUNXI_DRAM_PHY0_BASE + 0x840) & 3)
>  		result = false;
>  
>  	if (para->bus_full_width) {
> -		mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc);
> +		mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc);
>  		if (readl(SUNXI_DRAM_PHY0_BASE + 0xa40) & 3)
>  			result = false;
>  	}
>  
> -	ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x898);
> -	ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x850);
> +	ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x898);
> +	ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x850);
>  	for (i = 0; i < 9; i++) {
>  		val1 = readl(&ptr1[i]);
>  		val2 = readl(&ptr2[i]);
>  		if (val1 - val2 <= 6)
>  			result = false;
>  	}
> -	ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x8bc);
> -	ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x874);
> +	ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8bc);
> +	ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x874);
>  	for (i = 0; i < 9; i++) {
>  		val1 = readl(&ptr1[i]);
>  		val2 = readl(&ptr2[i]);
> @@ -426,8 +426,8 @@ static bool mctl_phy_read_training(struct dram_para *para)
>  	}
>  
>  	if (para->bus_full_width) {
> -		ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xa98);
> -		ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xa50);
> +		ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa98);
> +		ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa50);
>  		for (i = 0; i < 9; i++) {
>  			val1 = readl(&ptr1[i]);
>  			val2 = readl(&ptr2[i]);
> @@ -435,8 +435,8 @@ static bool mctl_phy_read_training(struct dram_para *para)
>  				result = false;
>  		}
>  
> -		ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xabc);
> -		ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xa74);
> +		ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xabc);
> +		ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa74);
>  		for (i = 0; i < 9; i++) {
>  			val1 = readl(&ptr1[i]);
>  			val2 = readl(&ptr2[i]);
> @@ -454,12 +454,12 @@ static bool mctl_phy_read_training(struct dram_para *para)
>  		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 6);
>  		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 1);
>  
> -		mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc);
> +		mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc);
>  		if (readl(SUNXI_DRAM_PHY0_BASE + 0x840) & 3)
>  			result = false;
>  
>  		if (para->bus_full_width) {
> -			mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc);
> +			mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc);
>  			if (readl(SUNXI_DRAM_PHY0_BASE + 0xa40) & 3)
>  				result = false;
>  		}
> @@ -488,26 +488,26 @@ static bool mctl_phy_write_training(struct dram_para *para)
>  	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
>  	setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x20);
>  
> -	mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3);
> +	mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3);
>  	if (readl(SUNXI_DRAM_PHY0_BASE + 0x8e0) & 0xc)
>  		result = false;
>  
>  	if (para->bus_full_width) {
> -		mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3);
> +		mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3);
>  		if (readl(SUNXI_DRAM_PHY0_BASE + 0xae0) & 0xc)
>  			result = false;
>  	}
>  
> -	ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x938);
> -	ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x8f0);
> +	ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x938);
> +	ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8f0);
>  	for (i = 0; i < 9; i++) {
>  		val1 = readl(&ptr1[i]);
>  		val2 = readl(&ptr2[i]);
>  		if (val1 - val2 <= 6)
>  			result = false;
>  	}
> -	ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x95c);
> -	ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x914);
> +	ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x95c);
> +	ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x914);
>  	for (i = 0; i < 9; i++) {
>  		val1 = readl(&ptr1[i]);
>  		val2 = readl(&ptr2[i]);
> @@ -516,16 +516,16 @@ static bool mctl_phy_write_training(struct dram_para *para)
>  	}
>  
>  	if (para->bus_full_width) {
> -		ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xb38);
> -		ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xaf0);
> +		ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb38);
> +		ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xaf0);
>  		for (i = 0; i < 9; i++) {
>  			val1 = readl(&ptr1[i]);
>  			val2 = readl(&ptr2[i]);
>  			if (val1 - val2 <= 6)
>  				result = false;
>  		}
> -		ptr1 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xb5c);
> -		ptr2 = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xb14);
> +		ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb5c);
> +		ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb14);
>  		for (i = 0; i < 9; i++) {
>  			val1 = readl(&ptr1[i]);
>  			val2 = readl(&ptr2[i]);
> @@ -542,12 +542,12 @@ static bool mctl_phy_write_training(struct dram_para *para)
>  		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
>  		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x20);
>  
> -		mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3);
> +		mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3);
>  		if (readl(SUNXI_DRAM_PHY0_BASE + 0x8e0) & 0xc)
>  			result = false;
>  
>  		if (para->bus_full_width) {
> -			mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3);
> +			mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3);
>  			if (readl(SUNXI_DRAM_PHY0_BASE + 0xae0) & 0xc)
>  				result = false;
>  		}
> @@ -569,7 +569,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
>  	setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
>  	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
>  
> -	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x484);
> +	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
>  	for (i = 0; i < 9; i++) {
>  		writel_relaxed(0x16, ptr);
>  		writel_relaxed(0x16, ptr + 0x30);
> @@ -580,7 +580,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
>  	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
>  	writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
>  
> -	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
> +	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
>  	for (i = 0; i < 9; i++) {
>  		writel_relaxed(0x1a, ptr);
>  		writel_relaxed(0x1a, ptr + 0x30);
> @@ -591,7 +591,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
>  	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
>  	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
>  
> -	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x604);
> +	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
>  	for (i = 0; i < 9; i++) {
>  		writel_relaxed(0x1a, ptr);
>  		writel_relaxed(0x1a, ptr + 0x30);
> @@ -602,7 +602,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
>  	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
>  	writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
>  
> -	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x658);
> +	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
>  	for (i = 0; i < 9; i++) {
>  		writel_relaxed(0x1a, ptr);
>  		writel_relaxed(0x1a, ptr + 0x30);
> @@ -621,7 +621,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
>  	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
>  	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
>  
> -	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x480);
> +	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
>  	for (i = 0; i < 9; i++) {
>  		writel_relaxed(0x10, ptr);
>  		writel_relaxed(0x10, ptr + 0x30);
> @@ -632,7 +632,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
>  	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
>  	writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
>  
> -	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
> +	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
>  	for (i = 0; i < 9; i++) {
>  		writel_relaxed(0x12, ptr);
>  		writel_relaxed(0x12, ptr + 0x30);
> @@ -643,7 +643,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
>  	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
>  	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
>  
> -	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x600);
> +	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
>  	for (i = 0; i < 9; i++) {
>  		writel_relaxed(0x12, ptr);
>  		writel_relaxed(0x12, ptr + 0x30);
> @@ -654,7 +654,7 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
>  	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
>  	writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
>  
> -	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x654);
> +	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
>  	for (i = 0; i < 9; i++) {
>  		writel_relaxed(0x14, ptr);
>  		writel_relaxed(0x14, ptr + 0x30);
> @@ -702,12 +702,12 @@ static bool mctl_phy_init(struct dram_para *para)
>  	writel(9, SUNXI_DRAM_PHY0_BASE + 0x370);
>  	writel(9, SUNXI_DRAM_PHY0_BASE + 0x37c);
>  
> -	ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0xc0);
> +	ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xc0);
>  	for (i = 0; i < ARRAY_SIZE(phy_init); i++)
>  		writel(phy_init[i], &ptr[i]);
>  
>  	if (IS_ENABLED(CONFIG_DRAM_SUN50I_H616_UNKNOWN_FEATURE)) {
> -		ptr = (u32*)(SUNXI_DRAM_PHY0_BASE + 0x780);
> +		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780);
>  		for (i = 0; i < 32; i++)
>  			writel(0x16, &ptr[i]);
>  		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x78c);
> @@ -738,7 +738,7 @@ static bool mctl_phy_init(struct dram_para *para)
>  
>  	clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x14c, 8);
>  
> -	mctl_await_completion((u32*)(SUNXI_DRAM_PHY0_BASE + 0x180), 4, 4);
> +	mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x180), 4, 4);
>  
>  	writel(0x37, SUNXI_DRAM_PHY0_BASE + 0x58);
>  	clrbits_le32(&mctl_com->unk_0x500, 0x200);


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

* Re: [PATCH 3/8] sunxi: parameterize H616 DRAM ODT values
  2022-12-11 16:32 ` [PATCH 3/8] sunxi: parameterize H616 DRAM ODT values Jernej Skrabec
@ 2023-01-04  0:36   ` Andre Przywara
  0 siblings, 0 replies; 29+ messages in thread
From: Andre Przywara @ 2023-01-04  0:36 UTC (permalink / raw)
  To: Jernej Skrabec; +Cc: jagan, u-boot

On Sun, 11 Dec 2022 17:32:08 +0100
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:

Hi Jernej,

> While ODT values for same memory type are similar, they are not
> necessary the same. Let's parameterize them and make parameter same as
> in vendor DRAM settings. That way it will be easy to introduce new board
> support.

checked that this results in the same parameters to writel().
One small thing below:

> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
> ---
>  .../include/asm/arch-sunxi/dram_sun50i_h616.h |  3 +
>  arch/arm/mach-sunxi/Kconfig                   | 15 +++++
>  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 59 ++++++++++++-------
>  configs/orangepi_zero2_defconfig              |  3 +
>  4 files changed, 58 insertions(+), 22 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> index 134679d55205..c9e1f84bfcdd 100644
> --- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> @@ -144,6 +144,9 @@ struct dram_para {
>  	u8 rows;
>  	u8 ranks;
>  	u8 bus_full_width;
> +	u32 dx_odt;
> +	u32 dx_dri;
> +	u32 ca_dri;
>  };
>  
>  
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index dbe6005daab1..cad53f19912c 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -83,6 +83,21 @@ config DRAM_SUN50I_H616_UNKNOWN_FEATURE
>  	---help---
>  	  Select this when DRAM on your H616 board needs this unknown
>  	  feature.
> +
> +config DRAM_SUN50I_H616_DX_ODT
> +	hex "H616 DRAM DX ODT parameter"
> +	help
> +	  DX ODT value from vendor DRAM settings.
> +
> +config DRAM_SUN50I_H616_DX_DRI
> +	hex "H616 DRAM DX DRI parameter"
> +	help
> +	  DX DRI value from vendor DRAM settings.
> +
> +config DRAM_SUN50I_H616_CA_DRI
> +	hex "H616 DRAM CA DRI parameter"
> +	help
> +	  CA DRI value from vendor DRAM settings.
>  endif
>  
>  config SUN6I_PRCM
> diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> index 49983bf7a1b8..06a07dfbf9cc 100644
> --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> @@ -234,37 +234,49 @@ static const u8 phy_init[] = {
>  	0x09, 0x05, 0x18
>  };
>  
> -static void mctl_phy_configure_odt(void)
> +static void mctl_phy_configure_odt(struct dram_para *para)
>  {
> -	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x388);
> -	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x38c);
> +	unsigned int val;
>  
> -	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x3c8);
> -	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x3cc);
> +	val = para->dx_dri & 0x1f;
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x388);
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x38c);
>  
> -	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x408);
> -	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x40c);
> +	val = (para->dx_dri >> 8) & 0x1f;
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3c8);
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3cc);
>  
> -	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x448);
> -	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x44c);
> +	val = (para->dx_dri >> 16) & 0x1f;
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x408);
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x40c);
>  
> -	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x340);
> -	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x344);
> +	val = (para->dx_dri >> 24) & 0x1f;
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x448);
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x44c);
>  
> -	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x348);
> -	writel_relaxed(0xe, SUNXI_DRAM_PHY0_BASE + 0x34c);
> +	val = para->ca_dri & 0x1f;
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x340);
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x344);
>  
> -	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x380);
> -	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x384);
> +	val = (para->ca_dri >> 8) & 0x1f;
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x348);
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x34c);
>  
> -	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x3c0);
> -	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x3c4);
> +	val = para->dx_odt & 0x1f;
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x380);
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x384);
>  
> -	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x400);
> -	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x404);
> +	val = (para->dx_odt >> 8) & 0x1f;
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3c0);
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3c4);
>  
> -	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x440);
> -	writel_relaxed(0x8, SUNXI_DRAM_PHY0_BASE + 0x444);
> +	val = (para->dx_odt >> 16) & 0x1f;
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x400);
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x404);
> +
> +	val = (para->dx_odt >> 24) & 0x1f;
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x440);
> +	writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x444);
>  
>  	dmb();
>  }
> @@ -722,7 +734,7 @@ static bool mctl_phy_init(struct dram_para *para)
>  	writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x45c);
>  
>  	if (IS_ENABLED(CONFIG_DRAM_ODT_EN))
> -		mctl_phy_configure_odt();
> +		mctl_phy_configure_odt(para);
>  
>  	clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 7, 0xa);
>  
> @@ -1007,6 +1019,9 @@ unsigned long sunxi_dram_init(void)
>  	struct dram_para para = {
>  		.clk = CONFIG_DRAM_CLK,
>  		.type = SUNXI_DRAM_TYPE_DDR3,
> +		.dx_odt = CONFIG_DRAM_SUN50I_H616_DX_ODT,
> +		.dx_dri = CONFIG_DRAM_SUN50I_H616_DX_DRI,
> +		.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
>  	};
>  	unsigned long size;
>  
> diff --git a/configs/orangepi_zero2_defconfig b/configs/orangepi_zero2_defconfig
> index 877eccf31bd6..ca398faef1d3 100644
> --- a/configs/orangepi_zero2_defconfig
> +++ b/configs/orangepi_zero2_defconfig
> @@ -6,6 +6,9 @@ CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING=y
>  CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
>  CONFIG_DRAM_SUN50I_H616_READ_TRAINING=y
>  CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING=y
> +CONFIG_DRAM_SUN50I_H616_DX_ODT=0x8080808
> +CONFIG_DRAM_SUN50I_H616_DX_DRI=0xe0e0e0e
> +CONFIG_DRAM_SUN50I_H616_CA_DRI=0xe0e

Can you make those values 8 nibbles and 4 nibbles long (so starting
with a 0)? It's somewhat confusing to read like this, it *looks* like a
32-bit value, but it's actually only 28 bits wide. This gets confusing
when matching up values against dumps or a hex editor.

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

Cheers,
Andre

>  CONFIG_MACH_SUN50I_H616=y
>  CONFIG_MMC0_CD_PIN="PF6"
>  CONFIG_R_I2C_ENABLE=y


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

* Re: [PATCH 5/8] sunxi: Always configure ODT on H616 DRAM
  2022-12-11 16:32 ` [PATCH 5/8] sunxi: Always configure ODT on H616 DRAM Jernej Skrabec
@ 2023-01-04  0:37   ` Andre Przywara
  2023-01-04 21:12     ` Jernej Škrabec
  0 siblings, 1 reply; 29+ messages in thread
From: Andre Przywara @ 2023-01-04  0:37 UTC (permalink / raw)
  To: Jernej Skrabec; +Cc: jagan, u-boot

On Sun, 11 Dec 2022 17:32:10 +0100
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:

> Vendor H616 DRAM code always configure part which we call ODT
> configuration. Let's reflect that here too.

I wonder if we need this patch at all. "depends on !H616" looks
counter-intuitive, since this suggests it's always off.
As it stands, it doesn't hurt. "default y" does the right thing, and if
people want to shoot themselves in the foot: fine by me.

At least I would like to keep the Kconfig part. We could change the
condition in the code into an explaining comment, if you still want to
force this on.

And coming back from patch 7/8: how does this correspond to
DRAM_SUN50I_H616_ODT_EN?

Cheers,
Andre

> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
> ---
>  arch/arm/mach-sunxi/Kconfig            | 2 +-
>  arch/arm/mach-sunxi/dram_sun50i_h616.c | 3 +--
>  2 files changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index abcbd0fb9061..778304b77e26 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -488,12 +488,12 @@ config DRAM_ZQ
>  
>  config DRAM_ODT_EN
>  	bool "sunxi dram odt enable"
> +	depends on !MACH_SUN50I_H616
>  	default y if MACH_SUN8I_A23
>  	default y if MACH_SUNXI_H3_H5
>  	default y if MACH_SUN8I_R40
>  	default y if MACH_SUN50I
>  	default y if MACH_SUN50I_H6
> -	default y if MACH_SUN50I_H616
>  	---help---
>  	Select this to enable dram odt (on die termination).
>  
> diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> index 14a01a3c4e54..bf5b4ddfb5c2 100644
> --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> @@ -736,8 +736,7 @@ static bool mctl_phy_init(struct dram_para *para)
>  	writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x3dc);
>  	writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x45c);
>  
> -	if (IS_ENABLED(CONFIG_DRAM_ODT_EN))
> -		mctl_phy_configure_odt(para);
> +	mctl_phy_configure_odt(para);
>  
>  	clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 7, 0xa);
>  


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

* Re: [PATCH 6/8] sunxi: Make bit delay function in H616 DRAM code void
  2022-12-11 16:32 ` [PATCH 6/8] sunxi: Make bit delay function in H616 DRAM code void Jernej Skrabec
@ 2023-01-04  0:37   ` Andre Przywara
  0 siblings, 0 replies; 29+ messages in thread
From: Andre Przywara @ 2023-01-04  0:37 UTC (permalink / raw)
  To: Jernej Skrabec; +Cc: jagan, u-boot

On Sun, 11 Dec 2022 17:32:11 +0100
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:

> Mentioned function result is always true and result isn't checked
> anyway. Let's make it void.
> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>

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

Cheers,
Andre

> ---
>  arch/arm/mach-sunxi/dram_sun50i_h616.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> index bf5b4ddfb5c2..3b2ba168498c 100644
> --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> @@ -572,7 +572,7 @@ static bool mctl_phy_write_training(struct dram_para *para)
>  	return result;
>  }
>  
> -static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
> +static void mctl_phy_bit_delay_compensation(struct dram_para *para)
>  {
>  	u32 *ptr;
>  	int i;
> @@ -683,8 +683,6 @@ static bool mctl_phy_bit_delay_compensation(struct dram_para *para)
>  
>  		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
>  	}
> -
> -	return true;
>  }
>  
>  static bool mctl_phy_init(struct dram_para *para)


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

* Re: [PATCH 7/8] sunxi: Parameterize bit delay code in H616 DRAM driver
  2022-12-11 16:32 ` [PATCH 7/8] sunxi: Parameterize bit delay code in H616 DRAM driver Jernej Skrabec
@ 2023-01-04  0:37   ` Andre Przywara
  2023-01-04 21:28     ` Jernej Škrabec
  0 siblings, 1 reply; 29+ messages in thread
From: Andre Przywara @ 2023-01-04  0:37 UTC (permalink / raw)
  To: Jernej Skrabec; +Cc: jagan, u-boot

On Sun, 11 Dec 2022 17:32:12 +0100
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:

Hi Jernej,

> These values are highly board specific and thus make sense to add
> parameter for them. To ease adding support for new boards, let's make
> them same as in vendor DRAM settings.

So scrolling up and down: does this patch miss the TPR11 and TPR12
values in the OPi-Zero2 defconfig? And should we not default to 0 in
Kconfig to help spotting this omission more easily for new boards?
If I pieced the bits together correctly, we end up with the same values
in the register with TPR11=0xfffedddb and TPR12=0xeddca998, and ODT_EN
being irrelevant.

> Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
> ---
>  .../include/asm/arch-sunxi/dram_sun50i_h616.h |   4 +
>  arch/arm/mach-sunxi/Kconfig                   |  18 ++
>  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 189 +++++++++++++-----
>  3 files changed, 162 insertions(+), 49 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> index b5140c79b70e..c7890c83391f 100644
> --- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> @@ -145,6 +145,7 @@ check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240);
>  #define TPR10_READ_CALIBRATION	BIT(21)
>  #define TPR10_READ_TRAINING	BIT(22)
>  #define TPR10_WRITE_TRAINING	BIT(23)
> +#define TPR10_UNKNOWN_FEAT3	BIT(30)

As mentioned in the other patch: if we don't know the meaning of this
bit, I'd prefer using BIT(30) directly, or at least encode BIT30
in the name.

>  
>  struct dram_para {
>  	u32 clk;
> @@ -156,7 +157,10 @@ struct dram_para {
>  	u32 dx_odt;
>  	u32 dx_dri;
>  	u32 ca_dri;
> +	u32 odt_en;
>  	u32 tpr10;
> +	u32 tpr11;
> +	u32 tpr12;
>  };
>  
>  
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index 778304b77e26..b050f0a56971 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -67,11 +67,29 @@ config DRAM_SUN50I_H616_CA_DRI
>  	help
>  	  CA DRI value from vendor DRAM settings.
>  
> +config DRAM_SUN50I_H616_ODT_EN
> +	hex "H616 DRAM ODT EN parameter"
> +	default 0x1
> +	help
> +	  ODT EN value from vendor DRAM settings.
> +
>  config DRAM_SUN50I_H616_TPR10
>  	hex "H616 DRAM TPR10 parameter"
>  	help
>  	  TPR10 value from vendor DRAM settings. It tells which features
>  	  should be configured, like write leveling, read calibration, etc.
> +
> +config DRAM_SUN50I_H616_TPR11
> +	hex "H616 DRAM TPR11 parameter"
> +	default 0x0
> +	help
> +	  TPR11 value from vendor DRAM settings.
> +
> +config DRAM_SUN50I_H616_TPR12
> +	hex "H616 DRAM TPR12 parameter"
> +	default 0x0
> +	help
> +	  TPR12 value from vendor DRAM settings.
>  endif
>  
>  config SUN6I_PRCM
> diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> index 3b2ba168498c..df06cea42464 100644
> --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> @@ -574,7 +574,7 @@ static bool mctl_phy_write_training(struct dram_para *para)
>  
>  static void mctl_phy_bit_delay_compensation(struct dram_para *para)
>  {
> -	u32 *ptr;
> +	u32 *ptr, val;
>  	int i;
>  
>  	if (para->tpr10 & TPR10_UNKNOWN_FEAT2) {
> @@ -582,49 +582,93 @@ static void mctl_phy_bit_delay_compensation(struct dram_para *para)
>  		setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
>  		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
>  
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = para->tpr11 & 0x3f;
> +		else
> +			val = (para->tpr11 & 0xf) << 1;
> +
>  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
>  		for (i = 0; i < 9; i++) {
> -			writel_relaxed(0x16, ptr);
> -			writel_relaxed(0x16, ptr + 0x30);
> +			writel_relaxed(val, ptr);
> +			writel_relaxed(val, ptr + 0x30);
>  			ptr += 2;
>  		}
> -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4d0);
> -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x590);
> -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
> -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
> +
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = (para->odt_en >> 15) & 0x1e;

So I guess odt_en stands for "ODT enable". Looking at the D1 DRAM
driver, they have a boot0 parameter odt_en which is either 0x0 or 0x1,
so it looks like a boolean value. This seems to be also the case here?
In the D1 driver, this seems to gate the ZQ value being used, which
provides the actual timing values.
So is TPR10_UNKNOWN_FEAT3 actually this ODT_EN switch, and the variable
containing the timing bits should be zq_value or CONFIG_DRAM_ZQ?

> +		else
> +			val = (para->tpr11 >> 15) & 0x1e;

So I am wondering if it's less confusing to mask first, then shift?
Granted, this here is shift from [19:16] into [5:1], so it's not easy
either way, but I think it's easier to match the mask with the provided
TPR11 value.

> +
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x4d0);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x590);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x4cc);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x58c);
> +
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = (para->tpr11 >> 8) & 0x3f;
> +		else
> +			val = (para->tpr11 >> 3) & 0x1e;
>  
>  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
>  		for (i = 0; i < 9; i++) {
> -			writel_relaxed(0x1a, ptr);
> -			writel_relaxed(0x1a, ptr + 0x30);
> +			writel_relaxed(val, ptr);
> +			writel_relaxed(val, ptr + 0x30);
>  			ptr += 2;
>  		}
> -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x524);
> -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e4);
> -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
> -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
> +
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = (para->odt_en >> 19) & 0x1e;

Is this really odt_en as a base, while *most* of the other bits use
TPR11 as well? Just asking, since it doesn't fit into my naive pattern
matching ;-)

The rest looks correct (minus the repeat of the above mentioned
issues), I compared the register offsets between - and +.

Cheers,
Andre

> +		else
> +			val = (para->tpr11 >> 19) & 0x1e;
> +
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x524);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5e4);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x520);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5e0);
> +
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = (para->tpr11 >> 16) & 0x3f;
> +		else
> +			val = (para->tpr11 >> 7) & 0x1e;
>  
>  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
>  		for (i = 0; i < 9; i++) {
> -			writel_relaxed(0x1a, ptr);
> -			writel_relaxed(0x1a, ptr + 0x30);
> +			writel_relaxed(val, ptr);
> +			writel_relaxed(val, ptr + 0x30);
>  			ptr += 2;
>  		}
> -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x650);
> -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x710);
> -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
> -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
> +
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = (para->odt_en >> 23) & 0x1e;
> +		else
> +			val = (para->tpr11 >> 23) & 0x1e;
> +
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x650);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x710);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x64c);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x70c);
> +
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = (para->tpr11 >> 24) & 0x3f;
> +		else
> +			val = (para->tpr11 >> 11) & 0x1e;
>  
>  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
>  		for (i = 0; i < 9; i++) {
> -			writel_relaxed(0x1a, ptr);
> -			writel_relaxed(0x1a, ptr + 0x30);
> +			writel_relaxed(val, ptr);
> +			writel_relaxed(val, ptr + 0x30);
>  			ptr += 2;
>  		}
> -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a4);
> -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x764);
> -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a0);
> -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x760);
> +
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = (para->odt_en >> 27) & 0x1e;
> +		else
> +			val = (para->tpr11 >> 27) & 0x1e;
> +
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6a4);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x764);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6a0);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x760);
>  
>  		dmb();
>  
> @@ -635,49 +679,93 @@ static void mctl_phy_bit_delay_compensation(struct dram_para *para)
>  		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
>  		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
>  
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = para->tpr12 & 0x3f;
> +		else
> +			val = (para->tpr12 & 0xf) << 1;
> +
>  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
>  		for (i = 0; i < 9; i++) {
> -			writel_relaxed(0x10, ptr);
> -			writel_relaxed(0x10, ptr + 0x30);
> +			writel_relaxed(val, ptr);
> +			writel_relaxed(val, ptr + 0x30);
>  			ptr += 2;
>  		}
> -		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x528);
> -		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x5e8);
> -		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
> -		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
> +
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = (para->odt_en << 1) & 0x1e;
> +		else
> +			val = (para->tpr12 >> 15) & 0x1e;
> +
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x528);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5e8);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x4c8);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x588);
> +
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = (para->tpr12 >> 8) & 0x3f;
> +		else
> +			val = (para->tpr12 >> 3) & 0x1e;
>  
>  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
>  		for (i = 0; i < 9; i++) {
> -			writel_relaxed(0x12, ptr);
> -			writel_relaxed(0x12, ptr + 0x30);
> +			writel_relaxed(val, ptr);
> +			writel_relaxed(val, ptr + 0x30);
>  			ptr += 2;
>  		}
> -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x52c);
> -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5ec);
> -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
> -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
> +
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = (para->odt_en >> 3) & 0x1e;
> +		else
> +			val = (para->tpr12 >> 19) & 0x1e;
> +
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x52c);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5ec);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x51c);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5dc);
> +
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = (para->tpr12 >> 16) & 0x3f;
> +		else
> +			val = (para->tpr12 >> 7) & 0x1e;
>  
>  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
>  		for (i = 0; i < 9; i++) {
> -			writel_relaxed(0x12, ptr);
> -			writel_relaxed(0x12, ptr + 0x30);
> +			writel_relaxed(val, ptr);
> +			writel_relaxed(val, ptr + 0x30);
>  			ptr += 2;
>  		}
> -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x6a8);
> -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x768);
> -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
> -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
> +
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = (para->odt_en >> 7) & 0x1e;
> +		else
> +			val = (para->tpr12 >> 23) & 0x1e;
> +
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6a8);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x768);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x648);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x708);
> +
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = (para->tpr12 >> 24) & 0x3f;
> +		else
> +			val = (para->tpr12 >> 11) & 0x1e;
>  
>  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
>  		for (i = 0; i < 9; i++) {
> -			writel_relaxed(0x14, ptr);
> -			writel_relaxed(0x14, ptr + 0x30);
> +			writel_relaxed(val, ptr);
> +			writel_relaxed(val, ptr + 0x30);
>  			ptr += 2;
>  		}
> -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x6ac);
> -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x76c);
> -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x69c);
> -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x75c);
> +
> +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> +			val = (para->odt_en >> 11) & 0x1e;
> +		else
> +			val = (para->tpr12 >> 27) & 0x1e;
> +
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6ac);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x76c);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x69c);
> +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x75c);
>  
>  		dmb();
>  
> @@ -1021,7 +1109,10 @@ unsigned long sunxi_dram_init(void)
>  		.dx_odt = CONFIG_DRAM_SUN50I_H616_DX_ODT,
>  		.dx_dri = CONFIG_DRAM_SUN50I_H616_DX_DRI,
>  		.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
> +		.odt_en = CONFIG_DRAM_SUN50I_H616_ODT_EN,
>  		.tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
> +		.tpr11 = CONFIG_DRAM_SUN50I_H616_TPR11,
> +		.tpr12 = CONFIG_DRAM_SUN50I_H616_TPR12,
>  	};
>  	unsigned long size;
>  


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

* Re: [PATCH 8/8] sunxi: Parameterize H616 DRAM code some more
  2022-12-11 16:32 ` [PATCH 8/8] sunxi: Parameterize H616 DRAM code some more Jernej Skrabec
  2022-12-11 18:33   ` Jernej Škrabec
@ 2023-01-04  0:38   ` Andre Przywara
  2023-01-04 21:30     ` Jernej Škrabec
  1 sibling, 1 reply; 29+ messages in thread
From: Andre Przywara @ 2023-01-04  0:38 UTC (permalink / raw)
  To: Jernej Skrabec; +Cc: jagan, u-boot

On Sun, 11 Dec 2022 17:32:13 +0100
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:

> Part of the code, previously known as "unknown feature" also doesn't
> have constant values. They are derived from TPR0 parameter in vendor
> DRAM code. Introduce that parameter here too, to ease adding new boards.

That seems to also miss the value for the OPi Zero2 defconfig.

> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
> ---
>  .../include/asm/arch-sunxi/dram_sun50i_h616.h |  1 +
>  arch/arm/mach-sunxi/Kconfig                   |  6 ++++
>  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 35 +++++++++++++++----
>  3 files changed, 35 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> index c7890c83391f..ff736bd88d10 100644
> --- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> @@ -158,6 +158,7 @@ struct dram_para {
>  	u32 dx_dri;
>  	u32 ca_dri;
>  	u32 odt_en;
> +	u32 tpr0;
>  	u32 tpr10;
>  	u32 tpr11;
>  	u32 tpr12;
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index b050f0a56971..7858a7045f7e 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -73,6 +73,12 @@ config DRAM_SUN50I_H616_ODT_EN
>  	help
>  	  ODT EN value from vendor DRAM settings.
>  
> +config DRAM_SUN50I_H616_TPR0
> +	hex "H616 DRAM TPR0 parameter"
> +	default 0x0

Is 0x0 really a feasible default value? I'd suggest we don't provide a
default, so force people to be prompted for a value, if nothing is in
(a new board's) defconfig.

The rest looks OK, though I can't really comment on the actual bits -
but who can anyway ;-)

Cheers,
Andre


> +	help
> +	  TPR0 value from vendor DRAM settings.
> +
>  config DRAM_SUN50I_H616_TPR10
>  	hex "H616 DRAM TPR10 parameter"
>  	help
> diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> index df06cea42464..6d8f8d371bfe 100644
> --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> @@ -808,15 +808,35 @@ static bool mctl_phy_init(struct dram_para *para)
>  		writel(phy_init[i], &ptr[i]);
>  
>  	if (para->tpr10 & TPR10_UNKNOWN_FEAT0) {
> +		if (para->tpr0 & BIT(30))
> +			val = (para->tpr0 >> 7) & 0x3e;
> +		else
> +			val = (para->tpr10 >> 3) & 0x1e;
> +
>  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780);
>  		for (i = 0; i < 32; i++)
> -			writel(0x16, &ptr[i]);
> -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x78c);
> -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7a4);
> -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7b8);
> -		writel(0x8, SUNXI_DRAM_PHY0_BASE + 0x7d4);
> -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7dc);
> -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7e0);
> +			writel(val, &ptr[i]);
> +
> +		val = (para->tpr10 << 1) & 0x1e;
> +		writel(val, SUNXI_DRAM_PHY0_BASE + 0x7dc);
> +		writel(val, SUNXI_DRAM_PHY0_BASE + 0x7e0);
> +
> +		/* following configuration is DDR3 specific */
> +		val = (para->tpr10 >> 7) & 0x1e;
> +		writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d4);
> +		/*
> +		 * TODO: Offsets 0x79c, 0x794 and 0x7e4 may need
> +		 * to be set here. However, this doesn't seem to
> +		 * be needed by any board seen in the wild for now.
> +		 * It's not implemented because it would unnecessarily
> +		 * introduce PARA2 and TPR2 options.
> +		 */
> +		if (para->tpr0 & BIT(31)) {
> +			val = (para->tpr0 << 1) & 0x3e;
> +			writel(val, SUNXI_DRAM_PHY0_BASE + 0x78c);
> +			writel(val, SUNXI_DRAM_PHY0_BASE + 0x7a4);
> +			writel(val, SUNXI_DRAM_PHY0_BASE + 0x7b8);
> +		}
>  	}
>  
>  	writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x3dc);
> @@ -1110,6 +1130,7 @@ unsigned long sunxi_dram_init(void)
>  		.dx_dri = CONFIG_DRAM_SUN50I_H616_DX_DRI,
>  		.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
>  		.odt_en = CONFIG_DRAM_SUN50I_H616_ODT_EN,
> +		.tpr0 = CONFIG_DRAM_SUN50I_H616_TPR0,
>  		.tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
>  		.tpr11 = CONFIG_DRAM_SUN50I_H616_TPR11,
>  		.tpr12 = CONFIG_DRAM_SUN50I_H616_TPR12,


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

* Re: [PATCH 0/8] sunxi: Update H616 DRAM driver
  2022-12-11 16:32 [PATCH 0/8] sunxi: Update H616 DRAM driver Jernej Skrabec
                   ` (8 preceding siblings ...)
  2022-12-12  1:04 ` [PATCH 0/8] sunxi: Update H616 DRAM driver Andre Przywara
@ 2023-01-04  0:47 ` Andre Przywara
  2023-01-04 21:02   ` Jernej Škrabec
  9 siblings, 1 reply; 29+ messages in thread
From: Andre Przywara @ 2023-01-04  0:47 UTC (permalink / raw)
  To: Jernej Skrabec; +Cc: jagan, u-boot

On Sun, 11 Dec 2022 17:32:05 +0100
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:

Hi Jernej,

> Current H616 DRAM driver is completely customized to Orange Pi Zero2
> board, which is currently the only H616 board supported by U-Boot.
> Needless to say, this is not ideal for adding new boards. With changes
> in this series, all DDR3 boards are supported and all that is needed is
> just vendor DRAM values extracted from Android image. New DRAM types
> should also be easier to support, since a lot of constants used before
> are not really DRAM type dependent.
> 
> Changes were verified by decompiling driver and generated values were
> compared to previous, hard coded ones. This was done without dram_para
> structures, so compiler was able to heavily optimize code and produce
> constants.

so many thanks again for putting this together!
I came to like (the idea of) this series very much lately, as this
removes timing/delay values from the code, and easily allows putting the
vendor provided values in the defconfig.
I used that approach as well for the D1 driver, and am wondering if we
should extend this to other SoCs, potentially unifying the Kconfig part?

And you hinted at a v2, can you provide an estimate for this? If you
send it still this week, I would like to put it into U-Boot's next
branch, otherwise it goes straight into master, should the merge window
open next week as planned.

Btw., to verify the feasibility of drivers/ram/sunxi, I moved the H616
driver into there, together with the Kconfig parts, I wonder what you
think about this? An example of how this looks is in the D1 driver
patches.

Cheers,
Andre

> 
> Please take a look.
> 
> Best regards,
> Jernej
> 
> Jernej Skrabec (8):
>   sunxi: Fix write to H616 DRAM CR register
>   sunxi: cosmetic: Fix H616 DRAM driver code style
>   sunxi: parameterize H616 DRAM ODT values
>   sunxi: Convert H616 DRAM options to single setting
>   sunxi: Always configure ODT on H616 DRAM
>   sunxi: Make bit delay function in H616 DRAM code void
>   sunxi: Parameterize bit delay code in H616 DRAM driver
>   sunxi: Parameterize H616 DRAM code some more
> 
>  .../include/asm/arch-sunxi/dram_sun50i_h616.h |  18 +
>  arch/arm/mach-sunxi/Kconfig                   |  67 +--
>  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 445 +++++++++++-------
>  configs/orangepi_zero2_defconfig              |   8 +-
>  4 files changed, 348 insertions(+), 190 deletions(-)
> 


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

* Re: [PATCH 0/8] sunxi: Update H616 DRAM driver
  2023-01-04  0:47 ` Andre Przywara
@ 2023-01-04 21:02   ` Jernej Škrabec
  2023-01-04 23:21     ` Andre Przywara
  0 siblings, 1 reply; 29+ messages in thread
From: Jernej Škrabec @ 2023-01-04 21:02 UTC (permalink / raw)
  To: Andre Przywara; +Cc: jagan, u-boot

Hi Andre!

Dne sreda, 04. januar 2023 ob 01:47:16 CET je Andre Przywara napisal(a):
> On Sun, 11 Dec 2022 17:32:05 +0100
> Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
> 
> Hi Jernej,
> 
> > Current H616 DRAM driver is completely customized to Orange Pi Zero2
> > board, which is currently the only H616 board supported by U-Boot.
> > Needless to say, this is not ideal for adding new boards. With changes
> > in this series, all DDR3 boards are supported and all that is needed is
> > just vendor DRAM values extracted from Android image. New DRAM types
> > should also be easier to support, since a lot of constants used before
> > are not really DRAM type dependent.
> > 
> > Changes were verified by decompiling driver and generated values were
> > compared to previous, hard coded ones. This was done without dram_para
> > structures, so compiler was able to heavily optimize code and produce
> > constants.
> 
> so many thanks again for putting this together!
> I came to like (the idea of) this series very much lately, as this
> removes timing/delay values from the code, and easily allows putting the
> vendor provided values in the defconfig.
> I used that approach as well for the D1 driver, and am wondering if we
> should extend this to other SoCs, potentially unifying the Kconfig part?

While it would be nice, I'm not sure it's worth the effort and there is a 
chance that something might break during rework.

> 
> And you hinted at a v2, can you provide an estimate for this? If you
> send it still this week, I would like to put it into U-Boot's next
> branch, otherwise it goes straight into master, should the merge window
> open next week as planned.

I have changes for v2 in my github repo. I don't have any estimation, since I 
had some time off from programming lately and I'm just only catching up. 
Weekend at earliest, but no promises.

> 
> Btw., to verify the feasibility of drivers/ram/sunxi, I moved the H616
> driver into there, together with the Kconfig parts, I wonder what you
> think about this? An example of how this looks is in the D1 driver
> patches.

Looks good, but I don't know what are implications regarding interface. Is 
just code move or that implies that some ram framework must be used?

Best regards,
Jernej

> 
> Cheers,
> Andre
> 
> > Please take a look.
> > 
> > Best regards,
> > Jernej
> > 
> > Jernej Skrabec (8):
> >   sunxi: Fix write to H616 DRAM CR register
> >   sunxi: cosmetic: Fix H616 DRAM driver code style
> >   sunxi: parameterize H616 DRAM ODT values
> >   sunxi: Convert H616 DRAM options to single setting
> >   sunxi: Always configure ODT on H616 DRAM
> >   sunxi: Make bit delay function in H616 DRAM code void
> >   sunxi: Parameterize bit delay code in H616 DRAM driver
> >   sunxi: Parameterize H616 DRAM code some more
> >  
> >  .../include/asm/arch-sunxi/dram_sun50i_h616.h |  18 +
> >  arch/arm/mach-sunxi/Kconfig                   |  67 +--
> >  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 445 +++++++++++-------
> >  configs/orangepi_zero2_defconfig              |   8 +-
> >  4 files changed, 348 insertions(+), 190 deletions(-)





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

* Re: [PATCH 5/8] sunxi: Always configure ODT on H616 DRAM
  2023-01-04  0:37   ` Andre Przywara
@ 2023-01-04 21:12     ` Jernej Škrabec
  0 siblings, 0 replies; 29+ messages in thread
From: Jernej Škrabec @ 2023-01-04 21:12 UTC (permalink / raw)
  To: Andre Przywara; +Cc: jagan, u-boot

Dne sreda, 04. januar 2023 ob 01:37:17 CET je Andre Przywara napisal(a):
> On Sun, 11 Dec 2022 17:32:10 +0100
> 
> Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
> > Vendor H616 DRAM code always configure part which we call ODT
> > configuration. Let's reflect that here too.
> 
> I wonder if we need this patch at all. "depends on !H616" looks
> counter-intuitive, since this suggests it's always off.

I don't see it that way. It just means it's unused for H616.

> As it stands, it doesn't hurt. "default y" does the right thing, and if
> people want to shoot themselves in the foot: fine by me.
> 
> At least I would like to keep the Kconfig part. We could change the
> condition in the code into an explaining comment, if you still want to
> force this on.
> 
> And coming back from patch 7/8: how does this correspond to
> DRAM_SUN50I_H616_ODT_EN?

The thing is that I can't give you good explanation for anything above due to 
nature of reverse engineering. It's just how vendor code is done and I would 
argue that my original assumption when I was writing this driver was wrong and 
I shouldn't use this symbol at all in first place. I'm not even sure if I named 
mctl_phy_configure_odt() completely correct. It has to do something with ODT, 
but I don't know if it gets enabled here or not. To me, it looks more like 
that just some parameters are set here.

Best regards,
Jernej

> 
> Cheers,
> Andre
> 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
> > ---
> > 
> >  arch/arm/mach-sunxi/Kconfig            | 2 +-
> >  arch/arm/mach-sunxi/dram_sun50i_h616.c | 3 +--
> >  2 files changed, 2 insertions(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> > index abcbd0fb9061..778304b77e26 100644
> > --- a/arch/arm/mach-sunxi/Kconfig
> > +++ b/arch/arm/mach-sunxi/Kconfig
> > @@ -488,12 +488,12 @@ config DRAM_ZQ
> > 
> >  config DRAM_ODT_EN
> >  
> >  	bool "sunxi dram odt enable"
> > 
> > +	depends on !MACH_SUN50I_H616
> > 
> >  	default y if MACH_SUN8I_A23
> >  	default y if MACH_SUNXI_H3_H5
> >  	default y if MACH_SUN8I_R40
> >  	default y if MACH_SUN50I
> >  	default y if MACH_SUN50I_H6
> > 
> > -	default y if MACH_SUN50I_H616
> > 
> >  	---help---
> >  	Select this to enable dram odt (on die termination).
> > 
> > diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > b/arch/arm/mach-sunxi/dram_sun50i_h616.c index 14a01a3c4e54..bf5b4ddfb5c2
> > 100644
> > --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > @@ -736,8 +736,7 @@ static bool mctl_phy_init(struct dram_para *para)
> > 
> >  	writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x3dc);
> >  	writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x45c);
> > 
> > -	if (IS_ENABLED(CONFIG_DRAM_ODT_EN))
> > -		mctl_phy_configure_odt(para);
> > +	mctl_phy_configure_odt(para);
> > 
> >  	clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 7, 0xa);





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

* Re: [PATCH 7/8] sunxi: Parameterize bit delay code in H616 DRAM driver
  2023-01-04  0:37   ` Andre Przywara
@ 2023-01-04 21:28     ` Jernej Škrabec
  0 siblings, 0 replies; 29+ messages in thread
From: Jernej Škrabec @ 2023-01-04 21:28 UTC (permalink / raw)
  To: Andre Przywara; +Cc: jagan, u-boot

Dne sreda, 04. januar 2023 ob 01:37:47 CET je Andre Przywara napisal(a):
> On Sun, 11 Dec 2022 17:32:12 +0100
> Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
> 
> Hi Jernej,
> 
> > These values are highly board specific and thus make sense to add
> > parameter for them. To ease adding support for new boards, let's make
> > them same as in vendor DRAM settings.
> 
> So scrolling up and down: does this patch miss the TPR11 and TPR12
> values in the OPi-Zero2 defconfig? 

No, because 0 (which is default) is correct here.

> And should we not default to 0 in
> Kconfig to help spotting this omission more easily for new boards?

Not all boards need to set all the values. I set default values for symbols 
which seem to have same value for multiple boards.

> If I pieced the bits together correctly, we end up with the same values
> in the register with TPR11=0xfffedddb and TPR12=0xeddca998, and ODT_EN
> being irrelevant.
> 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
> > ---
> > 
> >  .../include/asm/arch-sunxi/dram_sun50i_h616.h |   4 +
> >  arch/arm/mach-sunxi/Kconfig                   |  18 ++
> >  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 189 +++++++++++++-----
> >  3 files changed, 162 insertions(+), 49 deletions(-)
> > 
> > diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h index
> > b5140c79b70e..c7890c83391f 100644
> > --- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > @@ -145,6 +145,7 @@ check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240);
> > 
> >  #define TPR10_READ_CALIBRATION	BIT(21)
> >  #define TPR10_READ_TRAINING	BIT(22)
> >  #define TPR10_WRITE_TRAINING	BIT(23)
> > 
> > +#define TPR10_UNKNOWN_FEAT3	BIT(30)
> 
> As mentioned in the other patch: if we don't know the meaning of this
> bit, I'd prefer using BIT(30) directly, or at least encode BIT30
> in the name.
> 
> >  struct dram_para {
> >  
> >  	u32 clk;
> > 
> > @@ -156,7 +157,10 @@ struct dram_para {
> > 
> >  	u32 dx_odt;
> >  	u32 dx_dri;
> >  	u32 ca_dri;
> > 
> > +	u32 odt_en;
> > 
> >  	u32 tpr10;
> > 
> > +	u32 tpr11;
> > +	u32 tpr12;
> > 
> >  };
> > 
> > diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> > index 778304b77e26..b050f0a56971 100644
> > --- a/arch/arm/mach-sunxi/Kconfig
> > +++ b/arch/arm/mach-sunxi/Kconfig
> > @@ -67,11 +67,29 @@ config DRAM_SUN50I_H616_CA_DRI
> > 
> >  	help
> >  	
> >  	  CA DRI value from vendor DRAM settings.
> > 
> > +config DRAM_SUN50I_H616_ODT_EN
> > +	hex "H616 DRAM ODT EN parameter"
> > +	default 0x1
> > +	help
> > +	  ODT EN value from vendor DRAM settings.
> > +
> > 
> >  config DRAM_SUN50I_H616_TPR10
> >  
> >  	hex "H616 DRAM TPR10 parameter"
> >  	help
> >  	
> >  	  TPR10 value from vendor DRAM settings. It tells which features
> >  	  should be configured, like write leveling, read calibration, 
etc.
> > 
> > +
> > +config DRAM_SUN50I_H616_TPR11
> > +	hex "H616 DRAM TPR11 parameter"
> > +	default 0x0
> > +	help
> > +	  TPR11 value from vendor DRAM settings.
> > +
> > +config DRAM_SUN50I_H616_TPR12
> > +	hex "H616 DRAM TPR12 parameter"
> > +	default 0x0
> > +	help
> > +	  TPR12 value from vendor DRAM settings.
> > 
> >  endif
> >  
> >  config SUN6I_PRCM
> > 
> > diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > b/arch/arm/mach-sunxi/dram_sun50i_h616.c index 3b2ba168498c..df06cea42464
> > 100644
> > --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > @@ -574,7 +574,7 @@ static bool mctl_phy_write_training(struct dram_para
> > *para)> 
> >  static void mctl_phy_bit_delay_compensation(struct dram_para *para)
> >  {
> > 
> > -	u32 *ptr;
> > +	u32 *ptr, val;
> > 
> >  	int i;
> >  	
> >  	if (para->tpr10 & TPR10_UNKNOWN_FEAT2) {
> > 
> > @@ -582,49 +582,93 @@ static void mctl_phy_bit_delay_compensation(struct
> > dram_para *para)> 
> >  		setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 8);
> >  		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
> > 
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = para->tpr11 & 0x3f;
> > +		else
> > +			val = (para->tpr11 & 0xf) << 1;
> > +
> > 
> >  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484);
> >  		for (i = 0; i < 9; i++) {
> > 
> > -			writel_relaxed(0x16, ptr);
> > -			writel_relaxed(0x16, ptr + 0x30);
> > +			writel_relaxed(val, ptr);
> > +			writel_relaxed(val, ptr + 0x30);
> > 
> >  			ptr += 2;
> >  		
> >  		}
> > 
> > -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4d0);
> > -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x590);
> > -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x4cc);
> > -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x58c);
> > +
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = (para->odt_en >> 15) & 0x1e;
> 
> So I guess odt_en stands for "ODT enable". Looking at the D1 DRAM
> driver, they have a boot0 parameter odt_en which is either 0x0 or 0x1,
> so it looks like a boolean value. This seems to be also the case here?

Nope. While I only ever see odt_en being 1, based on vendor code it can have 
additional bits set, as it can be seen from above code.

> In the D1 driver, this seems to gate the ZQ value being used, which
> provides the actual timing values.
> So is TPR10_UNKNOWN_FEAT3 actually this ODT_EN switch, and the variable
> containing the timing bits should be zq_value or CONFIG_DRAM_ZQ?

No idea.

> 
> > +		else
> > +			val = (para->tpr11 >> 15) & 0x1e;
> 
> So I am wondering if it's less confusing to mask first, then shift?
> Granted, this here is shift from [19:16] into [5:1], so it's not easy
> either way, but I think it's easier to match the mask with the provided
> TPR11 value.

I did it this way because mask is much smaller and easier to read, but neither 
are straightforward to understand. I guess some macro could be crafted for 
such purpose.

> 
> > +
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x4d0);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x590);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x4cc);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x58c);
> > +
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = (para->tpr11 >> 8) & 0x3f;
> > +		else
> > +			val = (para->tpr11 >> 3) & 0x1e;
> > 
> >  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8);
> >  		for (i = 0; i < 9; i++) {
> > 
> > -			writel_relaxed(0x1a, ptr);
> > -			writel_relaxed(0x1a, ptr + 0x30);
> > +			writel_relaxed(val, ptr);
> > +			writel_relaxed(val, ptr + 0x30);
> > 
> >  			ptr += 2;
> >  		
> >  		}
> > 
> > -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x524);
> > -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e4);
> > -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x520);
> > -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x5e0);
> > +
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = (para->odt_en >> 19) & 0x1e;
> 
> Is this really odt_en as a base, while *most* of the other bits use
> TPR11 as well? Just asking, since it doesn't fit into my naive pattern
> matching ;-)

odt_en is name from device tree. It doesn't seem to match actual purpose, but 
there is not much we can do without documentation.

Best regards,
Jernej

> 
> The rest looks correct (minus the repeat of the above mentioned
> issues), I compared the register offsets between - and +.
> 
> Cheers,
> Andre
> 
> > +		else
> > +			val = (para->tpr11 >> 19) & 0x1e;
> > +
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x524);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5e4);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x520);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5e0);
> > +
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = (para->tpr11 >> 16) & 0x3f;
> > +		else
> > +			val = (para->tpr11 >> 7) & 0x1e;
> > 
> >  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604);
> >  		for (i = 0; i < 9; i++) {
> > 
> > -			writel_relaxed(0x1a, ptr);
> > -			writel_relaxed(0x1a, ptr + 0x30);
> > +			writel_relaxed(val, ptr);
> > +			writel_relaxed(val, ptr + 0x30);
> > 
> >  			ptr += 2;
> >  		
> >  		}
> > 
> > -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x650);
> > -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x710);
> > -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x64c);
> > -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x70c);
> > +
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = (para->odt_en >> 23) & 0x1e;
> > +		else
> > +			val = (para->tpr11 >> 23) & 0x1e;
> > +
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x650);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x710);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x64c);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x70c);
> > +
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = (para->tpr11 >> 24) & 0x3f;
> > +		else
> > +			val = (para->tpr11 >> 11) & 0x1e;
> > 
> >  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658);
> >  		for (i = 0; i < 9; i++) {
> > 
> > -			writel_relaxed(0x1a, ptr);
> > -			writel_relaxed(0x1a, ptr + 0x30);
> > +			writel_relaxed(val, ptr);
> > +			writel_relaxed(val, ptr + 0x30);
> > 
> >  			ptr += 2;
> >  		
> >  		}
> > 
> > -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a4);
> > -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x764);
> > -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x6a0);
> > -		writel_relaxed(0x1e, SUNXI_DRAM_PHY0_BASE + 0x760);
> > +
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = (para->odt_en >> 27) & 0x1e;
> > +		else
> > +			val = (para->tpr11 >> 27) & 0x1e;
> > +
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6a4);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x764);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6a0);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x760);
> > 
> >  		dmb();
> > 
> > @@ -635,49 +679,93 @@ static void mctl_phy_bit_delay_compensation(struct
> > dram_para *para)> 
> >  		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 0x80);
> >  		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 4);
> > 
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = para->tpr12 & 0x3f;
> > +		else
> > +			val = (para->tpr12 & 0xf) << 1;
> > +
> > 
> >  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480);
> >  		for (i = 0; i < 9; i++) {
> > 
> > -			writel_relaxed(0x10, ptr);
> > -			writel_relaxed(0x10, ptr + 0x30);
> > +			writel_relaxed(val, ptr);
> > +			writel_relaxed(val, ptr + 0x30);
> > 
> >  			ptr += 2;
> >  		
> >  		}
> > 
> > -		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x528);
> > -		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x5e8);
> > -		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x4c8);
> > -		writel_relaxed(0x18, SUNXI_DRAM_PHY0_BASE + 0x588);
> > +
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = (para->odt_en << 1) & 0x1e;
> > +		else
> > +			val = (para->tpr12 >> 15) & 0x1e;
> > +
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x528);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5e8);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x4c8);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x588);
> > +
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = (para->tpr12 >> 8) & 0x3f;
> > +		else
> > +			val = (para->tpr12 >> 3) & 0x1e;
> > 
> >  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4);
> >  		for (i = 0; i < 9; i++) {
> > 
> > -			writel_relaxed(0x12, ptr);
> > -			writel_relaxed(0x12, ptr + 0x30);
> > +			writel_relaxed(val, ptr);
> > +			writel_relaxed(val, ptr + 0x30);
> > 
> >  			ptr += 2;
> >  		
> >  		}
> > 
> > -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x52c);
> > -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5ec);
> > -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x51c);
> > -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x5dc);
> > +
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = (para->odt_en >> 3) & 0x1e;
> > +		else
> > +			val = (para->tpr12 >> 19) & 0x1e;
> > +
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x52c);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5ec);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x51c);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x5dc);
> > +
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = (para->tpr12 >> 16) & 0x3f;
> > +		else
> > +			val = (para->tpr12 >> 7) & 0x1e;
> > 
> >  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600);
> >  		for (i = 0; i < 9; i++) {
> > 
> > -			writel_relaxed(0x12, ptr);
> > -			writel_relaxed(0x12, ptr + 0x30);
> > +			writel_relaxed(val, ptr);
> > +			writel_relaxed(val, ptr + 0x30);
> > 
> >  			ptr += 2;
> >  		
> >  		}
> > 
> > -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x6a8);
> > -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x768);
> > -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x648);
> > -		writel_relaxed(0x1a, SUNXI_DRAM_PHY0_BASE + 0x708);
> > +
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = (para->odt_en >> 7) & 0x1e;
> > +		else
> > +			val = (para->tpr12 >> 23) & 0x1e;
> > +
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6a8);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x768);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x648);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x708);
> > +
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = (para->tpr12 >> 24) & 0x3f;
> > +		else
> > +			val = (para->tpr12 >> 11) & 0x1e;
> > 
> >  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654);
> >  		for (i = 0; i < 9; i++) {
> > 
> > -			writel_relaxed(0x14, ptr);
> > -			writel_relaxed(0x14, ptr + 0x30);
> > +			writel_relaxed(val, ptr);
> > +			writel_relaxed(val, ptr + 0x30);
> > 
> >  			ptr += 2;
> >  		
> >  		}
> > 
> > -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x6ac);
> > -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x76c);
> > -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x69c);
> > -		writel_relaxed(0x1c, SUNXI_DRAM_PHY0_BASE + 0x75c);
> > +
> > +		if (para->tpr10 & TPR10_UNKNOWN_FEAT3)
> > +			val = (para->odt_en >> 11) & 0x1e;
> > +		else
> > +			val = (para->tpr12 >> 27) & 0x1e;
> > +
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x6ac);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x76c);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x69c);
> > +		writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x75c);
> > 
> >  		dmb();
> > 
> > @@ -1021,7 +1109,10 @@ unsigned long sunxi_dram_init(void)
> > 
> >  		.dx_odt = CONFIG_DRAM_SUN50I_H616_DX_ODT,
> >  		.dx_dri = CONFIG_DRAM_SUN50I_H616_DX_DRI,
> >  		.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
> > 
> > +		.odt_en = CONFIG_DRAM_SUN50I_H616_ODT_EN,
> > 
> >  		.tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
> > 
> > +		.tpr11 = CONFIG_DRAM_SUN50I_H616_TPR11,
> > +		.tpr12 = CONFIG_DRAM_SUN50I_H616_TPR12,
> > 
> >  	};
> >  	unsigned long size;




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

* Re: [PATCH 8/8] sunxi: Parameterize H616 DRAM code some more
  2023-01-04  0:38   ` Andre Przywara
@ 2023-01-04 21:30     ` Jernej Škrabec
  0 siblings, 0 replies; 29+ messages in thread
From: Jernej Škrabec @ 2023-01-04 21:30 UTC (permalink / raw)
  To: Andre Przywara; +Cc: jagan, u-boot

Dne sreda, 04. januar 2023 ob 01:38:12 CET je Andre Przywara napisal(a):
> On Sun, 11 Dec 2022 17:32:13 +0100
> 
> Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
> > Part of the code, previously known as "unknown feature" also doesn't
> > have constant values. They are derived from TPR0 parameter in vendor
> > DRAM code. Introduce that parameter here too, to ease adding new boards.
> 
> That seems to also miss the value for the OPi Zero2 defconfig.

Again, Zero2 doesn't use all features.

> 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
> > ---
> > 
> >  .../include/asm/arch-sunxi/dram_sun50i_h616.h |  1 +
> >  arch/arm/mach-sunxi/Kconfig                   |  6 ++++
> >  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 35 +++++++++++++++----
> >  3 files changed, 35 insertions(+), 7 deletions(-)
> > 
> > diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h index
> > c7890c83391f..ff736bd88d10 100644
> > --- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> > @@ -158,6 +158,7 @@ struct dram_para {
> > 
> >  	u32 dx_dri;
> >  	u32 ca_dri;
> >  	u32 odt_en;
> > 
> > +	u32 tpr0;
> > 
> >  	u32 tpr10;
> >  	u32 tpr11;
> >  	u32 tpr12;
> > 
> > diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> > index b050f0a56971..7858a7045f7e 100644
> > --- a/arch/arm/mach-sunxi/Kconfig
> > +++ b/arch/arm/mach-sunxi/Kconfig
> > @@ -73,6 +73,12 @@ config DRAM_SUN50I_H616_ODT_EN
> > 
> >  	help
> >  	
> >  	  ODT EN value from vendor DRAM settings.
> > 
> > +config DRAM_SUN50I_H616_TPR0
> > +	hex "H616 DRAM TPR0 parameter"
> > +	default 0x0
> 
> Is 0x0 really a feasible default value? I'd suggest we don't provide a
> default, so force people to be prompted for a value, if nothing is in
> (a new board's) defconfig.

This is not used on all boards, so imo is ok to have it as default.

Best regards,
Jernej

> 
> The rest looks OK, though I can't really comment on the actual bits -
> but who can anyway ;-)
> 
> Cheers,
> Andre
> 
> > +	help
> > +	  TPR0 value from vendor DRAM settings.
> > +
> > 
> >  config DRAM_SUN50I_H616_TPR10
> >  
> >  	hex "H616 DRAM TPR10 parameter"
> >  	help
> > 
> > diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > b/arch/arm/mach-sunxi/dram_sun50i_h616.c index df06cea42464..6d8f8d371bfe
> > 100644
> > --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> > @@ -808,15 +808,35 @@ static bool mctl_phy_init(struct dram_para *para)
> > 
> >  		writel(phy_init[i], &ptr[i]);
> >  	
> >  	if (para->tpr10 & TPR10_UNKNOWN_FEAT0) {
> > 
> > +		if (para->tpr0 & BIT(30))
> > +			val = (para->tpr0 >> 7) & 0x3e;
> > +		else
> > +			val = (para->tpr10 >> 3) & 0x1e;
> > +
> > 
> >  		ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780);
> >  		for (i = 0; i < 32; i++)
> > 
> > -			writel(0x16, &ptr[i]);
> > -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x78c);
> > -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7a4);
> > -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7b8);
> > -		writel(0x8, SUNXI_DRAM_PHY0_BASE + 0x7d4);
> > -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7dc);
> > -		writel(0xe, SUNXI_DRAM_PHY0_BASE + 0x7e0);
> > +			writel(val, &ptr[i]);
> > +
> > +		val = (para->tpr10 << 1) & 0x1e;
> > +		writel(val, SUNXI_DRAM_PHY0_BASE + 0x7dc);
> > +		writel(val, SUNXI_DRAM_PHY0_BASE + 0x7e0);
> > +
> > +		/* following configuration is DDR3 specific */
> > +		val = (para->tpr10 >> 7) & 0x1e;
> > +		writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d4);
> > +		/*
> > +		 * TODO: Offsets 0x79c, 0x794 and 0x7e4 may need
> > +		 * to be set here. However, this doesn't seem to
> > +		 * be needed by any board seen in the wild for now.
> > +		 * It's not implemented because it would unnecessarily
> > +		 * introduce PARA2 and TPR2 options.
> > +		 */
> > +		if (para->tpr0 & BIT(31)) {
> > +			val = (para->tpr0 << 1) & 0x3e;
> > +			writel(val, SUNXI_DRAM_PHY0_BASE + 0x78c);
> > +			writel(val, SUNXI_DRAM_PHY0_BASE + 0x7a4);
> > +			writel(val, SUNXI_DRAM_PHY0_BASE + 0x7b8);
> > +		}
> > 
> >  	}
> >  	
> >  	writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x3dc);
> > 
> > @@ -1110,6 +1130,7 @@ unsigned long sunxi_dram_init(void)
> > 
> >  		.dx_dri = CONFIG_DRAM_SUN50I_H616_DX_DRI,
> >  		.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
> >  		.odt_en = CONFIG_DRAM_SUN50I_H616_ODT_EN,
> > 
> > +		.tpr0 = CONFIG_DRAM_SUN50I_H616_TPR0,
> > 
> >  		.tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
> >  		.tpr11 = CONFIG_DRAM_SUN50I_H616_TPR11,
> >  		.tpr12 = CONFIG_DRAM_SUN50I_H616_TPR12,





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

* Re: [PATCH 0/8] sunxi: Update H616 DRAM driver
  2023-01-04 21:02   ` Jernej Škrabec
@ 2023-01-04 23:21     ` Andre Przywara
  0 siblings, 0 replies; 29+ messages in thread
From: Andre Przywara @ 2023-01-04 23:21 UTC (permalink / raw)
  To: Jernej Škrabec; +Cc: jagan, u-boot

On Wed, 04 Jan 2023 22:02:33 +0100
Jernej Škrabec <jernej.skrabec@gmail.com> wrote:

Hi Jernej,

> Dne sreda, 04. januar 2023 ob 01:47:16 CET je Andre Przywara napisal(a):
> > On Sun, 11 Dec 2022 17:32:05 +0100
> > Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
> > 
> > Hi Jernej,
> >   
> > > Current H616 DRAM driver is completely customized to Orange Pi Zero2
> > > board, which is currently the only H616 board supported by U-Boot.
> > > Needless to say, this is not ideal for adding new boards. With changes
> > > in this series, all DDR3 boards are supported and all that is needed is
> > > just vendor DRAM values extracted from Android image. New DRAM types
> > > should also be easier to support, since a lot of constants used before
> > > are not really DRAM type dependent.
> > > 
> > > Changes were verified by decompiling driver and generated values were
> > > compared to previous, hard coded ones. This was done without dram_para
> > > structures, so compiler was able to heavily optimize code and produce
> > > constants.  
> > 
> > so many thanks again for putting this together!
> > I came to like (the idea of) this series very much lately, as this
> > removes timing/delay values from the code, and easily allows putting the
> > vendor provided values in the defconfig.
> > I used that approach as well for the D1 driver, and am wondering if we
> > should extend this to other SoCs, potentially unifying the Kconfig part?  
> 
> While it would be nice, I'm not sure it's worth the effort and there is a 
> chance that something might break during rework.

Fair enough, was just an idea.

> > And you hinted at a v2, can you provide an estimate for this? If you
> > send it still this week, I would like to put it into U-Boot's next
> > branch, otherwise it goes straight into master, should the merge window
> > open next week as planned.  
> 
> I have changes for v2 in my github repo. I don't have any estimation, since I 
> had some time off from programming lately

Sounds good!

> and I'm just only catching up. 
> Weekend at earliest, but no promises.

No worries, that was a genuine question, for my planning. I have plenty
of other things to do, and we have still plenty of time (till end of
January or so) to get things merged.

> > Btw., to verify the feasibility of drivers/ram/sunxi, I moved the H616
> > driver into there, together with the Kconfig parts, I wonder what you
> > think about this? An example of how this looks is in the D1 driver
> > patches.  
> 
> Looks good, but I don't know what are implications regarding interface. Is 
> just code move or that implies that some ram framework must be used?

I don't know what Simon and Tom will say, but I was cheekily just using
the directory, ignoring the current DM_SPL preference for code in
there. For the D1/T113s code this is probably a no-brainer, but
I also found it a nice and simple solution to declutter and cleanup
arch/arm/mach-sunxi and its Kconfig.
So yeah, it's just moving the files and Kconfig stanzas there, and
otherwise leaves the actual code untouched. We still call
sunxi_dram_init() from our legacy SPL code.

Cheers,
Andre


> 
> Best regards,
> Jernej
> 
> > 
> > Cheers,
> > Andre
> >   
> > > Please take a look.
> > > 
> > > Best regards,
> > > Jernej
> > > 
> > > Jernej Skrabec (8):
> > >   sunxi: Fix write to H616 DRAM CR register
> > >   sunxi: cosmetic: Fix H616 DRAM driver code style
> > >   sunxi: parameterize H616 DRAM ODT values
> > >   sunxi: Convert H616 DRAM options to single setting
> > >   sunxi: Always configure ODT on H616 DRAM
> > >   sunxi: Make bit delay function in H616 DRAM code void
> > >   sunxi: Parameterize bit delay code in H616 DRAM driver
> > >   sunxi: Parameterize H616 DRAM code some more
> > >  
> > >  .../include/asm/arch-sunxi/dram_sun50i_h616.h |  18 +
> > >  arch/arm/mach-sunxi/Kconfig                   |  67 +--
> > >  arch/arm/mach-sunxi/dram_sun50i_h616.c        | 445 +++++++++++-------
> > >  configs/orangepi_zero2_defconfig              |   8 +-
> > >  4 files changed, 348 insertions(+), 190 deletions(-)  
> 
> 
> 
> 


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

end of thread, other threads:[~2023-01-04 23:23 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-11 16:32 [PATCH 0/8] sunxi: Update H616 DRAM driver Jernej Skrabec
2022-12-11 16:32 ` [PATCH 1/8] sunxi: Fix write to H616 DRAM CR register Jernej Skrabec
2023-01-04  0:35   ` Andre Przywara
2022-12-11 16:32 ` [PATCH 2/8] sunxi: cosmetic: Fix H616 DRAM driver code style Jernej Skrabec
2023-01-04  0:36   ` Andre Przywara
2022-12-11 16:32 ` [PATCH 3/8] sunxi: parameterize H616 DRAM ODT values Jernej Skrabec
2023-01-04  0:36   ` Andre Przywara
2022-12-11 16:32 ` [PATCH 4/8] sunxi: Convert H616 DRAM options to single setting Jernej Skrabec
2022-12-12 17:50   ` Andre Przywara
2022-12-13 16:23     ` Jernej Škrabec
2022-12-13 16:51       ` Andre Przywara
2022-12-13 17:08         ` Jernej Škrabec
2022-12-11 16:32 ` [PATCH 5/8] sunxi: Always configure ODT on H616 DRAM Jernej Skrabec
2023-01-04  0:37   ` Andre Przywara
2023-01-04 21:12     ` Jernej Škrabec
2022-12-11 16:32 ` [PATCH 6/8] sunxi: Make bit delay function in H616 DRAM code void Jernej Skrabec
2023-01-04  0:37   ` Andre Przywara
2022-12-11 16:32 ` [PATCH 7/8] sunxi: Parameterize bit delay code in H616 DRAM driver Jernej Skrabec
2023-01-04  0:37   ` Andre Przywara
2023-01-04 21:28     ` Jernej Škrabec
2022-12-11 16:32 ` [PATCH 8/8] sunxi: Parameterize H616 DRAM code some more Jernej Skrabec
2022-12-11 18:33   ` Jernej Škrabec
2023-01-04  0:38   ` Andre Przywara
2023-01-04 21:30     ` Jernej Škrabec
2022-12-12  1:04 ` [PATCH 0/8] sunxi: Update H616 DRAM driver Andre Przywara
2022-12-12 16:14   ` Jernej Škrabec
2023-01-04  0:47 ` Andre Przywara
2023-01-04 21:02   ` Jernej Škrabec
2023-01-04 23:21     ` Andre Przywara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).