* [PATCH v2 00/10] sunxi: Update H616 DRAM driver
@ 2023-04-10 8:21 Jernej Skrabec
2023-04-10 8:21 ` [PATCH v2 01/10] sunxi: Fix write to H616 DRAM CR register Jernej Skrabec
` (10 more replies)
0 siblings, 11 replies; 19+ messages in thread
From: Jernej Skrabec @ 2023-04-10 8:21 UTC (permalink / raw)
To: andre.przywara; +Cc: jagan, u-boot, linux-sunxi, Jernej Skrabec
Current H616 DRAM driver is completely customized to Orange Pi Zero2
board, which is only one of two H616 boards 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
Changes from v1:
- added tags
- updated dram config macros to have 8 or 4 nibbles
- renamed unknown macros to something useful when known
- removed unknown macro when not known what it does
- added patch 9 and 10 which introduces TPR2 (needed on one h313 board)
- update commit subjects
Jernej Skrabec (10):
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 "unknown feature" in H616 DRAM driver
sunxi: Parameterize some of H616 DDR3 timings
sunxi: Add TPR2 parameter for H616 DRAM driver
.../include/asm/arch-sunxi/dram_sun50i_h616.h | 17 +
arch/arm/mach-sunxi/Kconfig | 83 +--
arch/arm/mach-sunxi/dram_sun50i_h616.c | 530 ++++++++++++------
.../mach-sunxi/dram_timings/h616_ddr3_1333.c | 20 +-
configs/orangepi_zero2_defconfig | 8 +-
configs/x96_mate_defconfig | 7 +
6 files changed, 442 insertions(+), 223 deletions(-)
--
2.40.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 01/10] sunxi: Fix write to H616 DRAM CR register
2023-04-10 8:21 [PATCH v2 00/10] sunxi: Update H616 DRAM driver Jernej Skrabec
@ 2023-04-10 8:21 ` Jernej Skrabec
2023-04-10 8:21 ` [PATCH v2 02/10] sunxi: cosmetic: Fix H616 DRAM driver code style Jernej Skrabec
` (9 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Jernej Skrabec @ 2023-04-10 8:21 UTC (permalink / raw)
To: andre.przywara; +Cc: jagan, u-boot, linux-sunxi, 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.
Acked-by: Andre Przywara <andre.przywara@arm.com>
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.40.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 02/10] sunxi: cosmetic: Fix H616 DRAM driver code style
2023-04-10 8:21 [PATCH v2 00/10] sunxi: Update H616 DRAM driver Jernej Skrabec
2023-04-10 8:21 ` [PATCH v2 01/10] sunxi: Fix write to H616 DRAM CR register Jernej Skrabec
@ 2023-04-10 8:21 ` Jernej Skrabec
2023-04-10 8:21 ` [PATCH v2 03/10] sunxi: parameterize H616 DRAM ODT values Jernej Skrabec
` (8 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Jernej Skrabec @ 2023-04-10 8:21 UTC (permalink / raw)
To: andre.przywara; +Cc: jagan, u-boot, linux-sunxi, Jernej Skrabec
Fix code style for pointer declaration. This is just cosmetic change to
avoid checkpatch errors in later commits.
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
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.40.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 03/10] sunxi: parameterize H616 DRAM ODT values
2023-04-10 8:21 [PATCH v2 00/10] sunxi: Update H616 DRAM driver Jernej Skrabec
2023-04-10 8:21 ` [PATCH v2 01/10] sunxi: Fix write to H616 DRAM CR register Jernej Skrabec
2023-04-10 8:21 ` [PATCH v2 02/10] sunxi: cosmetic: Fix H616 DRAM driver code style Jernej Skrabec
@ 2023-04-10 8:21 ` Jernej Skrabec
2023-04-10 8:21 ` [PATCH v2 04/10] sunxi: Convert H616 DRAM options to single setting Jernej Skrabec
` (7 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Jernej Skrabec @ 2023-04-10 8:21 UTC (permalink / raw)
To: andre.przywara; +Cc: jagan, u-boot, linux-sunxi, 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.
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
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 +
configs/x96_mate_defconfig | 3 +
5 files changed, 61 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 6417aee944bc..14fb9a95905a 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 72fc419ca7e4..d70b15a07705 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=0x08080808
+CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e
+CONFIG_DRAM_SUN50I_H616_CA_DRI=0x0e0e
CONFIG_MACH_SUN50I_H616=y
CONFIG_R_I2C_ENABLE=y
CONFIG_SPL_SPI_SUNXI=y
diff --git a/configs/x96_mate_defconfig b/configs/x96_mate_defconfig
index 38b82c3a3ecd..60cc8fbe751c 100644
--- a/configs/x96_mate_defconfig
+++ b/configs/x96_mate_defconfig
@@ -3,6 +3,9 @@ CONFIG_ARCH_SUNXI=y
CONFIG_DEFAULT_DEVICE_TREE="sun50i-h616-x96-mate"
CONFIG_SPL=y
CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
+CONFIG_DRAM_SUN50I_H616_DX_ODT=0x03030303
+CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e
+CONFIG_DRAM_SUN50I_H616_CA_DRI=0x1c12
CONFIG_MACH_SUN50I_H616=y
CONFIG_R_I2C_ENABLE=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
--
2.40.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 04/10] sunxi: Convert H616 DRAM options to single setting
2023-04-10 8:21 [PATCH v2 00/10] sunxi: Update H616 DRAM driver Jernej Skrabec
` (2 preceding siblings ...)
2023-04-10 8:21 ` [PATCH v2 03/10] sunxi: parameterize H616 DRAM ODT values Jernej Skrabec
@ 2023-04-10 8:21 ` Jernej Skrabec
2023-04-11 10:13 ` Andre Przywara
2023-04-10 8:21 ` [PATCH v2 05/10] sunxi: Always configure ODT on H616 DRAM Jernej Skrabec
` (6 subsequent siblings)
10 siblings, 1 reply; 19+ messages in thread
From: Jernej Skrabec @ 2023-04-10 8:21 UTC (permalink / raw)
To: andre.przywara; +Cc: jagan, u-boot, linux-sunxi, 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 | 9 +
arch/arm/mach-sunxi/Kconfig | 38 +---
arch/arm/mach-sunxi/dram_sun50i_h616.c | 197 +++++++++---------
configs/orangepi_zero2_defconfig | 5 +-
configs/x96_mate_defconfig | 1 +
5 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..dbdc6b694ec1 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,14 @@ 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)
+#define TPR10_CA_BIT_DELAY BIT(16)
+#define TPR10_DX_BIT_DELAY0 BIT(17)
+#define TPR10_DX_BIT_DELAY1 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 +155,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 14fb9a95905a..1b47a49f938c 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..630c7c3be882 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_DX_BIT_DELAY1) {
+ 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_DX_BIT_DELAY0) {
+ 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_CA_BIT_DELAY) {
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 d70b15a07705..6cb942f511a1 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=0x08080808
CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e
CONFIG_DRAM_SUN50I_H616_CA_DRI=0x0e0e
+CONFIG_DRAM_SUN50I_H616_TPR10=0xf83438
CONFIG_MACH_SUN50I_H616=y
CONFIG_R_I2C_ENABLE=y
CONFIG_SPL_SPI_SUNXI=y
diff --git a/configs/x96_mate_defconfig b/configs/x96_mate_defconfig
index 60cc8fbe751c..b00daa458b28 100644
--- a/configs/x96_mate_defconfig
+++ b/configs/x96_mate_defconfig
@@ -6,6 +6,7 @@ CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
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_TPR10=0x2f0007
CONFIG_MACH_SUN50I_H616=y
CONFIG_R_I2C_ENABLE=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
--
2.40.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 05/10] sunxi: Always configure ODT on H616 DRAM
2023-04-10 8:21 [PATCH v2 00/10] sunxi: Update H616 DRAM driver Jernej Skrabec
` (3 preceding siblings ...)
2023-04-10 8:21 ` [PATCH v2 04/10] sunxi: Convert H616 DRAM options to single setting Jernej Skrabec
@ 2023-04-10 8:21 ` Jernej Skrabec
2023-04-11 10:13 ` Andre Przywara
2023-04-10 8:21 ` [PATCH v2 06/10] sunxi: Make bit delay function in H616 DRAM code void Jernej Skrabec
` (5 subsequent siblings)
10 siblings, 1 reply; 19+ messages in thread
From: Jernej Skrabec @ 2023-04-10 8:21 UTC (permalink / raw)
To: andre.przywara; +Cc: jagan, u-boot, linux-sunxi, 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 1b47a49f938c..4300d388e066 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 630c7c3be882..7d2434309b07 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.40.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 06/10] sunxi: Make bit delay function in H616 DRAM code void
2023-04-10 8:21 [PATCH v2 00/10] sunxi: Update H616 DRAM driver Jernej Skrabec
` (4 preceding siblings ...)
2023-04-10 8:21 ` [PATCH v2 05/10] sunxi: Always configure ODT on H616 DRAM Jernej Skrabec
@ 2023-04-10 8:21 ` Jernej Skrabec
2023-04-10 8:21 ` [PATCH v2 07/10] sunxi: Parameterize bit delay code in H616 DRAM driver Jernej Skrabec
` (4 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Jernej Skrabec @ 2023-04-10 8:21 UTC (permalink / raw)
To: andre.przywara; +Cc: jagan, u-boot, linux-sunxi, Jernej Skrabec
Mentioned function result is always true and result isn't checked
anyway. Let's make it void.
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
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 7d2434309b07..3fe45845b78e 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.40.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 07/10] sunxi: Parameterize bit delay code in H616 DRAM driver
2023-04-10 8:21 [PATCH v2 00/10] sunxi: Update H616 DRAM driver Jernej Skrabec
` (5 preceding siblings ...)
2023-04-10 8:21 ` [PATCH v2 06/10] sunxi: Make bit delay function in H616 DRAM code void Jernej Skrabec
@ 2023-04-10 8:21 ` Jernej Skrabec
2023-04-11 10:14 ` Andre Przywara
2023-04-10 8:21 ` [PATCH v2 08/10] sunxi: Parameterize "unknown feature" " Jernej Skrabec
` (3 subsequent siblings)
10 siblings, 1 reply; 19+ messages in thread
From: Jernej Skrabec @ 2023-04-10 8:21 UTC (permalink / raw)
To: andre.przywara; +Cc: jagan, u-boot, linux-sunxi, 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 | 3 +
arch/arm/mach-sunxi/Kconfig | 18 ++
arch/arm/mach-sunxi/dram_sun50i_h616.c | 189 +++++++++++++-----
configs/x96_mate_defconfig | 2 +
4 files changed, 163 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 dbdc6b694ec1..034ba98bc243 100644
--- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
+++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
@@ -155,7 +155,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 4300d388e066..7b38e83c2d7e 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 3fe45845b78e..f5d8718fefff 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_DX_BIT_DELAY1) {
@@ -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 & BIT(30))
+ 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 & BIT(30))
+ 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 & BIT(30))
+ 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 & BIT(30))
+ 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 & BIT(30))
+ 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 & BIT(30))
+ 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 & BIT(30))
+ 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 & BIT(30))
+ 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 & BIT(30))
+ 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 & BIT(30))
+ 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 & BIT(30))
+ 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 & BIT(30))
+ 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 & BIT(30))
+ 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 & BIT(30))
+ 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 & BIT(30))
+ 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 & BIT(30))
+ 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;
diff --git a/configs/x96_mate_defconfig b/configs/x96_mate_defconfig
index b00daa458b28..acc64898da19 100644
--- a/configs/x96_mate_defconfig
+++ b/configs/x96_mate_defconfig
@@ -7,6 +7,8 @@ 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_TPR10=0x2f0007
+CONFIG_DRAM_SUN50I_H616_TPR11=0xffffdddd
+CONFIG_DRAM_SUN50I_H616_TPR12=0xfedf7557
CONFIG_MACH_SUN50I_H616=y
CONFIG_R_I2C_ENABLE=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
--
2.40.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 08/10] sunxi: Parameterize "unknown feature" in H616 DRAM driver
2023-04-10 8:21 [PATCH v2 00/10] sunxi: Update H616 DRAM driver Jernej Skrabec
` (6 preceding siblings ...)
2023-04-10 8:21 ` [PATCH v2 07/10] sunxi: Parameterize bit delay code in H616 DRAM driver Jernej Skrabec
@ 2023-04-10 8:21 ` Jernej Skrabec
2023-04-11 10:14 ` Andre Przywara
2023-04-10 8:21 ` [PATCH v2 09/10] sunxi: Parameterize some of H616 DDR3 timings Jernej Skrabec
` (2 subsequent siblings)
10 siblings, 1 reply; 19+ messages in thread
From: Jernej Skrabec @ 2023-04-10 8:21 UTC (permalink / raw)
To: andre.przywara; +Cc: jagan, u-boot, linux-sunxi, 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.
Let's move that code to separate function and introduce TPR0 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 | 47 ++++++++++++++-----
configs/x96_mate_defconfig | 1 +
4 files changed, 44 insertions(+), 11 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 034ba98bc243..615532c6eebb 100644
--- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
+++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
@@ -156,6 +156,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 7b38e83c2d7e..fe34755f88ec 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 f5d8718fefff..44bb15367beb 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
@@ -773,6 +773,39 @@ static void mctl_phy_bit_delay_compensation(struct dram_para *para)
}
}
+static void mctl_phy_ca_bit_delay_compensation(struct dram_para *para)
+{
+ u32 val, *ptr;
+ int i;
+
+ 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(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);
+ if (para->ranks == 2) {
+ val = (para->tpr10 >> 11) & 0x1e;
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x79c);
+ }
+ 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);
+ }
+}
+
static bool mctl_phy_init(struct dram_para *para)
{
struct sunxi_mctl_com_reg * const mctl_com =
@@ -807,17 +840,8 @@ 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 (para->tpr10 & TPR10_CA_BIT_DELAY) {
- 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);
- }
+ if (para->tpr10 & TPR10_CA_BIT_DELAY)
+ mctl_phy_ca_bit_delay_compensation(para);
writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x3dc);
writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x45c);
@@ -1110,6 +1134,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,
diff --git a/configs/x96_mate_defconfig b/configs/x96_mate_defconfig
index acc64898da19..aedb3277022a 100644
--- a/configs/x96_mate_defconfig
+++ b/configs/x96_mate_defconfig
@@ -6,6 +6,7 @@ CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
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
--
2.40.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 09/10] sunxi: Parameterize some of H616 DDR3 timings
2023-04-10 8:21 [PATCH v2 00/10] sunxi: Update H616 DRAM driver Jernej Skrabec
` (7 preceding siblings ...)
2023-04-10 8:21 ` [PATCH v2 08/10] sunxi: Parameterize "unknown feature" " Jernej Skrabec
@ 2023-04-10 8:21 ` Jernej Skrabec
2023-04-11 10:14 ` Andre Przywara
2023-04-10 8:21 ` [PATCH v2 10/10] sunxi: Add TPR2 parameter for H616 DRAM driver Jernej Skrabec
2023-04-11 10:19 ` [PATCH v2 00/10] sunxi: Update " Andre Przywara
10 siblings, 1 reply; 19+ messages in thread
From: Jernej Skrabec @ 2023-04-10 8:21 UTC (permalink / raw)
To: andre.przywara; +Cc: jagan, u-boot, linux-sunxi, Jernej Skrabec
Currently twr2rd, trd2wr and twtp are constants, but according to
vendor driver they are calculated from other values. Do that here too,
in preparation for later introduction of new parameter.
While at it, introduce constant for t_wr_lat, which was incorrectly
calculated from tcl before.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c b/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c
index 8f508344bc17..f109e920820b 100644
--- a/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c
+++ b/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c
@@ -48,10 +48,11 @@ void mctl_set_timing_params(struct dram_para *para)
u8 tcl = 7; /* JEDEC: CL / 2 => 6 */
u8 tcwl = 5; /* JEDEC: 8 */
u8 t_rdata_en = 9; /* ? */
+ u8 t_wr_lat = 5; /* ? */
- u8 twtp = 14; /* (WL + BL / 2 + tWR) / 2 */
- u8 twr2rd = trtp + 7; /* (WL + BL / 2 + tWTR) / 2 */
- u8 trd2wr = 5; /* (RL + BL / 2 + 2 - WL) / 2 */
+ u8 twtp = tcl + 2 + tcwl; /* (WL + BL / 2 + tWR) / 2 */
+ u8 twr2rd = trtp + 2 + tcwl; /* (WL + BL / 2 + tWTR) / 2 */
+ u8 trd2wr = tcl + 3 - tcwl; /* (RL + BL / 2 + 2 - WL) / 2 */
/* set DRAM timing */
writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | tras,
@@ -85,7 +86,7 @@ void mctl_set_timing_params(struct dram_para *para)
clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660);
/* Configure DFI timing */
- writel((tcl - 2) | 0x2000000 | (t_rdata_en << 16) | 0x808000,
+ writel(t_wr_lat | 0x2000000 | (t_rdata_en << 16) | 0x808000,
&mctl_ctl->dfitmg0);
writel(0x100202, &mctl_ctl->dfitmg1);
--
2.40.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 10/10] sunxi: Add TPR2 parameter for H616 DRAM driver
2023-04-10 8:21 [PATCH v2 00/10] sunxi: Update H616 DRAM driver Jernej Skrabec
` (8 preceding siblings ...)
2023-04-10 8:21 ` [PATCH v2 09/10] sunxi: Parameterize some of H616 DDR3 timings Jernej Skrabec
@ 2023-04-10 8:21 ` Jernej Skrabec
2023-04-11 10:15 ` Andre Przywara
2023-04-11 10:19 ` [PATCH v2 00/10] sunxi: Update " Andre Przywara
10 siblings, 1 reply; 19+ messages in thread
From: Jernej Skrabec @ 2023-04-10 8:21 UTC (permalink / raw)
To: andre.przywara; +Cc: jagan, u-boot, linux-sunxi, Jernej Skrabec
It turns out that some H616 and related SoCs (like H313) need TPR2
parameter for proper working. Add it.
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 | 75 +++++++++++++------
.../mach-sunxi/dram_timings/h616_ddr3_1333.c | 17 ++++-
4 files changed, 75 insertions(+), 24 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 615532c6eebb..6db869c0985b 100644
--- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
+++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
@@ -157,6 +157,7 @@ struct dram_para {
u32 ca_dri;
u32 odt_en;
u32 tpr0;
+ u32 tpr2;
u32 tpr10;
u32 tpr11;
u32 tpr12;
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index fe34755f88ec..6be8a4de53fe 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -79,6 +79,12 @@ config DRAM_SUN50I_H616_TPR0
help
TPR0 value from vendor DRAM settings.
+config DRAM_SUN50I_H616_TPR2
+ hex "H616 DRAM TPR2 parameter"
+ default 0x0
+ help
+ TPR2 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 44bb15367beb..1f9416d6eaf5 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
@@ -788,21 +788,37 @@ static void mctl_phy_ca_bit_delay_compensation(struct dram_para *para)
writel(val, &ptr[i]);
val = (para->tpr10 << 1) & 0x1e;
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d8);
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7dc);
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7e0);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x7f4);
/* following configuration is DDR3 specific */
val = (para->tpr10 >> 7) & 0x1e;
- writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d4);
- if (para->ranks == 2) {
- val = (para->tpr10 >> 11) & 0x1e;
- writel(val, SUNXI_DRAM_PHY0_BASE + 0x79c);
- }
- 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);
+ if (para->tpr2 & 1) {
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x794);
+ if (para->ranks == 2) {
+ val = (para->tpr10 >> 11) & 0x1e;
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x7e4);
+ }
+ if (para->tpr0 & BIT(31)) {
+ val = (para->tpr0 << 1) & 0x3e;
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x790);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x7b8);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x7cc);
+ }
+ } else {
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d4);
+ if (para->ranks == 2) {
+ val = (para->tpr10 >> 11) & 0x1e;
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x79c);
+ }
+ 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);
+ }
}
}
@@ -812,7 +828,7 @@ static bool mctl_phy_init(struct dram_para *para)
(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
struct sunxi_mctl_ctl_reg * const mctl_ctl =
(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
- u32 val, *ptr;
+ u32 val, val2, *ptr, mr0, mr2;
int i;
if (para->bus_full_width)
@@ -821,20 +837,28 @@ static bool mctl_phy_init(struct dram_para *para)
val = 3;
clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x3c, 0xf, val);
- writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x14);
- writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x35c);
- writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x368);
- writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x374);
+ if (para->tpr2 & 0x100) {
+ val = 9;
+ val2 = 7;
+ } else {
+ val = 13;
+ val2 = 9;
+ }
+
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x14);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x35c);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x368);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x374);
writel(0, SUNXI_DRAM_PHY0_BASE + 0x18);
writel(0, SUNXI_DRAM_PHY0_BASE + 0x360);
writel(0, SUNXI_DRAM_PHY0_BASE + 0x36c);
writel(0, SUNXI_DRAM_PHY0_BASE + 0x378);
- writel(9, SUNXI_DRAM_PHY0_BASE + 0x1c);
- writel(9, SUNXI_DRAM_PHY0_BASE + 0x364);
- writel(9, SUNXI_DRAM_PHY0_BASE + 0x370);
- writel(9, SUNXI_DRAM_PHY0_BASE + 0x37c);
+ writel(val2, SUNXI_DRAM_PHY0_BASE + 0x1c);
+ writel(val2, SUNXI_DRAM_PHY0_BASE + 0x364);
+ writel(val2, SUNXI_DRAM_PHY0_BASE + 0x370);
+ writel(val2, SUNXI_DRAM_PHY0_BASE + 0x37c);
ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xc0);
for (i = 0; i < ARRAY_SIZE(phy_init); i++)
@@ -890,7 +914,15 @@ static bool mctl_phy_init(struct dram_para *para)
writel(1, &mctl_ctl->swctl);
mctl_await_completion(&mctl_ctl->swstat, 1, 1);
- writel(0x1f14, &mctl_ctl->mrctrl1);
+ if (para->tpr2 & 0x100) {
+ mr0 = 0x1b50;
+ mr2 = 0x10;
+ } else {
+ mr0 = 0x1f14;
+ mr2 = 0x20;
+ }
+
+ writel(mr0, &mctl_ctl->mrctrl1);
writel(0x80000030, &mctl_ctl->mrctrl0);
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
@@ -898,7 +930,7 @@ static bool mctl_phy_init(struct dram_para *para)
writel(0x80001030, &mctl_ctl->mrctrl0);
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
- writel(0x20, &mctl_ctl->mrctrl1);
+ writel(mr2, &mctl_ctl->mrctrl1);
writel(0x80002030, &mctl_ctl->mrctrl0);
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
@@ -1135,6 +1167,7 @@ unsigned long sunxi_dram_init(void)
.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
.odt_en = CONFIG_DRAM_SUN50I_H616_ODT_EN,
.tpr0 = CONFIG_DRAM_SUN50I_H616_TPR0,
+ .tpr2 = CONFIG_DRAM_SUN50I_H616_TPR2,
.tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
.tpr11 = CONFIG_DRAM_SUN50I_H616_TPR11,
.tpr12 = CONFIG_DRAM_SUN50I_H616_TPR12,
diff --git a/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c b/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c
index f109e920820b..eea4d6abec81 100644
--- a/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c
+++ b/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c
@@ -50,9 +50,20 @@ void mctl_set_timing_params(struct dram_para *para)
u8 t_rdata_en = 9; /* ? */
u8 t_wr_lat = 5; /* ? */
- u8 twtp = tcl + 2 + tcwl; /* (WL + BL / 2 + tWR) / 2 */
- u8 twr2rd = trtp + 2 + tcwl; /* (WL + BL / 2 + tWTR) / 2 */
- u8 trd2wr = tcl + 3 - tcwl; /* (RL + BL / 2 + 2 - WL) / 2 */
+ u8 twtp; /* (WL + BL / 2 + tWR) / 2 */
+ u8 twr2rd; /* (WL + BL / 2 + tWTR) / 2 */
+ u8 trd2wr; /* (RL + BL / 2 + 2 - WL) / 2 */
+
+ if (para->tpr2 & 0x100) {
+ tcl = 5;
+ tcwl = 4;
+ t_rdata_en = 5;
+ t_wr_lat = 3;
+ }
+
+ twtp = tcl + 2 + tcwl;
+ twr2rd = trtp + 2 + tcwl;
+ trd2wr = tcl + 3 - tcwl;
/* set DRAM timing */
writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | tras,
--
2.40.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v2 04/10] sunxi: Convert H616 DRAM options to single setting
2023-04-10 8:21 ` [PATCH v2 04/10] sunxi: Convert H616 DRAM options to single setting Jernej Skrabec
@ 2023-04-11 10:13 ` Andre Przywara
2023-04-12 5:05 ` Jernej Škrabec
0 siblings, 1 reply; 19+ messages in thread
From: Andre Przywara @ 2023-04-11 10:13 UTC (permalink / raw)
To: Jernej Skrabec; +Cc: jagan, u-boot, linux-sunxi
On Mon, 10 Apr 2023 10:21:13 +0200
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
> 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>
Thanks, based on my previous review, and the changes to the bit names:
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Just one note here, mostly for the reference when people stumble upon
this patch: this enables the CA bit delay compensation code for the X96,
which was not enabled before, because DRAM_SUN50I_H616_UNKNOWN_FEATURE
was not set. I don't know if the fixed values written by this
code here were meant for the OrangePi Zero2 (which though never
runs this code), but for the X96 Mate the values written by this patch
will be changed in a later patch.
Cheers,
Andre
> ---
> .../include/asm/arch-sunxi/dram_sun50i_h616.h | 9 +
> arch/arm/mach-sunxi/Kconfig | 38 +---
> arch/arm/mach-sunxi/dram_sun50i_h616.c | 197 +++++++++---------
> configs/orangepi_zero2_defconfig | 5 +-
> configs/x96_mate_defconfig | 1 +
> 5 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..dbdc6b694ec1 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,14 @@ 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)
>
> +#define TPR10_CA_BIT_DELAY BIT(16)
> +#define TPR10_DX_BIT_DELAY0 BIT(17)
> +#define TPR10_DX_BIT_DELAY1 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 +155,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 14fb9a95905a..1b47a49f938c 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..630c7c3be882 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_DX_BIT_DELAY1) {
> + 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_DX_BIT_DELAY0) {
> + 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_CA_BIT_DELAY) {
> 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 d70b15a07705..6cb942f511a1 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=0x08080808
> CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e
> CONFIG_DRAM_SUN50I_H616_CA_DRI=0x0e0e
> +CONFIG_DRAM_SUN50I_H616_TPR10=0xf83438
> CONFIG_MACH_SUN50I_H616=y
> CONFIG_R_I2C_ENABLE=y
> CONFIG_SPL_SPI_SUNXI=y
> diff --git a/configs/x96_mate_defconfig b/configs/x96_mate_defconfig
> index 60cc8fbe751c..b00daa458b28 100644
> --- a/configs/x96_mate_defconfig
> +++ b/configs/x96_mate_defconfig
> @@ -6,6 +6,7 @@ CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
> 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_TPR10=0x2f0007
> CONFIG_MACH_SUN50I_H616=y
> CONFIG_R_I2C_ENABLE=y
> # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 05/10] sunxi: Always configure ODT on H616 DRAM
2023-04-10 8:21 ` [PATCH v2 05/10] sunxi: Always configure ODT on H616 DRAM Jernej Skrabec
@ 2023-04-11 10:13 ` Andre Przywara
0 siblings, 0 replies; 19+ messages in thread
From: Andre Przywara @ 2023-04-11 10:13 UTC (permalink / raw)
To: Jernej Skrabec; +Cc: jagan, u-boot, linux-sunxi
On Mon, 10 Apr 2023 10:21:14 +0200
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
Hi,
> 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>
Still not a big fan of "depends on !MACH_SUN50I_H616", but the logic
seems fine nevertheless:
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Cheers,
Andre
> ---
> 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 1b47a49f938c..4300d388e066 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 630c7c3be882..7d2434309b07 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] 19+ messages in thread
* Re: [PATCH v2 07/10] sunxi: Parameterize bit delay code in H616 DRAM driver
2023-04-10 8:21 ` [PATCH v2 07/10] sunxi: Parameterize bit delay code in H616 DRAM driver Jernej Skrabec
@ 2023-04-11 10:14 ` Andre Przywara
0 siblings, 0 replies; 19+ messages in thread
From: Andre Przywara @ 2023-04-11 10:14 UTC (permalink / raw)
To: Jernej Skrabec; +Cc: jagan, u-boot, linux-sunxi
On Mon, 10 Apr 2023 10:21:16 +0200
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
> 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>
Some bits still look odd, as mentioned in the previous review, but I
guess there is really not much we can do about it. Meh. Seems to work,
though, and the values seem to match before and after, so:
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Cheers,
Andre
> ---
> .../include/asm/arch-sunxi/dram_sun50i_h616.h | 3 +
> arch/arm/mach-sunxi/Kconfig | 18 ++
> arch/arm/mach-sunxi/dram_sun50i_h616.c | 189 +++++++++++++-----
> configs/x96_mate_defconfig | 2 +
> 4 files changed, 163 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 dbdc6b694ec1..034ba98bc243 100644
> --- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> @@ -155,7 +155,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 4300d388e066..7b38e83c2d7e 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 3fe45845b78e..f5d8718fefff 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_DX_BIT_DELAY1) {
> @@ -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 & BIT(30))
> + 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 & BIT(30))
> + 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 & BIT(30))
> + 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 & BIT(30))
> + 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 & BIT(30))
> + 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 & BIT(30))
> + 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 & BIT(30))
> + 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 & BIT(30))
> + 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 & BIT(30))
> + 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 & BIT(30))
> + 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 & BIT(30))
> + 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 & BIT(30))
> + 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 & BIT(30))
> + 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 & BIT(30))
> + 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 & BIT(30))
> + 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 & BIT(30))
> + 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;
>
> diff --git a/configs/x96_mate_defconfig b/configs/x96_mate_defconfig
> index b00daa458b28..acc64898da19 100644
> --- a/configs/x96_mate_defconfig
> +++ b/configs/x96_mate_defconfig
> @@ -7,6 +7,8 @@ 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_TPR10=0x2f0007
> +CONFIG_DRAM_SUN50I_H616_TPR11=0xffffdddd
> +CONFIG_DRAM_SUN50I_H616_TPR12=0xfedf7557
> CONFIG_MACH_SUN50I_H616=y
> CONFIG_R_I2C_ENABLE=y
> # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 08/10] sunxi: Parameterize "unknown feature" in H616 DRAM driver
2023-04-10 8:21 ` [PATCH v2 08/10] sunxi: Parameterize "unknown feature" " Jernej Skrabec
@ 2023-04-11 10:14 ` Andre Przywara
0 siblings, 0 replies; 19+ messages in thread
From: Andre Przywara @ 2023-04-11 10:14 UTC (permalink / raw)
To: Jernej Skrabec; +Cc: jagan, u-boot, linux-sunxi
On Mon, 10 Apr 2023 10:21:17 +0200
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
Hi Jernej,
> 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.
>
> Let's move that code to separate function and introduce TPR0 parameter
> here too, to ease adding new boards.
so the values written now don't really match the previously used ones (not
even for the OPi-Zero2 boot0 TPR0/10 registers), but then again this whole
code was not in use before. The whole transformation looks vaguely correct,
though, and it works on the X96 Mate (which now uses this code), so:
Acked-by: Andre Przywara <andre.przywara@arm.com>
Thanks,
Andre
> 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 | 47 ++++++++++++++-----
> configs/x96_mate_defconfig | 1 +
> 4 files changed, 44 insertions(+), 11 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 034ba98bc243..615532c6eebb 100644
> --- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> @@ -156,6 +156,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 7b38e83c2d7e..fe34755f88ec 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 f5d8718fefff..44bb15367beb 100644
> --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> @@ -773,6 +773,39 @@ static void mctl_phy_bit_delay_compensation(struct dram_para *para)
> }
> }
>
> +static void mctl_phy_ca_bit_delay_compensation(struct dram_para *para)
> +{
> + u32 val, *ptr;
> + int i;
> +
> + 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(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);
> + if (para->ranks == 2) {
> + val = (para->tpr10 >> 11) & 0x1e;
> + writel(val, SUNXI_DRAM_PHY0_BASE + 0x79c);
> + }
> + 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);
> + }
> +}
> +
> static bool mctl_phy_init(struct dram_para *para)
> {
> struct sunxi_mctl_com_reg * const mctl_com =
> @@ -807,17 +840,8 @@ 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 (para->tpr10 & TPR10_CA_BIT_DELAY) {
> - 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);
> - }
> + if (para->tpr10 & TPR10_CA_BIT_DELAY)
> + mctl_phy_ca_bit_delay_compensation(para);
>
> writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x3dc);
> writel(0x80, SUNXI_DRAM_PHY0_BASE + 0x45c);
> @@ -1110,6 +1134,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,
> diff --git a/configs/x96_mate_defconfig b/configs/x96_mate_defconfig
> index acc64898da19..aedb3277022a 100644
> --- a/configs/x96_mate_defconfig
> +++ b/configs/x96_mate_defconfig
> @@ -6,6 +6,7 @@ CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
> 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
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 09/10] sunxi: Parameterize some of H616 DDR3 timings
2023-04-10 8:21 ` [PATCH v2 09/10] sunxi: Parameterize some of H616 DDR3 timings Jernej Skrabec
@ 2023-04-11 10:14 ` Andre Przywara
0 siblings, 0 replies; 19+ messages in thread
From: Andre Przywara @ 2023-04-11 10:14 UTC (permalink / raw)
To: Jernej Skrabec; +Cc: jagan, u-boot, linux-sunxi
On Mon, 10 Apr 2023 10:21:18 +0200
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
> Currently twr2rd, trd2wr and twtp are constants, but according to
> vendor driver they are calculated from other values. Do that here too,
> in preparation for later introduction of new parameter.
>
> While at it, introduce constant for t_wr_lat, which was incorrectly
> calculated from tcl before.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
The transformations look correct, though I cannot really judge their
meanings. Nevertheless:
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Cheers,
Andre
> ---
> arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c b/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c
> index 8f508344bc17..f109e920820b 100644
> --- a/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c
> +++ b/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c
> @@ -48,10 +48,11 @@ void mctl_set_timing_params(struct dram_para *para)
> u8 tcl = 7; /* JEDEC: CL / 2 => 6 */
> u8 tcwl = 5; /* JEDEC: 8 */
> u8 t_rdata_en = 9; /* ? */
> + u8 t_wr_lat = 5; /* ? */
>
> - u8 twtp = 14; /* (WL + BL / 2 + tWR) / 2 */
> - u8 twr2rd = trtp + 7; /* (WL + BL / 2 + tWTR) / 2 */
> - u8 trd2wr = 5; /* (RL + BL / 2 + 2 - WL) / 2 */
> + u8 twtp = tcl + 2 + tcwl; /* (WL + BL / 2 + tWR) / 2 */
> + u8 twr2rd = trtp + 2 + tcwl; /* (WL + BL / 2 + tWTR) / 2 */
> + u8 trd2wr = tcl + 3 - tcwl; /* (RL + BL / 2 + 2 - WL) / 2 */
>
> /* set DRAM timing */
> writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | tras,
> @@ -85,7 +86,7 @@ void mctl_set_timing_params(struct dram_para *para)
> clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660);
>
> /* Configure DFI timing */
> - writel((tcl - 2) | 0x2000000 | (t_rdata_en << 16) | 0x808000,
> + writel(t_wr_lat | 0x2000000 | (t_rdata_en << 16) | 0x808000,
> &mctl_ctl->dfitmg0);
> writel(0x100202, &mctl_ctl->dfitmg1);
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 10/10] sunxi: Add TPR2 parameter for H616 DRAM driver
2023-04-10 8:21 ` [PATCH v2 10/10] sunxi: Add TPR2 parameter for H616 DRAM driver Jernej Skrabec
@ 2023-04-11 10:15 ` Andre Przywara
0 siblings, 0 replies; 19+ messages in thread
From: Andre Przywara @ 2023-04-11 10:15 UTC (permalink / raw)
To: Jernej Skrabec; +Cc: jagan, u-boot, linux-sunxi
On Mon, 10 Apr 2023 10:21:19 +0200
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
Hi,
> It turns out that some H616 and related SoCs (like H313) need TPR2
> parameter for proper working. Add it.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
I don't have any boards that don't use a TPR2 value of 0, so
cannot test the new case, but for TPR2==0 the same values will be
written into the registers as before. So:
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Thanks,
Andre
> ---
> .../include/asm/arch-sunxi/dram_sun50i_h616.h | 1 +
> arch/arm/mach-sunxi/Kconfig | 6 ++
> arch/arm/mach-sunxi/dram_sun50i_h616.c | 75 +++++++++++++------
> .../mach-sunxi/dram_timings/h616_ddr3_1333.c | 17 ++++-
> 4 files changed, 75 insertions(+), 24 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 615532c6eebb..6db869c0985b 100644
> --- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> @@ -157,6 +157,7 @@ struct dram_para {
> u32 ca_dri;
> u32 odt_en;
> u32 tpr0;
> + u32 tpr2;
> u32 tpr10;
> u32 tpr11;
> u32 tpr12;
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index fe34755f88ec..6be8a4de53fe 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -79,6 +79,12 @@ config DRAM_SUN50I_H616_TPR0
> help
> TPR0 value from vendor DRAM settings.
>
> +config DRAM_SUN50I_H616_TPR2
> + hex "H616 DRAM TPR2 parameter"
> + default 0x0
> + help
> + TPR2 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 44bb15367beb..1f9416d6eaf5 100644
> --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> @@ -788,21 +788,37 @@ static void mctl_phy_ca_bit_delay_compensation(struct dram_para *para)
> writel(val, &ptr[i]);
>
> val = (para->tpr10 << 1) & 0x1e;
> + writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d8);
> writel(val, SUNXI_DRAM_PHY0_BASE + 0x7dc);
> writel(val, SUNXI_DRAM_PHY0_BASE + 0x7e0);
> + writel(val, SUNXI_DRAM_PHY0_BASE + 0x7f4);
>
> /* following configuration is DDR3 specific */
> val = (para->tpr10 >> 7) & 0x1e;
> - writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d4);
> - if (para->ranks == 2) {
> - val = (para->tpr10 >> 11) & 0x1e;
> - writel(val, SUNXI_DRAM_PHY0_BASE + 0x79c);
> - }
> - 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);
> + if (para->tpr2 & 1) {
> + writel(val, SUNXI_DRAM_PHY0_BASE + 0x794);
> + if (para->ranks == 2) {
> + val = (para->tpr10 >> 11) & 0x1e;
> + writel(val, SUNXI_DRAM_PHY0_BASE + 0x7e4);
> + }
> + if (para->tpr0 & BIT(31)) {
> + val = (para->tpr0 << 1) & 0x3e;
> + writel(val, SUNXI_DRAM_PHY0_BASE + 0x790);
> + writel(val, SUNXI_DRAM_PHY0_BASE + 0x7b8);
> + writel(val, SUNXI_DRAM_PHY0_BASE + 0x7cc);
> + }
> + } else {
> + writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d4);
> + if (para->ranks == 2) {
> + val = (para->tpr10 >> 11) & 0x1e;
> + writel(val, SUNXI_DRAM_PHY0_BASE + 0x79c);
> + }
> + 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);
> + }
> }
> }
>
> @@ -812,7 +828,7 @@ static bool mctl_phy_init(struct dram_para *para)
> (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
> struct sunxi_mctl_ctl_reg * const mctl_ctl =
> (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
> - u32 val, *ptr;
> + u32 val, val2, *ptr, mr0, mr2;
> int i;
>
> if (para->bus_full_width)
> @@ -821,20 +837,28 @@ static bool mctl_phy_init(struct dram_para *para)
> val = 3;
> clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x3c, 0xf, val);
>
> - writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x14);
> - writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x35c);
> - writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x368);
> - writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x374);
> + if (para->tpr2 & 0x100) {
> + val = 9;
> + val2 = 7;
> + } else {
> + val = 13;
> + val2 = 9;
> + }
> +
> + writel(val, SUNXI_DRAM_PHY0_BASE + 0x14);
> + writel(val, SUNXI_DRAM_PHY0_BASE + 0x35c);
> + writel(val, SUNXI_DRAM_PHY0_BASE + 0x368);
> + writel(val, SUNXI_DRAM_PHY0_BASE + 0x374);
>
> writel(0, SUNXI_DRAM_PHY0_BASE + 0x18);
> writel(0, SUNXI_DRAM_PHY0_BASE + 0x360);
> writel(0, SUNXI_DRAM_PHY0_BASE + 0x36c);
> writel(0, SUNXI_DRAM_PHY0_BASE + 0x378);
>
> - writel(9, SUNXI_DRAM_PHY0_BASE + 0x1c);
> - writel(9, SUNXI_DRAM_PHY0_BASE + 0x364);
> - writel(9, SUNXI_DRAM_PHY0_BASE + 0x370);
> - writel(9, SUNXI_DRAM_PHY0_BASE + 0x37c);
> + writel(val2, SUNXI_DRAM_PHY0_BASE + 0x1c);
> + writel(val2, SUNXI_DRAM_PHY0_BASE + 0x364);
> + writel(val2, SUNXI_DRAM_PHY0_BASE + 0x370);
> + writel(val2, SUNXI_DRAM_PHY0_BASE + 0x37c);
>
> ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xc0);
> for (i = 0; i < ARRAY_SIZE(phy_init); i++)
> @@ -890,7 +914,15 @@ static bool mctl_phy_init(struct dram_para *para)
> writel(1, &mctl_ctl->swctl);
> mctl_await_completion(&mctl_ctl->swstat, 1, 1);
>
> - writel(0x1f14, &mctl_ctl->mrctrl1);
> + if (para->tpr2 & 0x100) {
> + mr0 = 0x1b50;
> + mr2 = 0x10;
> + } else {
> + mr0 = 0x1f14;
> + mr2 = 0x20;
> + }
> +
> + writel(mr0, &mctl_ctl->mrctrl1);
> writel(0x80000030, &mctl_ctl->mrctrl0);
> mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
>
> @@ -898,7 +930,7 @@ static bool mctl_phy_init(struct dram_para *para)
> writel(0x80001030, &mctl_ctl->mrctrl0);
> mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
>
> - writel(0x20, &mctl_ctl->mrctrl1);
> + writel(mr2, &mctl_ctl->mrctrl1);
> writel(0x80002030, &mctl_ctl->mrctrl0);
> mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
>
> @@ -1135,6 +1167,7 @@ unsigned long sunxi_dram_init(void)
> .ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
> .odt_en = CONFIG_DRAM_SUN50I_H616_ODT_EN,
> .tpr0 = CONFIG_DRAM_SUN50I_H616_TPR0,
> + .tpr2 = CONFIG_DRAM_SUN50I_H616_TPR2,
> .tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
> .tpr11 = CONFIG_DRAM_SUN50I_H616_TPR11,
> .tpr12 = CONFIG_DRAM_SUN50I_H616_TPR12,
> diff --git a/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c b/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c
> index f109e920820b..eea4d6abec81 100644
> --- a/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c
> +++ b/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c
> @@ -50,9 +50,20 @@ void mctl_set_timing_params(struct dram_para *para)
> u8 t_rdata_en = 9; /* ? */
> u8 t_wr_lat = 5; /* ? */
>
> - u8 twtp = tcl + 2 + tcwl; /* (WL + BL / 2 + tWR) / 2 */
> - u8 twr2rd = trtp + 2 + tcwl; /* (WL + BL / 2 + tWTR) / 2 */
> - u8 trd2wr = tcl + 3 - tcwl; /* (RL + BL / 2 + 2 - WL) / 2 */
> + u8 twtp; /* (WL + BL / 2 + tWR) / 2 */
> + u8 twr2rd; /* (WL + BL / 2 + tWTR) / 2 */
> + u8 trd2wr; /* (RL + BL / 2 + 2 - WL) / 2 */
> +
> + if (para->tpr2 & 0x100) {
> + tcl = 5;
> + tcwl = 4;
> + t_rdata_en = 5;
> + t_wr_lat = 3;
> + }
> +
> + twtp = tcl + 2 + tcwl;
> + twr2rd = trtp + 2 + tcwl;
> + trd2wr = tcl + 3 - tcwl;
>
> /* set DRAM timing */
> writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | tras,
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 00/10] sunxi: Update H616 DRAM driver
2023-04-10 8:21 [PATCH v2 00/10] sunxi: Update H616 DRAM driver Jernej Skrabec
` (9 preceding siblings ...)
2023-04-10 8:21 ` [PATCH v2 10/10] sunxi: Add TPR2 parameter for H616 DRAM driver Jernej Skrabec
@ 2023-04-11 10:19 ` Andre Przywara
10 siblings, 0 replies; 19+ messages in thread
From: Andre Przywara @ 2023-04-11 10:19 UTC (permalink / raw)
To: Jernej Skrabec; +Cc: jagan, u-boot, linux-sunxi
On Mon, 10 Apr 2023 10:21:09 +0200
Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
Hi Jernej,
> Current H616 DRAM driver is completely customized to Orange Pi Zero2
> board, which is only one of two H616 boards 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.
many thanks for your work on this, and the changes and updates, also
for including the X96 Mate values in its defconfig. I tested it there, and
it seems to work (TM). Also it's a massive improvement, and paves the way
for other boards, and LPDDR3/LPDDR4 support, so I will include it in the
pull request later this week.
Queued for sunxi/master.
Cheers,
Andre
>
> Changes from v1:
> - added tags
> - updated dram config macros to have 8 or 4 nibbles
> - renamed unknown macros to something useful when known
> - removed unknown macro when not known what it does
> - added patch 9 and 10 which introduces TPR2 (needed on one h313 board)
> - update commit subjects
>
> Jernej Skrabec (10):
> 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 "unknown feature" in H616 DRAM driver
> sunxi: Parameterize some of H616 DDR3 timings
> sunxi: Add TPR2 parameter for H616 DRAM driver
>
> .../include/asm/arch-sunxi/dram_sun50i_h616.h | 17 +
> arch/arm/mach-sunxi/Kconfig | 83 +--
> arch/arm/mach-sunxi/dram_sun50i_h616.c | 530 ++++++++++++------
> .../mach-sunxi/dram_timings/h616_ddr3_1333.c | 20 +-
> configs/orangepi_zero2_defconfig | 8 +-
> configs/x96_mate_defconfig | 7 +
> 6 files changed, 442 insertions(+), 223 deletions(-)
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 04/10] sunxi: Convert H616 DRAM options to single setting
2023-04-11 10:13 ` Andre Przywara
@ 2023-04-12 5:05 ` Jernej Škrabec
0 siblings, 0 replies; 19+ messages in thread
From: Jernej Škrabec @ 2023-04-12 5:05 UTC (permalink / raw)
To: Andre Przywara; +Cc: jagan, u-boot, linux-sunxi
Dne torek, 11. april 2023 ob 12:13:04 CEST je Andre Przywara napisal(a):
> On Mon, 10 Apr 2023 10:21:13 +0200
>
> Jernej Skrabec <jernej.skrabec@gmail.com> wrote:
> > 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>
>
> Thanks, based on my previous review, and the changes to the bit names:
>
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
>
> Just one note here, mostly for the reference when people stumble upon
> this patch: this enables the CA bit delay compensation code for the X96,
> which was not enabled before, because C
> was not set. I don't know if the fixed values written by this
> code here were meant for the OrangePi Zero2 (which though never
> runs this code), but for the X96 Mate the values written by this patch
> will be changed in a later patch.
DRAM_SUN50I_H616_UNKNOWN_FEATURE was tested with T95 box, but there is no
upstream support for it (yet). I think this series was tested with enough
(mostly not supported in mainline) devices that it's safe to say it works.
Note that there are several versions of vendor DRAM driver which naturally
differ slightly. This series is based on V0.651.
Thanks for merging!
Best regards,
Jernej
>
> Cheers,
> Andre
>
> > ---
> >
> > .../include/asm/arch-sunxi/dram_sun50i_h616.h | 9 +
> > arch/arm/mach-sunxi/Kconfig | 38 +---
> > arch/arm/mach-sunxi/dram_sun50i_h616.c | 197 +++++++++---------
> > configs/orangepi_zero2_defconfig | 5 +-
> > configs/x96_mate_defconfig | 1 +
> > 5 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..dbdc6b694ec1 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,14 @@ 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)
> >
> > +#define TPR10_CA_BIT_DELAY BIT(16)
> > +#define TPR10_DX_BIT_DELAY0 BIT(17)
> > +#define TPR10_DX_BIT_DELAY1 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 +155,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 14fb9a95905a..1b47a49f938c 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..630c7c3be882
> > 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_DX_BIT_DELAY1) {
> > + 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_DX_BIT_DELAY0) {
> > + 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_CA_BIT_DELAY) {
> >
> > 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 d70b15a07705..6cb942f511a1
> > 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=0x08080808
> > CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e
> > CONFIG_DRAM_SUN50I_H616_CA_DRI=0x0e0e
> >
> > +CONFIG_DRAM_SUN50I_H616_TPR10=0xf83438
> >
> > CONFIG_MACH_SUN50I_H616=y
> > CONFIG_R_I2C_ENABLE=y
> > CONFIG_SPL_SPI_SUNXI=y
> >
> > diff --git a/configs/x96_mate_defconfig b/configs/x96_mate_defconfig
> > index 60cc8fbe751c..b00daa458b28 100644
> > --- a/configs/x96_mate_defconfig
> > +++ b/configs/x96_mate_defconfig
> > @@ -6,6 +6,7 @@ CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y
> >
> > 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_TPR10=0x2f0007
> >
> > CONFIG_MACH_SUN50I_H616=y
> > CONFIG_R_I2C_ENABLE=y
> > # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2023-04-12 5:05 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-10 8:21 [PATCH v2 00/10] sunxi: Update H616 DRAM driver Jernej Skrabec
2023-04-10 8:21 ` [PATCH v2 01/10] sunxi: Fix write to H616 DRAM CR register Jernej Skrabec
2023-04-10 8:21 ` [PATCH v2 02/10] sunxi: cosmetic: Fix H616 DRAM driver code style Jernej Skrabec
2023-04-10 8:21 ` [PATCH v2 03/10] sunxi: parameterize H616 DRAM ODT values Jernej Skrabec
2023-04-10 8:21 ` [PATCH v2 04/10] sunxi: Convert H616 DRAM options to single setting Jernej Skrabec
2023-04-11 10:13 ` Andre Przywara
2023-04-12 5:05 ` Jernej Škrabec
2023-04-10 8:21 ` [PATCH v2 05/10] sunxi: Always configure ODT on H616 DRAM Jernej Skrabec
2023-04-11 10:13 ` Andre Przywara
2023-04-10 8:21 ` [PATCH v2 06/10] sunxi: Make bit delay function in H616 DRAM code void Jernej Skrabec
2023-04-10 8:21 ` [PATCH v2 07/10] sunxi: Parameterize bit delay code in H616 DRAM driver Jernej Skrabec
2023-04-11 10:14 ` Andre Przywara
2023-04-10 8:21 ` [PATCH v2 08/10] sunxi: Parameterize "unknown feature" " Jernej Skrabec
2023-04-11 10:14 ` Andre Przywara
2023-04-10 8:21 ` [PATCH v2 09/10] sunxi: Parameterize some of H616 DDR3 timings Jernej Skrabec
2023-04-11 10:14 ` Andre Przywara
2023-04-10 8:21 ` [PATCH v2 10/10] sunxi: Add TPR2 parameter for H616 DRAM driver Jernej Skrabec
2023-04-11 10:15 ` Andre Przywara
2023-04-11 10:19 ` [PATCH v2 00/10] sunxi: Update " Andre Przywara
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox