[U-Boot] [PATCH 0/3] sunxi: dram: More flexible dram for sun[457]i

In a nutshell, this patchset allows to use Kconfig capabilities of the current u-boot code to reproduce the old Cubietruck demo, which showcased reclocking DRAM from 432MHz to 600MHz (the old 'highspeedtruck' branch): http://lists.denx.de/pipermail/u-boot/2014-July/183981.html
But now only a special customized Cubietruck defconfig is sufficient, and there is no need to patch the u-boot source code anymore.
Siarhei Siamashka (3): sunxi: dram: Optionally use standard JEDEC timings for sun[457]i sunxi: dram: Support more sun[457]i dram parameters in Kconfig sunxi: dram: Allow to configure vdd-dll voltage on sun[457]i
arch/arm/include/asm/arch-sunxi/dram.h | 1 + arch/arm/include/asm/arch-sunxi/dram_sun4i.h | 1 + board/sunxi/Kconfig | 83 +++++++++++ board/sunxi/board.c | 10 +- board/sunxi/dram_sun4i_auto.c | 20 ++- board/sunxi/dram_sun5i_auto.c | 20 ++- board/sunxi/dram_timings_sun4i.h | 205 +++++++++++++++++++++++++++ 7 files changed, 332 insertions(+), 8 deletions(-) create mode 100644 board/sunxi/dram_timings_sun4i.h

In addition to the current Android magic settings, allow to optionally use DDR3 timing parameters, which are tailored for different clock frequencies and JEDEC speed bins. This should improve reliability and performance.
Adding '+S:CONFIG_DRAM_TIMINGS_DDR3_1066F_1333H=y' to the board defconfig allows to use timings, which are calculated for the DDR3-1066F speed bin. A lot of DDR3 chips, which are used in real Allwinner based devices, support DDR3-1066F speed bin timings.
And adding '+S:CONFIG_DRAM_TIMINGS_DDR3_800E_1066G_1333J=y' should work with any DDR3 chips, because this targets the slowest JEDEC speed bins.
The vendor magic values are still used by default for DRAM, but board maintainers now have more flexibility in DRAM timings selection.
Signed-off-by: Siarhei Siamashka siarhei.siamashka@gmail.com --- board/sunxi/Kconfig | 32 ++++++ board/sunxi/dram_sun4i_auto.c | 8 +- board/sunxi/dram_sun5i_auto.c | 8 +- board/sunxi/dram_timings_sun4i.h | 205 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 249 insertions(+), 4 deletions(-) create mode 100644 board/sunxi/dram_timings_sun4i.h
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index adbd2b5..da4e8ba 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -55,6 +55,38 @@ config DRAM_EMR1 default 4 if MACH_SUN5I || MACH_SUN7I ---help--- Set the dram controller emr1 value. + +choice + prompt "sunxi dram timings" + default DRAM_TIMINGS_VENDOR_MAGIC + ---help--- + Select the timings of the DDR3 chips. + +config DRAM_TIMINGS_VENDOR_MAGIC + bool "Magic vendor timings from Android" + ---help--- + The same DRAM timings as in the Allwinner boot0 bootloader. + +config DRAM_TIMINGS_DDR3_1066F_1333H + bool "JEDEC DDR3-1333H with down binning to DDR3-1066F" + ---help--- + Use the timings of the standard JEDEC DDR3-1066F speed bin for + DRAM_CLK <= 533MHz and the timings of the DDR3-1333H speed bin + for DRAM_CLK > 533MHz. This covers the majority of DDR3 chips + used in Allwinner A10/A13/A20 devices. In the case of DDR3-1333 + or DDR3-1600 chips, be sure to check the DRAM datasheet to confirm + that down binning to DDR3-1066F is supported (because DDR3-1066F + uses a bit faster timings than DDR3-1333H). + +config DRAM_TIMINGS_DDR3_800E_1066G_1333J + bool "JEDEC DDR3-800E / DDR3-1066G / DDR3-1333J" + ---help--- + Use the timings of the slowest possible JEDEC speed bin for the + selected DRAM_CLK. Depending on the DRAM_CLK value, it may be + DDR3-800E, DDR3-1066G or DDR3-1333J. + +endchoice + endif
config SYS_CONFIG_NAME diff --git a/board/sunxi/dram_sun4i_auto.c b/board/sunxi/dram_sun4i_auto.c index 826bacf..ed54150 100644 --- a/board/sunxi/dram_sun4i_auto.c +++ b/board/sunxi/dram_sun4i_auto.c @@ -8,18 +8,22 @@ static struct dram_para dram_para = { .density = 0, .io_width = 0, .bus_width = 0, - .cas = 6, .zq = CONFIG_DRAM_ZQ, .odt_en = 0, .size = 0, +#ifdef CONFIG_DRAM_TIMINGS_VENDOR_MAGIC + .cas = 6, .tpr0 = 0x30926692, .tpr1 = 0x1090, .tpr2 = 0x1a0c8, + .emr2 = 0, +#else +# include "dram_timings_sun4i.h" +#endif .tpr3 = 0, .tpr4 = 0, .tpr5 = 0, .emr1 = CONFIG_DRAM_EMR1, - .emr2 = 0, .emr3 = 0, };
diff --git a/board/sunxi/dram_sun5i_auto.c b/board/sunxi/dram_sun5i_auto.c index e86b08e..bd9fd4b 100644 --- a/board/sunxi/dram_sun5i_auto.c +++ b/board/sunxi/dram_sun5i_auto.c @@ -10,18 +10,22 @@ static struct dram_para dram_para = { .density = 0, .io_width = 0, .bus_width = 0, - .cas = 9, .zq = CONFIG_DRAM_ZQ, .odt_en = 0, .size = 0, +#ifdef CONFIG_DRAM_TIMINGS_VENDOR_MAGIC + .cas = 9, .tpr0 = 0x42d899b7, .tpr1 = 0xa090, .tpr2 = 0x22a00, + .emr2 = 0x10, +#else +# include "dram_timings_sun4i.h" +#endif .tpr3 = 0, .tpr4 = 0, .tpr5 = 0, .emr1 = CONFIG_DRAM_EMR1, - .emr2 = 0x10, .emr3 = 0, };
diff --git a/board/sunxi/dram_timings_sun4i.h b/board/sunxi/dram_timings_sun4i.h new file mode 100644 index 0000000..29b934d --- /dev/null +++ b/board/sunxi/dram_timings_sun4i.h @@ -0,0 +1,205 @@ +/* This file is automatically generated, do not edit */ + +#if defined(CONFIG_DRAM_TIMINGS_DDR3_1066F_1333H) +# if CONFIG_DRAM_CLK <= 360 /* DDR3-1066F @360MHz, timings: 6-5-5-14 */ + .cas = 6, + .tpr0 = 0x268e5590, + .tpr1 = 0xa090, + .tpr2 = 0x22a00, + .emr2 = 0x0, +# elif CONFIG_DRAM_CLK <= 384 /* DDR3-1066F @384MHz, timings: 6-6-6-15 */ + .cas = 6, + .tpr0 = 0x288f6690, + .tpr1 = 0xa0a0, + .tpr2 = 0x22a00, + .emr2 = 0x0, +# elif CONFIG_DRAM_CLK <= 396 /* DDR3-1066F @396MHz, timings: 6-6-6-15 */ + .cas = 6, + .tpr0 = 0x2a8f6690, + .tpr1 = 0xa0a0, + .tpr2 = 0x22a00, + .emr2 = 0x0, +# elif CONFIG_DRAM_CLK <= 408 /* DDR3-1066F @408MHz, timings: 7-6-6-16 */ + .cas = 7, + .tpr0 = 0x2ab06690, + .tpr1 = 0xa0a8, + .tpr2 = 0x22a00, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 432 /* DDR3-1066F @432MHz, timings: 7-6-6-17 */ + .cas = 7, + .tpr0 = 0x2cb16690, + .tpr1 = 0xa0b0, + .tpr2 = 0x22e00, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 456 /* DDR3-1066F @456MHz, timings: 7-6-6-18 */ + .cas = 7, + .tpr0 = 0x30b26690, + .tpr1 = 0xa0b8, + .tpr2 = 0x22e00, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 468 /* DDR3-1066F @468MHz, timings: 7-7-7-18 */ + .cas = 7, + .tpr0 = 0x30b27790, + .tpr1 = 0xa0c0, + .tpr2 = 0x23200, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 480 /* DDR3-1066F @480MHz, timings: 7-7-7-18 */ + .cas = 7, + .tpr0 = 0x32b27790, + .tpr1 = 0xa0c0, + .tpr2 = 0x23200, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 504 /* DDR3-1066F @504MHz, timings: 7-7-7-19 */ + .cas = 7, + .tpr0 = 0x34d37790, + .tpr1 = 0xa0d0, + .tpr2 = 0x23600, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 528 /* DDR3-1066F @528MHz, timings: 7-7-7-20 */ + .cas = 7, + .tpr0 = 0x36d47790, + .tpr1 = 0xa0d8, + .tpr2 = 0x23600, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 540 /* DDR3-1333H @540MHz, timings: 9-8-8-20 */ + .cas = 9, + .tpr0 = 0x36b488b4, + .tpr1 = 0xa0c8, + .tpr2 = 0x2b600, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 552 /* DDR3-1333H @552MHz, timings: 9-8-8-20 */ + .cas = 9, + .tpr0 = 0x38b488b4, + .tpr1 = 0xa0c8, + .tpr2 = 0x2ba00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 576 /* DDR3-1333H @576MHz, timings: 9-8-8-21 */ + .cas = 9, + .tpr0 = 0x3ab588b4, + .tpr1 = 0xa0d0, + .tpr2 = 0x2ba00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 600 /* DDR3-1333H @600MHz, timings: 9-9-9-22 */ + .cas = 9, + .tpr0 = 0x3cb699b4, + .tpr1 = 0xa0d8, + .tpr2 = 0x2be00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 624 /* DDR3-1333H @624MHz, timings: 9-9-9-23 */ + .cas = 9, + .tpr0 = 0x3eb799b4, + .tpr1 = 0xa0e8, + .tpr2 = 0x2be00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 648 /* DDR3-1333H @648MHz, timings: 9-9-9-24 */ + .cas = 9, + .tpr0 = 0x42b899b4, + .tpr1 = 0xa0f0, + .tpr2 = 0x2c200, + .emr2 = 0x10, +# else +# error CONFIG_DRAM_CLK is set too high +# endif +#elif defined(CONFIG_DRAM_TIMINGS_DDR3_800E_1066G_1333J) +# if CONFIG_DRAM_CLK <= 360 /* DDR3-800E @360MHz, timings: 6-6-6-14 */ + .cas = 6, + .tpr0 = 0x268e6690, + .tpr1 = 0xa090, + .tpr2 = 0x22a00, + .emr2 = 0x0, +# elif CONFIG_DRAM_CLK <= 384 /* DDR3-800E @384MHz, timings: 6-6-6-15 */ + .cas = 6, + .tpr0 = 0x2a8f6690, + .tpr1 = 0xa0a0, + .tpr2 = 0x22a00, + .emr2 = 0x0, +# elif CONFIG_DRAM_CLK <= 396 /* DDR3-800E @396MHz, timings: 6-6-6-15 */ + .cas = 6, + .tpr0 = 0x2a8f6690, + .tpr1 = 0xa0a0, + .tpr2 = 0x22a00, + .emr2 = 0x0, +# elif CONFIG_DRAM_CLK <= 408 /* DDR3-1066G @408MHz, timings: 8-7-7-16 */ + .cas = 8, + .tpr0 = 0x2cb07790, + .tpr1 = 0xa0a8, + .tpr2 = 0x22a00, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 432 /* DDR3-1066G @432MHz, timings: 8-7-7-17 */ + .cas = 8, + .tpr0 = 0x2eb17790, + .tpr1 = 0xa0b0, + .tpr2 = 0x22e00, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 456 /* DDR3-1066G @456MHz, timings: 8-7-7-18 */ + .cas = 8, + .tpr0 = 0x30b27790, + .tpr1 = 0xa0b8, + .tpr2 = 0x22e00, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 468 /* DDR3-1066G @468MHz, timings: 8-8-8-18 */ + .cas = 8, + .tpr0 = 0x32b28890, + .tpr1 = 0xa0c0, + .tpr2 = 0x23200, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 480 /* DDR3-1066G @480MHz, timings: 8-8-8-18 */ + .cas = 8, + .tpr0 = 0x34b28890, + .tpr1 = 0xa0c0, + .tpr2 = 0x23200, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 504 /* DDR3-1066G @504MHz, timings: 8-8-8-19 */ + .cas = 8, + .tpr0 = 0x36d38890, + .tpr1 = 0xa0d0, + .tpr2 = 0x23600, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 528 /* DDR3-1066G @528MHz, timings: 8-8-8-20 */ + .cas = 8, + .tpr0 = 0x38d48890, + .tpr1 = 0xa0d8, + .tpr2 = 0x23600, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 540 /* DDR3-1333J @540MHz, timings: 10-9-9-20 */ + .cas = 10, + .tpr0 = 0x38b499b4, + .tpr1 = 0xa0c8, + .tpr2 = 0x2b600, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 552 /* DDR3-1333J @552MHz, timings: 10-9-9-20 */ + .cas = 10, + .tpr0 = 0x3ab499b4, + .tpr1 = 0xa0c8, + .tpr2 = 0x2ba00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 576 /* DDR3-1333J @576MHz, timings: 10-9-9-21 */ + .cas = 10, + .tpr0 = 0x3cb599b4, + .tpr1 = 0xa0d0, + .tpr2 = 0x2ba00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 600 /* DDR3-1333J @600MHz, timings: 10-9-9-22 */ + .cas = 10, + .tpr0 = 0x3eb699b4, + .tpr1 = 0xa0d8, + .tpr2 = 0x2be00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 624 /* DDR3-1333J @624MHz, timings: 10-10-10-23 */ + .cas = 10, + .tpr0 = 0x40b7aab4, + .tpr1 = 0xa0e8, + .tpr2 = 0x2be00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 648 /* DDR3-1333J @648MHz, timings: 10-10-10-24 */ + .cas = 10, + .tpr0 = 0x44b8aab4, + .tpr1 = 0xa0f0, + .tpr2 = 0x2c200, + .emr2 = 0x10, +# else +# error CONFIG_DRAM_CLK is set too high +# endif +#else +# error CONFIG_DRAM_TIMINGS_* is not defined +#endif

This patch allows to configure all the important DRAM parameters in Kconfig.
Signed-off-by: Siarhei Siamashka siarhei.siamashka@gmail.com --- board/sunxi/Kconfig | 43 +++++++++++++++++++++++++++++++++++++++++++ board/sunxi/dram_sun4i_auto.c | 6 ++++-- board/sunxi/dram_sun5i_auto.c | 5 ++++- 3 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index da4e8ba..4a21589 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -41,6 +41,15 @@ config DRAM_CLK Set the dram clock speed, valid range 240 - 480, must be a multiple of 24.
+if MACH_SUN5I || MACH_SUN7I +config DRAM_MBUS_CLK + int "sunxi mbus clock speed" + default 300 + ---help--- + Set the mbus clock speed. The maximum on sun5i hardware is 300MHz. + +endif + config DRAM_ZQ int "sunxi dram zq value" default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN8I @@ -56,6 +65,40 @@ config DRAM_EMR1 ---help--- Set the dram controller emr1 value.
+config DRAM_ODT_EN + int "sunxi dram odt_en value" + default 0 + ---help--- + Set the dram controller odt_en parameter. This can be used to + enable/disable the ODT feature. + +config DRAM_TPR3 + hex "sunxi dram tpr3 value" + default 0 + ---help--- + Set the dram controller tpr3 parameter. This parameter configures + the delay on the command lane and also phase shifts, which are + applied for sampling incoming read data. The default value 0 + means that no phase/delay adjustments are necessary. Properly + configuring this parameter increases reliability at high DRAM + clock speeds. + +config DRAM_DQS_GATING_DELAY + hex "sunxi dram dqs_gating_delay value" + default 0 + ---help--- + Set the dram controller dqs_gating_delay parmeter. Each byte + encodes the DQS gating delay for each byte lane. The delay + granularity is 1/4 cycle. For example, the value 0x05060606 + means that the delay is 5 quarter-cycles for one lane (1.25 + cycles) and 6 quarter-cycles (1.5 cycles) for 3 other lanes. + The default value 0 means autodetection. The results of hardware + autodetection are not very reliable and depend on the chip + temperature (sometimes producing different results on cold start + and warm reboot). But the accuracy of hardware autodetection + is usually good enough, unless running at really high DRAM + clocks speeds (up to 600MHz). If unsure, keep as 0. + choice prompt "sunxi dram timings" default DRAM_TIMINGS_VENDOR_MAGIC diff --git a/board/sunxi/dram_sun4i_auto.c b/board/sunxi/dram_sun4i_auto.c index ed54150..09e0c9a 100644 --- a/board/sunxi/dram_sun4i_auto.c +++ b/board/sunxi/dram_sun4i_auto.c @@ -9,7 +9,7 @@ static struct dram_para dram_para = { .io_width = 0, .bus_width = 0, .zq = CONFIG_DRAM_ZQ, - .odt_en = 0, + .odt_en = CONFIG_DRAM_ODT_EN, .size = 0, #ifdef CONFIG_DRAM_TIMINGS_VENDOR_MAGIC .cas = 6, @@ -19,12 +19,14 @@ static struct dram_para dram_para = { .emr2 = 0, #else # include "dram_timings_sun4i.h" + .active_windowing = 1, #endif - .tpr3 = 0, + .tpr3 = CONFIG_DRAM_TPR3, .tpr4 = 0, .tpr5 = 0, .emr1 = CONFIG_DRAM_EMR1, .emr3 = 0, + .dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY, };
unsigned long sunxi_dram_init(void) diff --git a/board/sunxi/dram_sun5i_auto.c b/board/sunxi/dram_sun5i_auto.c index bd9fd4b..e52d54c 100644 --- a/board/sunxi/dram_sun5i_auto.c +++ b/board/sunxi/dram_sun5i_auto.c @@ -5,13 +5,14 @@
static struct dram_para dram_para = { .clock = CONFIG_DRAM_CLK, + .mbus_clock = CONFIG_DRAM_MBUS_CLK, .type = 3, .rank_num = 1, .density = 0, .io_width = 0, .bus_width = 0, .zq = CONFIG_DRAM_ZQ, - .odt_en = 0, + .odt_en = CONFIG_DRAM_ODT_EN, .size = 0, #ifdef CONFIG_DRAM_TIMINGS_VENDOR_MAGIC .cas = 9, @@ -21,12 +22,14 @@ static struct dram_para dram_para = { .emr2 = 0x10, #else # include "dram_timings_sun4i.h" + .active_windowing = 1, #endif .tpr3 = 0, .tpr4 = 0, .tpr5 = 0, .emr1 = CONFIG_DRAM_EMR1, .emr3 = 0, + .dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY, };
unsigned long sunxi_dram_init(void)

Higher vdd-dll voltage allows to use higher dram and mbus clock speeds. The vdd-int/vdd-dll voltage is currently set to 1.25V by default, which is much lower than 1.4V, allowed by datasheets (the exact maximum differs for different SoCs).
There are different use cases. For a tablet, it may be preferable to favor longer battery life and use lower dram clock speed & voltage. But for non-battery powered devices, especially the ones driving full-hd monitors, memory performance may be a lot more important than the power consumption.
A configurable vdd-dll voltage provides better flexibility.
Signed-off-by: Siarhei Siamashka siarhei.siamashka@gmail.com --- arch/arm/include/asm/arch-sunxi/dram.h | 1 + arch/arm/include/asm/arch-sunxi/dram_sun4i.h | 1 + board/sunxi/Kconfig | 8 ++++++++ board/sunxi/board.c | 10 +++++++++- board/sunxi/dram_sun4i_auto.c | 6 ++++++ board/sunxi/dram_sun5i_auto.c | 7 +++++++ 6 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 7ff43e6..61ed77c 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -25,6 +25,7 @@ #endif
unsigned long sunxi_dram_init(void); +u32 sunxi_dram_get_min_dll_volt(void);
/* * Wait up to 1s for value to be set in given part of reg. diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun4i.h b/arch/arm/include/asm/arch-sunxi/dram_sun4i.h index 40c385a..32493cc 100644 --- a/arch/arm/include/asm/arch-sunxi/dram_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/dram_sun4i.h @@ -88,6 +88,7 @@ struct dram_para { u32 emr3; u32 dqs_gating_delay; u32 active_windowing; + u32 min_dll_volt; };
#define DRAM_CCR_COMMAND_RATE_1T (0x1 << 5) diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 4a21589..3092edc 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -99,6 +99,14 @@ config DRAM_DQS_GATING_DELAY is usually good enough, unless running at really high DRAM clocks speeds (up to 600MHz). If unsure, keep as 0.
+config DRAM_MIN_DLL_VOLT + int "sunxi dram odt_en value" + default 1250 + ---help--- + Set the minimum VDD-DLL/VDD-INT voltage (mV), required for + reliable DRAM operation. On Allwinner A10/A13/A20 devices with + AXP209 PMIC it is provided from DCDC3. + choice prompt "sunxi dram timings" default DRAM_TIMINGS_VENDOR_MAGIC diff --git a/board/sunxi/board.c b/board/sunxi/board.c index b70e00c..ce6aef5 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -154,11 +154,19 @@ void i2c_init_board(void) clock_twi_onoff(0, 1); }
+__weak u32 sunxi_dram_get_min_dll_volt(void) +{ + return 0; +} + #ifdef CONFIG_SPL_BUILD void sunxi_board_init(void) { int power_failed = 0; unsigned long ramsize; + u32 min_dll_volt = sunxi_dram_get_min_dll_volt(); + if (min_dll_volt < 1250) + min_dll_volt = 1250;
#ifdef CONFIG_AXP152_POWER power_failed = axp152_init(); @@ -170,7 +178,7 @@ void sunxi_board_init(void) #ifdef CONFIG_AXP209_POWER power_failed |= axp209_init(); power_failed |= axp209_set_dcdc2(1400); - power_failed |= axp209_set_dcdc3(1250); + power_failed |= axp209_set_dcdc3(min_dll_volt); power_failed |= axp209_set_ldo2(3000); power_failed |= axp209_set_ldo3(2800); power_failed |= axp209_set_ldo4(2800); diff --git a/board/sunxi/dram_sun4i_auto.c b/board/sunxi/dram_sun4i_auto.c index 09e0c9a..c0c8a28 100644 --- a/board/sunxi/dram_sun4i_auto.c +++ b/board/sunxi/dram_sun4i_auto.c @@ -27,9 +27,15 @@ static struct dram_para dram_para = { .emr1 = CONFIG_DRAM_EMR1, .emr3 = 0, .dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY, + .min_dll_volt = CONFIG_DRAM_MIN_DLL_VOLT, };
unsigned long sunxi_dram_init(void) { return dramc_init(&dram_para); } + +u32 sunxi_dram_get_min_dll_volt(void) +{ + return dram_para.min_dll_volt; +} diff --git a/board/sunxi/dram_sun5i_auto.c b/board/sunxi/dram_sun5i_auto.c index e52d54c..30febe5 100644 --- a/board/sunxi/dram_sun5i_auto.c +++ b/board/sunxi/dram_sun5i_auto.c @@ -30,9 +30,16 @@ static struct dram_para dram_para = { .emr1 = CONFIG_DRAM_EMR1, .emr3 = 0, .dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY, + .min_dll_volt = CONFIG_DRAM_MIN_DLL_VOLT, };
unsigned long sunxi_dram_init(void) { return dramc_init(&dram_para); } + + +u32 sunxi_dram_get_min_dll_volt(void) +{ + return dram_para.min_dll_volt; +}

Hi,
Thanks for the dram timing patches. Since they do not make any changes without them being explictly enabled in Kconfig, I've queued up patches 1 & 2 into u-boot-sunxi/next for merging upstream.
I would like to see this one handled slightly different though, see below.
I assume you're also preparing some defconfig patches to use the new settings on boards where we know exactly which DRAM chips are used (e.g. cubieboard and olinuxino boards) and thus what the proper timings are ?
Also a small wiki page explaining how to figure out the right timing based on dram chip markings would be welcome.
On 31-01-15 23:27, Siarhei Siamashka wrote:
Higher vdd-dll voltage allows to use higher dram and mbus clock speeds. The vdd-int/vdd-dll voltage is currently set to 1.25V by default, which is much lower than 1.4V, allowed by datasheets (the exact maximum differs for different SoCs).
There are different use cases. For a tablet, it may be preferable to favor longer battery life and use lower dram clock speed & voltage. But for non-battery powered devices, especially the ones driving full-hd monitors, memory performance may be a lot more important than the power consumption.
A configurable vdd-dll voltage provides better flexibility.
Signed-off-by: Siarhei Siamashka siarhei.siamashka@gmail.com
arch/arm/include/asm/arch-sunxi/dram.h | 1 + arch/arm/include/asm/arch-sunxi/dram_sun4i.h | 1 + board/sunxi/Kconfig | 8 ++++++++ board/sunxi/board.c | 10 +++++++++- board/sunxi/dram_sun4i_auto.c | 6 ++++++ board/sunxi/dram_sun5i_auto.c | 7 +++++++ 6 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 7ff43e6..61ed77c 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -25,6 +25,7 @@ #endif
unsigned long sunxi_dram_init(void); +u32 sunxi_dram_get_min_dll_volt(void);
/*
- Wait up to 1s for value to be set in given part of reg.
diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun4i.h b/arch/arm/include/asm/arch-sunxi/dram_sun4i.h index 40c385a..32493cc 100644 --- a/arch/arm/include/asm/arch-sunxi/dram_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/dram_sun4i.h @@ -88,6 +88,7 @@ struct dram_para { u32 emr3; u32 dqs_gating_delay; u32 active_windowing;
u32 min_dll_volt; };
#define DRAM_CCR_COMMAND_RATE_1T (0x1 << 5)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 4a21589..3092edc 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -99,6 +99,14 @@ config DRAM_DQS_GATING_DELAY is usually good enough, unless running at really high DRAM clocks speeds (up to 600MHz). If unsure, keep as 0.
+config DRAM_MIN_DLL_VOLT
- int "sunxi dram odt_en value"
- default 1250
- ---help---
- Set the minimum VDD-DLL/VDD-INT voltage (mV), required for
- reliable DRAM operation. On Allwinner A10/A13/A20 devices with
- AXP209 PMIC it is provided from DCDC3.
- choice prompt "sunxi dram timings" default DRAM_TIMINGS_VENDOR_MAGIC
Can you please split this patch in 2:
1) Add a CONFIG_AXP209_POWER, mirroring config AXP221_POWER in drivers/power/Kconfig (put it at the top of the Kconfig file please), and update all the sunxi defconfig-s which currently set AXP209_POWER in CONFIG_SYS_EXTRA_OPTIONS to instead set +S:CONFIG_AXP209_POWER=y in there defconfigs
2) Add a config AXP209_DCDC3_VOLT with a default of 1250 (copy & paste from AXP221_DCDC1_VOLT) and then in board/sunxi/board.c simply replace:
power_failed |= axp209_set_dcdc3(min_dll_volt); with: power_failed |= axp209_set_dcdc3(CONFIG_AXP209_DCDC3_VOLT);
This approach has 3 advantages: 1) it is consistent with what we're doing for the axp221 2) it cleans up a bit of our CONFIG_SYS_EXTRA_OPTIONS (ab)use 3) it avoids the IMHO unnecessary indirection you add with the suggested sunxi_dram_get_min_dll_volt approach
Thanks & Regards,
Hans
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index b70e00c..ce6aef5 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -154,11 +154,19 @@ void i2c_init_board(void) clock_twi_onoff(0, 1); }
+__weak u32 sunxi_dram_get_min_dll_volt(void) +{
- return 0;
+}
#ifdef CONFIG_SPL_BUILD void sunxi_board_init(void) { int power_failed = 0; unsigned long ramsize;
u32 min_dll_volt = sunxi_dram_get_min_dll_volt();
if (min_dll_volt < 1250)
min_dll_volt = 1250;
#ifdef CONFIG_AXP152_POWER power_failed = axp152_init();
@@ -170,7 +178,7 @@ void sunxi_board_init(void) #ifdef CONFIG_AXP209_POWER power_failed |= axp209_init(); power_failed |= axp209_set_dcdc2(1400);
- power_failed |= axp209_set_dcdc3(1250);
- power_failed |= axp209_set_dcdc3(min_dll_volt); power_failed |= axp209_set_ldo2(3000); power_failed |= axp209_set_ldo3(2800); power_failed |= axp209_set_ldo4(2800);
diff --git a/board/sunxi/dram_sun4i_auto.c b/board/sunxi/dram_sun4i_auto.c index 09e0c9a..c0c8a28 100644 --- a/board/sunxi/dram_sun4i_auto.c +++ b/board/sunxi/dram_sun4i_auto.c @@ -27,9 +27,15 @@ static struct dram_para dram_para = { .emr1 = CONFIG_DRAM_EMR1, .emr3 = 0, .dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY,
.min_dll_volt = CONFIG_DRAM_MIN_DLL_VOLT, };
unsigned long sunxi_dram_init(void) { return dramc_init(&dram_para); }
+u32 sunxi_dram_get_min_dll_volt(void) +{
- return dram_para.min_dll_volt;
+} diff --git a/board/sunxi/dram_sun5i_auto.c b/board/sunxi/dram_sun5i_auto.c index e52d54c..30febe5 100644 --- a/board/sunxi/dram_sun5i_auto.c +++ b/board/sunxi/dram_sun5i_auto.c @@ -30,9 +30,16 @@ static struct dram_para dram_para = { .emr1 = CONFIG_DRAM_EMR1, .emr3 = 0, .dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY,
.min_dll_volt = CONFIG_DRAM_MIN_DLL_VOLT, };
unsigned long sunxi_dram_init(void) { return dramc_init(&dram_para); }
+u32 sunxi_dram_get_min_dll_volt(void) +{
- return dram_para.min_dll_volt;
+}

On Mon, 02 Feb 2015 14:13:18 +0100 Hans de Goede hdegoede@redhat.com wrote:
Hi,
Thanks for the dram timing patches. Since they do not make any changes without them being explictly enabled in Kconfig, I've queued up patches 1 & 2 into u-boot-sunxi/next for merging upstream.
I would like to see this one handled slightly different though, see below.
I assume you're also preparing some defconfig patches to use the new settings on boards where we know exactly which DRAM chips are used (e.g. cubieboard and olinuxino boards) and thus what the proper timings are ?
In fact I'm working on providing a more feature complete update for
http://lists.denx.de/pipermail/u-boot/2015-January/202306.html
with integrated DRAM reliability tests and the ability to probe the DRAM and CPU overclocking limits. Which should allow us to collect some data from more real devices and make decisions about what kind of configuration we want to have set for them by default.
Also a small wiki page explaining how to figure out the right timing based on dram chip markings would be welcome.
On 31-01-15 23:27, Siarhei Siamashka wrote:
Higher vdd-dll voltage allows to use higher dram and mbus clock speeds. The vdd-int/vdd-dll voltage is currently set to 1.25V by default, which is much lower than 1.4V, allowed by datasheets (the exact maximum differs for different SoCs).
There are different use cases. For a tablet, it may be preferable to favor longer battery life and use lower dram clock speed & voltage. But for non-battery powered devices, especially the ones driving full-hd monitors, memory performance may be a lot more important than the power consumption.
A configurable vdd-dll voltage provides better flexibility.
Signed-off-by: Siarhei Siamashka siarhei.siamashka@gmail.com
arch/arm/include/asm/arch-sunxi/dram.h | 1 + arch/arm/include/asm/arch-sunxi/dram_sun4i.h | 1 + board/sunxi/Kconfig | 8 ++++++++ board/sunxi/board.c | 10 +++++++++- board/sunxi/dram_sun4i_auto.c | 6 ++++++ board/sunxi/dram_sun5i_auto.c | 7 +++++++ 6 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 7ff43e6..61ed77c 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -25,6 +25,7 @@ #endif
unsigned long sunxi_dram_init(void); +u32 sunxi_dram_get_min_dll_volt(void);
/*
- Wait up to 1s for value to be set in given part of reg.
diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun4i.h b/arch/arm/include/asm/arch-sunxi/dram_sun4i.h index 40c385a..32493cc 100644 --- a/arch/arm/include/asm/arch-sunxi/dram_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/dram_sun4i.h @@ -88,6 +88,7 @@ struct dram_para { u32 emr3; u32 dqs_gating_delay; u32 active_windowing;
u32 min_dll_volt; };
#define DRAM_CCR_COMMAND_RATE_1T (0x1 << 5)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 4a21589..3092edc 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -99,6 +99,14 @@ config DRAM_DQS_GATING_DELAY is usually good enough, unless running at really high DRAM clocks speeds (up to 600MHz). If unsure, keep as 0.
+config DRAM_MIN_DLL_VOLT
- int "sunxi dram odt_en value"
- default 1250
- ---help---
- Set the minimum VDD-DLL/VDD-INT voltage (mV), required for
- reliable DRAM operation. On Allwinner A10/A13/A20 devices with
- AXP209 PMIC it is provided from DCDC3.
- choice prompt "sunxi dram timings" default DRAM_TIMINGS_VENDOR_MAGIC
Can you please split this patch in 2:
- Add a CONFIG_AXP209_POWER, mirroring config AXP221_POWER
in drivers/power/Kconfig (put it at the top of the Kconfig file please), and update all the sunxi defconfig-s which currently set AXP209_POWER in CONFIG_SYS_EXTRA_OPTIONS to instead set +S:CONFIG_AXP209_POWER=y in there defconfigs
- Add a config AXP209_DCDC3_VOLT with a default of 1250
(copy & paste from AXP221_DCDC1_VOLT) and then in board/sunxi/board.c simply replace:
power_failed |= axp209_set_dcdc3(min_dll_volt); with: power_failed |= axp209_set_dcdc3(CONFIG_AXP209_DCDC3_VOLT);
This approach has 3 advantages:
- it is consistent with what we're doing for the axp221
- it cleans up a bit of our CONFIG_SYS_EXTRA_OPTIONS (ab)use
- it avoids the IMHO unnecessary indirection you add with the suggested sunxi_dram_get_min_dll_volt approach
The fundamental difference of your approach is that it focuses on the voltage "producer" (the DCDC3 rail of the PMIC) instead of the voltage "consumer" (the VDD-INT/VDD-DLL pins of the SoC). We even already have a minor inconsistency on A10s, which has a different PMIC and uses DCDC4 for powering VDD-INT/VDD-DLL instead of DCDC3 on A10/A13/A20.
I see the 'required minimum voltage' as an important part of the DRAM settings. And I want it to be a part of the 'dram_para' structure, so that the SPL binary (the relevant sectors on the SD card) can be edited by external tools to update the DRAM configuration.
Thanks & Regards,
Hans
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index b70e00c..ce6aef5 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -154,11 +154,19 @@ void i2c_init_board(void) clock_twi_onoff(0, 1); }
+__weak u32 sunxi_dram_get_min_dll_volt(void) +{
- return 0;
+}
#ifdef CONFIG_SPL_BUILD void sunxi_board_init(void) { int power_failed = 0; unsigned long ramsize;
u32 min_dll_volt = sunxi_dram_get_min_dll_volt();
if (min_dll_volt < 1250)
min_dll_volt = 1250;
#ifdef CONFIG_AXP152_POWER power_failed = axp152_init();
@@ -170,7 +178,7 @@ void sunxi_board_init(void) #ifdef CONFIG_AXP209_POWER power_failed |= axp209_init(); power_failed |= axp209_set_dcdc2(1400);
- power_failed |= axp209_set_dcdc3(1250);
- power_failed |= axp209_set_dcdc3(min_dll_volt); power_failed |= axp209_set_ldo2(3000); power_failed |= axp209_set_ldo3(2800); power_failed |= axp209_set_ldo4(2800);
diff --git a/board/sunxi/dram_sun4i_auto.c b/board/sunxi/dram_sun4i_auto.c index 09e0c9a..c0c8a28 100644 --- a/board/sunxi/dram_sun4i_auto.c +++ b/board/sunxi/dram_sun4i_auto.c @@ -27,9 +27,15 @@ static struct dram_para dram_para = { .emr1 = CONFIG_DRAM_EMR1, .emr3 = 0, .dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY,
.min_dll_volt = CONFIG_DRAM_MIN_DLL_VOLT, };
unsigned long sunxi_dram_init(void) { return dramc_init(&dram_para); }
+u32 sunxi_dram_get_min_dll_volt(void) +{
- return dram_para.min_dll_volt;
+} diff --git a/board/sunxi/dram_sun5i_auto.c b/board/sunxi/dram_sun5i_auto.c index e52d54c..30febe5 100644 --- a/board/sunxi/dram_sun5i_auto.c +++ b/board/sunxi/dram_sun5i_auto.c @@ -30,9 +30,16 @@ static struct dram_para dram_para = { .emr1 = CONFIG_DRAM_EMR1, .emr3 = 0, .dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY,
.min_dll_volt = CONFIG_DRAM_MIN_DLL_VOLT, };
unsigned long sunxi_dram_init(void) { return dramc_init(&dram_para); }
+u32 sunxi_dram_get_min_dll_volt(void) +{
- return dram_para.min_dll_volt;
+}

Hi,
On 11-02-15 04:38, Siarhei Siamashka wrote:
On Mon, 02 Feb 2015 14:13:18 +0100 Hans de Goede hdegoede@redhat.com wrote:
Hi,
Thanks for the dram timing patches. Since they do not make any changes without them being explictly enabled in Kconfig, I've queued up patches 1 & 2 into u-boot-sunxi/next for merging upstream.
I would like to see this one handled slightly different though, see below.
I assume you're also preparing some defconfig patches to use the new settings on boards where we know exactly which DRAM chips are used (e.g. cubieboard and olinuxino boards) and thus what the proper timings are ?
In fact I'm working on providing a more feature complete update for
http://lists.denx.de/pipermail/u-boot/2015-January/202306.html
with integrated DRAM reliability tests and the ability to probe the DRAM and CPU overclocking limits. Which should allow us to collect some data from more real devices and make decisions about what kind of configuration we want to have set for them by default.
Also a small wiki page explaining how to figure out the right timing based on dram chip markings would be welcome.
On 31-01-15 23:27, Siarhei Siamashka wrote:
Higher vdd-dll voltage allows to use higher dram and mbus clock speeds. The vdd-int/vdd-dll voltage is currently set to 1.25V by default, which is much lower than 1.4V, allowed by datasheets (the exact maximum differs for different SoCs).
There are different use cases. For a tablet, it may be preferable to favor longer battery life and use lower dram clock speed & voltage. But for non-battery powered devices, especially the ones driving full-hd monitors, memory performance may be a lot more important than the power consumption.
A configurable vdd-dll voltage provides better flexibility.
Signed-off-by: Siarhei Siamashka siarhei.siamashka@gmail.com
arch/arm/include/asm/arch-sunxi/dram.h | 1 + arch/arm/include/asm/arch-sunxi/dram_sun4i.h | 1 + board/sunxi/Kconfig | 8 ++++++++ board/sunxi/board.c | 10 +++++++++- board/sunxi/dram_sun4i_auto.c | 6 ++++++ board/sunxi/dram_sun5i_auto.c | 7 +++++++ 6 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 7ff43e6..61ed77c 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -25,6 +25,7 @@ #endif
unsigned long sunxi_dram_init(void); +u32 sunxi_dram_get_min_dll_volt(void);
/* * Wait up to 1s for value to be set in given part of reg. diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun4i.h b/arch/arm/include/asm/arch-sunxi/dram_sun4i.h index 40c385a..32493cc 100644 --- a/arch/arm/include/asm/arch-sunxi/dram_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/dram_sun4i.h @@ -88,6 +88,7 @@ struct dram_para { u32 emr3; u32 dqs_gating_delay; u32 active_windowing;
u32 min_dll_volt; };
#define DRAM_CCR_COMMAND_RATE_1T (0x1 << 5)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 4a21589..3092edc 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -99,6 +99,14 @@ config DRAM_DQS_GATING_DELAY is usually good enough, unless running at really high DRAM clocks speeds (up to 600MHz). If unsure, keep as 0.
+config DRAM_MIN_DLL_VOLT
- int "sunxi dram odt_en value"
- default 1250
- ---help---
- Set the minimum VDD-DLL/VDD-INT voltage (mV), required for
- reliable DRAM operation. On Allwinner A10/A13/A20 devices with
- AXP209 PMIC it is provided from DCDC3.
- choice prompt "sunxi dram timings" default DRAM_TIMINGS_VENDOR_MAGIC
Can you please split this patch in 2:
- Add a CONFIG_AXP209_POWER, mirroring config AXP221_POWER
in drivers/power/Kconfig (put it at the top of the Kconfig file please), and update all the sunxi defconfig-s which currently set AXP209_POWER in CONFIG_SYS_EXTRA_OPTIONS to instead set +S:CONFIG_AXP209_POWER=y in there defconfigs
- Add a config AXP209_DCDC3_VOLT with a default of 1250
(copy & paste from AXP221_DCDC1_VOLT) and then in board/sunxi/board.c simply replace:
power_failed |= axp209_set_dcdc3(min_dll_volt); with: power_failed |= axp209_set_dcdc3(CONFIG_AXP209_DCDC3_VOLT);
This approach has 3 advantages:
- it is consistent with what we're doing for the axp221
- it cleans up a bit of our CONFIG_SYS_EXTRA_OPTIONS (ab)use
- it avoids the IMHO unnecessary indirection you add with the suggested sunxi_dram_get_min_dll_volt approach
The fundamental difference of your approach is that it focuses on the voltage "producer" (the DCDC3 rail of the PMIC) instead of the voltage "consumer" (the VDD-INT/VDD-DLL pins of the SoC). We even already have a minor inconsistency on A10s, which has a different PMIC and uses DCDC4 for powering VDD-INT/VDD-DLL instead of DCDC3 on A10/A13/A20.
I see the 'required minimum voltage' as an important part of the DRAM settings. And I want it to be a part of the 'dram_para' structure, so that the SPL binary (the relevant sectors on the SD card) can be edited by external tools to update the DRAM configuration.
OK, fair enough, still can you remove all the unnecessary indirection please ?
Just make dram_para a global, and directly use it in the set_dcdcd call in board.c
Regards,
Hans
Thanks & Regards,
Hans
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index b70e00c..ce6aef5 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -154,11 +154,19 @@ void i2c_init_board(void) clock_twi_onoff(0, 1); }
+__weak u32 sunxi_dram_get_min_dll_volt(void) +{
- return 0;
+}
#ifdef CONFIG_SPL_BUILD void sunxi_board_init(void) { int power_failed = 0; unsigned long ramsize;
u32 min_dll_volt = sunxi_dram_get_min_dll_volt();
if (min_dll_volt < 1250)
min_dll_volt = 1250;
#ifdef CONFIG_AXP152_POWER power_failed = axp152_init();
@@ -170,7 +178,7 @@ void sunxi_board_init(void) #ifdef CONFIG_AXP209_POWER power_failed |= axp209_init(); power_failed |= axp209_set_dcdc2(1400);
- power_failed |= axp209_set_dcdc3(1250);
- power_failed |= axp209_set_dcdc3(min_dll_volt); power_failed |= axp209_set_ldo2(3000); power_failed |= axp209_set_ldo3(2800); power_failed |= axp209_set_ldo4(2800);
diff --git a/board/sunxi/dram_sun4i_auto.c b/board/sunxi/dram_sun4i_auto.c index 09e0c9a..c0c8a28 100644 --- a/board/sunxi/dram_sun4i_auto.c +++ b/board/sunxi/dram_sun4i_auto.c @@ -27,9 +27,15 @@ static struct dram_para dram_para = { .emr1 = CONFIG_DRAM_EMR1, .emr3 = 0, .dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY,
.min_dll_volt = CONFIG_DRAM_MIN_DLL_VOLT, };
unsigned long sunxi_dram_init(void) { return dramc_init(&dram_para); }
+u32 sunxi_dram_get_min_dll_volt(void) +{
- return dram_para.min_dll_volt;
+} diff --git a/board/sunxi/dram_sun5i_auto.c b/board/sunxi/dram_sun5i_auto.c index e52d54c..30febe5 100644 --- a/board/sunxi/dram_sun5i_auto.c +++ b/board/sunxi/dram_sun5i_auto.c @@ -30,9 +30,16 @@ static struct dram_para dram_para = { .emr1 = CONFIG_DRAM_EMR1, .emr3 = 0, .dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY,
.min_dll_volt = CONFIG_DRAM_MIN_DLL_VOLT, };
unsigned long sunxi_dram_init(void) { return dramc_init(&dram_para); }
+u32 sunxi_dram_get_min_dll_volt(void) +{
- return dram_para.min_dll_volt;
+}
participants (2)
-
Hans de Goede
-
Siarhei Siamashka