[U-Boot] [PATCH v2 15/23] sunxi: A64: use H3 DRAM initialization code for A64

Maxime Ripard maxime.ripard at free-electrons.com
Mon Dec 12 13:29:52 CET 2016


On Tue, Dec 06, 2016 at 02:15:17PM +0000, Andre Przywara wrote:
> Hi,
> 
> On 06/12/16 11:20, Maxime Ripard wrote:
> > On Mon, Dec 05, 2016 at 01:52:22AM +0000, Andre Przywara wrote:
> >> From: Jens Kuske <jenskuske at gmail.com>
> >>
> >> The A64 DRAM controller is very similar to the H3 one,
> >> so the code can be reused with some small changes.
> >> [Andre: fixed up typo, merged in fixes from Jens]
> >>
> >> Signed-off-by: Jens Kuske <jenskuske at gmail.com>
> >> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> >> ---
> >>  arch/arm/include/asm/arch-sunxi/clock_sun6i.h   |   1 +
> >>  arch/arm/include/asm/arch-sunxi/dram.h          |   2 +-
> >>  arch/arm/include/asm/arch-sunxi/dram_sun8i_h3.h |  10 +-
> >>  arch/arm/mach-sunxi/Makefile                    |   1 +
> >>  arch/arm/mach-sunxi/clock_sun6i.c               |   2 +-
> >>  arch/arm/mach-sunxi/dram_sun8i_h3.c             | 139 +++++++++++++++++++-----
> >>  6 files changed, 123 insertions(+), 32 deletions(-)
> >>
> >> diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
> >> index be9fcfd..3f87672 100644
> >> --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
> >> +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
> >> @@ -322,6 +322,7 @@ struct sunxi_ccm_reg {
> >>  #define CCM_DRAMCLK_CFG_DIV0_MASK	(0xf << 8)
> >>  #define CCM_DRAMCLK_CFG_SRC_PLL5	(0x0 << 20)
> >>  #define CCM_DRAMCLK_CFG_SRC_PLL6x2	(0x1 << 20)
> >> +#define CCM_DRAMCLK_CFG_SRC_PLL11	(0x1 << 20) /* A64 only */
> >>  #define CCM_DRAMCLK_CFG_SRC_MASK	(0x3 << 20)
> >>  #define CCM_DRAMCLK_CFG_UPD		(0x1 << 16)
> >>  #define CCM_DRAMCLK_CFG_RST		(0x1 << 31)
> >> diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h
> >> index e0be744..53e6d47 100644
> >> --- a/arch/arm/include/asm/arch-sunxi/dram.h
> >> +++ b/arch/arm/include/asm/arch-sunxi/dram.h
> >> @@ -24,7 +24,7 @@
> >>  #include <asm/arch/dram_sun8i_a33.h>
> >>  #elif defined(CONFIG_MACH_SUN8I_A83T)
> >>  #include <asm/arch/dram_sun8i_a83t.h>
> >> -#elif defined(CONFIG_MACH_SUN8I_H3)
> >> +#elif defined(CONFIG_MACH_SUN8I_H3) || defined(CONFIG_MACH_SUN50I)
> >>  #include <asm/arch/dram_sun8i_h3.h>
> >>  #elif defined(CONFIG_MACH_SUN9I)
> >>  #include <asm/arch/dram_sun9i.h>
> >> diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun8i_h3.h b/arch/arm/include/asm/arch-sunxi/dram_sun8i_h3.h
> >> index 867fd12..b0e5d93 100644
> >> --- a/arch/arm/include/asm/arch-sunxi/dram_sun8i_h3.h
> >> +++ b/arch/arm/include/asm/arch-sunxi/dram_sun8i_h3.h
> >> @@ -15,7 +15,8 @@
> >>  
> >>  struct sunxi_mctl_com_reg {
> >>  	u32 cr;			/* 0x00 control register */
> >> -	u8 res0[0xc];		/* 0x04 */
> >> +	u8 res0[0x8];		/* 0x04 */
> >> +	u32 tmr;		/* 0x0c (A64 only) */
> > 
> > #ifdef?
> 
> What would that change aside from making it hard to read?
> This is a structure definition, so it doesn't generate any code on its
> own. And we only access that field from the A64, so it keeps its
> reserved nature for the H3.

Yes, but at least we can catch improper writes to the register on !A64
platforms at compile time. We already use that construct in the u-boot
code, and you're using it every where in the code already, so it
wouldn't really make it harder to read than it already is.

> 
> >>  	u32 mcr[16][2];		/* 0x10 */
> >>  	u32 bwcr;		/* 0x90 bandwidth control register */
> >>  	u32 maer;		/* 0x94 master enable register */
> >> @@ -32,7 +33,9 @@ struct sunxi_mctl_com_reg {
> >>  	u32 swoffr;		/* 0xc4 */
> >>  	u8 res2[0x8];		/* 0xc8 */
> >>  	u32 cccr;		/* 0xd0 */
> >> -	u8 res3[0x72c];		/* 0xd4 */
> >> +	u8 res3[0x54];		/* 0xd4 */
> >> +	u32 mdfs_bwlr[3];	/* 0x128 (A64 only) */
> >> +	u8 res4[0x6cc];		/* 0x134 */
> > 
> > Ditto.
> > 
> >>  	u32 protect;		/* 0x800 */
> >>  };
> >>  
> >> @@ -81,7 +84,8 @@ struct sunxi_mctl_ctl_reg {
> >>  	u32 rfshtmg;		/* 0x90 refresh timing */
> >>  	u32 rfshctl1;		/* 0x94 */
> >>  	u32 pwrtmg;		/* 0x98 */
> >> -	u8 res3[0x20];		/* 0x9c */
> >> +	u8 res3[0x1c];		/* 0x9c */
> >> +	u32 vtfcr;		/* 0xb8 (A64 only) */
> > 
> > Ditto
> > 
> >>  	u32 dqsgmr;		/* 0xbc */
> >>  	u32 dtcr;		/* 0xc0 */
> >>  	u32 dtar[4];		/* 0xc4 */
> >> diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
> >> index e73114e..7daba11 100644
> >> --- a/arch/arm/mach-sunxi/Makefile
> >> +++ b/arch/arm/mach-sunxi/Makefile
> >> @@ -50,4 +50,5 @@ obj-$(CONFIG_MACH_SUN8I_A33)	+= dram_sun8i_a33.o
> >>  obj-$(CONFIG_MACH_SUN8I_A83T)	+= dram_sun8i_a83t.o
> >>  obj-$(CONFIG_MACH_SUN8I_H3)	+= dram_sun8i_h3.o
> >>  obj-$(CONFIG_MACH_SUN9I)	+= dram_sun9i.o
> >> +obj-$(CONFIG_MACH_SUN50I)	+= dram_sun8i_h3.o
> >>  endif
> >> diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c
> >> index 80cfc0b..99f515d 100644
> >> --- a/arch/arm/mach-sunxi/clock_sun6i.c
> >> +++ b/arch/arm/mach-sunxi/clock_sun6i.c
> >> @@ -217,7 +217,7 @@ done:
> >>  }
> >>  #endif
> >>  
> >> -#ifdef CONFIG_MACH_SUN8I_A33
> >> +#if defined(CONFIG_MACH_SUN8I_A33) || defined(CONFIG_MACH_SUN50I)
> >>  void clock_set_pll11(unsigned int clk, bool sigma_delta_enable)
> >>  {
> >>  	struct sunxi_ccm_reg * const ccm =
> >> diff --git a/arch/arm/mach-sunxi/dram_sun8i_h3.c b/arch/arm/mach-sunxi/dram_sun8i_h3.c
> >> index 1647d76..2dc2071 100644
> >> --- a/arch/arm/mach-sunxi/dram_sun8i_h3.c
> >> +++ b/arch/arm/mach-sunxi/dram_sun8i_h3.c
> >> @@ -32,30 +32,6 @@ static inline int ns_to_t(int nanoseconds)
> >>  	return DIV_ROUND_UP(ctrl_freq * nanoseconds, 1000);
> >>  }
> >>  
> >> -static u32 bin_to_mgray(int val)
> >> -{
> >> -	static const u8 lookup_table[32] = {
> >> -		0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
> >> -		0x0c, 0x0d, 0x0e, 0x0f, 0x0a, 0x0b, 0x08, 0x09,
> >> -		0x18, 0x19, 0x1a, 0x1b, 0x1e, 0x1f, 0x1c, 0x1d,
> >> -		0x14, 0x15, 0x16, 0x17, 0x12, 0x13, 0x10, 0x11,
> >> -	};
> >> -
> >> -	return lookup_table[clamp(val, 0, 31)];
> >> -}
> >> -
> >> -static int mgray_to_bin(u32 val)
> >> -{
> >> -	static const u8 lookup_table[32] = {
> >> -		0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
> >> -		0x0e, 0x0f, 0x0c, 0x0d, 0x08, 0x09, 0x0a, 0x0b,
> >> -		0x1e, 0x1f, 0x1c, 0x1d, 0x18, 0x19, 0x1a, 0x1b,
> >> -		0x10, 0x11, 0x12, 0x13, 0x16, 0x17, 0x14, 0x15,
> >> -	};
> >> -
> >> -	return lookup_table[val & 0x1f];
> >> -}
> >> -
> >>  static void mctl_phy_init(u32 val)
> >>  {
> >>  	struct sunxi_mctl_ctl_reg * const mctl_ctl =
> >> @@ -91,8 +67,9 @@ static void mctl_set_master_priority(void)
> >>  	struct sunxi_mctl_com_reg * const mctl_com =
> >>  			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
> >>  
> >> +#if defined(CONFIG_MACH_SUN8I_H3)
> >>  	/* enable bandwidth limit windows and set windows size 1us */
> >> -	writel(0x00010190, &mctl_com->bwcr);
> >> +	writel((1 << 16) | (400 << 0), &mctl_com->bwcr);
> >>  
> >>  	/* set cpu high priority */
> >>  	writel(0x00000001, &mctl_com->mapr);
> >> @@ -121,6 +98,38 @@ static void mctl_set_master_priority(void)
> >>  	writel(0x04001800, &mctl_com->mcr[10][1]);
> >>  	writel(0x04000009, &mctl_com->mcr[11][0]);
> >>  	writel(0x00400120, &mctl_com->mcr[11][1]);
> >> +#elif defined(CONFIG_MACH_SUN50I)
> >> +	/* enable bandwidth limit windows and set windows size 1us */
> >> +	writel(399, &mctl_com->tmr);
> >> +	writel((1 << 16), &mctl_com->bwcr);
> >> +
> >> +	writel(0x00a0000d, &mctl_com->mcr[0][0]);
> >> +	writel(0x00500064, &mctl_com->mcr[0][1]);
> >> +	writel(0x06000009, &mctl_com->mcr[1][0]);
> >> +	writel(0x01000578, &mctl_com->mcr[1][1]);
> >> +	writel(0x0200000d, &mctl_com->mcr[2][0]);
> >> +	writel(0x00600100, &mctl_com->mcr[2][1]);
> >> +	writel(0x01000009, &mctl_com->mcr[3][0]);
> >> +	writel(0x00500064, &mctl_com->mcr[3][1]);
> >> +	writel(0x07000009, &mctl_com->mcr[4][0]);
> >> +	writel(0x01000640, &mctl_com->mcr[4][1]);
> >> +	writel(0x01000009, &mctl_com->mcr[5][0]);
> >> +	writel(0x00000080, &mctl_com->mcr[5][1]);
> >> +	writel(0x01000009, &mctl_com->mcr[6][0]);
> >> +	writel(0x00400080, &mctl_com->mcr[6][1]);
> >> +	writel(0x0100000d, &mctl_com->mcr[7][0]);
> >> +	writel(0x00400080, &mctl_com->mcr[7][1]);
> >> +	writel(0x0100000d, &mctl_com->mcr[8][0]);
> >> +	writel(0x00400080, &mctl_com->mcr[8][1]);
> >> +	writel(0x04000009, &mctl_com->mcr[9][0]);
> >> +	writel(0x00400100, &mctl_com->mcr[9][1]);
> >> +	writel(0x20000209, &mctl_com->mcr[10][0]);
> >> +	writel(0x08001800, &mctl_com->mcr[10][1]);
> >> +	writel(0x05000009, &mctl_com->mcr[11][0]);
> >> +	writel(0x00400090, &mctl_com->mcr[11][1]);
> >> +
> >> +	writel(0x81000004, &mctl_com->mdfs_bwlr[2]);
> > 
> > Where is this pulled from? having some defines would be great..
> 
> AFAIK this is from register dumps after boot0 has done its job. I am
> afraid this is as far as we get in the moment. IIRC even the disassembly
> of boot0 shows that these registers are just initialised with those
> magic values and are not computed somehow.
> So the original source code _might_ have names to it, but I guess we
> will never know.

Can you please make that a comment?

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20161212/17062492/attachment.sig>


More information about the U-Boot mailing list