diff mbox

[U-Boot,3/9] sunxi: Stop differentiating between 512M and 1G variants of the same board

Message ID 1421583812-26556-3-git-send-email-hdegoede@redhat.com
State Accepted
Delegated to: Hans de Goede
Headers show

Commit Message

Hans de Goede Jan. 18, 2015, 12:23 p.m. UTC
While working on adding more boards I noticed that we lack a config for
the 512M cubieboard, and that some of the new boards which I want to add also
have 512M and 1G variants, rather then adding 2 defconfig's for all of these,
lets switch the exising boards which have both a 512M and 1024M variant over
to the sun4i dram autoconfig code.

This also drops the foo_RAMSIZE_defconfig variants of boards where we currently
have 2 separate configs already.

Note:
1) The newly introduced CONFIG_DRAM_EMR1 kconfig value is not used with
a value other then its default for now, but we need this to be configurable
to support some new boards with auto dram config.

2) We always set all CONFIG_DRAM_foo values in defconfigs, even if they match
the defaults, this is done to make it more clear what values are used for a
certain board.

This has been tested on a Mele A1000, Mini-X and a Cubieboard, all 1G
variants, the dram autoconfig code has also been tested on a 512M mk802
(a defconfig for the mk802 is added in a later patch).

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/include/asm/arch-sunxi/dram_sun4i.h |  2 +-
 board/sunxi/Kconfig                          | 36 +++++++++++++++-------------
 board/sunxi/MAINTAINERS                      |  2 --
 board/sunxi/Makefile                         |  8 +++----
 board/sunxi/dram_cubieboard.c                | 31 ------------------------
 board/sunxi/dram_sun4i_360_1024_iow16.c      | 31 ------------------------
 board/sunxi/dram_sun4i_360_1024_iow8.c       | 31 ------------------------
 board/sunxi/dram_sun4i_360_512.c             | 31 ------------------------
 board/sunxi/dram_sun4i_auto.c                | 31 ++++++++++++++++++++++++
 configs/Cubieboard_defconfig                 |  3 +++
 configs/Mele_A1000G_defconfig                |  8 -------
 configs/Mele_A1000_defconfig                 |  3 +++
 configs/Mini-X-1Gb_defconfig                 |  7 ------
 configs/Mini-X_defconfig                     |  3 +++
 14 files changed, 63 insertions(+), 164 deletions(-)
 delete mode 100644 board/sunxi/dram_cubieboard.c
 delete mode 100644 board/sunxi/dram_sun4i_360_1024_iow16.c
 delete mode 100644 board/sunxi/dram_sun4i_360_1024_iow8.c
 delete mode 100644 board/sunxi/dram_sun4i_360_512.c
 create mode 100644 board/sunxi/dram_sun4i_auto.c
 delete mode 100644 configs/Mele_A1000G_defconfig
 delete mode 100644 configs/Mini-X-1Gb_defconfig

Comments

Ian Campbell Jan. 18, 2015, 4:22 p.m. UTC | #1
On Sun, 2015-01-18 at 13:23 +0100, Hans de Goede wrote:
> diff --git a/board/sunxi/dram_sun4i_auto.c b/board/sunxi/dram_sun4i_auto.c
> new file mode 100644
> index 0000000..115b597
> --- /dev/null
> +++ b/board/sunxi/dram_sun4i_auto.c
> @@ -0,0 +1,31 @@
> +/* this file is generated, don't edit it yourself */

This isn't strictly true any more, is it?

Acked-by: Ian Campbell <ijc@hellion.org.uk>

Ian.
Hans de Goede Jan. 18, 2015, 4:45 p.m. UTC | #2
Hi,

On 18-01-15 17:22, Ian Campbell wrote:
> On Sun, 2015-01-18 at 13:23 +0100, Hans de Goede wrote:
>> diff --git a/board/sunxi/dram_sun4i_auto.c b/board/sunxi/dram_sun4i_auto.c
>> new file mode 100644
>> index 0000000..115b597
>> --- /dev/null
>> +++ b/board/sunxi/dram_sun4i_auto.c
>> @@ -0,0 +1,31 @@
>> +/* this file is generated, don't edit it yourself */
>
> This isn't strictly true any more, is it?

Yeah I was thinking the same thing when working on this but I
wasn't sure what to do I'll drop the comment, as it is clearly
false.

And thanks for the reviews.

> Acked-by: Ian Campbell <ijc@hellion.org.uk>

Regards,

Hans
Siarhei Siamashka Jan. 18, 2015, 9:46 p.m. UTC | #3
On Sun, 18 Jan 2015 13:23:26 +0100
Hans de Goede <hdegoede@redhat.com> wrote:

> While working on adding more boards I noticed that we lack a config for
> the 512M cubieboard, and that some of the new boards which I want to add also
> have 512M and 1G variants, rather then adding 2 defconfig's for all of these,
> lets switch the exising boards which have both a 512M and 1024M variant over
> to the sun4i dram autoconfig code.
> 
> This also drops the foo_RAMSIZE_defconfig variants of boards where we currently
> have 2 separate configs already.
> 
> Note:
> 1) The newly introduced CONFIG_DRAM_EMR1 kconfig value is not used with
> a value other then its default for now, but we need this to be configurable
> to support some new boards with auto dram config.
> 
> 2) We always set all CONFIG_DRAM_foo values in defconfigs, even if they match
> the defaults, this is done to make it more clear what values are used for a
> certain board.
> 
> This has been tested on a Mele A1000, Mini-X and a Cubieboard, all 1G
> variants, the dram autoconfig code has also been tested on a 512M mk802
> (a defconfig for the mk802 is added in a later patch).
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>

Thanks for finally finding time to do some refinements in this pile of
junk dram settings for the boards that you are maintaining.

I think that adding the Kconfig options is fine as long as they
are not abused and the 'dram_para' structure is kept. We want to
be able to update DRAM settings without the need of recompiling SPL.
Currently this can be relatively easily done by finding and patching
the 'dram_para' structure inside of the SPL binary.

In general this looks like a good change. However see below.

[...]

> +++ b/board/sunxi/dram_sun4i_auto.c
> @@ -0,0 +1,31 @@
> +/* this file is generated, don't edit it yourself */
> +
> +#include <common.h>
> +#include <asm/arch/dram.h>
> +
> +static struct dram_para dram_para = {
> +	.clock = CONFIG_DRAM_CLK,
> +	.type = 3,
> +	.rank_num = 1,
> +	.density = 0,
> +	.io_width = 0,
> +	.bus_width = 0,
> +	.cas = 6,
> +	.zq = CONFIG_DRAM_ZQ,
> +	.odt_en = 0,
> +	.size = 0,
> +	.tpr0 = 0x30926692,
> +	.tpr1 = 0x1090,
> +	.tpr2 = 0x1a0c8,
> +	.tpr3 = 0,
> +	.tpr4 = 0,
> +	.tpr5 = 0,
> +	.emr1 = CONFIG_DRAM_EMR1,
> +	.emr2 = 0,
> +	.emr3 = 0,
> +};

As we already discussed earlier
    http://lists.denx.de/pipermail/u-boot/2014-September/189266.html
these tpr0/tpr1/tpr2 settings are configured for DDR2-800E (and 400MHz
clock speed because of double data rate). Yes, DDR2 (!) instead of
DDR3. This in practice is not very much off from DDR3-800, except for
the tXS parameter. But tXS is only relevant for self-refresh, which is
currently not used by the u-boot or the mainline kernel anyway. That's
why this all does not crash and burn in an obvious way.

Anyway, these timings are still wrong for the boards running DRAM
at the clock speeds higher than 400MHz. For example, they are ~20%
outside of the valid range at 480MHz and this all works by pure luck,
thanks to the hardware typically having some safety/overclocking margin.

If we look at the parameters used by the sun7i boards:
	.cas = 9,
	.tpr0 = 0x42d899b7,
	.tpr1 = 0xa090,
	.tpr2 = 0x22a00,
... then we can see that the settings are also a bit fishy. The
tpr1/tpr2 parameters are matching DDR3-800 timings. And tpr0 is
matching DDR3-1333 timings with 1KB (!) page size, while many sunxi
devices are using 2KB pages. So it's some weird crossbreed, which
is however somewhat less wrong than the settings from sun4i boards.

I would suggest trying one of the following DRAM settings, generated
as explained at http://linux-sunxi.org/Mainline_U-boot#DRAM_Settings
And injecting the .clock, .zq and .emr1 parameters from Kconfig.

static struct dram_para dram_para = { /* DRAM timings: 7-7-7-18 (480 MHz) */
	.clock     = 480,
	.type      = 3,
	.rank_num  = 1,
	.cas       = 7,
	.zq        = 0x7b,
	.odt_en    = 0,
	.tpr0      = 0x30927790,
	.tpr1      = 0xa0b0,
	.tpr2      = 0x23200,
	.tpr3      = 0x0,
	.tpr4      = 0x0,
	.tpr5      = 0x0,
	.emr1      = 0x0,
	.emr2      = 0x8,
	.emr3      = 0x0,
	.active_windowing = 1,
};

static struct dram_para dram_para = { /* DRAM timings: 7-8-8-20 (528 MHz) */
	.clock     = 528,
	.type      = 3,
	.rank_num  = 1,
	.cas       = 7,
	.zq        = 0x7b,
	.odt_en    = 0,
	.tpr0      = 0x36948890,
	.tpr1      = 0xa0c0,
	.tpr2      = 0x23600,
	.tpr3      = 0x0,
	.tpr4      = 0x0,
	.tpr5      = 0x0,
	.emr1      = 0x0,
	.emr2      = 0x8,
	.emr3      = 0x0,
	.active_windowing = 1,
};

Alternatively, we can add runtime calculation of cas/tpr0/tpr1/tpr2/emr2
parameters directly into SPL, thus better matching the selected DRAM
clock speed and reducing memory access latency. The disadvantages of
this approach are:
1. Somewhat increased SPL size.
2. Some DDR3 chips have better timings than generic JEDEC speed bins, so
   using generic timings for every board may be not very optimal.

This all is only blocked on the lack of cooperation from the u-boot
sunxi boards maintainers, who appear to be kinda happy with the status
quo and prefer the sacred magic settings from the vendors over what is
suggested by the geeks doing reverse engineering ;-)

To sum it up. We need motivated testers in order to improve things.
Clever hackers are not really required.
Hans de Goede Jan. 19, 2015, 2:35 p.m. UTC | #4
Hi,

On 18-01-15 22:46, Siarhei Siamashka wrote:
> On Sun, 18 Jan 2015 13:23:26 +0100
> Hans de Goede <hdegoede@redhat.com> wrote:
>
>> While working on adding more boards I noticed that we lack a config for
>> the 512M cubieboard, and that some of the new boards which I want to add also
>> have 512M and 1G variants, rather then adding 2 defconfig's for all of these,
>> lets switch the exising boards which have both a 512M and 1024M variant over
>> to the sun4i dram autoconfig code.
>>
>> This also drops the foo_RAMSIZE_defconfig variants of boards where we currently
>> have 2 separate configs already.
>>
>> Note:
>> 1) The newly introduced CONFIG_DRAM_EMR1 kconfig value is not used with
>> a value other then its default for now, but we need this to be configurable
>> to support some new boards with auto dram config.
>>
>> 2) We always set all CONFIG_DRAM_foo values in defconfigs, even if they match
>> the defaults, this is done to make it more clear what values are used for a
>> certain board.
>>
>> This has been tested on a Mele A1000, Mini-X and a Cubieboard, all 1G
>> variants, the dram autoconfig code has also been tested on a 512M mk802
>> (a defconfig for the mk802 is added in a later patch).
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>
> Thanks for finally finding time to do some refinements in this pile of
> junk dram settings for the boards that you are maintaining.
>
> I think that adding the Kconfig options is fine as long as they
> are not abused and the 'dram_para' structure is kept. We want to
> be able to update DRAM settings without the need of recompiling SPL.
> Currently this can be relatively easily done by finding and patching
> the 'dram_para' structure inside of the SPL binary.
>
> In general this looks like a good change. However see below.
>
> [...]
>
>> +++ b/board/sunxi/dram_sun4i_auto.c
>> @@ -0,0 +1,31 @@
>> +/* this file is generated, don't edit it yourself */
>> +
>> +#include <common.h>
>> +#include <asm/arch/dram.h>
>> +
>> +static struct dram_para dram_para = {
>> +	.clock = CONFIG_DRAM_CLK,
>> +	.type = 3,
>> +	.rank_num = 1,
>> +	.density = 0,
>> +	.io_width = 0,
>> +	.bus_width = 0,
>> +	.cas = 6,
>> +	.zq = CONFIG_DRAM_ZQ,
>> +	.odt_en = 0,
>> +	.size = 0,
>> +	.tpr0 = 0x30926692,
>> +	.tpr1 = 0x1090,
>> +	.tpr2 = 0x1a0c8,
>> +	.tpr3 = 0,
>> +	.tpr4 = 0,
>> +	.tpr5 = 0,
>> +	.emr1 = CONFIG_DRAM_EMR1,
>> +	.emr2 = 0,
>> +	.emr3 = 0,
>> +};
>
> As we already discussed earlier
>      http://lists.denx.de/pipermail/u-boot/2014-September/189266.html
> these tpr0/tpr1/tpr2 settings are configured for DDR2-800E (and 400MHz
> clock speed because of double data rate). Yes, DDR2 (!) instead of
> DDR3. This in practice is not very much off from DDR3-800, except for
> the tXS parameter. But tXS is only relevant for self-refresh, which is
> currently not used by the u-boot or the mainline kernel anyway. That's
> why this all does not crash and burn in an obvious way.
>
> Anyway, these timings are still wrong for the boards running DRAM
> at the clock speeds higher than 400MHz. For example, they are ~20%
> outside of the valid range at 480MHz and this all works by pure luck,
> thanks to the hardware typically having some safety/overclocking margin.
>
> If we look at the parameters used by the sun7i boards:
> 	.cas = 9,
> 	.tpr0 = 0x42d899b7,
> 	.tpr1 = 0xa090,
> 	.tpr2 = 0x22a00,
> ... then we can see that the settings are also a bit fishy. The
> tpr1/tpr2 parameters are matching DDR3-800 timings. And tpr0 is
> matching DDR3-1333 timings with 1KB (!) page size, while many sunxi
> devices are using 2KB pages. So it's some weird crossbreed, which
> is however somewhat less wrong than the settings from sun4i boards.
>
> I would suggest trying one of the following DRAM settings, generated
> as explained at http://linux-sunxi.org/Mainline_U-boot#DRAM_Settings
> And injecting the .clock, .zq and .emr1 parameters from Kconfig.
>
> static struct dram_para dram_para = { /* DRAM timings: 7-7-7-18 (480 MHz) */
> 	.clock     = 480,
> 	.type      = 3,
> 	.rank_num  = 1,
> 	.cas       = 7,
> 	.zq        = 0x7b,
> 	.odt_en    = 0,
> 	.tpr0      = 0x30927790,
> 	.tpr1      = 0xa0b0,
> 	.tpr2      = 0x23200,
> 	.tpr3      = 0x0,
> 	.tpr4      = 0x0,
> 	.tpr5      = 0x0,
> 	.emr1      = 0x0,
> 	.emr2      = 0x8,
> 	.emr3      = 0x0,
> 	.active_windowing = 1,
> };
>
> static struct dram_para dram_para = { /* DRAM timings: 7-8-8-20 (528 MHz) */
> 	.clock     = 528,
> 	.type      = 3,
> 	.rank_num  = 1,
> 	.cas       = 7,
> 	.zq        = 0x7b,
> 	.odt_en    = 0,
> 	.tpr0      = 0x36948890,
> 	.tpr1      = 0xa0c0,
> 	.tpr2      = 0x23600,
> 	.tpr3      = 0x0,
> 	.tpr4      = 0x0,
> 	.tpr5      = 0x0,
> 	.emr1      = 0x0,
> 	.emr2      = 0x8,
> 	.emr3      = 0x0,
> 	.active_windowing = 1,
> };
>
> Alternatively, we can add runtime calculation of cas/tpr0/tpr1/tpr2/emr2
> parameters directly into SPL, thus better matching the selected DRAM
> clock speed and reducing memory access latency. The disadvantages of
> this approach are:
> 1. Somewhat increased SPL size.
> 2. Some DDR3 chips have better timings than generic JEDEC speed bins, so
>     using generic timings for every board may be not very optimal.
>
> This all is only blocked on the lack of cooperation from the u-boot
> sunxi boards maintainers, who appear to be kinda happy with the status
> quo and prefer the sacred magic settings from the vendors over what is
> suggested by the geeks doing reverse engineering ;-)

Siarhei, thanks for bringing this topic up once again, I agree that this
is ideally something which we should fix. The problem is that the only
way to know that any new settings which we do are actually good, is to
test them on lots of boards, and I do not mean one of each board, but
at least 10 of each board or some such.

Unfortunately that is not really feasible due to -ENOHWARDARE (not 10
of each) and -ENOTIME.

Still I would like to get this sorted, so I would like to move to the
recommended timings for the generic JEDEC speed bins, you rightfully
point out that those may not be 100% optimal, but given that we're
dealing with a lot of cheap boards, I think that those are our best bet.

The plan would be for you to submit a patch for that, and then I'll add
that to my sunxi-wip branch right away, this way all the testing I do,
as well as all the testing people using my sunxi-wip branch do will use
the new timings, and then once v2015.04 stabilizes a bit we can add
that patch to u-boot-sunxi/next, getting it ready for v2015.07 .

Does that sound like a plan ?

Ian, what do you think about this ?

As for runtime calculation, it might be easier to instead do something
like this in the "new" dram_sun4i_auto.c file which my patch-set
introduces:

#if CONFIG_DRAM_CLK > 528
#error DRAM clocks above 528 Mhz are not supported
#elif CONFIG_DRAM_CLK > 480

static struct dram_para dram_para = { /* DRAM timings: 7-8-8-20 (528 MHz) */
	.clock     = CONFIG_DRAM_CLK,
...
};

#elif CONFIG_DRAM_CLK > 400

static struct dram_para dram_para = { /* DRAM timings: 7-7-7-18 (480 MHz) */
	.clock     = CONFIG_DRAM_CLK,
...
};

#elif CONFIG_DRAM_CLK > 360

static struct dram_para dram_para = { /* DRAM timings: a-b-c-d (400 MHz) */
	.clock     = CONFIG_DRAM_CLK,
...
};

#else

static struct dram_para dram_para = { /* DRAM timings: a-b-c-d (360 MHz) */
	.clock     = CONFIG_DRAM_CLK,
...
};

#endif

This way we will not grow the spl, and keep an easy editable set of
dram_para in the spl for people who like to hexedit the spl ...

Regards,

Hans
Ian Campbell Jan. 20, 2015, 8:51 a.m. UTC | #5
On Mon, 2015-01-19 at 15:35 +0100, Hans de Goede wrote:
> Siarhei, thanks for bringing this topic up once again, I agree that this
> is ideally something which we should fix. The problem is that the only
> way to know that any new settings which we do are actually good, is to
> test them on lots of boards, and I do not mean one of each board, but
> at least 10 of each board or some such.

I agree. Having settings which are optimal for Hans' board but untested
elsewhere would not be a good idea IMHO.

> Still I would like to get this sorted, so I would like to move to the
> recommended timings for the generic JEDEC speed bins, you rightfully
> point out that those may not be 100% optimal, but given that we're
> dealing with a lot of cheap boards, I think that those are our best bet.

Agreed. In the absence of an ability to test lots of boards this is
probably the best we can do.

An alternative would be to use the settings from the factory firmware,
but I don't think we have any real reason to think these will be any
better in general than the JEDEC timings, at least not without lots of
testing (see previous paragraph).

> The plan would be for you to submit a patch for that, and then I'll add
> that to my sunxi-wip branch right away, this way all the testing I do,
> as well as all the testing people using my sunxi-wip branch do will use
> the new timings, and then once v2015.04 stabilizes a bit we can add
> that patch to u-boot-sunxi/next, getting it ready for v2015.07 .
> 
> Does that sound like a plan ?
> 
> Ian, what do you think about this ?

Go for it.

> This way we will not grow the spl, and keep an easy editable set of
> dram_para in the spl for people who like to hexedit the spl ...

At the start of the #ifdef chain you could add

#ifdef CONFIG...CUSTOM_DRAM_SETTINGS
static struct dram_para dram_para = {
    CONFIG_...CUSTOM_DRAM_SETTINGS
};
#elif ...

along with a corresponding Kconfig entry (perhaps depends on EXPERT?).

Then people who really want to tweak things could enter
"CONFIG....=.clock=XXX,.type=YYY,.." in their .config (menuconfig etc)
or defconfig to their heart's content. (only question is what the
character limit on a config option is...)

Ian.
diff mbox

Patch

diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun4i.h b/arch/arm/include/asm/arch-sunxi/dram_sun4i.h
index 6c1ec5b..40c385a 100644
--- a/arch/arm/include/asm/arch-sunxi/dram_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/dram_sun4i.h
@@ -76,7 +76,7 @@  struct dram_para {
 	u32 cas;
 	u32 zq;
 	u32 odt_en;
-	u32 size;
+	u32 size; /* For compat with dram.c files from u-boot-sunxi, unused */
 	u32 tpr0;
 	u32 tpr1;
 	u32 tpr2;
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index e65b8af..f7064d0 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -37,21 +37,31 @@  config MACH_SUN9I
 
 endchoice
 
-if MACH_SUN6I || MACH_SUN8I
-
 config DRAM_CLK
-	int "sun6i dram clock speed"
-	default 312
+	int "sunxi dram clock speed"
+	default 312 if MACH_SUN6I || MACH_SUN8I
+	default 360 if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
 	---help---
 	Set the dram clock speed, valid range 240 - 480, must be a multiple
-	of 24.
+	of 24. Note on sun4i / sun5i / sun7i this is only used by boards
+	which use dram autoconfig.
 
 config DRAM_ZQ
-	int "sun6i dram zq value"
-	default 123
+	int "sunxi dram zq value"
+	default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN8I
+	default 127 if MACH_SUN7I
 	---help---
-	Set the dram zq value.
-
+	Set the dram zq value. Note on sun4i / sun5i / sun7i this is only
+	used by boards which use dram autoconfig.
+
+if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
+config DRAM_EMR1
+	int "sunxi dram emr1 value"
+	default 0 if MACH_SUN4I
+	default 4 if MACH_SUN5I || MACH_SUN7I
+	---help---
+	Set the dram controller emr1 value. Note this is only used by boards
+	which use dram autoconfig.
 endif
 
 config SYS_CONFIG_NAME
@@ -141,10 +151,6 @@  config TARGET_PCDUINO3
 	bool "PCDUINO3"
 	depends on MACH_SUN7I
 
-config TARGET_MELE_A1000G
-	bool "MELE_A1000G"
-	depends on MACH_SUN4I
-
 config TARGET_MELE_A1000
 	bool "MELE_A1000"
 	depends on MACH_SUN4I
@@ -157,10 +163,6 @@  config TARGET_MELE_M9
 	bool "MELE_M9"
 	depends on MACH_SUN6I
 
-config TARGET_MINI_X_1GB
-	bool "MINI_X_1GB"
-	depends on MACH_SUN4I
-
 config TARGET_MINI_X
 	bool "MINI_X"
 	depends on MACH_SUN4I
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index 7cd0b20..16429d4 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -8,10 +8,8 @@  F:	configs/ba10_tv_box_defconfig
 F:	configs/Chuwi_V7_CW0825_defconfig
 F:	configs/Cubieboard_defconfig
 F:	configs/Mele_A1000_defconfig
-F:	configs/Mele_A1000G_defconfig
 F:	configs/Mele_M3_defconfig
 F:	configs/Mini-X_defconfig
-F:	configs/Mini-X-1Gb_defconfig
 F:	include/configs/sun5i.h
 F:	configs/A10s-OLinuXino-M_defconfig
 F:	configs/A13-OLinuXino_defconfig
diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index b0a9b9e..606bf73 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -24,15 +24,13 @@  obj-$(CONFIG_TARGET_BA10_TV_BOX)	+= dram_sun4i_384_1024_iow8.o
 obj-$(CONFIG_TARGET_BANANAPI)		+= dram_bananapi.o
 obj-$(CONFIG_TARGET_BANANAPRO)		+= dram_bananapi.o
 obj-$(CONFIG_TARGET_CHUWI_V7_CW0825)	+= dram_sun4i_408_1024_iow16.o
-obj-$(CONFIG_TARGET_CUBIEBOARD)		+= dram_cubieboard.o
+obj-$(CONFIG_TARGET_CUBIEBOARD)		+= dram_sun4i_auto.o
 obj-$(CONFIG_TARGET_CUBIEBOARD2)	+= dram_cubieboard2.o
 obj-$(CONFIG_TARGET_CUBIETRUCK)		+= dram_cubietruck.o
 obj-$(CONFIG_TARGET_I12_TVBOX)		+= dram_sun7i_384_1024_iow16.o
-obj-$(CONFIG_TARGET_MELE_A1000)		+= dram_sun4i_360_512.o
-obj-$(CONFIG_TARGET_MELE_A1000G)	+= dram_sun4i_360_1024_iow8.o
+obj-$(CONFIG_TARGET_MELE_A1000)		+= dram_sun4i_auto.o
 obj-$(CONFIG_TARGET_MELE_M3)		+= dram_sun7i_384_1024_iow16.o
-obj-$(CONFIG_TARGET_MINI_X)		+= dram_sun4i_360_512.o
-obj-$(CONFIG_TARGET_MINI_X_1GB)		+= dram_sun4i_360_1024_iow16.o
+obj-$(CONFIG_TARGET_MINI_X)		+= dram_sun4i_auto.o
 obj-$(CONFIG_TARGET_MSI_PRIMO73)	+= dram_sun7i_384_1024_iow16.o
 obj-$(CONFIG_TARGET_PCDUINO)		+= dram_sun4i_408_1024_iow8.o
 obj-$(CONFIG_TARGET_PCDUINO3)		+= dram_linksprite_pcduino3.o
diff --git a/board/sunxi/dram_cubieboard.c b/board/sunxi/dram_cubieboard.c
deleted file mode 100644
index 399028c..0000000
--- a/board/sunxi/dram_cubieboard.c
+++ /dev/null
@@ -1,31 +0,0 @@ 
-/* this file is generated, don't edit it yourself */
-
-#include <common.h>
-#include <asm/arch/dram.h>
-
-static struct dram_para dram_para = {
-	.clock = 480,
-	.type = 3,
-	.rank_num = 1,
-	.density = 4096,
-	.io_width = 16,
-	.bus_width = 32,
-	.cas = 6,
-	.zq = 123,
-	.odt_en = 0,
-	.size = 1024,
-	.tpr0 = 0x30926692,
-	.tpr1 = 0x1090,
-	.tpr2 = 0x1a0c8,
-	.tpr3 = 0,
-	.tpr4 = 0,
-	.tpr5 = 0,
-	.emr1 = 0,
-	.emr2 = 0,
-	.emr3 = 0,
-};
-
-unsigned long sunxi_dram_init(void)
-{
-	return dramc_init(&dram_para);
-}
diff --git a/board/sunxi/dram_sun4i_360_1024_iow16.c b/board/sunxi/dram_sun4i_360_1024_iow16.c
deleted file mode 100644
index 3763713..0000000
--- a/board/sunxi/dram_sun4i_360_1024_iow16.c
+++ /dev/null
@@ -1,31 +0,0 @@ 
-/* this file is generated, don't edit it yourself */
-
-#include <common.h>
-#include <asm/arch/dram.h>
-
-static struct dram_para dram_para = {
-	.clock = 360,
-	.type = 3,
-	.rank_num = 1,
-	.density = 4096,
-	.io_width = 16,
-	.bus_width = 32,
-	.cas = 6,
-	.zq = 123,
-	.odt_en = 0,
-	.size = 1024,
-	.tpr0 = 0x30926692,
-	.tpr1 = 0x1090,
-	.tpr2 = 0x1a0c8,
-	.tpr3 = 0,
-	.tpr4 = 0,
-	.tpr5 = 0,
-	.emr1 = 0,
-	.emr2 = 0,
-	.emr3 = 0,
-};
-
-unsigned long sunxi_dram_init(void)
-{
-	return dramc_init(&dram_para);
-}
diff --git a/board/sunxi/dram_sun4i_360_1024_iow8.c b/board/sunxi/dram_sun4i_360_1024_iow8.c
deleted file mode 100644
index 2a5c9ed..0000000
--- a/board/sunxi/dram_sun4i_360_1024_iow8.c
+++ /dev/null
@@ -1,31 +0,0 @@ 
-/* this file is generated, don't edit it yourself */
-
-#include <common.h>
-#include <asm/arch/dram.h>
-
-static struct dram_para dram_para = {
-	.clock = 360,
-	.type = 3,
-	.rank_num = 1,
-	.density = 2048,
-	.io_width = 8,
-	.bus_width = 32,
-	.cas = 6,
-	.zq = 123,
-	.odt_en = 0,
-	.size = 1024,
-	.tpr0 = 0x30926692,
-	.tpr1 = 0x1090,
-	.tpr2 = 0x1a0c8,
-	.tpr3 = 0,
-	.tpr4 = 0,
-	.tpr5 = 0,
-	.emr1 = 0,
-	.emr2 = 0,
-	.emr3 = 0,
-};
-
-unsigned long sunxi_dram_init(void)
-{
-	return dramc_init(&dram_para);
-}
diff --git a/board/sunxi/dram_sun4i_360_512.c b/board/sunxi/dram_sun4i_360_512.c
deleted file mode 100644
index 48aa6e2..0000000
--- a/board/sunxi/dram_sun4i_360_512.c
+++ /dev/null
@@ -1,31 +0,0 @@ 
-/* this file is generated, don't edit it yourself */
-
-#include <common.h>
-#include <asm/arch/dram.h>
-
-static struct dram_para dram_para = {
-	.clock = 360,
-	.type = 3,
-	.rank_num = 1,
-	.density = 2048,
-	.io_width = 16,
-	.bus_width = 32,
-	.cas = 6,
-	.zq = 123,
-	.odt_en = 0,
-	.size = 512,
-	.tpr0 = 0x30926692,
-	.tpr1 = 0x1090,
-	.tpr2 = 0x1a0c8,
-	.tpr3 = 0,
-	.tpr4 = 0,
-	.tpr5 = 0,
-	.emr1 = 0,
-	.emr2 = 0,
-	.emr3 = 0,
-};
-
-unsigned long sunxi_dram_init(void)
-{
-	return dramc_init(&dram_para);
-}
diff --git a/board/sunxi/dram_sun4i_auto.c b/board/sunxi/dram_sun4i_auto.c
new file mode 100644
index 0000000..115b597
--- /dev/null
+++ b/board/sunxi/dram_sun4i_auto.c
@@ -0,0 +1,31 @@ 
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+	.clock = CONFIG_DRAM_CLK,
+	.type = 3,
+	.rank_num = 1,
+	.density = 0,
+	.io_width = 0,
+	.bus_width = 0,
+	.cas = 6,
+	.zq = CONFIG_DRAM_ZQ,
+	.odt_en = 0,
+	.size = 0,
+	.tpr0 = 0x30926692,
+	.tpr1 = 0x1090,
+	.tpr2 = 0x1a0c8,
+	.tpr3 = 0,
+	.tpr4 = 0,
+	.tpr5 = 0,
+	.emr1 = CONFIG_DRAM_EMR1,
+	.emr2 = 0,
+	.emr3 = 0,
+};
+
+unsigned long sunxi_dram_init(void)
+{
+	return dramc_init(&dram_para);
+}
diff --git a/configs/Cubieboard_defconfig b/configs/Cubieboard_defconfig
index 0bc45fd..b256b95 100644
--- a/configs/Cubieboard_defconfig
+++ b/configs/Cubieboard_defconfig
@@ -5,3 +5,6 @@  CONFIG_FDTFILE="sun4i-a10-cubieboard.dtb"
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN4I=y
 +S:CONFIG_TARGET_CUBIEBOARD=y
++S:CONFIG_DRAM_CLK=480
++S:CONFIG_DRAM_ZQ=123
++S:CONFIG_DRAM_EMR1=0
diff --git a/configs/Mele_A1000G_defconfig b/configs/Mele_A1000G_defconfig
deleted file mode 100644
index 9cb3285..0000000
--- a/configs/Mele_A1000G_defconfig
+++ /dev/null
@@ -1,8 +0,0 @@ 
-CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),AHCI,USB_EHCI"
-CONFIG_FDTFILE="sun4i-a10-a1000.dtb"
-CONFIG_VIDEO_VGA=y
-+S:CONFIG_ARM=y
-+S:CONFIG_ARCH_SUNXI=y
-+S:CONFIG_MACH_SUN4I=y
-+S:CONFIG_TARGET_MELE_A1000G=y
diff --git a/configs/Mele_A1000_defconfig b/configs/Mele_A1000_defconfig
index 97d9454..3b4a19e 100644
--- a/configs/Mele_A1000_defconfig
+++ b/configs/Mele_A1000_defconfig
@@ -6,3 +6,6 @@  CONFIG_VIDEO_VGA=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN4I=y
 +S:CONFIG_TARGET_MELE_A1000=y
++S:CONFIG_DRAM_CLK=360
++S:CONFIG_DRAM_ZQ=123
++S:CONFIG_DRAM_EMR1=0
diff --git a/configs/Mini-X-1Gb_defconfig b/configs/Mini-X-1Gb_defconfig
deleted file mode 100644
index b8fea01..0000000
--- a/configs/Mini-X-1Gb_defconfig
+++ /dev/null
@@ -1,7 +0,0 @@ 
-CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,USB_EHCI"
-CONFIG_FDTFILE="sun4i-a10-mini-xplus.dtb"
-+S:CONFIG_ARM=y
-+S:CONFIG_ARCH_SUNXI=y
-+S:CONFIG_MACH_SUN4I=y
-+S:CONFIG_TARGET_MINI_X_1GB=y
diff --git a/configs/Mini-X_defconfig b/configs/Mini-X_defconfig
index 0f6bbe0..bb39464 100644
--- a/configs/Mini-X_defconfig
+++ b/configs/Mini-X_defconfig
@@ -5,3 +5,6 @@  CONFIG_FDTFILE="sun4i-a10-mini-xplus.dtb"
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN4I=y
 +S:CONFIG_TARGET_MINI_X=y
++S:CONFIG_DRAM_CLK=360
++S:CONFIG_DRAM_ZQ=123
++S:CONFIG_DRAM_EMR1=0