Skip to contentSkip to conversation

Add LPDDR3 support for A83T

PATCH Superseded Vishnu Patekar 2 participants 8 messages Jan 6, 2016 – Jan 8, 2016

Subsystems (2)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover Add LPDDR3 support for A83T

This adds LPDDR3 support for A83T and support for Banana Pi M3 which has LPDDR3. These patches are based on u-boot-sunxi next branch.

These patches tesed on Banana-pi M3. DCDC5 voltage is kept as 1.2V.

Vishnu Patekar (3):
sunxi: groundwork to support new dram type for A83T
sunxi: add support for LPDDR3 for A83T
sunxi: Add suport for A83T based Banana-pi M3 Board

 arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c        | 67 +++++++++++++++++++----
 arch/arm/dts/Makefile                             |  3 +-
 arch/arm/dts/sun8i-a83t-bananapi-m3-v1.2.dts      | 64 ++++++++++++++++++++++
 arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h |  9 ++-
 board/sunxi/MAINTAINERS                           |  5 ++
 configs/Bananapi_m3_defconfig                     | 25 +++++++++
 6 files changed, 159 insertions(+), 14 deletions(-)
 create mode 100644 arch/arm/dts/sun8i-a83t-bananapi-m3-v1.2.dts
 create mode 100644 configs/Bananapi_m3_defconfig
Signature · 1 line
1.9.1
#1 lore raw

PATCH 1/3 sunxi: groundwork to support new dram type for A83T

Different A83T boards have different DRAM types. Banapi M3 has LPDDR3, Allwinner Homlet 1.2 has DDR3.

This adds groundwork to support for new DRAM type for A83T. DRAM_TYPE=3 for DDR3 and 7 for LPDDR3 will passed to SYS_EXTRA_OPTIONS from respective board defconfig.

---
 arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c        | 11 ++++++++++-
 arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h |  4 +++-
 2 files changed, 13 insertions(+), 2 deletions(-)
arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +10 -1
index d757e40..cac7f43 100644
@@ -25,6 +25,7 @@ struct dram_para {
 	u8 rank;
 	u8 rows;
 	u8 bus_width;
+	u8 dram_type;
 	u16 page_size;
 };
 
@@ -34,7 +35,7 @@ static void mctl_set_cr(struct dram_para *para)
 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
 
 	writel(MCTL_CR_CS1_CONTROL(para->cs1) | MCTL_CR_UNKNOWN |
-		MCTL_CR_CHANNEL(1) | MCTL_CR_DDR3 |
+		MCTL_CR_CHANNEL(1) | MCTL_CR_DRAM_TYPE(para->dram_type) |
 		(para->seq ? MCTL_CR_SEQUENCE : 0) |
 		((para->bus_width == 16) ? MCTL_CR_BUSW16 : MCTL_CR_BUSW8) |
 		MCTL_CR_PAGE_SIZE(para->page_size) | MCTL_CR_ROW(para->rows) |
@@ -86,6 +87,7 @@ static void auto_set_timing_para(struct dram_para *para)
 {
 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
 		(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
 	u32 reg_val;
 
 	u8 tccd		= 2;
@@ -398,6 +400,13 @@ unsigned long sunxi_dram_init(void)
 		.page_size = 2048,
 	};
 
+#if defined(CONFIG_MACH_SUN8I_A83T)
+#if (CONFIG_DRAM_TYPE == 3) || (CONFIG_DRAM_TYPE == 7)
+	para.dram_type = CONFIG_DRAM_TYPE;
+#else
+#error Unsupported DRAM type, Please set DRAM type (3:DDR3, 7:LPDDR3)
+#endif
+#endif
 	setbits_le32(SUNXI_PRCM_BASE + 0x1e0, 0x1 << 8);
 
 	writel(0, (SUNXI_PRCM_BASE + 0x1e8));
arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h +3 -1
index 2891b71..05b6a89 100644
@@ -186,7 +186,7 @@ struct sunxi_mctl_ctl_reg {
 #define MCTL_CR_BUSW8			(0 << 12)
 #define MCTL_CR_BUSW16			(1 << 12)
 #define MCTL_CR_SEQUENCE		(1 << 15)
-#define MCTL_CR_DDR3			(3 << 16)
+#define MCTL_CR_DRAM_TYPE(x)		((x) << 16)
 #define MCTL_CR_CHANNEL_MASK		(1 << 19)
 #define MCTL_CR_CHANNEL(x)		(((x) - 1) << 19)
 #define MCTL_CR_UNKNOWN			(0x4 << 20)
@@ -198,4 +198,6 @@ struct sunxi_mctl_ctl_reg {
 #define MCTL_MR2			0x18 /* CWL=8 */
 #define MCTL_MR3			0x0
 
+#define DRAM_TYPE_DDR3		3
+#define DRAM_TYPE_LPDDR3	7
 #endif /* _SUNXI_DRAM_SUN8I_A83T_H */
Signature · 1 line
1.9.1
#2 lore raw

PATCH 1/3 sunxi: groundwork to support new dram type for A83T

Hi,

Quoted 6 lines · Vishnu Patekar

Different A83T boards have different DRAM types. Banapi M3 has LPDDR3, Allwinner Homlet 1.2 has DDR3.

This adds groundwork to support for new DRAM type for A83T. DRAM_TYPE=3 for DDR3 and 7 for LPDDR3 will passed to SYS_EXTRA_OPTIONS from respective board defconfig.

NACK SYS_EXTRA_OPTIONS is obsolete, please add a DRAM_CONFIG_FOO Kconfig options for this, please also adjust patch 3/3 for this.

Regards,

Hans

Quoted 71 lines
---
  arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c        | 11 ++++++++++-
  arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h |  4 +++-
  2 files changed, 13 insertions(+), 2 deletions(-)
arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +10 -1
index d757e40..cac7f43 100644
@@ -25,6 +25,7 @@ struct dram_para {
  	u8 rank;
  	u8 rows;
  	u8 bus_width;
+	u8 dram_type;
  	u16 page_size;
  };
 
@@ -34,7 +35,7 @@ static void mctl_set_cr(struct dram_para *para)
  			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
 
  	writel(MCTL_CR_CS1_CONTROL(para->cs1) | MCTL_CR_UNKNOWN |
-		MCTL_CR_CHANNEL(1) | MCTL_CR_DDR3 |
+		MCTL_CR_CHANNEL(1) | MCTL_CR_DRAM_TYPE(para->dram_type) |
  		(para->seq ? MCTL_CR_SEQUENCE : 0) |
  		((para->bus_width == 16) ? MCTL_CR_BUSW16 : MCTL_CR_BUSW8) |
  		MCTL_CR_PAGE_SIZE(para->page_size) | MCTL_CR_ROW(para->rows) |
@@ -86,6 +87,7 @@ static void auto_set_timing_para(struct dram_para *para)
  {
  	struct sunxi_mctl_ctl_reg * const mctl_ctl =
  		(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
  	u32 reg_val;
 
  	u8 tccd		= 2;
@@ -398,6 +400,13 @@ unsigned long sunxi_dram_init(void)
  		.page_size = 2048,
  	};
 
+#if defined(CONFIG_MACH_SUN8I_A83T)
+#if (CONFIG_DRAM_TYPE == 3) || (CONFIG_DRAM_TYPE == 7)
+	para.dram_type = CONFIG_DRAM_TYPE;
+#else
+#error Unsupported DRAM type, Please set DRAM type (3:DDR3, 7:LPDDR3)
+#endif
+#endif
  	setbits_le32(SUNXI_PRCM_BASE + 0x1e0, 0x1 << 8);
 
  	writel(0, (SUNXI_PRCM_BASE + 0x1e8));
arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h +3 -1
index 2891b71..05b6a89 100644
@@ -186,7 +186,7 @@ struct sunxi_mctl_ctl_reg {
  #define MCTL_CR_BUSW8			(0 << 12)
  #define MCTL_CR_BUSW16			(1 << 12)
  #define MCTL_CR_SEQUENCE		(1 << 15)
-#define MCTL_CR_DDR3			(3 << 16)
+#define MCTL_CR_DRAM_TYPE(x)		((x) << 16)
  #define MCTL_CR_CHANNEL_MASK		(1 << 19)
  #define MCTL_CR_CHANNEL(x)		(((x) - 1) << 19)
  #define MCTL_CR_UNKNOWN			(0x4 << 20)
@@ -198,4 +198,6 @@ struct sunxi_mctl_ctl_reg {
  #define MCTL_MR2			0x18 /* CWL=8 */
  #define MCTL_MR3			0x0
 
+#define DRAM_TYPE_DDR3		3
+#define DRAM_TYPE_LPDDR3	7
  #endif /* _SUNXI_DRAM_SUN8I_A83T_H */
#3 lore raw

PATCH 1/3 sunxi: groundwork to support new dram type for A83T

Hello Hans,

Quoted 7 lines · Hans de Goede

Hi,

Quoted 4 lines · Vishnu Patekar

Different A83T boards have different DRAM types. Banapi M3 has LPDDR3, Allwinner Homlet 1.2 has DDR3.

Quoted 7 lines
Quoted 3 lines

This adds groundwork to support for new DRAM type for A83T. DRAM_TYPE=3 for DDR3 and 7 for LPDDR3 will passed to SYS_EXTRA_OPTIONS from respective board defconfig.

NACK SYS_EXTRA_OPTIONS is obsolete, please add a DRAM_CONFIG_FOO Kconfig options for this, please also adjust patch 3/3 for this.

Okie, will introduce DRAM_TYPE as int in sunxi/boards/Kconfig for A83T.

I think, int value is sufficient. 3 for DDR3 and 7 for LPDDR3.

Regards,
Vishnu

Quoted 82 lines

Regards,

Hans

Quoted 75 lines
---
  arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c        | 11 ++++++++++-
  arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h |  4 +++-
  2 files changed, 13 insertions(+), 2 deletions(-)
arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +2 -1
index d757e40..cac7f43 100644
@@ -25,6 +25,7 @@ struct dram_para {
        u8 rank;
        u8 rows;
        u8 bus_width;
+       u8 dram_type;
        u16 page_size;
  };
 
@@ -34,7 +35,7 @@ static void mctl_set_cr(struct dram_para *para)
                        (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
 
        writel(MCTL_CR_CS1_CONTROL(para->cs1) | MCTL_CR_UNKNOWN |
-               MCTL_CR_CHANNEL(1) | MCTL_CR_DDR3 |
+               MCTL_CR_CHANNEL(1) | MCTL_CR_DRAM_TYPE(para->dram_type) |
                (para->seq ? MCTL_CR_SEQUENCE : 0) |
                ((para->bus_width == 16) ? MCTL_CR_BUSW16 : MCTL_CR_BUSW8)

|

                MCTL_CR_PAGE_SIZE(para->page_size) |

MCTL_CR_ROW(para->rows) |

arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +8 -0
@@ -86,6 +87,7 @@ static void auto_set_timing_para(struct dram_para *para)
  {
        struct sunxi_mctl_ctl_reg * const mctl_ctl =
                (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
        u32 reg_val;
 
        u8 tccd         = 2;
@@ -398,6 +400,13 @@ unsigned long sunxi_dram_init(void)
                .page_size = 2048,
        };
 
+#if defined(CONFIG_MACH_SUN8I_A83T)
+#if (CONFIG_DRAM_TYPE == 3) || (CONFIG_DRAM_TYPE == 7)
+       para.dram_type = CONFIG_DRAM_TYPE;
+#else
+#error Unsupported DRAM type, Please set DRAM type (3:DDR3, 7:LPDDR3)
+#endif
+#endif
        setbits_le32(SUNXI_PRCM_BASE + 0x1e0, 0x1 << 8);
 
        writel(0, (SUNXI_PRCM_BASE + 0x1e8));
arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h +3 -1
index 2891b71..05b6a89 100644
@@ -186,7 +186,7 @@ struct sunxi_mctl_ctl_reg {
  #define MCTL_CR_BUSW8                 (0 << 12)
  #define MCTL_CR_BUSW16                        (1 << 12)
  #define MCTL_CR_SEQUENCE              (1 << 15)
-#define MCTL_CR_DDR3                   (3 << 16)
+#define MCTL_CR_DRAM_TYPE(x)           ((x) << 16)
  #define MCTL_CR_CHANNEL_MASK          (1 << 19)
  #define MCTL_CR_CHANNEL(x)            (((x) - 1) << 19)
  #define MCTL_CR_UNKNOWN                       (0x4 << 20)
@@ -198,4 +198,6 @@ struct sunxi_mctl_ctl_reg {
  #define MCTL_MR2                      0x18 /* CWL=8 */
  #define MCTL_MR3                      0x0
 
+#define DRAM_TYPE_DDR3         3
+#define DRAM_TYPE_LPDDR3       7
  #endif /* _SUNXI_DRAM_SUN8I_A83T_H */
#4 lore raw

PATCH 2/3 sunxi: add support for LPDDR3 for A83T

In reply to Vishnu Patekar

Banana-pi M3 has LPDDR3 DRAM. this adds support for LPDDR3 for A83T. Mostly the timing parameters are different from DDR3.

---
 arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c        | 56 ++++++++++++++++++-----
 arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h |  5 ++
 2 files changed, 50 insertions(+), 11 deletions(-)
arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +45 -11
index cac7f43..9c229bf 100644
@@ -131,10 +131,42 @@ static void auto_set_timing_para(struct dram_para *para)
 	/* Set work mode register */
 	mctl_set_cr(para);
 	/* Set mode register */
-	writel(MCTL_MR0, &mctl_ctl->mr0);
-	writel(MCTL_MR1, &mctl_ctl->mr1);
-	writel(MCTL_MR2, &mctl_ctl->mr2);
-	writel(MCTL_MR3, &mctl_ctl->mr3);
+	if (para->dram_type == DRAM_TYPE_DDR3) {
+		writel(MCTL_MR0, &mctl_ctl->mr0);
+		writel(MCTL_MR1, &mctl_ctl->mr1);
+		writel(MCTL_MR2, &mctl_ctl->mr2);
+		writel(MCTL_MR3, &mctl_ctl->mr3);
+	} else if (para->dram_type == DRAM_TYPE_LPDDR3) {
+		writel(MCTL_LPDDR3_MR0, &mctl_ctl->mr0);
+		writel(MCTL_LPDDR3_MR1, &mctl_ctl->mr1);
+		writel(MCTL_LPDDR3_MR2, &mctl_ctl->mr2);
+		writel(MCTL_LPDDR3_MR3, &mctl_ctl->mr3);
+
+		/* timing parameters for LPDDR3 */
+		tfaw = max(ns_to_t(50), 4);
+		trrd = max(ns_to_t(10), 2);
+		trcd = max(ns_to_t(24), 2);
+		trc = ns_to_t(70);
+		txp = max(ns_to_t(8), 2);
+		twtr = max(ns_to_t(8), 2);
+		trtp = max(ns_to_t(8), 2);
+		trp = max(ns_to_t(27), 2);
+		tras = ns_to_t(42);
+		trefi = ns_to_t(3900) / 32;
+		trfc = ns_to_t(210);
+		tmrw		= 5;
+		tmrd		= 5;
+		tckesr		= 5;
+		tcwl		= 3;	/* CWL 8 */
+		t_rdata_en	= 5;
+		tdinit0	= (200 * CONFIG_DRAM_CLK) + 1;		/* 200us */
+		tdinit1	= (100 * CONFIG_DRAM_CLK) / 1000 + 1;	/* 100ns */
+		tdinit2	= (11 * CONFIG_DRAM_CLK) + 1;	/* 200us */
+		tdinit3	= (1 * CONFIG_DRAM_CLK) + 1;	/* 1us */
+		twtp	= tcwl + 4 + twr + 1;	/* CWL + BL/2 + tWR */
+		twr2rd	= tcwl + 4 + 1 + twtr;	/* WL + BL / 2 + tWTR */
+		trd2wr	= tcl + 4 + 5 - tcwl + 1; /* RL + BL / 2 + 2 - WL */
+	}
 	/* Set dram timing */
 	reg_val = (twtp << 24) | (tfaw << 16) | (trasmax << 8) | (tras << 0);
 	writel(reg_val, &mctl_ctl->dramtmg0);
@@ -232,7 +264,6 @@ static int mctl_channel_init(struct dram_para *para)
 	u32 low_data_lines_status;  /* Training status of datalines 0 - 7 */
 	u32 high_data_lines_status; /* Training status of datalines 8 - 15 */
 	u32 i, rval;
-
 	auto_set_timing_para(para);
 
 	/* Set dram master access priority */
@@ -289,6 +320,10 @@ static int mctl_channel_init(struct dram_para *para)
 	clrbits_le32(&mctl_ctl->pgcr2, (0x3 << 6));
 	clrbits_le32(&mctl_ctl->dqsgmr, (0x1 << 8) | (0x7));
 
+	if (para->dram_type == DRAM_TYPE_LPDDR3)
+		clrsetbits_le32(&mctl_ctl->dxccr, (0x1 << 27) | (0x3<<6) ,
+				0x1 << 31);
+
 	if (readl(&mctl_com->cr) & 0x1)
 		writel(0x00000303, &mctl_ctl->odtmap);
 	else
@@ -299,7 +334,10 @@ static int mctl_channel_init(struct dram_para *para)
 	clrsetbits_le32(ZQnPR(0), 0x000000ff, CONFIG_DRAM_ZQ & 0xff);
 	clrsetbits_le32(ZQnPR(1), 0x000000ff, (CONFIG_DRAM_ZQ >> 8) & 0xff);
 	/* CA calibration */
-	mctl_set_pir(0x0201f3 | 0x1<<10);
+	if (para->dram_type == DRAM_TYPE_DDR3)
+		mctl_set_pir(0x0201f3 | 0x1<<10);
+	else
+		mctl_set_pir(0x020173 | 0x1<<10);
 
 	/* DQS gate training */
 	if (mctl_train_dram(para) != 0) {
@@ -359,6 +397,7 @@ static void mctl_sys_init(struct dram_para *para)
 	clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
 	clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
 	clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
+	udelay(1000);
 	clrbits_le32(&ccm->dram_clk_cfg, 0x01<<31);
 
 	clock_set_pll5(CONFIG_DRAM_CLK * 1000000 * DRAM_CLK_MUL);
@@ -368,11 +407,6 @@ static void mctl_sys_init(struct dram_para *para)
 			CCM_DRAMCLK_CFG_RST | CCM_DRAMCLK_CFG_UPD);
 	mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0);
 
-	setbits_le32(&ccm->ahb_reset0_cfg, 1 << 14);
-	setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
-	setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
-	setbits_le32(&ccm->mbus_clk_cfg, MBUS_CLK_GATE);
-
 	setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
 	setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
 	setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h +5 -0
index 05b6a89..842ad3c 100644
@@ -198,6 +198,11 @@ struct sunxi_mctl_ctl_reg {
 #define MCTL_MR2			0x18 /* CWL=8 */
 #define MCTL_MR3			0x0
 
+#define MCTL_LPDDR3_MR0			0x0
+#define MCTL_LPDDR3_MR1			0xc3	/* twr=8, bl=8 */
+#define MCTL_LPDDR3_MR2			0xa	/* RL=12, CWL=6 */
+#define MCTL_LPDDR3_MR3			0x0
+
 #define DRAM_TYPE_DDR3		3
 #define DRAM_TYPE_LPDDR3	7
 #endif /* _SUNXI_DRAM_SUN8I_A83T_H */
Signature · 1 line
1.9.1
#5 lore raw

PATCH 2/3 sunxi: add support for LPDDR3 for A83T

Hi,

Quoted 101 lines · Vishnu Patekar

Banana-pi M3 has LPDDR3 DRAM. this adds support for LPDDR3 for A83T. Mostly the timing parameters are different from DDR3.

---
  arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c        | 56 ++++++++++++++++++-----
  arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h |  5 ++
  2 files changed, 50 insertions(+), 11 deletions(-)
arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +45 -6
index cac7f43..9c229bf 100644
@@ -131,10 +131,42 @@ static void auto_set_timing_para(struct dram_para *para)
  	/* Set work mode register */
  	mctl_set_cr(para);
  	/* Set mode register */
-	writel(MCTL_MR0, &mctl_ctl->mr0);
-	writel(MCTL_MR1, &mctl_ctl->mr1);
-	writel(MCTL_MR2, &mctl_ctl->mr2);
-	writel(MCTL_MR3, &mctl_ctl->mr3);
+	if (para->dram_type == DRAM_TYPE_DDR3) {
+		writel(MCTL_MR0, &mctl_ctl->mr0);
+		writel(MCTL_MR1, &mctl_ctl->mr1);
+		writel(MCTL_MR2, &mctl_ctl->mr2);
+		writel(MCTL_MR3, &mctl_ctl->mr3);
+	} else if (para->dram_type == DRAM_TYPE_LPDDR3) {
+		writel(MCTL_LPDDR3_MR0, &mctl_ctl->mr0);
+		writel(MCTL_LPDDR3_MR1, &mctl_ctl->mr1);
+		writel(MCTL_LPDDR3_MR2, &mctl_ctl->mr2);
+		writel(MCTL_LPDDR3_MR3, &mctl_ctl->mr3);
+
+		/* timing parameters for LPDDR3 */
+		tfaw = max(ns_to_t(50), 4);
+		trrd = max(ns_to_t(10), 2);
+		trcd = max(ns_to_t(24), 2);
+		trc = ns_to_t(70);
+		txp = max(ns_to_t(8), 2);
+		twtr = max(ns_to_t(8), 2);
+		trtp = max(ns_to_t(8), 2);
+		trp = max(ns_to_t(27), 2);
+		tras = ns_to_t(42);
+		trefi = ns_to_t(3900) / 32;
+		trfc = ns_to_t(210);
+		tmrw		= 5;
+		tmrd		= 5;
+		tckesr		= 5;
+		tcwl		= 3;	/* CWL 8 */
+		t_rdata_en	= 5;
+		tdinit0	= (200 * CONFIG_DRAM_CLK) + 1;		/* 200us */
+		tdinit1	= (100 * CONFIG_DRAM_CLK) / 1000 + 1;	/* 100ns */
+		tdinit2	= (11 * CONFIG_DRAM_CLK) + 1;	/* 200us */
+		tdinit3	= (1 * CONFIG_DRAM_CLK) + 1;	/* 1us */
+		twtp	= tcwl + 4 + twr + 1;	/* CWL + BL/2 + tWR */
+		twr2rd	= tcwl + 4 + 1 + twtr;	/* WL + BL / 2 + tWTR */
+		trd2wr	= tcl + 4 + 5 - tcwl + 1; /* RL + BL / 2 + 2 - WL */
+	}
  	/* Set dram timing */
  	reg_val = (twtp << 24) | (tfaw << 16) | (trasmax << 8) | (tras << 0);
  	writel(reg_val, &mctl_ctl->dramtmg0);
@@ -232,7 +264,6 @@ static int mctl_channel_init(struct dram_para *para)
  	u32 low_data_lines_status;  /* Training status of datalines 0 - 7 */
  	u32 high_data_lines_status; /* Training status of datalines 8 - 15 */
  	u32 i, rval;
-
  	auto_set_timing_para(para);
 
  	/* Set dram master access priority */
@@ -289,6 +320,10 @@ static int mctl_channel_init(struct dram_para *para)
  	clrbits_le32(&mctl_ctl->pgcr2, (0x3 << 6));
  	clrbits_le32(&mctl_ctl->dqsgmr, (0x1 << 8) | (0x7));
 
+	if (para->dram_type == DRAM_TYPE_LPDDR3)
+		clrsetbits_le32(&mctl_ctl->dxccr, (0x1 << 27) | (0x3<<6) ,
+				0x1 << 31);
+
  	if (readl(&mctl_com->cr) & 0x1)
  		writel(0x00000303, &mctl_ctl->odtmap);
  	else
@@ -299,7 +334,10 @@ static int mctl_channel_init(struct dram_para *para)
  	clrsetbits_le32(ZQnPR(0), 0x000000ff, CONFIG_DRAM_ZQ & 0xff);
  	clrsetbits_le32(ZQnPR(1), 0x000000ff, (CONFIG_DRAM_ZQ >> 8) & 0xff);
  	/* CA calibration */
-	mctl_set_pir(0x0201f3 | 0x1<<10);
+	if (para->dram_type == DRAM_TYPE_DDR3)
+		mctl_set_pir(0x0201f3 | 0x1<<10);
+	else
+		mctl_set_pir(0x020173 | 0x1<<10);
 
  	/* DQS gate training */
  	if (mctl_train_dram(para) != 0) {
@@ -359,6 +397,7 @@ static void mctl_sys_init(struct dram_para *para)
  	clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
  	clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
  	clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
+	udelay(1000);
  	clrbits_le32(&ccm->dram_clk_cfg, 0x01<<31);
 
  	clock_set_pll5(CONFIG_DRAM_CLK * 1000000 * DRAM_CLK_MUL);
@@ -368,11 +407,6 @@ static void mctl_sys_init(struct dram_para *para)
  			CCM_DRAMCLK_CFG_RST | CCM_DRAMCLK_CFG_UPD);

arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c static void mctl_sys_init(struct dram_para *para) · line 412

Quoted 10 lines
arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +0 -5
  	mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0);
 
-	setbits_le32(&ccm->ahb_reset0_cfg, 1 << 14);
-	setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
-	setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
-	setbits_le32(&ccm->mbus_clk_cfg, MBUS_CLK_GATE);
-
  	setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
  	setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
  	setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);

This seems like an unrelated cleanup, please put this chunk in a separate patch.

Regards,

Hans

p.s.

Thanks for your work on this, it is great to see the bpi-m3 get supported.

Next step kernel mmc support ? This should be easy (does require modelling the clocks somewhat more complete in dts) given that it just works in u-boot.

mmc support should also make the wifi on the bpi-m3 work ...

Quoted 17 lines
arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h +5 -0
index 05b6a89..842ad3c 100644
@@ -198,6 +198,11 @@ struct sunxi_mctl_ctl_reg {
  #define MCTL_MR2			0x18 /* CWL=8 */
  #define MCTL_MR3			0x0
 
+#define MCTL_LPDDR3_MR0			0x0
+#define MCTL_LPDDR3_MR1			0xc3	/* twr=8, bl=8 */
+#define MCTL_LPDDR3_MR2			0xa	/* RL=12, CWL=6 */
+#define MCTL_LPDDR3_MR3			0x0
+
  #define DRAM_TYPE_DDR3		3
  #define DRAM_TYPE_LPDDR3	7
  #endif /* _SUNXI_DRAM_SUN8I_A83T_H */
#6 lore raw

PATCH 2/3 sunxi: add support for LPDDR3 for A83T

Hello Hans,

Quoted 118 lines · Hans de Goede

Hi,

Quoted 114 lines · Vishnu Patekar

Banana-pi M3 has LPDDR3 DRAM. this adds support for LPDDR3 for A83T. Mostly the timing parameters are different from DDR3.

---
  arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c        | 56
++++++++++++++++++-----
  arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h |  5 ++
  2 files changed, 50 insertions(+), 11 deletions(-)
arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +35 -4
index cac7f43..9c229bf 100644
@@ -131,10 +131,42 @@ static void auto_set_timing_para(struct dram_para
 *para)
        /* Set work mode register */
        mctl_set_cr(para);
        /* Set mode register */
-       writel(MCTL_MR0, &mctl_ctl->mr0);
-       writel(MCTL_MR1, &mctl_ctl->mr1);
-       writel(MCTL_MR2, &mctl_ctl->mr2);
-       writel(MCTL_MR3, &mctl_ctl->mr3);
+       if (para->dram_type == DRAM_TYPE_DDR3) {
+               writel(MCTL_MR0, &mctl_ctl->mr0);
+               writel(MCTL_MR1, &mctl_ctl->mr1);
+               writel(MCTL_MR2, &mctl_ctl->mr2);
+               writel(MCTL_MR3, &mctl_ctl->mr3);
+       } else if (para->dram_type == DRAM_TYPE_LPDDR3) {
+               writel(MCTL_LPDDR3_MR0, &mctl_ctl->mr0);
+               writel(MCTL_LPDDR3_MR1, &mctl_ctl->mr1);
+               writel(MCTL_LPDDR3_MR2, &mctl_ctl->mr2);
+               writel(MCTL_LPDDR3_MR3, &mctl_ctl->mr3);
+
+               /* timing parameters for LPDDR3 */
+               tfaw = max(ns_to_t(50), 4);
+               trrd = max(ns_to_t(10), 2);
+               trcd = max(ns_to_t(24), 2);
+               trc = ns_to_t(70);
+               txp = max(ns_to_t(8), 2);
+               twtr = max(ns_to_t(8), 2);
+               trtp = max(ns_to_t(8), 2);
+               trp = max(ns_to_t(27), 2);
+               tras = ns_to_t(42);
+               trefi = ns_to_t(3900) / 32;
+               trfc = ns_to_t(210);
+               tmrw            = 5;
+               tmrd            = 5;
+               tckesr          = 5;
+               tcwl            = 3;    /* CWL 8 */
+               t_rdata_en      = 5;
+               tdinit0 = (200 * CONFIG_DRAM_CLK) + 1;          /* 200us
 */
+               tdinit1 = (100 * CONFIG_DRAM_CLK) / 1000 + 1;   /* 100ns
 */
+               tdinit2 = (11 * CONFIG_DRAM_CLK) + 1;   /* 200us */
+               tdinit3 = (1 * CONFIG_DRAM_CLK) + 1;    /* 1us */
+               twtp    = tcwl + 4 + twr + 1;   /* CWL + BL/2 + tWR */
+               twr2rd  = tcwl + 4 + 1 + twtr;  /* WL + BL / 2 + tWTR */
+               trd2wr  = tcl + 4 + 5 - tcwl + 1; /* RL + BL / 2 + 2 - WL

*/
+ }

        /* Set dram timing */
        reg_val = (twtp << 24) | (tfaw << 16) | (trasmax << 8) | (tras <<
0);
        writel(reg_val, &mctl_ctl->dramtmg0);
arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +0 -1
@@ -232,7 +264,6 @@ static int mctl_channel_init(struct dram_para *para)
        u32 low_data_lines_status;  /* Training status of datalines 0 - 7
 */
        u32 high_data_lines_status; /* Training status of datalines 8 - 15
 */
        u32 i, rval;
-
        auto_set_timing_para(para);
        /* Set dram master access priority */
arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +8 -1
@@ -289,6 +320,10 @@ static int mctl_channel_init(struct dram_para *para)
        clrbits_le32(&mctl_ctl->pgcr2, (0x3 << 6));
        clrbits_le32(&mctl_ctl->dqsgmr, (0x1 << 8) | (0x7));
 
+       if (para->dram_type == DRAM_TYPE_LPDDR3)
+               clrsetbits_le32(&mctl_ctl->dxccr, (0x1 << 27) | (0x3<<6) ,
+                               0x1 << 31);
+
        if (readl(&mctl_com->cr) & 0x1)
                writel(0x00000303, &mctl_ctl->odtmap);
        else
@@ -299,7 +334,10 @@ static int mctl_channel_init(struct dram_para *para)
        clrsetbits_le32(ZQnPR(0), 0x000000ff, CONFIG_DRAM_ZQ & 0xff);
        clrsetbits_le32(ZQnPR(1), 0x000000ff, (CONFIG_DRAM_ZQ >> 8) &
 0xff);
        /* CA calibration */
-       mctl_set_pir(0x0201f3 | 0x1<<10);
+       if (para->dram_type == DRAM_TYPE_DDR3)
+               mctl_set_pir(0x0201f3 | 0x1<<10);
+       else
+               mctl_set_pir(0x020173 | 0x1<<10);
 
        /* DQS gate training */
        if (mctl_train_dram(para) != 0) {
arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +1 -0
@@ -359,6 +397,7 @@ static void mctl_sys_init(struct dram_para *para)
        clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
        clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
        clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
+       udelay(1000);
        clrbits_le32(&ccm->dram_clk_cfg, 0x01<<31);
 
        clock_set_pll5(CONFIG_DRAM_CLK * 1000000 * DRAM_CLK_MUL);
@@ -368,11 +407,6 @@ static void mctl_sys_init(struct dram_para *para)
                        CCM_DRAMCLK_CFG_RST | CCM_DRAMCLK_CFG_UPD);
        mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0);
 
Quoted 12 lines

arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c static void mctl_sys_init(struct dram_para *para) · line 412

Quoted 8 lines
arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +0 -5
-       setbits_le32(&ccm->ahb_reset0_cfg, 1 << 14);
-       setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
-       setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
-       setbits_le32(&ccm->mbus_clk_cfg, MBUS_CLK_GATE);
-
        setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
        setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
        setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);

This seems like an unrelated cleanup, please put this chunk in a separate patch.

Yes, just redundant 4 lines here. I'll put it in separate patch.

Quoted 6 lines

Regards,

Hans

Quoted 7 lines

p.s.

Thanks for your work on this, it is great to see the bpi-m3 get supported.

Next step kernel mmc support ? This should be easy (does require modelling the
clocks somewhat more complete in dts) given that it just works in u-boot.

Yes, easier ones like this, I'll add support as soon as I get free time.

Quoted 26 lines

mmc support should also make the wifi on the bpi-m3 work ...

Quoted 18 lines
arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h +5 -0
index 05b6a89..842ad3c 100644
@@ -198,6 +198,11 @@ struct sunxi_mctl_ctl_reg {
  #define MCTL_MR2                      0x18 /* CWL=8 */
  #define MCTL_MR3                      0x0
 
+#define MCTL_LPDDR3_MR0                        0x0
+#define MCTL_LPDDR3_MR1                        0xc3    /* twr=8, bl=8 */
+#define MCTL_LPDDR3_MR2                        0xa     /* RL=12, CWL=6 */
+#define MCTL_LPDDR3_MR3                        0x0
+
  #define DRAM_TYPE_DDR3                3
  #define DRAM_TYPE_LPDDR3      7
  #endif /* _SUNXI_DRAM_SUN8I_A83T_H */
#7 lore raw

PATCH 3/3 sunxi: Add suport for A83T based Banana-pi M3 Board

In reply to Vishnu Patekar

Add dts and defconfig for Banana-pi M3 board.

It has 2G LPDDR3, UART, ethernet, USB, HDMI, USB Sata, MIPI DSI,
mic, BLE 4.0, AP6212 Wifi , etc on it.
It is paired with AXP813 PMIC which is almost same as AXP818.

---
 arch/arm/dts/Makefile                        |  3 +-
 arch/arm/dts/sun8i-a83t-bananapi-m3-v1.2.dts | 64 ++++++++++++++++++++++++++++
 board/sunxi/MAINTAINERS                      |  5 +++
 configs/Bananapi_m3_defconfig                | 25 +++++++++++
 4 files changed, 96 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/dts/sun8i-a83t-bananapi-m3-v1.2.dts
 create mode 100644 configs/Bananapi_m3_defconfig
arch/arm/dts/Makefile +2 -1
index 0bcd316..2ab0926 100644
@@ -178,7 +178,8 @@ dtb-$(CONFIG_MACH_SUN8I_A33) += \
 	sun8i-a33-q8-tablet.dtb \
 	sun8i-a33-sinlinx-sina33.dtb
 dtb-$(CONFIG_MACH_SUN8I_A83T) += \
-	sun8i-a83t-allwinner-h8homlet-v2.dtb
+	sun8i-a83t-allwinner-h8homlet-v2.dtb \
+	sun8i-a83t-bananapi-m3-v1.2.dtb
 dtb-$(CONFIG_MACH_SUN8I_H3) += \
 	sun8i-h3-orangepi-pc.dtb \
 	sun8i-h3-orangepi-plus.dtb
arch/arm/dts/sun8i-a83t-bananapi-m3-v1.2.dts new file +64 -0

64 lines not on this page · raw message

board/sunxi/MAINTAINERS +5 -0
index 131c341..575847a 100644
@@ -84,6 +84,11 @@ M:	Paul Kocialkowski <[email protected]>
 S:	Maintained
 F:	configs/Ampe_A76_defconfig
 
+BANANA PI M3 A83T BOARD
+M:	VishnuPatekar <[email protected]>
+S:	Maintained
+F:	configs/Bananapi_m3_defconfig
+
 COLOMBUS BOARD
 M:	Maxime Ripard <[email protected]>
 S:	Maintained
configs/Bananapi_m3_defconfig new file +25 -0
new file mode 100644
index 0000000..b0aff9a
@@ -0,0 +1,25 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN8I_A83T=y
+CONFIG_DRAM_CLK=480
+CONFIG_DRAM_ZQ=15355
+CONFIG_DRAM_ODT_EN=y
+CONFIG_SYS_EXTRA_OPTIONS="DRAM_TYPE=7"
+#CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
+#CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_AXP_GPIO=y
+#CONFIG_USB_MUSB_HOST=y
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-a83t-bananapi-m3-v1.2"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL=y
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_AXP_DCDC1_VOLT=3000
+CONFIG_AXP_DCDC2_VOLT=900
+CONFIG_AXP_DCDC3_VOLT=900
+CONFIG_AXP_DCDC4_VOLT=0
+CONFIG_AXP_DCDC5_VOLT=1200
+CONFIG_AXP_ALDO2_VOLT=0
+CONFIG_AXP_ALDO3_VOLT=0
+CONFIG_AXP_DLDO4_VOLT=0
Signature · 1 line
1.9.1