diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index 1720f7db01ddf7594a53acf43aed660caf178705..1c4b7633f92308b28fb48ef5df9e29888cacb052 100644
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_MACH_SUN5I)	+= clock_sun4i.o
 obj-$(CONFIG_MACH_SUN6I)	+= clock_sun6i.o
 obj-$(CONFIG_MACH_SUN7I)	+= clock_sun4i.o
 obj-$(CONFIG_MACH_SUN8I)	+= clock_sun6i.o
+obj-$(CONFIG_MACH_SUN9I)	+= clock_sun9i.o
 
 ifndef CONFIG_SPL_BUILD
 ifdef CONFIG_ARMV7_PSCI
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c
index d7a7040b72c70a27948841c038d4312b0cda46d2..e2a78676b1654fc6fece0f6fe9058957fe04c595 100644
--- a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c
+++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c
@@ -45,10 +45,10 @@ void clock_init_safe(void)
 
 void clock_init_uart(void)
 {
+#if CONFIG_CONS_INDEX < 5
 	struct sunxi_ccm_reg *const ccm =
 		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
 
-#if CONFIG_CONS_INDEX < 5
 	/* uart clock source is apb2 */
 	writel(APB2_CLK_SRC_OSC24M|
 	       APB2_CLK_RATE_N_1|
@@ -68,9 +68,6 @@ void clock_init_uart(void)
 	/* enable R_PIO and R_UART clocks, and de-assert resets */
 	prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_UART);
 #endif
-
-	/* Dup with clock_init_safe(), drop once sun6i SPL support lands */
-	writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg);
 }
 
 int clock_twi_onoff(int port, int state)
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun9i.c b/arch/arm/cpu/armv7/sunxi/clock_sun9i.c
new file mode 100644
index 0000000000000000000000000000000000000000..27179ba19c601b4ed99ec2bf5b47778e1b278a68
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/clock_sun9i.c
@@ -0,0 +1,68 @@
+/*
+ * sun9i specific clock code
+ *
+ * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/prcm.h>
+#include <asm/arch/sys_proto.h>
+
+void clock_init_uart(void)
+{
+	struct sunxi_ccm_reg *const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+	/* open the clock for uart */
+	setbits_le32(&ccm->apb1_gate,
+		     CLK_GATE_OPEN << (APB1_GATE_UART_SHIFT +
+				       CONFIG_CONS_INDEX - 1));
+	/* deassert uart reset */
+	setbits_le32(&ccm->apb1_reset_cfg,
+		     1 << (APB1_RESET_UART_SHIFT +
+			   CONFIG_CONS_INDEX - 1));
+
+	/* Dup with clock_init_safe(), drop once sun9i SPL support lands */
+	writel(PLL4_CFG_DEFAULT, &ccm->pll4_periph0_cfg);
+}
+
+int clock_twi_onoff(int port, int state)
+{
+	struct sunxi_ccm_reg *const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+	if (port > 4)
+		return -1;
+
+	/* set the apb reset and clock gate for twi */
+	if (state) {
+		setbits_le32(&ccm->apb1_gate,
+			     CLK_GATE_OPEN << (APB1_GATE_TWI_SHIFT + port));
+		setbits_le32(&ccm->apb1_reset_cfg,
+			     1 << (APB1_RESET_UART_SHIFT + port));
+	} else {
+		clrbits_le32(&ccm->apb1_reset_cfg,
+			     1 << (APB1_RESET_UART_SHIFT + port));
+		clrbits_le32(&ccm->apb1_gate,
+			     CLK_GATE_OPEN << (APB1_GATE_TWI_SHIFT + port));
+	}
+
+	return 0;
+}
+
+unsigned int clock_get_pll4_periph0(void)
+{
+	struct sunxi_ccm_reg *const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	uint32_t rval = readl(&ccm->pll4_periph0_cfg);
+	int n = ((rval & CCM_PLL4_CTRL_N_MASK) >> CCM_PLL4_CTRL_N_SHIFT);
+	int p = ((rval & CCM_PLL4_CTRL_P_MASK) >> CCM_PLL4_CTRL_P_SHIFT);
+	int m = ((rval & CCM_PLL4_CTRL_M_MASK) >> CCM_PLL4_CTRL_M_SHIFT) + 1;
+	const int k = 1;
+
+	return ((24000000 * n * k) >> p) / m;
+}
diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h
index 505c363e46e1af460837262cff52a8d379f83e1f..3e5d99908192e6b8e99fbada1835281006481fe2 100644
--- a/arch/arm/include/asm/arch-sunxi/clock.h
+++ b/arch/arm/include/asm/arch-sunxi/clock.h
@@ -17,6 +17,8 @@
 /* clock control module regs definition */
 #if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I)
 #include <asm/arch/clock_sun6i.h>
+#elif defined(CONFIG_MACH_SUN9I)
+#include <asm/arch/clock_sun9i.h>
 #else
 #include <asm/arch/clock_sun4i.h>
 #endif
@@ -24,10 +26,6 @@
 #ifndef __ASSEMBLY__
 int clock_init(void);
 int clock_twi_onoff(int port, int state);
-void clock_set_pll1(unsigned int hz);
-void clock_set_pll3(unsigned int hz);
-unsigned int clock_get_pll5p(void);
-unsigned int clock_get_pll6(void);
 void clock_set_de_mod_clock(u32 *clk_cfg, unsigned int hz);
 void clock_init_safe(void);
 void clock_init_uart(void);
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
index 84a9a2bdbc312e6e97a41887b2a35632ddb23bfe..05fbad3e111a59139f5b8106005e1fba9891943a 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
@@ -186,6 +186,7 @@ struct sunxi_ccm_reg {
 
 /* ahb clock gate bit offset (second register) */
 #define AHB_GATE_OFFSET_GMAC		17
+#define AHB_GATE_OFFSET_DE_FE0		14
 #define AHB_GATE_OFFSET_DE_BE0		12
 #define AHB_GATE_OFFSET_HDMI		11
 #define AHB_GATE_OFFSET_LCD1		5
@@ -266,7 +267,10 @@ struct sunxi_ccm_reg {
 #define CCM_MMC_CTRL_PLL5		(0x2 << 24)
 #define CCM_MMC_CTRL_ENABLE		(0x1 << 31)
 
+#define CCM_DRAM_GATE_OFFSET_DE_FE1	24 /* Note the order of FE1 and */
+#define CCM_DRAM_GATE_OFFSET_DE_FE0	25 /* FE0 is swapped ! */
 #define CCM_DRAM_GATE_OFFSET_DE_BE0	26
+#define CCM_DRAM_GATE_OFFSET_DE_BE1	27
 
 #define CCM_LCD_CH0_CTRL_PLL3		(0 << 24)
 #define CCM_LCD_CH0_CTRL_PLL7		(1 << 24)
@@ -320,4 +324,11 @@ struct sunxi_ccm_reg {
 #define CCM_DE_CTRL_RST			(1 << 30)
 #define CCM_DE_CTRL_GATE		(1 << 31)
 
+#ifndef __ASSEMBLY__
+void clock_set_pll1(unsigned int hz);
+void clock_set_pll3(unsigned int hz);
+unsigned int clock_get_pll5p(void);
+unsigned int clock_get_pll6(void);
+#endif
+
 #endif /* _SUNXI_CLOCK_SUN4I_H */
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
index 4711260c1eef58196d40c46f856c3805012a2824..e101c540510dc81ba5616f18c41b78b9d7536e7e 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
@@ -320,6 +320,11 @@ struct sunxi_ccm_reg {
 #define CCM_DE_CTRL_PLL10		(5 << 24)
 #define CCM_DE_CTRL_GATE		(1 << 31)
 
+#ifndef __ASSEMBLY__
+void clock_set_pll1(unsigned int hz);
+void clock_set_pll3(unsigned int hz);
 void clock_set_pll5(unsigned int clk, bool sigma_delta_enable);
+unsigned int clock_get_pll6(void);
+#endif
 
 #endif /* _SUNXI_CLOCK_SUN6I_H */
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun9i.h b/arch/arm/include/asm/arch-sunxi/clock_sun9i.h
new file mode 100644
index 0000000000000000000000000000000000000000..c506b0a98f4f927cffea964929906a0c1e4164ee
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun9i.h
@@ -0,0 +1,139 @@
+/*
+ * sun9i clock register definitions
+ *
+ * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _SUNXI_CLOCK_SUN9I_H
+#define _SUNXI_CLOCK_SUN9I_H
+
+struct sunxi_ccm_reg {
+	u32 pll1_c0_cfg;	/* 0x00 c0cpu# pll configuration */
+	u32 pll2_c1_cfg;	/* 0x04 c1cpu# pll configuration */
+	u32 pll3_audio_cfg;	/* 0x08 audio pll configuration */
+	u32 pll4_periph0_cfg;	/* 0x0c peripheral0 pll configuration */
+	u32 pll5_ve_cfg;	/* 0x10 videoengine pll configuration */
+	u32 pll6_ddr_cfg;	/* 0x14 ddr pll configuration */
+	u32 pll7_video0_cfg;	/* 0x18 video0 pll configuration */
+	u32 pll8_video1_cfg;	/* 0x1c video1 pll configuration */
+	u32 pll9_gpu_cfg;	/* 0x20 gpu pll configuration */
+	u32 pll10_de_cfg;	/* 0x24 displayengine pll configuration */
+	u32 pll11_isp_cfg;	/* 0x28 isp pll6 ontrol */
+	u32 pll12_periph1_cfg;	/* 0x2c peripheral1 pll configuration */
+	u8 reserved1[0x20];	/* 0x30 */
+	u32 cpu_clk_source;	/* 0x50 cpu clk source configuration */
+	u32 c0_cfg;		/* 0x54 cpu cluster 0 clock configuration */
+	u32 c1_cfg;		/* 0x58 cpu cluster 1 clock configuration */
+	u32 gtbus_cfg;		/* 0x5c gtbus clock configuration */
+	u32 ahb0_cfg;		/* 0x60 ahb0 clock configuration */
+	u32 ahb1_cfg;		/* 0x64 ahb1 clock configuration */
+	u32 ahb2_cfg;		/* 0x68 ahb2 clock configuration */
+	u8 reserved2[0x04];	/* 0x6c */
+	u32 apb0_cfg;		/* 0x70 apb0 clock configuration */
+	u32 apb1_cfg;		/* 0x74 apb1 clock configuration */
+	u32 cci400_cfg;		/* 0x78 cci400 clock configuration */
+	u8 reserved3[0x04];	/* 0x7c */
+	u32 ats_cfg;		/* 0x80 ats clock configuration */
+	u32 trace_cfg;		/* 0x84 trace clock configuration */
+	u8 reserved4[0xf8];	/* 0x88 */
+	u32 clk_output_a;	/* 0x180 clk_output_a */
+	u32 clk_output_b;	/* 0x184 clk_output_a */
+	u8 reserved5[0x278];	/* 0x188 */
+
+	u32 nand0_clk_cfg0;	/* 0x400 nand0 clock configuration0 */
+	u32 nand0_clk_cfg1;	/* 0x404 nand1 clock configuration */
+	u8 reserved6[0x08];	/* 0x408 */
+	u32 sd0_clk_cfg;	/* 0x410 sd0 clock configuration */
+	u32 sd1_clk_cfg;	/* 0x414 sd1 clock configuration */
+	u32 sd2_clk_cfg;	/* 0x418 sd2 clock configuration */
+	u32 sd3_clk_cfg;	/* 0x41c sd3 clock configuration */
+	u8 reserved7[0x08];	/* 0x420 */
+	u32 ts_clk_cfg;		/* 0x428 transport stream clock cfg */
+	u32 ss_clk_cfg;		/* 0x42c security system clock cfg */
+	u32 spi0_clk_cfg;	/* 0x430 spi0 clock configuration */
+	u32 spi1_clk_cfg;	/* 0x434 spi1 clock configuration */
+	u32 spi2_clk_cfg;	/* 0x438 spi2 clock configuration */
+	u32 spi3_clk_cfg;	/* 0x43c spi3 clock configuration */
+	u8 reserved8[0x50];	/* 0x440 */
+	u32 de_clk_cfg;		/* 0x490 display engine clock configuration */
+	u8 reserved9[0x04];	/* 0x494 */
+	u32 mp_clk_cfg;		/* 0x498 mp clock configuration */
+	u32 lcd0_clk_cfg;	/* 0x49c LCD0 module clock */
+	u32 lcd1_clk_cfg;	/* 0x4a0 LCD1 module clock */
+	u8 reserved10[0x1c];	/* 0x4a4 */
+	u32 csi_isp_clk_cfg;	/* 0x4c0 CSI ISP module clock */
+	u32 csi0_clk_cfg;	/* 0x4c4 CSI0 module clock */
+	u32 csi1_clk_cfg;	/* 0x4c8 CSI1 module clock */
+	u32 fd_clk_cfg;		/* 0x4cc FD module clock */
+	u32 ve_clk_cfg;		/* 0x4d0 VE module clock */
+	u32 avs_clk_cfg;	/* 0x4d4 AVS module clock */
+	u8 reserved11[0x18];	/* 0x4d8 */
+	u32 gpu_core_clk_cfg;	/* 0x4f0 GPU core clock config */
+	u32 gpu_mem_clk_cfg;	/* 0x4f4 GPU memory clock config */
+	u32 gpu_axi_clk_cfg;	/* 0x4f8 GPU AXI clock config */
+	u8 reserved12[0x10];	/* 0x4fc */
+	u32 gp_adc_clk_cfg;	/* 0x50c General Purpose ADC clk config */
+	u8 reserved13[0x70];	/* 0x510 */
+
+	u32 ahb_gate0;		/* 0x580 AHB0 Gating Register */
+	u32 ahb_gate1;		/* 0x584 AHB1 Gating Register */
+	u32 ahb_gate2;		/* 0x588 AHB2 Gating Register */
+	u8 reserved14[0x04];	/* 0x58c */
+	u32 apb0_gate;		/* 0x590 APB0 Clock Gating Register */
+	u32 apb1_gate;		/* 0x594 APB1 Clock Gating Register */
+	u8 reserved15[0x08];	/* 0x598 */
+	u32 ahb_reset0_cfg;	/* 0x5a0 AHB0 Software Reset Register */
+	u32 ahb_reset1_cfg;	/* 0x5a4 AHB1 Software Reset Register */
+	u32 ahb_reset2_cfg;	/* 0x5a8 AHB2 Software Reset Register */
+	u8 reserved16[0x04];	/* 0x5ac */
+	u32 apb0_reset_cfg;	/* 0x5b0 Bus Software Reset Register 3 */
+	u32 apb1_reset_cfg;	/* 0x5b4 Bus Software Reset Register 4 */
+};
+
+/* pll4_periph0_cfg */
+#define PLL4_CFG_DEFAULT		0x90002800 /* 960 MHz */
+
+#define CCM_PLL4_CTRL_N_SHIFT		8
+#define CCM_PLL4_CTRL_N_MASK		(0xff << CCM_PLL4_CTRL_N_SHIFT)
+#define CCM_PLL4_CTRL_P_SHIFT		16
+#define CCM_PLL4_CTRL_P_MASK		(0x1 << CCM_PLL4_CTRL_P_SHIFT)
+#define CCM_PLL4_CTRL_M_SHIFT		18
+#define CCM_PLL4_CTRL_M_MASK		(0x1 << CCM_PLL4_CTRL_M_SHIFT)
+
+/* sd#_clk_cfg fields */
+#define CCM_MMC_CTRL_M(x)		((x) - 1)
+#define CCM_MMC_CTRL_OCLK_DLY(x)	((x) << 8)
+#define CCM_MMC_CTRL_N(x)		((x) << 16)
+#define CCM_MMC_CTRL_SCLK_DLY(x)	((x) << 20)
+#define CCM_MMC_CTRL_OSCM24		(0 << 24)
+#define CCM_MMC_CTRL_PLL_PERIPH0	(1 << 24)
+#define CCM_MMC_CTRL_ENABLE		(1 << 31)
+
+/* ahb_gate0 fields */
+/* On sun9i all sdc-s share their ahb gate, so ignore (x) */
+#define AHB_GATE_OFFSET_MMC(x)		8
+
+/* apb1_gate fields */
+#define APB1_GATE_UART_SHIFT		16
+#define APB1_GATE_UART_MASK		(0xff << APB1_GATE_UART_SHIFT)
+#define APB1_GATE_TWI_SHIFT		0
+#define APB1_GATE_TWI_MASK		(0xf << APB1_GATE_TWI_SHIFT)
+
+/* ahb_reset0_cfg fields */
+/* On sun9i all sdc-s share their ahb reset, so ignore (x) */
+#define AHB_RESET_OFFSET_MMC(x)		8
+
+/* apb1_reset_cfg fields */
+#define APB1_RESET_UART_SHIFT		16
+#define APB1_RESET_UART_MASK		(0xff << APB1_RESET_UART_SHIFT)
+#define APB1_RESET_TWI_SHIFT		0
+#define APB1_RESET_TWI_MASK		(0xf << APB1_RESET_TWI_SHIFT)
+
+
+#ifndef __ASSEMBLY__
+unsigned int clock_get_pll4_periph0(void);
+#endif
+
+#endif /* _SUNXI_CLOCK_SUN9I_H */
diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h
index 82b3d4676fd7fd51f952882d2c054d53c9e8d87e..73583ed445a57bbdb3863e826056921e0cd25f9e 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu.h
@@ -1,7 +1,5 @@
 /*
- * (C) Copyright 2007-2011
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- * Tom Cubie <tangliang@allwinnertech.com>
+ * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -9,146 +7,10 @@
 #ifndef _SUNXI_CPU_H
 #define _SUNXI_CPU_H
 
-#define SUNXI_SRAM_A1_BASE		0x00000000
-#define SUNXI_SRAM_A1_SIZE		(16 * 1024)	/* 16 kiB */
-
-#define SUNXI_SRAM_A2_BASE		0x00004000	/* 16 kiB */
-#define SUNXI_SRAM_A3_BASE		0x00008000	/* 13 kiB */
-#define SUNXI_SRAM_A4_BASE		0x0000b400	/* 3 kiB */
-#define SUNXI_SRAM_D_BASE		0x00010000	/* 4 kiB */
-#define SUNXI_SRAM_B_BASE		0x00020000	/* 64 kiB (secure) */
-
-#define SUNXI_SRAMC_BASE		0x01c00000
-#define SUNXI_DRAMC_BASE		0x01c01000
-#define SUNXI_DMA_BASE			0x01c02000
-#define SUNXI_NFC_BASE			0x01c03000
-#define SUNXI_TS_BASE			0x01c04000
-#define SUNXI_SPI0_BASE			0x01c05000
-#define SUNXI_SPI1_BASE			0x01c06000
-#define SUNXI_MS_BASE			0x01c07000
-#define SUNXI_TVD_BASE			0x01c08000
-#define SUNXI_CSI0_BASE			0x01c09000
-#define SUNXI_TVE0_BASE			0x01c0a000
-#define SUNXI_EMAC_BASE			0x01c0b000
-#define SUNXI_LCD0_BASE			0x01c0C000
-#define SUNXI_LCD1_BASE			0x01c0d000
-#define SUNXI_VE_BASE			0x01c0e000
-#define SUNXI_MMC0_BASE			0x01c0f000
-#define SUNXI_MMC1_BASE			0x01c10000
-#define SUNXI_MMC2_BASE			0x01c11000
-#define SUNXI_MMC3_BASE			0x01c12000
-#if !defined CONFIG_MACH_SUN6I && !defined CONFIG_MACH_SUN8I
-#define SUNXI_USB0_BASE			0x01c13000
-#define SUNXI_USB1_BASE			0x01c14000
-#endif
-#define SUNXI_SS_BASE			0x01c15000
-#define SUNXI_HDMI_BASE			0x01c16000
-#define SUNXI_SPI2_BASE			0x01c17000
-#define SUNXI_SATA_BASE			0x01c18000
-#if !defined CONFIG_MACH_SUN6I && !defined CONFIG_MACH_SUN8I
-#define SUNXI_PATA_BASE			0x01c19000
-#define SUNXI_ACE_BASE			0x01c1a000
-#define SUNXI_TVE1_BASE			0x01c1b000
-#define SUNXI_USB2_BASE			0x01c1c000
+#if defined(CONFIG_MACH_SUN9I)
+#include <asm/arch/cpu_sun9i.h>
 #else
-#define SUNXI_USB0_BASE			0x01c19000
-#define SUNXI_USB1_BASE			0x01c1a000
-#define SUNXI_USB2_BASE			0x01c1b000
+#include <asm/arch/cpu_sun4i.h>
 #endif
-#define SUNXI_CSI1_BASE			0x01c1d000
-#define SUNXI_TZASC_BASE		0x01c1e000
-#define SUNXI_SPI3_BASE			0x01c1f000
-
-#define SUNXI_CCM_BASE			0x01c20000
-#define SUNXI_INTC_BASE			0x01c20400
-#define SUNXI_PIO_BASE			0x01c20800
-#define SUNXI_TIMER_BASE		0x01c20c00
-#define SUNXI_SPDIF_BASE		0x01c21000
-#define SUNXI_AC97_BASE			0x01c21400
-#define SUNXI_IR0_BASE			0x01c21800
-#define SUNXI_IR1_BASE			0x01c21c00
-
-#define SUNXI_IIS_BASE			0x01c22400
-#define SUNXI_LRADC_BASE		0x01c22800
-#define SUNXI_AD_DA_BASE		0x01c22c00
-#define SUNXI_KEYPAD_BASE		0x01c23000
-#define SUNXI_TZPC_BASE			0x01c23400
-#define SUNXI_SID_BASE			0x01c23800
-#define SUNXI_SJTAG_BASE		0x01c23c00
-
-#define SUNXI_TP_BASE			0x01c25000
-#define SUNXI_PMU_BASE			0x01c25400
-#define SUN7I_CPUCFG_BASE              0x01c25c00
-
-#define SUNXI_UART0_BASE		0x01c28000
-#define SUNXI_UART1_BASE		0x01c28400
-#define SUNXI_UART2_BASE		0x01c28800
-#define SUNXI_UART3_BASE		0x01c28c00
-#define SUNXI_UART4_BASE		0x01c29000
-#define SUNXI_UART5_BASE		0x01c29400
-#define SUNXI_UART6_BASE		0x01c29800
-#define SUNXI_UART7_BASE		0x01c29c00
-#define SUNXI_PS2_0_BASE		0x01c2a000
-#define SUNXI_PS2_1_BASE		0x01c2a400
-
-#define SUNXI_TWI0_BASE			0x01c2ac00
-#define SUNXI_TWI1_BASE			0x01c2b000
-#define SUNXI_TWI2_BASE			0x01c2b400
-
-#define SUNXI_CAN_BASE			0x01c2bc00
-
-#define SUNXI_SCR_BASE			0x01c2c400
-
-#ifndef CONFIG_MACH_SUN6I
-#define SUNXI_GPS_BASE			0x01c30000
-#define SUNXI_MALI400_BASE		0x01c40000
-#define SUNXI_GMAC_BASE			0x01c50000
-#else
-#define SUNXI_GMAC_BASE			0x01c30000
-#endif
-
-#define SUNXI_DRAM_COM_BASE		0x01c62000
-#define SUNXI_DRAM_CTL0_BASE		0x01c63000
-#define SUNXI_DRAM_CTL1_BASE		0x01c64000
-#define SUNXI_DRAM_PHY0_BASE		0x01c65000
-#define SUNXI_DRAM_PHY1_BASE		0x01c66000
-
-/* module sram */
-#define SUNXI_SRAM_C_BASE		0x01d00000
-
-#define SUNXI_DE_FE0_BASE		0x01e00000
-#define SUNXI_DE_FE1_BASE		0x01e20000
-#define SUNXI_DE_BE0_BASE		0x01e60000
-#define SUNXI_DE_BE1_BASE		0x01e40000
-#define SUNXI_MP_BASE			0x01e80000
-#define SUNXI_AVG_BASE			0x01ea0000
-
-#define SUNXI_RTC_BASE			0x01f00000
-#define SUNXI_PRCM_BASE			0x01f01400
-#define SUN6I_CPUCFG_BASE		0x01f01c00
-#define SUNXI_R_UART_BASE		0x01f02800
-#define SUNXI_R_PIO_BASE		0x01f02c00
-#define SUN6I_P2WI_BASE			0x01f03400
-#define SUNXI_RSB_BASE			0x01f03400
-
-/* CoreSight Debug Module */
-#define SUNXI_CSDM_BASE			0x3f500000
-
-#define SUNXI_DDRII_DDRIII_BASE		0x40000000	/* 2 GiB */
-
-#define SUNXI_BROM_BASE			0xffff0000	/* 32 kiB */
-
-#define SUNXI_CPU_CFG			(SUNXI_TIMER_BASE + 0x13c)
-
-/* SS bonding ids used for cpu identification */
-#define SUNXI_SS_BOND_ID_A31		4
-#define SUNXI_SS_BOND_ID_A31S		5
-
-#ifndef __ASSEMBLY__
-void sunxi_board_init(void);
-void sunxi_reset(void);
-int sunxi_get_ss_bonding_id(void);
-int sunxi_get_sid(unsigned int *sid);
-#endif /* __ASSEMBLY__ */
 
-#endif /* _CPU_H */
+#endif /* _SUNXI_CPU_H */
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
new file mode 100644
index 0000000000000000000000000000000000000000..dae60696f945cab323896d6dd499de881ab87f78
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
@@ -0,0 +1,154 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _SUNXI_CPU_SUN4I_H
+#define _SUNXI_CPU_SUN4I_H
+
+#define SUNXI_SRAM_A1_BASE		0x00000000
+#define SUNXI_SRAM_A1_SIZE		(16 * 1024)	/* 16 kiB */
+
+#define SUNXI_SRAM_A2_BASE		0x00004000	/* 16 kiB */
+#define SUNXI_SRAM_A3_BASE		0x00008000	/* 13 kiB */
+#define SUNXI_SRAM_A4_BASE		0x0000b400	/* 3 kiB */
+#define SUNXI_SRAM_D_BASE		0x00010000	/* 4 kiB */
+#define SUNXI_SRAM_B_BASE		0x00020000	/* 64 kiB (secure) */
+
+#define SUNXI_SRAMC_BASE		0x01c00000
+#define SUNXI_DRAMC_BASE		0x01c01000
+#define SUNXI_DMA_BASE			0x01c02000
+#define SUNXI_NFC_BASE			0x01c03000
+#define SUNXI_TS_BASE			0x01c04000
+#define SUNXI_SPI0_BASE			0x01c05000
+#define SUNXI_SPI1_BASE			0x01c06000
+#define SUNXI_MS_BASE			0x01c07000
+#define SUNXI_TVD_BASE			0x01c08000
+#define SUNXI_CSI0_BASE			0x01c09000
+#define SUNXI_TVE0_BASE			0x01c0a000
+#define SUNXI_EMAC_BASE			0x01c0b000
+#define SUNXI_LCD0_BASE			0x01c0C000
+#define SUNXI_LCD1_BASE			0x01c0d000
+#define SUNXI_VE_BASE			0x01c0e000
+#define SUNXI_MMC0_BASE			0x01c0f000
+#define SUNXI_MMC1_BASE			0x01c10000
+#define SUNXI_MMC2_BASE			0x01c11000
+#define SUNXI_MMC3_BASE			0x01c12000
+#if !defined CONFIG_MACH_SUN6I && !defined CONFIG_MACH_SUN8I
+#define SUNXI_USB0_BASE			0x01c13000
+#define SUNXI_USB1_BASE			0x01c14000
+#endif
+#define SUNXI_SS_BASE			0x01c15000
+#define SUNXI_HDMI_BASE			0x01c16000
+#define SUNXI_SPI2_BASE			0x01c17000
+#define SUNXI_SATA_BASE			0x01c18000
+#if !defined CONFIG_MACH_SUN6I && !defined CONFIG_MACH_SUN8I
+#define SUNXI_PATA_BASE			0x01c19000
+#define SUNXI_ACE_BASE			0x01c1a000
+#define SUNXI_TVE1_BASE			0x01c1b000
+#define SUNXI_USB2_BASE			0x01c1c000
+#else
+#define SUNXI_USB0_BASE			0x01c19000
+#define SUNXI_USB1_BASE			0x01c1a000
+#define SUNXI_USB2_BASE			0x01c1b000
+#endif
+#define SUNXI_CSI1_BASE			0x01c1d000
+#define SUNXI_TZASC_BASE		0x01c1e000
+#define SUNXI_SPI3_BASE			0x01c1f000
+
+#define SUNXI_CCM_BASE			0x01c20000
+#define SUNXI_INTC_BASE			0x01c20400
+#define SUNXI_PIO_BASE			0x01c20800
+#define SUNXI_TIMER_BASE		0x01c20c00
+#define SUNXI_SPDIF_BASE		0x01c21000
+#define SUNXI_AC97_BASE			0x01c21400
+#define SUNXI_IR0_BASE			0x01c21800
+#define SUNXI_IR1_BASE			0x01c21c00
+
+#define SUNXI_IIS_BASE			0x01c22400
+#define SUNXI_LRADC_BASE		0x01c22800
+#define SUNXI_AD_DA_BASE		0x01c22c00
+#define SUNXI_KEYPAD_BASE		0x01c23000
+#define SUNXI_TZPC_BASE			0x01c23400
+#define SUNXI_SID_BASE			0x01c23800
+#define SUNXI_SJTAG_BASE		0x01c23c00
+
+#define SUNXI_TP_BASE			0x01c25000
+#define SUNXI_PMU_BASE			0x01c25400
+#define SUN7I_CPUCFG_BASE              0x01c25c00
+
+#define SUNXI_UART0_BASE		0x01c28000
+#define SUNXI_UART1_BASE		0x01c28400
+#define SUNXI_UART2_BASE		0x01c28800
+#define SUNXI_UART3_BASE		0x01c28c00
+#define SUNXI_UART4_BASE		0x01c29000
+#define SUNXI_UART5_BASE		0x01c29400
+#define SUNXI_UART6_BASE		0x01c29800
+#define SUNXI_UART7_BASE		0x01c29c00
+#define SUNXI_PS2_0_BASE		0x01c2a000
+#define SUNXI_PS2_1_BASE		0x01c2a400
+
+#define SUNXI_TWI0_BASE			0x01c2ac00
+#define SUNXI_TWI1_BASE			0x01c2b000
+#define SUNXI_TWI2_BASE			0x01c2b400
+
+#define SUNXI_CAN_BASE			0x01c2bc00
+
+#define SUNXI_SCR_BASE			0x01c2c400
+
+#ifndef CONFIG_MACH_SUN6I
+#define SUNXI_GPS_BASE			0x01c30000
+#define SUNXI_MALI400_BASE		0x01c40000
+#define SUNXI_GMAC_BASE			0x01c50000
+#else
+#define SUNXI_GMAC_BASE			0x01c30000
+#endif
+
+#define SUNXI_DRAM_COM_BASE		0x01c62000
+#define SUNXI_DRAM_CTL0_BASE		0x01c63000
+#define SUNXI_DRAM_CTL1_BASE		0x01c64000
+#define SUNXI_DRAM_PHY0_BASE		0x01c65000
+#define SUNXI_DRAM_PHY1_BASE		0x01c66000
+
+/* module sram */
+#define SUNXI_SRAM_C_BASE		0x01d00000
+
+#define SUNXI_DE_FE0_BASE		0x01e00000
+#define SUNXI_DE_FE1_BASE		0x01e20000
+#define SUNXI_DE_BE0_BASE		0x01e60000
+#define SUNXI_DE_BE1_BASE		0x01e40000
+#define SUNXI_MP_BASE			0x01e80000
+#define SUNXI_AVG_BASE			0x01ea0000
+
+#define SUNXI_RTC_BASE			0x01f00000
+#define SUNXI_PRCM_BASE			0x01f01400
+#define SUN6I_CPUCFG_BASE		0x01f01c00
+#define SUNXI_R_UART_BASE		0x01f02800
+#define SUNXI_R_PIO_BASE		0x01f02c00
+#define SUN6I_P2WI_BASE			0x01f03400
+#define SUNXI_RSB_BASE			0x01f03400
+
+/* CoreSight Debug Module */
+#define SUNXI_CSDM_BASE			0x3f500000
+
+#define SUNXI_DDRII_DDRIII_BASE		0x40000000	/* 2 GiB */
+
+#define SUNXI_BROM_BASE			0xffff0000	/* 32 kiB */
+
+#define SUNXI_CPU_CFG			(SUNXI_TIMER_BASE + 0x13c)
+
+/* SS bonding ids used for cpu identification */
+#define SUNXI_SS_BOND_ID_A31		4
+#define SUNXI_SS_BOND_ID_A31S		5
+
+#ifndef __ASSEMBLY__
+void sunxi_board_init(void);
+void sunxi_reset(void);
+int sunxi_get_ss_bonding_id(void);
+int sunxi_get_sid(unsigned int *sid);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _SUNXI_CPU_SUN4I_H */
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
new file mode 100644
index 0000000000000000000000000000000000000000..a2a7839c6bdfcf014710e697eef6b66f8dde9f33
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
@@ -0,0 +1,108 @@
+/*
+ * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ * (C) Copyright 2007-2013
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Jerry Wang <wangflord@allwinnertech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _SUNXI_CPU_SUN9I_H
+#define _SUNXI_CPU_SUN9I_H
+
+#define REGS_AHB0_BASE			0x01C00000
+#define REGS_AHB1_BASE			0x00800000
+#define REGS_AHB2_BASE			0x03000000
+#define REGS_APB0_BASE			0x06000000
+#define REGS_APB1_BASE			0x07000000
+#define REGS_RCPUS_BASE			0x08000000
+
+#define SUNXI_SRAM_D_BASE		0x08100000
+
+/* AHB0 Module */
+#define SUNXI_NFC_BASE			(REGS_AHB0_BASE + 0x3000)
+#define SUNXI_TSC_BASE			(REGS_AHB0_BASE + 0x4000)
+
+#define SUNXI_MMC0_BASE			(REGS_AHB0_BASE + 0x0f000)
+#define SUNXI_MMC1_BASE			(REGS_AHB0_BASE + 0x10000)
+#define SUNXI_MMC2_BASE			(REGS_AHB0_BASE + 0x11000)
+#define SUNXI_MMC3_BASE			(REGS_AHB0_BASE + 0x12000)
+#define SUNXI_MMC_COMMON_BASE		(REGS_AHB0_BASE + 0x13000)
+
+#define SUNXI_SPI0_BASE			(REGS_AHB0_BASE + 0x1A000)
+#define SUNXI_SPI1_BASE			(REGS_AHB0_BASE + 0x1B000)
+#define SUNXI_SPI2_BASE			(REGS_AHB0_BASE + 0x1C000)
+#define SUNXI_SPI3_BASE			(REGS_AHB0_BASE + 0x1D000)
+
+#define SUNXI_GIC400_BASE		(REGS_AHB0_BASE + 0x40000)
+#define SUNXI_ARMA9_GIC_BASE		(REGS_AHB0_BASE + 0x41000)
+#define SUNXI_ARMA9_CPUIF_BASE		(REGS_AHB0_BASE + 0x42000)
+
+/* AHB1 Module */
+#define SUNXI_DMA_BASE			(REGS_AHB1_BASE + 0x002000)
+#define SUNXI_USBOTG_BASE		(REGS_AHB1_BASE + 0x100000)
+#define SUNXI_USBEHCI0_BASE		(REGS_AHB1_BASE + 0x200000)
+#define SUNXI_USBEHCI1_BASE		(REGS_AHB1_BASE + 0x201000)
+#define SUNXI_USBEHCI2_BASE		(REGS_AHB1_BASE + 0x202000)
+
+/* AHB2 Module */
+#define SUNXI_DE_SYS_BASE		(REGS_AHB2_BASE + 0x000000)
+#define SUNXI_DISP_SYS_BASE		(REGS_AHB2_BASE + 0x010000)
+#define SUNXI_DE_FE0_BASE		(REGS_AHB2_BASE + 0x100000)
+#define SUNXI_DE_FE1_BASE		(REGS_AHB2_BASE + 0x140000)
+#define SUNXI_DE_FE2_BASE		(REGS_AHB2_BASE + 0x180000)
+
+#define SUNXI_DE_BE0_BASE		(REGS_AHB2_BASE + 0x200000)
+#define SUNXI_DE_BE1_BASE		(REGS_AHB2_BASE + 0x240000)
+#define SUNXI_DE_BE2_BASE		(REGS_AHB2_BASE + 0x280000)
+
+#define SUNXI_DE_DEU0_BASE		(REGS_AHB2_BASE + 0x300000)
+#define SUNXI_DE_DEU1_BASE		(REGS_AHB2_BASE + 0x340000)
+#define SUNXI_DE_DRC0_BASE		(REGS_AHB2_BASE + 0x400000)
+#define SUNXI_DE_DRC1_BASE		(REGS_AHB2_BASE + 0x440000)
+
+#define SUNXI_LCD0_BASE			(REGS_AHB2_BASE + 0xC00000)
+#define SUNXI_LCD1_BASE			(REGS_AHB2_BASE + 0xC10000)
+#define SUNXI_LCD2_BASE			(REGS_AHB2_BASE + 0xC20000)
+#define SUNXI_MIPI_DSI0_BASE		(REGS_AHB2_BASE + 0xC40000)
+/* Also seen as SUNXI_MIPI_DSI0_DPHY_BASE 0x01ca1000 */
+#define SUNXI_MIPI_DSI0_DPHY_BASE	(REGS_AHB2_BASE + 0xC40100)
+#define SUNXI_HDMI_BASE			(REGS_AHB2_BASE + 0xD00000)
+
+/* APB0 Module */
+#define SUNXI_CCM_BASE			(REGS_APB0_BASE + 0x0000)
+#define SUNXI_CCMMODULE_BASE		(REGS_APB0_BASE + 0x0400)
+#define SUNXI_PIO_BASE			(REGS_APB0_BASE + 0x0800)
+#define SUNXI_R_PIO_BASE		(0x08002C00)
+#define SUNXI_TIMER_BASE		(REGS_APB0_BASE + 0x0C00)
+#define SUNXI_PWM_BASE			(REGS_APB0_BASE + 0x1400)
+#define SUNXI_LRADC_BASE		(REGS_APB0_BASE + 0x1800)
+
+/* APB1 Module */
+#define SUNXI_UART0_BASE		(REGS_APB1_BASE + 0x0000)
+#define SUNXI_UART1_BASE		(REGS_APB1_BASE + 0x0400)
+#define SUNXI_UART2_BASE		(REGS_APB1_BASE + 0x0800)
+#define SUNXI_UART3_BASE		(REGS_APB1_BASE + 0x0C00)
+#define SUNXI_UART4_BASE		(REGS_APB1_BASE + 0x1000)
+#define SUNXI_UART5_BASE		(REGS_APB1_BASE + 0x1400)
+#define SUNXI_TWI0_BASE			(REGS_APB1_BASE + 0x2800)
+#define SUNXI_TWI1_BASE			(REGS_APB1_BASE + 0x2C00)
+#define SUNXI_TWI2_BASE			(REGS_APB1_BASE + 0x3000)
+#define SUNXI_TWI3_BASE			(REGS_APB1_BASE + 0x3400)
+#define SUNXI_TWI4_BASE			(REGS_APB1_BASE + 0x3800)
+
+/* RCPUS Module */
+#define SUNXI_RPRCM_BASE		(REGS_RCPUS_BASE + 0x1400)
+#define SUNXI_R_UART_BASE		(REGS_RCPUS_BASE + 0x2800)
+
+/* Misc. */
+#define SUNXI_BROM_BASE			0xFFFF0000 /* 32K */
+#define SUNXI_CPU_CFG			(SUNXI_TIMER_BASE + 0x13c)
+
+#ifndef __ASSEMBLY__
+void sunxi_board_init(void);
+void sunxi_reset(void);
+int sunxi_get_sid(unsigned int *sid);
+#endif
+
+#endif /* _SUNXI_CPU_SUN9I_H */
diff --git a/arch/arm/include/asm/arch-sunxi/display.h b/arch/arm/include/asm/arch-sunxi/display.h
index 2ac8a879dfb6feb5dd298c23322c87063b63d858..5e9425320366d96e44a1512baba2780108e66095 100644
--- a/arch/arm/include/asm/arch-sunxi/display.h
+++ b/arch/arm/include/asm/arch-sunxi/display.h
@@ -9,6 +9,107 @@
 #ifndef _SUNXI_DISPLAY_H
 #define _SUNXI_DISPLAY_H
 
+struct sunxi_de_fe_reg {
+	u32 enable;			/* 0x000 */
+	u32 frame_ctrl;			/* 0x004 */
+	u32 bypass;			/* 0x008 */
+	u32 algorithm_sel;		/* 0x00c */
+	u32 line_int_ctrl;		/* 0x010 */
+	u8 res0[0x0c];			/* 0x014 */
+	u32 ch0_addr;			/* 0x020 */
+	u32 ch1_addr;			/* 0x024 */
+	u32 ch2_addr;			/* 0x028 */
+	u32 field_sequence;		/* 0x02c */
+	u32 ch0_offset;			/* 0x030 */
+	u32 ch1_offset;			/* 0x034 */
+	u32 ch2_offset;			/* 0x038 */
+	u8 res1[0x04];			/* 0x03c */
+	u32 ch0_stride;			/* 0x040 */
+	u32 ch1_stride;			/* 0x044 */
+	u32 ch2_stride;			/* 0x048 */
+	u32 input_fmt;			/* 0x04c */
+	u32 ch3_addr;			/* 0x050 */
+	u32 ch4_addr;			/* 0x054 */
+	u32 ch5_addr;			/* 0x058 */
+	u32 output_fmt;			/* 0x05c */
+	u32 int_enable;			/* 0x060 */
+	u32 int_status;			/* 0x064 */
+	u32 status;			/* 0x068 */
+	u8 res2[0x04];			/* 0x06c */
+	u32 csc_coef00;			/* 0x070 */
+	u32 csc_coef01;			/* 0x074 */
+	u32 csc_coef02;			/* 0x078 */
+	u32 csc_coef03;			/* 0x07c */
+	u32 csc_coef10;			/* 0x080 */
+	u32 csc_coef11;			/* 0x084 */
+	u32 csc_coef12;			/* 0x088 */
+	u32 csc_coef13;			/* 0x08c */
+	u32 csc_coef20;			/* 0x090 */
+	u32 csc_coef21;			/* 0x094 */
+	u32 csc_coef22;			/* 0x098 */
+	u32 csc_coef23;			/* 0x09c */
+	u32 deinterlace_ctrl;		/* 0x0a0 */
+	u32 deinterlace_diag;		/* 0x0a4 */
+	u32 deinterlace_tempdiff;	/* 0x0a8 */
+	u32 deinterlace_sawtooth;	/* 0x0ac */
+	u32 deinterlace_spatcomp;	/* 0x0b0 */
+	u32 deinterlace_burstlen;	/* 0x0b4 */
+	u32 deinterlace_preluma;	/* 0x0b8 */
+	u32 deinterlace_tile_addr;	/* 0x0bc */
+	u32 deinterlace_tile_stride;	/* 0x0c0 */
+	u8 res3[0x0c];			/* 0x0c4 */
+	u32 wb_stride_enable;		/* 0x0d0 */
+	u32 ch3_stride;			/* 0x0d4 */
+	u32 ch4_stride;			/* 0x0d8 */
+	u32 ch5_stride;			/* 0x0dc */
+	u32 fe_3d_ctrl;			/* 0x0e0 */
+	u32 fe_3d_ch0_addr;		/* 0x0e4 */
+	u32 fe_3d_ch1_addr;		/* 0x0e8 */
+	u32 fe_3d_ch2_addr;		/* 0x0ec */
+	u32 fe_3d_ch0_offset;		/* 0x0f0 */
+	u32 fe_3d_ch1_offset;		/* 0x0f4 */
+	u32 fe_3d_ch2_offset;		/* 0x0f8 */
+	u8 res4[0x04];			/* 0x0fc */
+	u32 ch0_insize;			/* 0x100 */
+	u32 ch0_outsize;		/* 0x104 */
+	u32 ch0_horzfact;		/* 0x108 */
+	u32 ch0_vertfact;		/* 0x10c */
+	u32 ch0_horzphase;		/* 0x110 */
+	u32 ch0_vertphase0;		/* 0x114 */
+	u32 ch0_vertphase1;		/* 0x118 */
+	u8 res5[0x04];			/* 0x11c */
+	u32 ch0_horztapoffset0;		/* 0x120 */
+	u32 ch0_horztapoffset1;		/* 0x124 */
+	u32 ch0_verttapoffset;		/* 0x128 */
+	u8 res6[0xd4];			/* 0x12c */
+	u32 ch1_insize;			/* 0x200 */
+	u32 ch1_outsize;		/* 0x204 */
+	u32 ch1_horzfact;		/* 0x208 */
+	u32 ch1_vertfact;		/* 0x20c */
+	u32 ch1_horzphase;		/* 0x210 */
+	u32 ch1_vertphase0;		/* 0x214 */
+	u32 ch1_vertphase1;		/* 0x218 */
+	u8 res7[0x04];			/* 0x21c */
+	u32 ch1_horztapoffset0;		/* 0x220 */
+	u32 ch1_horztapoffset1;		/* 0x224 */
+	u32 ch1_verttapoffset;		/* 0x228 */
+	u8 res8[0x1d4];			/* 0x22c */
+	u32 ch0_horzcoef0[32];		/* 0x400 */
+	u32 ch0_horzcoef1[32];		/* 0x480 */
+	u32 ch0_vertcoef[32];		/* 0x500 */
+	u8 res9[0x80];			/* 0x580 */
+	u32 ch1_horzcoef0[32];		/* 0x600 */
+	u32 ch1_horzcoef1[32];		/* 0x680 */
+	u32 ch1_vertcoef[32];		/* 0x700 */
+	u8 res10[0x280];		/* 0x780 */
+	u32 vpp_enable;			/* 0xa00 */
+	u32 vpp_dcti;			/* 0xa04 */
+	u32 vpp_lp1;			/* 0xa08 */
+	u32 vpp_lp2;			/* 0xa0c */
+	u32 vpp_wle;			/* 0xa10 */
+	u32 vpp_ble;			/* 0xa14 */
+};
+
 struct sunxi_de_be_reg {
 	u8 res0[0x800];			/* 0x000 */
 	u32 mode;			/* 0x800 */
@@ -209,6 +310,20 @@ struct sunxi_tve_reg {
 	u32 cfg2;			/* 0x13c */
 };
 
+/*
+ * DE-FE register constants.
+ */
+#define SUNXI_DE_FE_WIDTH(x)			(((x) - 1) << 0)
+#define SUNXI_DE_FE_HEIGHT(y)			(((y) - 1) << 16)
+#define SUNXI_DE_FE_FACTOR_INT(n)		((n) << 16)
+#define SUNXI_DE_FE_ENABLE_EN			(1 << 0)
+#define SUNXI_DE_FE_FRAME_CTRL_REG_RDY		(1 << 0)
+#define SUNXI_DE_FE_FRAME_CTRL_COEF_RDY		(1 << 1)
+#define SUNXI_DE_FE_FRAME_CTRL_FRM_START	(1 << 16)
+#define SUNXI_DE_FE_BYPASS_CSC_BYPASS		(1 << 1)
+#define SUNXI_DE_FE_INPUT_FMT_ARGB8888		0x00000151
+#define SUNXI_DE_FE_OUTPUT_FMT_ARGB8888		0x00000002
+
 /*
  * DE-BE register constants.
  */
@@ -219,6 +334,7 @@ struct sunxi_tve_reg {
 #define SUNXI_DE_BE_MODE_LAYER0_ENABLE		(1 << 8)
 #define SUNXI_DE_BE_LAYER_STRIDE(x)		((x) << 5)
 #define SUNXI_DE_BE_REG_CTRL_LOAD_REGS		(1 << 0)
+#define SUNXI_DE_BE_LAYER_ATTR0_SRC_FE0		0x00000002
 #define SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888	(0x09 << 8)
 
 /*
@@ -249,9 +365,7 @@ struct sunxi_tve_reg {
 #define SUNXI_LCDC_TCON0_TIMING_V_TOTAL(n)	(((n) * 2) << 16)
 #define SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(n)	((n) << 26)
 #define SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE	(1 << 31)
-#define SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE0	(0 << 28)
-#define SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE60	(1 << 28)
-#define SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE120	(2 << 28)
+#define SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(x)	((x) << 28)
 #define SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(n)	(((n) & 0x1f) << 4)
 #define SUNXI_LCDC_TCON1_CTRL_ENABLE		(1 << 31)
 #define SUNXI_LCDC_TCON1_TIMING_H_BP(n)		(((n) - 1) << 0)
diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun4i.h b/arch/arm/include/asm/arch-sunxi/dram_sun4i.h
index 6c1ec5be8620e71f0343da7fa978cef5bb3922f6..40c385a5bc8025e5dc1ca48ffc441bf5440e5ffc 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/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h
index 537f1455643cc5ffae3d998599f3b941d2244568..74833b51d1285e12db5865946eb6a34526c645bf 100644
--- a/arch/arm/include/asm/arch-sunxi/mmc.h
+++ b/arch/arm/include/asm/arch-sunxi/mmc.h
@@ -43,10 +43,11 @@ struct sunxi_mmc {
 	u32 chda;		/* 0x90 */
 	u32 cbda;		/* 0x94 */
 	u32 res1[26];
-#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I)
+#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
+    defined(CONFIG_MACH_SUN9I)
 	u32 res2[64];
 #endif
-	u32 fifo;		/* 0x100 (0x200 on sun6i) FIFO access address */
+	u32 fifo;		/* 0x100 / 0x200 FIFO access address */
 };
 
 #define SUNXI_MMC_CLK_POWERSAVE		(0x1 << 17)
@@ -123,5 +124,8 @@ struct sunxi_mmc {
 #define SUNXI_MMC_IDIE_TXIRQ		(0x1 << 0)
 #define SUNXI_MMC_IDIE_RXIRQ		(0x1 << 1)
 
+#define SUNXI_MMC_COMMON_CLK_GATE		(1 << 16)
+#define SUNXI_MMC_COMMON_RESET			(1 << 18)
+
 struct mmc *sunxi_mmc_init(int sdc_no);
 #endif /* _SUNXI_MMC_H */
diff --git a/arch/arm/include/asm/arch-sunxi/usbc.h b/arch/arm/include/asm/arch-sunxi/usbc.h
index 8d2097336c4288d64cef37fdde88fb5c653e2b7e..cb538cdc7d4c9f632279ead2505d4e1591e1c823 100644
--- a/arch/arm/include/asm/arch-sunxi/usbc.h
+++ b/arch/arm/include/asm/arch-sunxi/usbc.h
@@ -11,6 +11,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+extern const struct musb_platform_ops sunxi_musb_ops;
+
 void *sunxi_usbc_get_io_base(int index);
 int sunxi_usbc_request_resources(int index);
 int sunxi_usbc_free_resources(int index);
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index 6a4d764b7c9a94eaa4efe0d49f79d2bcbaf23a07..738b55e74aba83d477f28bcc782d2a97f74d9140 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -33,21 +33,31 @@ config MACH_SUN8I
 
 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
@@ -60,10 +70,6 @@ config SYS_CONFIG_NAME
 choice
 	prompt "Board"
 
-config TARGET_A10_OLINUXINO_L
-	bool "A10_OLINUXINO_L"
-	depends on MACH_SUN4I
-
 config TARGET_A10S_OLINUXINO_M
 	bool "A10S_OLINUXINO_M"
 	depends on MACH_SUN5I
@@ -100,61 +106,25 @@ config TARGET_BANANAPRO
 	bool "BANANAPRO"
 	depends on MACH_SUN7I
 
-config TARGET_COLOMBUS
-	bool "COLOMBUS"
-	depends on MACH_SUN6I
-
 config TARGET_CUBIEBOARD2
 	bool "CUBIEBOARD2"
 	depends on MACH_SUN7I
 
-config TARGET_CUBIEBOARD
-	bool "CUBIEBOARD"
-	depends on MACH_SUN4I
-
 config TARGET_CUBIETRUCK
 	bool "CUBIETRUCK"
 	depends on MACH_SUN7I
 
-config TARGET_HUMMINGBIRD_A31
-	bool "HUMMINGBIRD_A31"
-	depends on MACH_SUN6I
-
-config TARGET_IPPO_Q8H_V5
-	bool "IPPO_Q8H_V5"
-	depends on MACH_SUN8I
-
-config TARGET_PCDUINO
-	bool "PCDUINO"
-	depends on MACH_SUN4I
-
 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
-
 config TARGET_MELE_M3
 	bool "MELE_M3"
 	depends on MACH_SUN7I
 
-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
+config TARGET_MK802_A10S
+	bool "MK802_A10S"
+	depends on MACH_SUN5I
 
 config TARGET_MSI_PRIMO73
 	bool "MSI Primo73 (7\" tablet)"
@@ -169,31 +139,10 @@ config TARGET_MSI_PRIMO73
 	OTG and 3.5mm headphone jack. More details are available at
 	    http://linux-sunxi.org/MSI_Primo73
 
-config TARGET_MSI_PRIMO81
-	bool "MSI Primo81 (7.85\" tablet)"
-	depends on MACH_SUN6I
-	---help---
-	The MSI Primo81 is an A31s based tablet, with 1G RAM, 16G NAND,
-	1024x768 IPS LCD display, mono speaker, 0.3 MP front camera, 2.0 MP
-	rear camera, 3500 mAh battery, gt911 touchscreen, mma8452 accelerometer
-	and rtl8188etv usb wifi. Has "power", "volume+" and "volume-" buttons
-	(both volume buttons are also connected to the UBOOT_SEL pin). The
-	external connectors are represented by MicroSD slot, MiniHDMI, MicroUSB
-	OTG and 3.5mm headphone jack. More details are available at
-	    http://linux-sunxi.org/MSI_Primo81
-
-config TARGET_BA10_TV_BOX
-	bool "BA10_TV_BOX"
-	depends on MACH_SUN4I
-
 config TARGET_I12_TVBOX
 	bool "I12_TVBOX"
 	depends on MACH_SUN7I
 
-config TARGET_QT840A
-	bool "QT840A"
-	depends on MACH_SUN7I
-
 config TARGET_R7DONGLE
 	bool "R7DONGLE"
 	depends on MACH_SUN5I
@@ -338,6 +287,13 @@ config VIDEO_LCD_MODE
 	This is in drivers/video/videomodes.c: video_get_params() format, e.g.
 	x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:0,vmode:0
 
+config VIDEO_LCD_DCLK_PHASE
+	int "LCD panel display clock phase"
+	depends on VIDEO
+	default 1
+	---help---
+	Select LCD panel display clock phase shift, range 0-3.
+
 config VIDEO_LCD_POWER
 	string "LCD panel power enable pin"
 	depends on VIDEO
@@ -363,6 +319,13 @@ config VIDEO_LCD_BL_PWM
 	Set the backlight pwm pin for the LCD panel. This takes a string in the
 	format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
 
+config VIDEO_LCD_BL_PWM_ACTIVE_LOW
+	bool "LCD panel backlight pwm is inverted"
+	depends on VIDEO
+	default y
+	---help---
+	Set this if the backlight pwm output is active low.
+
 
 # Note only one of these may be selected at a time! But hidden choices are
 # not supported by Kconfig
@@ -387,9 +350,32 @@ config VIDEO_LCD_PANEL_LVDS
 	bool "Generic lvds interface LCD panel"
 	select VIDEO_LCD_IF_LVDS
 
+config VIDEO_LCD_PANEL_MIPI_4_LANE_513_MBPS_VIA_SSD2828
+	bool "MIPI 4-lane, 513Mbps LCD panel via SSD2828 bridge chip"
+	select VIDEO_LCD_SSD2828
+	select VIDEO_LCD_IF_PARALLEL
+	---help---
+	 7.85" 768x1024 LCD panels, such as LG LP079X01 or AUO B079XAN01.0
+
+config VIDEO_LCD_PANEL_HITACHI_TX18D42VM
+	bool "Hitachi tx18d42vm LCD panel"
+	select VIDEO_LCD_HITACHI_TX18D42VM
+	select VIDEO_LCD_IF_LVDS
+	---help---
+	7.85" 1024x768 Hitachi tx18d42vm LCD panel support
+
 endchoice
 
 
+config USB_MUSB_SUNXI
+	bool "Enable sunxi OTG / DRC USB controller in host mode"
+	default n
+	---help---
+	Say y here to enable support for the sunxi OTG / DRC USB controller
+	used on almost all sunxi boards. Note currently u-boot can only have
+	one usb host controller enabled at a time, so enabling this on boards
+	which also use the ehci host controller will result in build errors.
+
 config USB_KEYBOARD
 	boolean "Enable USB keyboard support"
 	default y
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index 3a09be92de553482adc9b44c86b7a600e3911995..743e7f53518a3f093302dfd2a71f379c1e3cfc28 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -5,17 +5,20 @@ F:	board/sunxi/
 F:	include/configs/sun4i.h
 F:	configs/A10-OLinuXino-Lime_defconfig
 F:	configs/ba10_tv_box_defconfig
+F:	configs/Chuwi_V7_CW0825_defconfig
 F:	configs/Cubieboard_defconfig
+F:	configs/Hyundai_A7HD_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:	configs/mk802_defconfig
+F:	configs/mk802ii_defconfig
 F:	include/configs/sun5i.h
 F:	configs/A10s-OLinuXino-M_defconfig
 F:	configs/A13-OLinuXino_defconfig
 F:	configs/A13-OLinuXinoM_defconfig
 F:	configs/Auxtek-T004_defconfig
+F:	configs/mk802_a10s_defconfig
 F:	configs/r7-tv-dongle_defconfig
 F:	include/configs/sun6i.h
 F:	configs/CSQ_CS908_defconfig
@@ -58,6 +61,11 @@ M:	Maxime Ripard <maxime.ripard@free-electrons.com>
 S:	Maintained
 F:	configs/Colombus_defconfig
 
+GEMEI-G9 TABLET
+M: Priit Laes <plaes@plaes.org>
+S: Maintained
+F: configs/sunxi_Gemei_G9_defconfig
+
 HUMMINIGBIRD-A31 BOARD
 M:	Chen-Yu Tsai <wens@csie.org>
 S:	Maintained
@@ -82,3 +90,13 @@ LINKSPRITE-PCDUINO BOARD
 M:	Zoltan Herpai <wigyori@uid0.hu>
 S:	Maintained
 F:	configs/Linksprite_pcDuino_defconfig
+
+MARSBOARD-A10 BOARD
+M:	Aleksei Mamlin <mamlinav@gmail.com>
+S:	Maintained
+F:	configs/Marsboard_A10_defconfig
+
+MELE M5 BOARD
+M:	Ian Campbell <ijc@hellion.org.uk>
+S:	Maintained
+F:	configs/Mele_M5_defconfig
diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index fab0877a54df5aa0a73aa578205874e08eb0e464..71edb83c5d382f191a8312538df13d6372959d5e 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -11,29 +11,12 @@
 obj-y	+= board.o
 obj-$(CONFIG_SUNXI_GMAC)	+= gmac.o
 obj-$(CONFIG_SUNXI_AHCI)	+= ahci.o
-obj-$(CONFIG_TARGET_A10_OLINUXINO_L)	+= dram_a10_olinuxino_l.o
+obj-$(CONFIG_MACH_SUN4I)	+= dram_sun4i_auto.o
+obj-$(CONFIG_MACH_SUN7I)	+= dram_sun5i_auto.o
 obj-$(CONFIG_TARGET_A10S_OLINUXINO_M)	+= dram_a10s_olinuxino_m.o
 obj-$(CONFIG_TARGET_A13_OLINUXINO)	+= dram_a13_olinuxino.o
 obj-$(CONFIG_TARGET_A13_OLINUXINOM)	+= dram_a13_oli_micro.o
-obj-$(CONFIG_TARGET_A20_OLINUXINO_L)	+= dram_a20_olinuxino_l.o
-obj-$(CONFIG_TARGET_A20_OLINUXINO_L2)	+= dram_a20_olinuxino_l2.o
-obj-$(CONFIG_TARGET_A20_OLINUXINO_M)	+= dram_sun7i_384_1024_iow16.o
 # This is not a typo, uses the same mem settings as the a10s-olinuxino-m
 obj-$(CONFIG_TARGET_AUXTEK_T004)	+= dram_a10s_olinuxino_m.o
-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_CUBIEBOARD)		+= dram_cubieboard.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_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_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
-obj-$(CONFIG_TARGET_QT840A)		+= dram_sun7i_384_512_busw16_iow16.o
+obj-$(CONFIG_TARGET_MK802_A10S)		+= dram_sun5i_auto.o
 obj-$(CONFIG_TARGET_R7DONGLE)		+= dram_r7dongle.o
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 7d6d075f145ee93d4e3463544b7ccd3694ec9771..b70e00ce6bced72c405554e4951a076a48338069 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -28,7 +28,9 @@
 #include <asm/arch/dram.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
+#include <asm/arch/usbc.h>
 #include <asm/io.h>
+#include <linux/usb/musb.h>
 #include <net.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -189,6 +191,7 @@ void sunxi_board_init(void)
 	power_failed |= axp221_set_aldo1(CONFIG_AXP221_ALDO1_VOLT);
 	power_failed |= axp221_set_aldo2(CONFIG_AXP221_ALDO2_VOLT);
 	power_failed |= axp221_set_aldo3(CONFIG_AXP221_ALDO3_VOLT);
+	power_failed |= axp221_set_eldo(3, CONFIG_AXP221_ELDO3_VOLT);
 #endif
 
 	printf("DRAM:");
@@ -208,6 +211,26 @@ void sunxi_board_init(void)
 }
 #endif
 
+#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET)
+static struct musb_hdrc_config musb_config = {
+	.multipoint     = 1,
+	.dyn_fifo       = 1,
+	.num_eps        = 6,
+	.ram_bits       = 11,
+};
+
+static struct musb_hdrc_platform_data musb_plat = {
+#if defined(CONFIG_MUSB_HOST)
+	.mode           = MUSB_HOST,
+#else
+	.mode		= MUSB_PERIPHERAL,
+#endif
+	.config         = &musb_config,
+	.power          = 250,
+	.platform_ops	= &sunxi_musb_ops,
+};
+#endif
+
 #ifdef CONFIG_MISC_INIT_R
 int misc_init_r(void)
 {
@@ -227,6 +250,9 @@ int misc_init_r(void)
 		eth_setenv_enetaddr("ethaddr", mac_addr);
 	}
 
+#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET)
+	musb_register(&musb_plat, NULL, (void *)SUNXI_USB0_BASE);
+#endif
 	return 0;
 }
 #endif
diff --git a/board/sunxi/dram_a10_olinuxino_l.c b/board/sunxi/dram_a10_olinuxino_l.c
deleted file mode 100644
index 24a1bd9453deba483b852eab9d5a82226d6eabb8..0000000000000000000000000000000000000000
--- a/board/sunxi/dram_a10_olinuxino_l.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 = 16,
-	.cas = 6,
-	.zq = 123,
-	.odt_en = 0,
-	.size = 512,
-	.tpr0 = 0x30926692,
-	.tpr1 = 0x1090,
-	.tpr2 = 0x1a0c8,
-	.tpr3 = 0,
-	.tpr4 = 0,
-	.tpr5 = 0,
-	.emr1 = 0x4,
-	.emr2 = 0,
-	.emr3 = 0,
-};
-
-unsigned long sunxi_dram_init(void)
-{
-	return dramc_init(&dram_para);
-}
diff --git a/board/sunxi/dram_a20_olinuxino_l.c b/board/sunxi/dram_a20_olinuxino_l.c
deleted file mode 100644
index 2c74999708f3068a8bfdbb0748a31a1ad48879ff..0000000000000000000000000000000000000000
--- a/board/sunxi/dram_a20_olinuxino_l.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 = 16,
-	.cas = 9,
-	.zq = 0x7f,
-	.odt_en = 0,
-	.size = 512,
-	.tpr0 = 0x42d899b7,
-	.tpr1 = 0xa090,
-	.tpr2 = 0x22a00,
-	.tpr3 = 0,
-	.tpr4 = 0,
-	.tpr5 = 0,
-	.emr1 = 0x4,
-	.emr2 = 0x10,
-	.emr3 = 0,
-};
-
-unsigned long sunxi_dram_init(void)
-{
-	return dramc_init(&dram_para);
-}
diff --git a/board/sunxi/dram_cubieboard.c b/board/sunxi/dram_cubieboard.c
deleted file mode 100644
index 399028ca9620d06b46d23e47e5c012e75116b390..0000000000000000000000000000000000000000
--- 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_cubieboard2.c b/board/sunxi/dram_cubieboard2.c
deleted file mode 100644
index 9e753677c5b335a5ab4397d11f1e1978f3061065..0000000000000000000000000000000000000000
--- a/board/sunxi/dram_cubieboard2.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 = 9,
-	.zq = 0x7f,
-	.odt_en = 0,
-	.size = 1024,
-	.tpr0 = 0x42d899b7,
-	.tpr1 = 0xa090,
-	.tpr2 = 0x22a00,
-	.tpr3 = 0x0,
-	.tpr4 = 0x1,
-	.tpr5 = 0x0,
-	.emr1 = 0x4,
-	.emr2 = 0x10,
-	.emr3 = 0x0,
-};
-
-unsigned long sunxi_dram_init(void)
-{
-	return dramc_init(&dram_para);
-}
diff --git a/board/sunxi/dram_cubietruck.c b/board/sunxi/dram_cubietruck.c
deleted file mode 100644
index fbcd68771fe5d1fd0938f618536acad935c8798b..0000000000000000000000000000000000000000
--- a/board/sunxi/dram_cubietruck.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 = 432,
-	.type = 3,
-	.rank_num = 1,
-	.density = 4096,
-	.io_width = 8,
-	.bus_width = 32,
-	.cas = 9,
-	.zq = 0x7f,
-	.odt_en = 0,
-	.size = 2048,
-	.tpr0 = 0x42d899b7,
-	.tpr1 = 0xa090,
-	.tpr2 = 0x22a00,
-	.tpr3 = 0x0,
-	.tpr4 = 0x1,
-	.tpr5 = 0x0,
-	.emr1 = 0x4,
-	.emr2 = 0x10,
-	.emr3 = 0x0,
-};
-
-unsigned long sunxi_dram_init(void)
-{
-	return dramc_init(&dram_para);
-}
diff --git a/board/sunxi/dram_linksprite_pcduino3.c b/board/sunxi/dram_linksprite_pcduino3.c
deleted file mode 100644
index 9cc6e19ee550c30176b5e088979052cba0c8c861..0000000000000000000000000000000000000000
--- a/board/sunxi/dram_linksprite_pcduino3.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 = 9,
-	.zq = 0x7a,
-	.odt_en = 0,
-	.size = 1024,
-	.tpr0 = 0x42d899b7,
-	.tpr1 = 0xa090,
-	.tpr2 = 0x22a00,
-	.tpr3 = 0,
-	.tpr4 = 0,
-	.tpr5 = 0,
-	.emr1 = 0x4,
-	.emr2 = 0x10,
-	.emr3 = 0x0,
-};
-
-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 376371330dddf61d00e86cf1c20126eeb0686d56..0000000000000000000000000000000000000000
--- 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 2a5c9edd91396d79bd44f480bb0dedbe8c78e9e5..0000000000000000000000000000000000000000
--- 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_384_1024_iow8.c b/board/sunxi/dram_sun4i_384_1024_iow8.c
deleted file mode 100644
index b0fcc55654e3aa4ebaa13abd07a3ec1b89c98720..0000000000000000000000000000000000000000
--- a/board/sunxi/dram_sun4i_384_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 = 384,
-	.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 = 0x4,
-	.emr2 = 0,
-	.emr3 = 0,
-};
-
-unsigned long sunxi_dram_init(void)
-{
-	return dramc_init(&dram_para);
-}
diff --git a/board/sunxi/dram_sun4i_408_1024_iow8.c b/board/sunxi/dram_sun4i_408_1024_iow8.c
deleted file mode 100644
index c6d87d23d9022645f93f35448f58ca4ea60f5344..0000000000000000000000000000000000000000
--- a/board/sunxi/dram_sun4i_408_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 = 408,
-	.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_auto.c
similarity index 67%
rename from board/sunxi/dram_sun4i_360_512.c
rename to board/sunxi/dram_sun4i_auto.c
index 48aa6e2d63bb0092ba256c1fca967b3698aeb5f5..826bacf94ab1bc88b75f5aa5635e8725a5a0d780 100644
--- a/board/sunxi/dram_sun4i_360_512.c
+++ b/board/sunxi/dram_sun4i_auto.c
@@ -1,26 +1,24 @@
-/* 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,
+	.clock = CONFIG_DRAM_CLK,
 	.type = 3,
 	.rank_num = 1,
-	.density = 2048,
-	.io_width = 16,
-	.bus_width = 32,
+	.density = 0,
+	.io_width = 0,
+	.bus_width = 0,
 	.cas = 6,
-	.zq = 123,
+	.zq = CONFIG_DRAM_ZQ,
 	.odt_en = 0,
-	.size = 512,
+	.size = 0,
 	.tpr0 = 0x30926692,
 	.tpr1 = 0x1090,
 	.tpr2 = 0x1a0c8,
 	.tpr3 = 0,
 	.tpr4 = 0,
 	.tpr5 = 0,
-	.emr1 = 0,
+	.emr1 = CONFIG_DRAM_EMR1,
 	.emr2 = 0,
 	.emr3 = 0,
 };
diff --git a/board/sunxi/dram_a20_olinuxino_l2.c b/board/sunxi/dram_sun5i_auto.c
similarity index 61%
rename from board/sunxi/dram_a20_olinuxino_l2.c
rename to board/sunxi/dram_sun5i_auto.c
index 2115d37470abff78d0dd3e0a263f92d021f7a361..e86b08e67bd9968f39fabe95963185cf6c688d8f 100644
--- a/board/sunxi/dram_a20_olinuxino_l2.c
+++ b/board/sunxi/dram_sun5i_auto.c
@@ -1,26 +1,26 @@
-/* this file is generated, don't edit it yourself */
+/* DRAM parameters for auto dram configuration on sun5i and sun7i */
 
 #include <common.h>
 #include <asm/arch/dram.h>
 
 static struct dram_para dram_para = {
-	.clock = 480,
+	.clock = CONFIG_DRAM_CLK,
 	.type = 3,
 	.rank_num = 1,
-	.density = 4096,
-	.io_width = 16,
-	.bus_width = 32,
+	.density = 0,
+	.io_width = 0,
+	.bus_width = 0,
 	.cas = 9,
-	.zq = 0x7f,
+	.zq = CONFIG_DRAM_ZQ,
 	.odt_en = 0,
-	.size = 1024,
+	.size = 0,
 	.tpr0 = 0x42d899b7,
 	.tpr1 = 0xa090,
 	.tpr2 = 0x22a00,
 	.tpr3 = 0,
 	.tpr4 = 0,
 	.tpr5 = 0,
-	.emr1 = 0x4,
+	.emr1 = CONFIG_DRAM_EMR1,
 	.emr2 = 0x10,
 	.emr3 = 0,
 };
diff --git a/board/sunxi/dram_sun7i_384_1024_iow16.c b/board/sunxi/dram_sun7i_384_1024_iow16.c
deleted file mode 100644
index 04e4b1e9b99d5a65ff3009f0b07fe9cb6ff789dd..0000000000000000000000000000000000000000
--- a/board/sunxi/dram_sun7i_384_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 = 384,
-	.type = 3,
-	.rank_num = 1,
-	.density = 4096,
-	.io_width = 16,
-	.bus_width = 32,
-	.cas = 9,
-	.zq = 0x7f,
-	.odt_en = 0,
-	.size = 1024,
-	.tpr0 = 0x42d899b7,
-	.tpr1 = 0xa090,
-	.tpr2 = 0x22a00,
-	.tpr3 = 0,
-	.tpr4 = 0,
-	.tpr5 = 0,
-	.emr1 = 0x4,
-	.emr2 = 0x10,
-	.emr3 = 0,
-};
-
-unsigned long sunxi_dram_init(void)
-{
-	return dramc_init(&dram_para);
-}
diff --git a/board/sunxi/dram_sun7i_384_512_busw16_iow16.c b/board/sunxi/dram_sun7i_384_512_busw16_iow16.c
deleted file mode 100644
index 2e36011af51f4f3d0a26caf6922b6d960d577a55..0000000000000000000000000000000000000000
--- a/board/sunxi/dram_sun7i_384_512_busw16_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 = 384,
-	.type = 3,
-	.rank_num = 1,
-	.density = 4096,
-	.io_width = 16,
-	.bus_width = 16,
-	.cas = 9,
-	.zq = 0x7f,
-	.odt_en = 0,
-	.size = 512,
-	.tpr0 = 0x42d899b7,
-	.tpr1 = 0xa090,
-	.tpr2 = 0x22a00,
-	.tpr3 = 0,
-	.tpr4 = 0,
-	.tpr5 = 0,
-	.emr1 = 0x4,
-	.emr2 = 0x10,
-	.emr3 = 0,
-};
-
-unsigned long sunxi_dram_init(void)
-{
-	return dramc_init(&dram_para);
-}
diff --git a/configs/A10-OLinuXino-Lime_defconfig b/configs/A10-OLinuXino-Lime_defconfig
index f0cbf21025afefaecc05eb2af5527dfae1b0e61d..8fa1a330cd34e1a8202892595c549971b3275169 100644
--- a/configs/A10-OLinuXino-Lime_defconfig
+++ b/configs/A10-OLinuXino-Lime_defconfig
@@ -4,4 +4,6 @@ CONFIG_FDTFILE="sun4i-a10-olinuxino-lime.dtb"
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN4I=y
-+S:CONFIG_TARGET_A10_OLINUXINO_L=y
++S:CONFIG_DRAM_CLK=480
++S:CONFIG_DRAM_ZQ=123
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig
index f80b98ae90a2d37df500d941fc402b4e5f01ca83..17fd19da8fd459895354c1ad742b3d79e848913f 100644
--- a/configs/A20-OLinuXino-Lime2_defconfig
+++ b/configs/A20-OLinuXino-Lime2_defconfig
@@ -5,3 +5,6 @@ CONFIG_FDTFILE="sun7i-a20-olinuxino-lime2.dtb"
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN7I=y
 +S:CONFIG_TARGET_A20_OLINUXINO_L2=y
++S:CONFIG_DRAM_CLK=480
++S:CONFIG_DRAM_ZQ=127
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/A20-OLinuXino-Lime_defconfig b/configs/A20-OLinuXino-Lime_defconfig
index d9e66b715514830da86073f7316f2c846482810f..c8243a4ae8def661469e9122eab4a1c5a0de21db 100644
--- a/configs/A20-OLinuXino-Lime_defconfig
+++ b/configs/A20-OLinuXino-Lime_defconfig
@@ -5,3 +5,6 @@ CONFIG_FDTFILE="sun7i-a20-olinuxino-lime.dtb"
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN7I=y
 +S:CONFIG_TARGET_A20_OLINUXINO_L=y
++S:CONFIG_DRAM_CLK=480
++S:CONFIG_DRAM_ZQ=127
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/A20-OLinuXino_MICRO_defconfig b/configs/A20-OLinuXino_MICRO_defconfig
index 1c5a6f7a9faf1703a8d9d04dce5201647d2dc0db..ac94c79086c47edbbc9f6711eccdb526d81ba2db 100644
--- a/configs/A20-OLinuXino_MICRO_defconfig
+++ b/configs/A20-OLinuXino_MICRO_defconfig
@@ -9,3 +9,6 @@ CONFIG_VIDEO_VGA=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN7I=y
 +S:CONFIG_TARGET_A20_OLINUXINO_M=y
++S:CONFIG_DRAM_CLK=384
++S:CONFIG_DRAM_ZQ=127
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/Bananapi_defconfig b/configs/Bananapi_defconfig
index 196f6824cb422c6f43c137fb10baf0fd83fec61a..d94e08e0eb944c8a7f695e779e826480d9d46316 100644
--- a/configs/Bananapi_defconfig
+++ b/configs/Bananapi_defconfig
@@ -5,3 +5,6 @@ CONFIG_FDTFILE="sun7i-a20-bananapi.dtb"
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN7I=y
 +S:CONFIG_TARGET_BANANAPI=y
++S:CONFIG_DRAM_CLK=432
++S:CONFIG_DRAM_ZQ=127
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/Bananapro_defconfig b/configs/Bananapro_defconfig
index 7f9ce13e20e586f7836556af73734f5cd68d766f..02e4f3e9fedbcdf5bc9d23836089e7584f3261b4 100644
--- a/configs/Bananapro_defconfig
+++ b/configs/Bananapro_defconfig
@@ -7,3 +7,6 @@ CONFIG_USB2_VBUS_PIN="PH1"
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN7I=y
 +S:CONFIG_TARGET_BANANAPRO=y
++S:CONFIG_DRAM_CLK=432
++S:CONFIG_DRAM_ZQ=127
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/CSQ_CS908_defconfig b/configs/CSQ_CS908_defconfig
index 1b6cdbf811b3bfdb4f9fece099b69d5174b4275f..4040beea69e4dfb7ccf89c29f3d1346ccd4d74d4 100644
--- a/configs/CSQ_CS908_defconfig
+++ b/configs/CSQ_CS908_defconfig
@@ -4,7 +4,6 @@ CONFIG_FDTFILE="sun6i-a31s-cs908.dtb"
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN6I=y
-+S:CONFIG_TARGET_CSQ_CS908=y
 +S:CONFIG_DRAM_CLK=432
 +S:CONFIG_DRAM_ZQ=123
 # Ethernet phy power
diff --git a/configs/Chuwi_V7_CW0825_defconfig b/configs/Chuwi_V7_CW0825_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..680b6317df723260cb11a6052868390f86028314
--- /dev/null
+++ b/configs/Chuwi_V7_CW0825_defconfig
@@ -0,0 +1,19 @@
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER"
+CONFIG_FDTFILE="sun4i-a10-chuwi-v7-cw0825.dtb"
+CONFIG_USB_MUSB_SUNXI=y
+CONFIG_USB0_VBUS_PIN="PB9"
+CONFIG_VIDEO_LCD_MODE="x:1024,y:768,depth:24,pclk_khz:51000,le:19,ri:300,up:6,lo:31,hs:1,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_POWER="PH8"
+CONFIG_VIDEO_LCD_BL_EN="PH7"
+CONFIG_VIDEO_LCD_BL_PWM="PB2"
+CONFIG_VIDEO_LCD_SPI_CS="PA0"
+CONFIG_VIDEO_LCD_SPI_SCLK="PA1"
+CONFIG_VIDEO_LCD_SPI_MOSI="PA2"
+CONFIG_VIDEO_LCD_PANEL_HITACHI_TX18D42VM=y
++S:CONFIG_ARM=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN4I=y
++S:CONFIG_DRAM_CLK=408
++S:CONFIG_DRAM_ZQ=123
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/Colombus_defconfig b/configs/Colombus_defconfig
index f42ae5222e17022a6ccddd604c4915a0fe25df37..33edcc4205d66b332cd26d1ca89bd396fced28db 100644
--- a/configs/Colombus_defconfig
+++ b/configs/Colombus_defconfig
@@ -4,7 +4,6 @@ CONFIG_FDTFILE="sun6i-a31-colombus.dtb"
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN6I=y
-+S:CONFIG_TARGET_COLOMBUS=y
 +S:CONFIG_DRAM_CLK=240
 +S:CONFIG_DRAM_ZQ=251
 # Wifi power
diff --git a/configs/Cubieboard2_defconfig b/configs/Cubieboard2_defconfig
index 7e7a1ca3981cd4edeca132a71a9c1716fc011149..ef5b43aada9a85e712840846874d62c27dca68d5 100644
--- a/configs/Cubieboard2_defconfig
+++ b/configs/Cubieboard2_defconfig
@@ -5,3 +5,6 @@ CONFIG_FDTFILE="sun7i-a20-cubieboard2.dtb"
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN7I=y
 +S:CONFIG_TARGET_CUBIEBOARD2=y
++S:CONFIG_DRAM_CLK=480
++S:CONFIG_DRAM_ZQ=127
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/Cubieboard_defconfig b/configs/Cubieboard_defconfig
index 0bc45fd2cb28af8c559d68371e1e3b82b821be9d..4efc6e147e88c0b4f8d263f531db5f1c49ee22c9 100644
--- a/configs/Cubieboard_defconfig
+++ b/configs/Cubieboard_defconfig
@@ -4,4 +4,6 @@ CONFIG_FDTFILE="sun4i-a10-cubieboard.dtb"
 +S:CONFIG_ARM=y
 +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/Cubietruck_defconfig b/configs/Cubietruck_defconfig
index bc4441082b379669cb5edbd8a5b972de8ac92f19..f51c491af27e1a59a0957856b9dbeb72a8e584c1 100644
--- a/configs/Cubietruck_defconfig
+++ b/configs/Cubietruck_defconfig
@@ -6,3 +6,6 @@ CONFIG_VIDEO_VGA=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN7I=y
 +S:CONFIG_TARGET_CUBIETRUCK=y
++S:CONFIG_DRAM_CLK=432
++S:CONFIG_DRAM_ZQ=127
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/Hummingbird_A31_defconfig b/configs/Hummingbird_A31_defconfig
index 8896999e1e38a37086a29f5c0f3e1baf2b0bc740..027546391f16638184dede90512798c0b8b89f43 100644
--- a/configs/Hummingbird_A31_defconfig
+++ b/configs/Hummingbird_A31_defconfig
@@ -6,7 +6,6 @@ CONFIG_VIDEO_VGA_EXTERNAL_DAC_EN="PH25"
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN6I=y
-+S:CONFIG_TARGET_HUMMINGBIRD_A31=y
 +S:CONFIG_DRAM_CLK=312
 +S:CONFIG_DRAM_ZQ=251
 # Wifi power
diff --git a/configs/Hyundai_A7HD_defconfig b/configs/Hyundai_A7HD_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..60eb03ef26e7192995d850f43bec12581a9c1775
--- /dev/null
+++ b/configs/Hyundai_A7HD_defconfig
@@ -0,0 +1,22 @@
+# The Hyundai A7HD is a 7" 16:9 A10 powered tablet featuring 1G RAM, 8G
+# nand, 1024x600 IPS screen, a mini hdmi port, mini usb receptacle and a
+# headphones port for details see: http://linux-sunxi.org/Hyundai_A7HD
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER"
+CONFIG_FDTFILE="sun4i-a10-hyundai-a7hd.dtb"
+CONFIG_USB_MUSB_SUNXI=y
+CONFIG_USB0_VBUS_PIN="PB09"
+CONFIG_USB2_VBUS_PIN=""
+CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:18,pclk_khz:51000,le:45,ri:274,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_DCLK_PHASE=1
+CONFIG_VIDEO_LCD_POWER="PH2"
+CONFIG_VIDEO_LCD_BL_EN="PH9"
+CONFIG_VIDEO_LCD_BL_PWM="PB2"
+CONFIG_VIDEO_LCD_BL_PWM_ACTIVE_LOW=n
+CONFIG_VIDEO_LCD_PANEL_LVDS=y
++S:CONFIG_ARM=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN4I=y
++S:CONFIG_DRAM_CLK=360
++S:CONFIG_DRAM_ZQ=123
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/Ippo_q8h_v1_2_defconfig b/configs/Ippo_q8h_v1_2_defconfig
index 0447b06c2b178bf546917bf72b1eb39d4a94b80f..192a461f55f6462c3519a9d5aade9b1be0020b15 100644
--- a/configs/Ippo_q8h_v1_2_defconfig
+++ b/configs/Ippo_q8h_v1_2_defconfig
@@ -1,11 +1,13 @@
 CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5"
 CONFIG_FDTFILE="sun8i-a23-ippo-q8h-v1.2.dtb"
+CONFIG_USB_MUSB_SUNXI=y
+CONFIG_USB0_VBUS_PIN="axp_drivebus"
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:167,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_DCLK_PHASE=0
 CONFIG_VIDEO_LCD_POWER="PH7"
 CONFIG_VIDEO_LCD_BL_EN="PH6"
 CONFIG_VIDEO_LCD_BL_PWM="PH0"
-CONFIG_USB_KEYBOARD=n
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN8I=y
diff --git a/configs/Ippo_q8h_v5_defconfig b/configs/Ippo_q8h_v5_defconfig
index 4e82bf93653e371b85d7c8421b150b43b20ee82a..c894948d88351f12e751c6e7dce5297b7f54113f 100644
--- a/configs/Ippo_q8h_v5_defconfig
+++ b/configs/Ippo_q8h_v5_defconfig
@@ -1,11 +1,13 @@
 CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5"
 CONFIG_FDTFILE="sun8i-a23-ippo-q8h-v5.dtb"
+CONFIG_USB_MUSB_SUNXI=y
+CONFIG_USB0_VBUS_PIN="axp_drivebus"
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:168,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_DCLK_PHASE=0
 CONFIG_VIDEO_LCD_POWER="PH7"
 CONFIG_VIDEO_LCD_BL_EN="PH6"
 CONFIG_VIDEO_LCD_BL_PWM="PH0"
-CONFIG_USB_KEYBOARD=n
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN8I=y
diff --git a/configs/Linksprite_pcDuino3_defconfig b/configs/Linksprite_pcDuino3_defconfig
index a26ff0a70f40efcb2fc9cdac035d49465c0f90c9..64e01c8ffd47c3e1b0d670ed93a4d42f1def5ea8 100644
--- a/configs/Linksprite_pcDuino3_defconfig
+++ b/configs/Linksprite_pcDuino3_defconfig
@@ -5,3 +5,6 @@ CONFIG_FDTFILE="sun7i-a20-pcduino3.dtb"
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN7I=y
 +S:CONFIG_TARGET_PCDUINO3=y
++S:CONFIG_DRAM_CLK=480
++S:CONFIG_DRAM_ZQ=122
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/Linksprite_pcDuino3_fdt_defconfig b/configs/Linksprite_pcDuino3_fdt_defconfig
index a33f3a7981faa8723989d4b88ee0eda21bf84265..49718c798c946a04c5badc1e8e297fbf849ebc69 100644
--- a/configs/Linksprite_pcDuino3_fdt_defconfig
+++ b/configs/Linksprite_pcDuino3_fdt_defconfig
@@ -9,3 +9,6 @@ CONFIG_OF_SEPARATE=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN7I=y
 +S:CONFIG_TARGET_PCDUINO3=y
++S:CONFIG_DRAM_CLK=480
++S:CONFIG_DRAM_ZQ=122
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/Linksprite_pcDuino_defconfig b/configs/Linksprite_pcDuino_defconfig
index f5b0ca9877f6277ad241631fb62cb85e3324517c..1ba37bb3fbdd1d9a00c74053143512ffec648a9d 100644
--- a/configs/Linksprite_pcDuino_defconfig
+++ b/configs/Linksprite_pcDuino_defconfig
@@ -4,4 +4,6 @@ CONFIG_FDTFILE="sun4i-a10-pcduino.dtb"
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN4I=y
-+S:CONFIG_TARGET_PCDUINO=y
++S:CONFIG_DRAM_CLK=408
++S:CONFIG_DRAM_ZQ=123
++S:CONFIG_DRAM_EMR1=0
diff --git a/configs/MSI_Primo73_defconfig b/configs/MSI_Primo73_defconfig
index ef1adc5623136c5d0cf3bc654f1d309df6174fc3..6628184cb7e6f9cb40a1326aa8f8787a1fd47384 100644
--- a/configs/MSI_Primo73_defconfig
+++ b/configs/MSI_Primo73_defconfig
@@ -2,6 +2,7 @@ CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER"
 CONFIG_FDTFILE="sun7i-a20-primo73.dtb"
 CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:18,pclk_khz:60000,le:60,ri:160,up:13,lo:12,hs:100,vs:10,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_DCLK_PHASE=0
 CONFIG_VIDEO_LCD_POWER="PH8"
 CONFIG_VIDEO_LCD_BL_EN="PH7"
 CONFIG_VIDEO_LCD_BL_PWM="PB2"
@@ -10,3 +11,6 @@ CONFIG_USB_KEYBOARD=n
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN7I=y
 +S:CONFIG_TARGET_MSI_PRIMO73=y
++S:CONFIG_DRAM_CLK=384
++S:CONFIG_DRAM_ZQ=127
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/MSI_Primo81_defconfig b/configs/MSI_Primo81_defconfig
index b4b0f6d0e2362de0fa4720fa168fe748d4ee6b74..6657ad66c9727ac4ceb2bb5bad3a6f16d09f1b2f 100644
--- a/configs/MSI_Primo81_defconfig
+++ b/configs/MSI_Primo81_defconfig
@@ -1,11 +1,29 @@
+# The MSI Primo81 is an A31s based tablet, with 1G RAM, 16G NAND,
+# 1024x768 IPS LCD display, mono speaker, 0.3 MP front camera, 2.0 MP
+# rear camera, 3500 mAh battery, gt911 touchscreen, mma8452 accelerometer
+# and rtl8188etv usb wifi. Has "power", "volume+" and "volume-" buttons
+# (both volume buttons are also connected to the UBOOT_SEL pin). The
+# external connectors are represented by MicroSD slot, MiniHDMI, MicroUSB
+# OTG and 3.5mm headphone jack. More details are available at
+#     http://linux-sunxi.org/MSI_Primo81
+
 CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS=""
 CONFIG_FDTFILE="sun6i-a31s-primo81.dtb"
+CONFIG_VIDEO_LCD_MODE="x:768,y:1024,depth:18,pclk_khz:66000,le:56,ri:60,up:30,lo:36,hs:64,vs:50,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_PANEL_MIPI_4_LANE_513_MBPS_VIA_SSD2828=y
+CONFIG_VIDEO_LCD_SSD2828_TX_CLK=27
+CONFIG_VIDEO_LCD_SSD2828_RESET="PA26"
+CONFIG_VIDEO_LCD_SPI_CS="PH9"
+CONFIG_VIDEO_LCD_SPI_SCLK="PH10"
+CONFIG_VIDEO_LCD_SPI_MOSI="PH11"
+CONFIG_VIDEO_LCD_SPI_MISO="PH12"
+CONFIG_VIDEO_LCD_BL_EN="PA25"
+CONFIG_VIDEO_LCD_BL_PWM="PH13"
 CONFIG_USB_KEYBOARD=n
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN6I=y
-+S:CONFIG_TARGET_MSI_PRIMO81=y
 +S:CONFIG_DRAM_CLK=360
 +S:CONFIG_DRAM_ZQ=122
 # Wifi power
diff --git a/configs/Marsboard_A10_defconfig b/configs/Marsboard_A10_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..653cb01b93f3603f2535fd17c31db7aee0c03e48
--- /dev/null
+++ b/configs/Marsboard_A10_defconfig
@@ -0,0 +1,9 @@
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="SUNXI_EMAC,AHCI,USB_EHCI"
+CONFIG_FDTFILE="sun4i-a10-marsboard.dtb"
++S:CONFIG_ARM=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN4I=y
++S:CONFIG_DRAM_CLK=360
++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 9cb3285a71a714eb09944cf7d7aa92eb3c446a14..0000000000000000000000000000000000000000
--- 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 97d94542d348efa2138116e309e0339909cf326b..1a0a025bd9eaa3b67ea6f3fb6c626b0af6f71076 100644
--- a/configs/Mele_A1000_defconfig
+++ b/configs/Mele_A1000_defconfig
@@ -5,4 +5,6 @@ CONFIG_VIDEO_VGA=y
 +S:CONFIG_ARM=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/Mele_M3_defconfig b/configs/Mele_M3_defconfig
index 141d565cf8cfa6e1aa25224f562431fb2669c024..7f1710adad15cfb30ac77d294115beff726cd747 100644
--- a/configs/Mele_M3_defconfig
+++ b/configs/Mele_M3_defconfig
@@ -8,3 +8,6 @@ CONFIG_VIDEO_VGA=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN7I=y
 +S:CONFIG_TARGET_MELE_M3=y
++S:CONFIG_DRAM_CLK=384
++S:CONFIG_DRAM_ZQ=127
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/Mele_M5_defconfig b/configs/Mele_M5_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..2e1f80d50931645b4262d32bed156bf420a924cb
--- /dev/null
+++ b/configs/Mele_M5_defconfig
@@ -0,0 +1,13 @@
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,AHCI,USB_EHCI,STATUSLED=234"
+CONFIG_FDTFILE="sun7i-a20-m5.dtb"
+CONFIG_VIDEO_HDMI=y
++S:CONFIG_MMC0_CD_PIN="PH1"
++S:CONFIG_USB1_VBUS_PIN="PH6"
++S:CONFIG_USB2_VBUS_PIN="PH3"
++S:CONFIG_ARM=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN7I=y
++S:CONFIG_DRAM_CLK=432
++S:CONFIG_DRAM_ZQ=122
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/Mele_M9_defconfig b/configs/Mele_M9_defconfig
index e5ab0ec3029c62b478f06c76556feb969988c674..eaf9a7e349b3c765228398ccbbe4f3f34aff807a 100644
--- a/configs/Mele_M9_defconfig
+++ b/configs/Mele_M9_defconfig
@@ -4,7 +4,6 @@ CONFIG_FDTFILE="sun6i-a31-m9.dtb"
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN6I=y
-+S:CONFIG_TARGET_MELE_M9=y
 +S:CONFIG_DRAM_CLK=312
 +S:CONFIG_DRAM_ZQ=120
 # The Mele M9 uses 3.3V for general IO
diff --git a/configs/Mini-X_defconfig b/configs/Mini-X_defconfig
index 0f6bbe06b2c5d09585a334403b3dd97e91594dd3..6aea77716d35e62f608e67dc8fd20fb40e99e665 100644
--- a/configs/Mini-X_defconfig
+++ b/configs/Mini-X_defconfig
@@ -4,4 +4,6 @@ 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=y
++S:CONFIG_DRAM_CLK=360
++S:CONFIG_DRAM_ZQ=123
++S:CONFIG_DRAM_EMR1=0
diff --git a/configs/ba10_tv_box_defconfig b/configs/ba10_tv_box_defconfig
index 6ca7c57186af556755b8293dbab6640ce3a30933..400906d3779408f423517985b06ac7b950999328 100644
--- a/configs/ba10_tv_box_defconfig
+++ b/configs/ba10_tv_box_defconfig
@@ -1,8 +1,10 @@
 CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,USB_EHCI"
 CONFIG_FDTFILE="sun4i-a10-ba10-tvbox.dtb"
-CONFIG_USB1_VBUS_PIN="PH12"
+CONFIG_USB2_VBUS_PIN="PH12"
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN4I=y
-+S:CONFIG_TARGET_BA10_TV_BOX=y
++S:CONFIG_DRAM_CLK=384
++S:CONFIG_DRAM_ZQ=123
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/i12-tvbox_defconfig b/configs/i12-tvbox_defconfig
index 5f5037e6982e8a095e2fe1b8e4702ed10ff7a0bb..65791b7dc1d8aaa9ea31749b15099f21fb53a88f 100644
--- a/configs/i12-tvbox_defconfig
+++ b/configs/i12-tvbox_defconfig
@@ -5,3 +5,6 @@ CONFIG_FDTFILE="sun7i-a20-i12-tvbox.dtb"
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN7I=y
 +S:CONFIG_TARGET_I12_TVBOX=y
++S:CONFIG_DRAM_CLK=384
++S:CONFIG_DRAM_ZQ=127
++S:CONFIG_DRAM_EMR1=4
diff --git a/configs/mk802_a10s_defconfig b/configs/mk802_a10s_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..086e1e4fa8c79d1f8d0ff3394145906962628dd7
--- /dev/null
+++ b/configs/mk802_a10s_defconfig
@@ -0,0 +1,11 @@
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="AXP152_POWER,USB_EHCI"
+CONFIG_FDTFILE="sun5i-a10s-mk802.dtb"
+CONFIG_USB1_VBUS_PIN="PB10"
++S:CONFIG_ARM=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN5I=y
++S:CONFIG_TARGET_MK802_A10S=y
++S:CONFIG_DRAM_CLK=432
++S:CONFIG_DRAM_ZQ=123
++S:CONFIG_DRAM_EMR1=0
diff --git a/configs/mk802_defconfig b/configs/mk802_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..d6b51a5269bdf5d43df13221ab1d75aa15d0145c
--- /dev/null
+++ b/configs/mk802_defconfig
@@ -0,0 +1,10 @@
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="USB_EHCI"
+CONFIG_FDTFILE="sun4i-a10-mk802.dtb"
+CONFIG_USB2_VBUS_PIN="PH12"
++S:CONFIG_ARM=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN4I=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/mk802ii_defconfig
similarity index 53%
rename from configs/Mini-X-1Gb_defconfig
rename to configs/mk802ii_defconfig
index b8fea0124572a7aafd878e7200e641d1570e0032..500f4df4b97110ca2acc618740f7ec993965b00a 100644
--- a/configs/Mini-X-1Gb_defconfig
+++ b/configs/mk802ii_defconfig
@@ -1,7 +1,9 @@
 CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,USB_EHCI"
-CONFIG_FDTFILE="sun4i-a10-mini-xplus.dtb"
+CONFIG_FDTFILE="sun4i-a10-mk802ii.dtb"
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN4I=y
-+S:CONFIG_TARGET_MINI_X_1GB=y
++S:CONFIG_DRAM_CLK=360
++S:CONFIG_DRAM_ZQ=123
++S:CONFIG_DRAM_EMR1=0
diff --git a/configs/qt840a_defconfig b/configs/qt840a_defconfig
deleted file mode 100644
index 70f8159b39cfc8e2b4841e4dc88545ae6fcc7619..0000000000000000000000000000000000000000
--- a/configs/qt840a_defconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,MACPWR=SUNXI_GPH(21),USB_EHCI"
-CONFIG_FDTFILE="sun7i-a20-i12-tvbox.dtb"
-+S:CONFIG_ARM=y
-+S:CONFIG_ARCH_SUNXI=y
-+S:CONFIG_MACH_SUN7I=y
-+S:CONFIG_TARGET_QT840A=y
diff --git a/configs/sunxi_Gemei_G9_defconfig b/configs/sunxi_Gemei_G9_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..a85db2a2355c1d0093360889038fa453925039a3
--- /dev/null
+++ b/configs/sunxi_Gemei_G9_defconfig
@@ -0,0 +1,20 @@
+# Gemei G9 is an A10 based tablet, with 1G RAM, 16G NAND,
+# 1024x768 IPS LCD display, stereo speakers, 1.3MP front camera and 5 MP
+# rear camera, 8000mAh battery, GT901 2+1 touchscreen, Bosch BMA250
+# accelerometer and RTL8188CUS USB wifi. It also has MicroSD slot, MiniHDMI,
+# 1 x MicroUSB OTG port and 1 x MicroUSB host port and 3.5mm headphone jack.
+# More details are available at: http://linux-sunxi.org/Gemei_G9
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,USB_EHCI"
+CONFIG_FDTFILE="sun4i-gemei-g9.dtb"
+CONFIG_VIDEO_LCD_MODE="x:1024,y:768,depth:18,pclk_khz:100000,le:799,ri:260,up:15,lo:16,hs:1,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_PANEL_LVDS=y
+CONFIG_VIDEO_LCD_POWER="PH8"
+CONFIG_VIDEO_LCD_BL_EN="PH7"
+CONFIG_VIDEO_LCD_BL_PWM="PB2"
++S:CONFIG_ARM=y
++S:CONFIG_ARCH_SUNXI=y
++S:CONFIG_MACH_SUN4I=y
++S:CONFIG_DRAM_CLK=432
++S:CONFIG_DRAM_ZQ=123
++S:CONFIG_DRAM_EMR1=4
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 623498187ef0255e6fd5a647819a7bdf4477f8e3..510479516b80432328b26ad827788afd4769f82d 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -89,8 +89,13 @@ static int mmc_set_mod_clk(struct sunxi_mmc_host *mmchost, unsigned int hz)
 		pll = CCM_MMC_CTRL_OSCM24;
 		pll_hz = 24000000;
 	} else {
+#ifdef CONFIG_MACH_SUN9I
+		pll = CCM_MMC_CTRL_PLL_PERIPH0;
+		pll_hz = clock_get_pll4_periph0();
+#else
 		pll = CCM_MMC_CTRL_PLL6;
 		pll_hz = clock_get_pll6();
+#endif
 	}
 
 	div = pll_hz / hz;
@@ -146,10 +151,16 @@ static int mmc_clk_io_on(int sdc_no)
 	/* config ahb clock */
 	setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
 
-#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I)
+#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
+    defined(CONFIG_MACH_SUN9I)
 	/* unassert reset */
 	setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no));
 #endif
+#if defined(CONFIG_MACH_SUN9I)
+	/* sun9i has a mmc-common module, also set the gate and reset there */
+	writel(SUNXI_MMC_COMMON_CLK_GATE | SUNXI_MMC_COMMON_RESET,
+	       SUNXI_MMC_COMMON_BASE + 4 * sdc_no);
+#endif
 
 	return mmc_set_mod_clk(mmchost, 24000000);
 }
@@ -355,7 +366,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 		}
 	}
 
-	error = mmc_rint_wait(mmc, 0xfffff, SUNXI_MMC_RINT_COMMAND_DONE, "cmd");
+	error = mmc_rint_wait(mmc, 1000, SUNXI_MMC_RINT_COMMAND_DONE, "cmd");
 	if (error)
 		goto out;
 
@@ -439,7 +450,8 @@ struct mmc *sunxi_mmc_init(int sdc_no)
 	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 	cfg->host_caps = MMC_MODE_4BIT;
 	cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
-#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || defined(CONFIG_MACH_SUN8I)
+#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
+    defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN9I)
 	cfg->host_caps |= MMC_MODE_HC;
 #endif
 	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index e68e16b3211757271a27e99d0089fbf4b29fc83f..f8f0239484fd43811cbf9dc9fcff3bb6dec179ef 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -63,3 +63,13 @@ config AXP221_ALDO3_VOLT
 	Set the voltage (mV) to program the axp221 aldo3 at, set to 0 to
 	disable aldo3. This is typically connected to VCC-PLL and AVCC and
 	must be set to 3V.
+
+config AXP221_ELDO3_VOLT
+	int "axp221 eldo3 voltage"
+	depends on AXP221_POWER
+	default 0
+	---help---
+	Set the voltage (mV) to program the axp221 eldo3 at, set to 0 to
+	disable eldo3. On some A31(s) tablets it might be used to supply
+	1.2V for the SSD2828 chip (converter of parallel LCD interface
+	into MIPI DSI).
diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c
index 3b1a6a73aed8ecfd8f748c1ffc37db8fff747e2e..4565398b0bf37d70b55e7f403aef4c3e70877cc3 100644
--- a/drivers/power/axp209.c
+++ b/drivers/power/axp209.c
@@ -16,6 +16,11 @@ enum axp209_reg {
 	AXP209_DCDC3_VOLTAGE = 0x27,
 	AXP209_LDO24_VOLTAGE = 0x28,
 	AXP209_LDO3_VOLTAGE = 0x29,
+	AXP209_IRQ_ENABLE1 = 0x40,
+	AXP209_IRQ_ENABLE2 = 0x41,
+	AXP209_IRQ_ENABLE3 = 0x42,
+	AXP209_IRQ_ENABLE4 = 0x43,
+	AXP209_IRQ_ENABLE5 = 0x44,
 	AXP209_IRQ_STATUS5 = 0x4c,
 	AXP209_SHUTDOWN = 0x32,
 	AXP209_GPIO0_CTRL = 0x90,
@@ -143,7 +148,7 @@ int axp209_set_ldo4(int mvolt)
 int axp209_init(void)
 {
 	u8 ver;
-	int rc;
+	int i, rc;
 
 	rc = axp209_read(AXP209_CHIP_VERSION, &ver);
 	if (rc)
@@ -155,6 +160,13 @@ int axp209_init(void)
 	if (ver != 0x1)
 		return -1;
 
+	/* Mask all interrupts */
+	for (i = AXP209_IRQ_ENABLE1; i <= AXP209_IRQ_ENABLE5; i++) {
+		rc = axp209_write(i, 0);
+		if (rc)
+			return rc;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c
index 4c86f099a2df52bb8223ed17115cbbc3da3232bf..58bbd45a021af80bd8eee172be9054cf85572641 100644
--- a/drivers/power/axp221.c
+++ b/drivers/power/axp221.c
@@ -302,6 +302,39 @@ int axp221_set_aldo3(unsigned int mvolt)
 			      AXP221_OUTPUT_CTRL3_ALDO3_EN);
 }
 
+int axp221_set_eldo(int eldo_num, unsigned int mvolt)
+{
+	int ret;
+	u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
+	u8 addr, bits;
+
+	switch (eldo_num) {
+	case 3:
+		addr = AXP221_ELDO3_CTRL;
+		bits = AXP221_OUTPUT_CTRL2_ELDO3_EN;
+		break;
+	case 2:
+		addr = AXP221_ELDO2_CTRL;
+		bits = AXP221_OUTPUT_CTRL2_ELDO2_EN;
+		break;
+	case 1:
+		addr = AXP221_ELDO1_CTRL;
+		bits = AXP221_OUTPUT_CTRL2_ELDO1_EN;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (mvolt == 0)
+		return axp221_clrbits(AXP221_OUTPUT_CTRL2, bits);
+
+	ret = pmic_bus_write(addr, cfg);
+	if (ret)
+		return ret;
+
+	return axp221_setbits(AXP221_OUTPUT_CTRL2, bits);
+}
+
 int axp221_init(void)
 {
 	/* This cannot be 0 because it is used in SPL before BSS is ready */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index fdbf3f64f28fee2479ab7dca441508858b430f1e..ccbd7e295dda9d259cb1b54c208fc8e4e3678268 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -6,3 +6,84 @@ config VIDEO_X86
 	  Turn on this option to enable a very simple driver which uses vesa
 	  to discover the video mode and then provides a frame buffer for use
 	  by U-Boot.
+
+config VIDEO_LCD_SSD2828
+	bool "SSD2828 bridge chip"
+	default n
+	---help---
+	Support for the SSD2828 bridge chip, which can take pixel data coming
+	from a parallel LCD interface and translate it on the fly into MIPI DSI
+	interface for driving a MIPI compatible LCD panel. It uses SPI for
+	configuration.
+
+config VIDEO_LCD_SSD2828_TX_CLK
+	int "SSD2828 TX_CLK frequency (in MHz)"
+	depends on VIDEO_LCD_SSD2828
+	default 0
+	---help---
+	The frequency of the crystal, which is clocking SSD2828. It may be
+	anything in the 8MHz-30MHz range and the exact value should be
+	retrieved from the board schematics. Or in the case of Allwinner
+	hardware, it can be usually found as 'lcd_xtal_freq' variable in
+	FEX files. It can be also set to 0 for selecting PCLK from the
+	parallel LCD interface instead of TX_CLK as the PLL clock source.
+
+config VIDEO_LCD_SSD2828_RESET
+	string "RESET pin of SSD2828"
+	depends on VIDEO_LCD_SSD2828
+	default ""
+	---help---
+	The reset pin of SSD2828 chip. This takes a string in the format
+	understood by 'name_to_gpio' function, e.g. PH1 for pin 1 of port H.
+
+config VIDEO_LCD_HITACHI_TX18D42VM
+	bool "Hitachi tx18d42vm LVDS LCD panel support"
+	depends on VIDEO
+	default n
+	---help---
+	Support for Hitachi tx18d42vm LVDS LCD panels, these panels have a
+	lcd controller which needs to be initialized over SPI, once that is
+	done they work like a regular LVDS panel.
+
+config VIDEO_LCD_SPI_CS
+	string "SPI CS pin for LCD related config job"
+	depends on VIDEO_LCD_SSD2828 || VIDEO_LCD_HITACHI_TX18D42VM
+	default ""
+	---help---
+	This is one of the SPI communication pins, involved in setting up a
+	working LCD configuration. The exact role of SPI may differ for
+	different hardware setups. The option takes a string in the format
+	understood by 'name_to_gpio' function, e.g. PH1 for pin 1 of port H.
+
+config VIDEO_LCD_SPI_SCLK
+	string "SPI SCLK pin for LCD related config job"
+	depends on VIDEO_LCD_SSD2828 || VIDEO_LCD_HITACHI_TX18D42VM
+	default ""
+	---help---
+	This is one of the SPI communication pins, involved in setting up a
+	working LCD configuration. The exact role of SPI may differ for
+	different hardware setups. The option takes a string in the format
+	understood by 'name_to_gpio' function, e.g. PH1 for pin 1 of port H.
+
+config VIDEO_LCD_SPI_MOSI
+	string "SPI MOSI pin for LCD related config job"
+	depends on VIDEO_LCD_SSD2828 || VIDEO_LCD_HITACHI_TX18D42VM
+	default ""
+	---help---
+	This is one of the SPI communication pins, involved in setting up a
+	working LCD configuration. The exact role of SPI may differ for
+	different hardware setups. The option takes a string in the format
+	understood by 'name_to_gpio' function, e.g. PH1 for pin 1 of port H.
+
+config VIDEO_LCD_SPI_MISO
+	string "SPI MISO pin for LCD related config job (optional)"
+	depends on VIDEO_LCD_SSD2828
+	default ""
+	---help---
+	This is one of the SPI communication pins, involved in setting up a
+	working LCD configuration. The exact role of SPI may differ for
+	different hardware setups. If wired up, this pin may provide additional
+	useful functionality. Such as bi-directional communication with the
+	hardware and LCD panel id retrieval (if the panel can report it). The
+	option takes a string in the format understood by 'name_to_gpio'
+	function, e.g. PH1 for pin 1 of port H.
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 42b1eaaf760c9323210dfabf2a0ca939d3c04e28..c3fcf455d268eeb5442cbe3987c11bd5b0750f01 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -29,6 +29,8 @@ obj-$(CONFIG_VIDEO_COREBOOT) += coreboot_fb.o
 obj-$(CONFIG_VIDEO_CT69000) += ct69000.o videomodes.o
 obj-$(CONFIG_VIDEO_DA8XX) += da8xx-fb.o videomodes.o
 obj-$(CONFIG_VIDEO_IMX25LCDC) += imx25lcdc.o videomodes.o
+obj-$(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM) += hitachi_tx18d42vm_lcd.o
+obj-$(CONFIG_VIDEO_LCD_SSD2828) += ssd2828.o
 obj-$(CONFIG_VIDEO_MB862xx) += mb862xx.o videomodes.o
 obj-$(CONFIG_VIDEO_MB86R0xGDC) += mb86r0xgdc.o videomodes.o
 obj-$(CONFIG_VIDEO_MX3) += mx3fb.o videomodes.o
diff --git a/drivers/video/hitachi_tx18d42vm_lcd.c b/drivers/video/hitachi_tx18d42vm_lcd.c
new file mode 100644
index 0000000000000000000000000000000000000000..1ce4a8c93e3cc32c0d12b7f566e326612bf73572
--- /dev/null
+++ b/drivers/video/hitachi_tx18d42vm_lcd.c
@@ -0,0 +1,81 @@
+/*
+ * Hitachi tx18d42vm LVDS LCD panel driver
+ *
+ * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+
+#include <asm/gpio.h>
+#include <errno.h>
+
+/*
+ * Very simple write only SPI support, this does not use the generic SPI infra
+ * because that assumes R/W SPI, requiring a MISO pin. Also the necessary glue
+ * code alone would be larger then this minimal version.
+ */
+static void lcd_panel_spi_write(int cs, int clk, int mosi,
+				unsigned int data, int bits)
+{
+	int i, offset;
+
+	gpio_direction_output(cs, 0);
+	for (i = 0; i < bits; i++) {
+		gpio_direction_output(clk, 0);
+		offset = (bits - 1) - i;
+		gpio_direction_output(mosi, (data >> offset) & 1);
+		udelay(2);
+		gpio_direction_output(clk, 1);
+		udelay(2);
+	}
+	gpio_direction_output(cs, 1);
+	udelay(2);
+}
+
+int hitachi_tx18d42vm_init(void)
+{
+	const u16 init_data[] = {
+		0x0029,		/* reset */
+		0x0025,		/* standby */
+		0x0840,		/* enable normally black */
+		0x0430,		/* enable FRC/dither */
+		0x385f,		/* enter test mode(1) */
+		0x3ca4,		/* enter test mode(2) */
+		0x3409,		/* enable SDRRS, enlarge OE width */
+		0x4041,		/* adopt 2 line / 1 dot */
+	};
+	int i, cs, clk, mosi, ret = 0;
+
+	cs = name_to_gpio(CONFIG_VIDEO_LCD_SPI_CS);
+	clk = name_to_gpio(CONFIG_VIDEO_LCD_SPI_SCLK);
+	mosi = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MOSI);
+
+	if (cs == -1 || clk == -1 || mosi == 1) {
+		printf("Error tx18d42vm spi gpio config is invalid\n");
+		return -EINVAL;
+	}
+
+	if (gpio_request(cs, "tx18d42vm-spi-cs") != 0 ||
+	    gpio_request(clk, "tx18d42vm-spi-clk") != 0 ||
+	    gpio_request(mosi, "tx18d42vm-spi-mosi") != 0) {
+		printf("Error cannot request tx18d42vm spi gpios\n");
+		ret = -EBUSY;
+		goto out;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(init_data); i++)
+		lcd_panel_spi_write(cs, clk, mosi, init_data[i], 16);
+
+	mdelay(50); /* All the tx18d42vm drivers have a delay here ? */
+
+	lcd_panel_spi_write(cs, clk, mosi, 0x00ad, 16); /* display on */
+
+out:
+	gpio_free(mosi);
+	gpio_free(clk);
+	gpio_free(cs);
+
+	return ret;
+}
diff --git a/drivers/video/hitachi_tx18d42vm_lcd.h b/drivers/video/hitachi_tx18d42vm_lcd.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b728005f64e945e214195fe3e226249f452019d
--- /dev/null
+++ b/drivers/video/hitachi_tx18d42vm_lcd.h
@@ -0,0 +1,9 @@
+/*
+ * Hitachi tx18d42vm LVDS LCD panel driver
+ *
+ * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+void hitachi_tx18d42vm_init(void);
diff --git a/drivers/video/ssd2828.c b/drivers/video/ssd2828.c
new file mode 100644
index 0000000000000000000000000000000000000000..8b090822549c1febd46b1886a217650f15fe261b
--- /dev/null
+++ b/drivers/video/ssd2828.c
@@ -0,0 +1,436 @@
+/*
+ * (C) 2015 Siarhei Siamashka <siarhei.siamashka@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Support for the SSD2828 bridge chip, which can take pixel data coming
+ * from a parallel LCD interface and translate it on the flight into MIPI DSI
+ * interface for driving a MIPI compatible TFT display.
+ */
+
+#include <common.h>
+#include <mipi_display.h>
+#include <asm/arch/gpio.h>
+#include <asm/gpio.h>
+
+#include "videomodes.h"
+#include "ssd2828.h"
+
+#define		SSD2828_DIR	0xB0
+#define		SSD2828_VICR1	0xB1
+#define		SSD2828_VICR2	0xB2
+#define		SSD2828_VICR3	0xB3
+#define		SSD2828_VICR4	0xB4
+#define		SSD2828_VICR5	0xB5
+#define		SSD2828_VICR6	0xB6
+#define		SSD2828_CFGR	0xB7
+#define		SSD2828_VCR	0xB8
+#define		SSD2828_PCR	0xB9
+#define		SSD2828_PLCR	0xBA
+#define		SSD2828_CCR	0xBB
+#define		SSD2828_PSCR1	0xBC
+#define		SSD2828_PSCR2	0xBD
+#define		SSD2828_PSCR3	0xBE
+#define		SSD2828_PDR	0xBF
+#define		SSD2828_OCR	0xC0
+#define		SSD2828_MRSR	0xC1
+#define		SSD2828_RDCR	0xC2
+#define		SSD2828_ARSR	0xC3
+#define		SSD2828_LCR	0xC4
+#define		SSD2828_ICR	0xC5
+#define		SSD2828_ISR	0xC6
+#define		SSD2828_ESR	0xC7
+#define		SSD2828_DAR1	0xC9
+#define		SSD2828_DAR2	0xCA
+#define		SSD2828_DAR3	0xCB
+#define		SSD2828_DAR4	0xCC
+#define		SSD2828_DAR5	0xCD
+#define		SSD2828_DAR6	0xCE
+#define		SSD2828_HTTR1	0xCF
+#define		SSD2828_HTTR2	0xD0
+#define		SSD2828_LRTR1	0xD1
+#define		SSD2828_LRTR2	0xD2
+#define		SSD2828_TSR	0xD3
+#define		SSD2828_LRR	0xD4
+#define		SSD2828_PLLR	0xD5
+#define		SSD2828_TR	0xD6
+#define		SSD2828_TECR	0xD7
+#define		SSD2828_ACR1	0xD8
+#define		SSD2828_ACR2	0xD9
+#define		SSD2828_ACR3	0xDA
+#define		SSD2828_ACR4	0xDB
+#define		SSD2828_IOCR	0xDC
+#define		SSD2828_VICR7	0xDD
+#define		SSD2828_LCFR	0xDE
+#define		SSD2828_DAR7	0xDF
+#define		SSD2828_PUCR1	0xE0
+#define		SSD2828_PUCR2	0xE1
+#define		SSD2828_PUCR3	0xE2
+#define		SSD2828_CBCR1	0xE9
+#define		SSD2828_CBCR2	0xEA
+#define		SSD2828_CBSR	0xEB
+#define		SSD2828_ECR	0xEC
+#define		SSD2828_VSDR	0xED
+#define		SSD2828_TMR	0xEE
+#define		SSD2828_GPIO1	0xEF
+#define		SSD2828_GPIO2	0xF0
+#define		SSD2828_DLYA01	0xF1
+#define		SSD2828_DLYA23	0xF2
+#define		SSD2828_DLYB01	0xF3
+#define		SSD2828_DLYB23	0xF4
+#define		SSD2828_DLYC01	0xF5
+#define		SSD2828_DLYC23	0xF6
+#define		SSD2828_ACR5	0xF7
+#define		SSD2828_RR	0xFF
+
+#define	SSD2828_CFGR_HS					(1 << 0)
+#define	SSD2828_CFGR_CKE				(1 << 1)
+#define	SSD2828_CFGR_SLP				(1 << 2)
+#define	SSD2828_CFGR_VEN				(1 << 3)
+#define	SSD2828_CFGR_HCLK				(1 << 4)
+#define	SSD2828_CFGR_CSS				(1 << 5)
+#define	SSD2828_CFGR_DCS				(1 << 6)
+#define	SSD2828_CFGR_REN				(1 << 7)
+#define	SSD2828_CFGR_ECD				(1 << 8)
+#define	SSD2828_CFGR_EOT				(1 << 9)
+#define	SSD2828_CFGR_LPE				(1 << 10)
+#define	SSD2828_CFGR_TXD				(1 << 11)
+
+#define	SSD2828_VIDEO_MODE_NON_BURST_WITH_SYNC_PULSES	(0 << 2)
+#define	SSD2828_VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS	(1 << 2)
+#define	SSD2828_VIDEO_MODE_BURST			(2 << 2)
+
+#define	SSD2828_VIDEO_PIXEL_FORMAT_16BPP		0
+#define	SSD2828_VIDEO_PIXEL_FORMAT_18BPP_PACKED		1
+#define	SSD2828_VIDEO_PIXEL_FORMAT_18BPP_LOOSELY_PACKED	2
+#define	SSD2828_VIDEO_PIXEL_FORMAT_24BPP		3
+
+#define	SSD2828_LP_CLOCK_DIVIDER(n)			(((n) - 1) & 0x3F)
+
+/*
+ * SPI transfer, using the "24-bit 3 wire" mode (that's how it is called in
+ * the SSD2828 documentation). The 'dout' input parameter specifies 24-bits
+ * of data to be written to SSD2828. Returns the lowest 16-bits of data,
+ * that is received back.
+ */
+static u32 soft_spi_xfer_24bit_3wire(const struct ssd2828_config *drv, u32 dout)
+{
+	int j, bitlen = 24;
+	u32 tmpdin = 0;
+	/*
+	 * According to the "24 Bit 3 Wire SPI Interface Timing Characteristics"
+	 * and "TX_CLK Timing Characteristics" tables in the SSD2828 datasheet,
+	 * the lowest possible 'tx_clk' clock frequency is 8MHz, and SPI runs
+	 * at 1/8 of that after reset. So using 1 microsecond delays is safe in
+	 * the main loop. But the delays around chip select pin manipulations
+	 * need to be longer (up to 16 'tx_clk' cycles, or 2 microseconds in
+	 * the worst case).
+	 */
+	const int spi_delay_us = 1;
+	const int spi_cs_delay_us = 2;
+
+	gpio_set_value(drv->csx_pin, 0);
+	udelay(spi_cs_delay_us);
+	for (j = bitlen - 1; j >= 0; j--) {
+		gpio_set_value(drv->sck_pin, 0);
+		gpio_set_value(drv->sdi_pin, (dout & (1 << j)) != 0);
+		udelay(spi_delay_us);
+		if (drv->sdo_pin != -1)
+			tmpdin = (tmpdin << 1) | gpio_get_value(drv->sdo_pin);
+		gpio_set_value(drv->sck_pin, 1);
+		udelay(spi_delay_us);
+	}
+	udelay(spi_cs_delay_us);
+	gpio_set_value(drv->csx_pin, 1);
+	udelay(spi_cs_delay_us);
+	return tmpdin & 0xFFFF;
+}
+
+/*
+ * Read from a SSD2828 hardware register (regnum >= 0xB0)
+ */
+static u32 read_hw_register(const struct ssd2828_config *cfg, u8 regnum)
+{
+	soft_spi_xfer_24bit_3wire(cfg, 0x700000 | regnum);
+	return soft_spi_xfer_24bit_3wire(cfg, 0x730000);
+}
+
+/*
+ * Write to a SSD2828 hardware register (regnum >= 0xB0)
+ */
+static void write_hw_register(const struct ssd2828_config *cfg, u8 regnum,
+			      u16 val)
+{
+	soft_spi_xfer_24bit_3wire(cfg, 0x700000 | regnum);
+	soft_spi_xfer_24bit_3wire(cfg, 0x720000 | val);
+}
+
+/*
+ * Send MIPI command to the LCD panel (cmdnum < 0xB0)
+ */
+static void send_mipi_dcs_command(const struct ssd2828_config *cfg, u8 cmdnum)
+{
+	/* Set packet size to 1 (a single command with no parameters) */
+	write_hw_register(cfg, SSD2828_PSCR1, 1);
+	/* Send the command */
+	write_hw_register(cfg, SSD2828_PDR, cmdnum);
+}
+
+/*
+ * Reset SSD2828
+ */
+static void ssd2828_reset(const struct ssd2828_config *cfg)
+{
+	/* RESET needs 10 milliseconds according to the datasheet */
+	gpio_set_value(cfg->reset_pin, 0);
+	mdelay(10);
+	gpio_set_value(cfg->reset_pin, 1);
+	mdelay(10);
+}
+
+static int ssd2828_enable_gpio(const struct ssd2828_config *cfg)
+{
+	if (gpio_request(cfg->csx_pin, "ssd2828_csx")) {
+		printf("SSD2828: request for 'ssd2828_csx' pin failed\n");
+		return 1;
+	}
+	if (gpio_request(cfg->sck_pin, "ssd2828_sck")) {
+		gpio_free(cfg->csx_pin);
+		printf("SSD2828: request for 'ssd2828_sck' pin failed\n");
+		return 1;
+	}
+	if (gpio_request(cfg->sdi_pin, "ssd2828_sdi")) {
+		gpio_free(cfg->csx_pin);
+		gpio_free(cfg->sck_pin);
+		printf("SSD2828: request for 'ssd2828_sdi' pin failed\n");
+		return 1;
+	}
+	if (gpio_request(cfg->reset_pin, "ssd2828_reset")) {
+		gpio_free(cfg->csx_pin);
+		gpio_free(cfg->sck_pin);
+		gpio_free(cfg->sdi_pin);
+		printf("SSD2828: request for 'ssd2828_reset' pin failed\n");
+		return 1;
+	}
+	if (cfg->sdo_pin != -1 && gpio_request(cfg->sdo_pin, "ssd2828_sdo")) {
+		gpio_free(cfg->csx_pin);
+		gpio_free(cfg->sck_pin);
+		gpio_free(cfg->sdi_pin);
+		gpio_free(cfg->reset_pin);
+		printf("SSD2828: request for 'ssd2828_sdo' pin failed\n");
+		return 1;
+	}
+	gpio_direction_output(cfg->reset_pin, 0);
+	gpio_direction_output(cfg->csx_pin, 1);
+	gpio_direction_output(cfg->sck_pin, 1);
+	gpio_direction_output(cfg->sdi_pin, 1);
+	if (cfg->sdo_pin != -1)
+		gpio_direction_input(cfg->sdo_pin);
+
+	return 0;
+}
+
+static int ssd2828_free_gpio(const struct ssd2828_config *cfg)
+{
+	gpio_free(cfg->csx_pin);
+	gpio_free(cfg->sck_pin);
+	gpio_free(cfg->sdi_pin);
+	gpio_free(cfg->reset_pin);
+	if (cfg->sdo_pin != -1)
+		gpio_free(cfg->sdo_pin);
+	return 1;
+}
+
+/*
+ * PLL configuration register settings.
+ *
+ * See the "PLL Configuration Register Description" in the SSD2828 datasheet.
+ */
+static u32 construct_pll_config(u32 desired_pll_freq_kbps,
+				u32 reference_freq_khz)
+{
+	u32 div_factor = 1, mul_factor, fr = 0;
+	u32 output_freq_kbps;
+
+	/* The intermediate clock after division can't be less than 5MHz */
+	while (reference_freq_khz / (div_factor + 1) >= 5000)
+		div_factor++;
+	if (div_factor > 31)
+		div_factor = 31;
+
+	mul_factor = DIV_ROUND_UP(desired_pll_freq_kbps * div_factor,
+				  reference_freq_khz);
+
+	output_freq_kbps = reference_freq_khz * mul_factor / div_factor;
+
+	if (output_freq_kbps >= 501000)
+		fr = 3;
+	else if (output_freq_kbps >= 251000)
+		fr = 2;
+	else if (output_freq_kbps >= 126000)
+		fr = 1;
+
+	return (fr << 14) | (div_factor << 8) | mul_factor;
+}
+
+static u32 decode_pll_config(u32 pll_config, u32 reference_freq_khz)
+{
+	u32 mul_factor = pll_config & 0xFF;
+	u32 div_factor = (pll_config >> 8) & 0x1F;
+	if (mul_factor == 0)
+		mul_factor = 1;
+	if (div_factor == 0)
+		div_factor = 1;
+	return reference_freq_khz * mul_factor / div_factor;
+}
+
+static int ssd2828_configure_video_interface(const struct ssd2828_config *cfg,
+					     const struct ctfb_res_modes *mode)
+{
+	u32 val;
+
+	/* RGB Interface Control Register 1 */
+	write_hw_register(cfg, SSD2828_VICR1, (mode->vsync_len << 8) |
+					      (mode->hsync_len));
+
+	/* RGB Interface Control Register 2 */
+	u32 vbp = mode->vsync_len + mode->upper_margin;
+	u32 hbp = mode->hsync_len + mode->left_margin;
+	write_hw_register(cfg, SSD2828_VICR2, (vbp << 8) | hbp);
+
+	/* RGB Interface Control Register 3 */
+	write_hw_register(cfg, SSD2828_VICR3, (mode->lower_margin << 8) |
+					      (mode->right_margin));
+
+	/* RGB Interface Control Register 4 */
+	write_hw_register(cfg, SSD2828_VICR4, mode->xres);
+
+	/* RGB Interface Control Register 5 */
+	write_hw_register(cfg, SSD2828_VICR5, mode->yres);
+
+	/* RGB Interface Control Register 6 */
+	val = SSD2828_VIDEO_MODE_BURST;
+	switch (cfg->ssd2828_color_depth) {
+	case 16:
+		val |= SSD2828_VIDEO_PIXEL_FORMAT_16BPP;
+		break;
+	case 18:
+		val |= cfg->mipi_dsi_loosely_packed_pixel_format ?
+			SSD2828_VIDEO_PIXEL_FORMAT_18BPP_LOOSELY_PACKED :
+			SSD2828_VIDEO_PIXEL_FORMAT_18BPP_PACKED;
+		break;
+	case 24:
+		val |= SSD2828_VIDEO_PIXEL_FORMAT_24BPP;
+		break;
+	default:
+		printf("SSD2828: unsupported color depth\n");
+		return 1;
+	}
+	write_hw_register(cfg, SSD2828_VICR6, val);
+
+	/* Lane Configuration Register */
+	write_hw_register(cfg, SSD2828_LCFR,
+			  cfg->mipi_dsi_number_of_data_lanes - 1);
+
+	return 0;
+}
+
+int ssd2828_init(const struct ssd2828_config *cfg,
+		 const struct ctfb_res_modes *mode)
+{
+	u32 lp_div, pll_freq_kbps, reference_freq_khz, pll_config;
+	/* The LP clock speed is limited by 10MHz */
+	const u32 mipi_dsi_low_power_clk_khz = 10000;
+	/*
+	 * This is just the reset default value of CFGR register (0x301).
+	 * Because we are not always able to read back from SPI, have
+	 * it initialized here.
+	 */
+	u32 cfgr_reg = SSD2828_CFGR_EOT | /* EOT Packet Enable */
+		       SSD2828_CFGR_ECD | /* Disable ECC and CRC */
+		       SSD2828_CFGR_HS;   /* Data lanes are in HS mode */
+
+	/* Initialize the pins */
+	if (ssd2828_enable_gpio(cfg) != 0)
+		return 1;
+
+	/* Reset the chip */
+	ssd2828_reset(cfg);
+
+	/*
+	 * If there is a pin to read data back from SPI, then we are lucky. Try
+	 * to check if SPI is configured correctly and SSD2828 is actually able
+	 * to talk back.
+	 */
+	if (cfg->sdo_pin != -1) {
+		if (read_hw_register(cfg, SSD2828_DIR) != 0x2828 ||
+		    read_hw_register(cfg, SSD2828_CFGR) != cfgr_reg) {
+			printf("SSD2828: SPI communication failed.\n");
+			ssd2828_free_gpio(cfg);
+			return 1;
+		}
+	}
+
+	/*
+	 * Pick the reference clock for PLL. If we know the exact 'tx_clk'
+	 * clock speed, then everything is good. If not, then we can fallback
+	 * to 'pclk' (pixel clock from the parallel LCD interface). In the
+	 * case of using this fallback, it is necessary to have parallel LCD
+	 * already initialized and running at this point.
+	 */
+	reference_freq_khz = cfg->ssd2828_tx_clk_khz;
+	if (reference_freq_khz  == 0) {
+		reference_freq_khz = mode->pixclock_khz;
+		/* Use 'pclk' as the reference clock for PLL */
+		cfgr_reg |= SSD2828_CFGR_CSS;
+	}
+
+	/*
+	 * Setup the parallel LCD timings in the appropriate registers.
+	 */
+	if (ssd2828_configure_video_interface(cfg, mode) != 0) {
+		ssd2828_free_gpio(cfg);
+		return 1;
+	}
+
+	/* Configuration Register */
+	cfgr_reg &= ~SSD2828_CFGR_HS;  /* Data lanes are in LP mode */
+	cfgr_reg |= SSD2828_CFGR_CKE;  /* Clock lane is in HS mode */
+	cfgr_reg |= SSD2828_CFGR_DCS;  /* Only use DCS packets */
+	write_hw_register(cfg, SSD2828_CFGR, cfgr_reg);
+
+	/* PLL Configuration Register */
+	pll_config = construct_pll_config(
+				cfg->mipi_dsi_bitrate_per_data_lane_mbps * 1000,
+				reference_freq_khz);
+	write_hw_register(cfg, SSD2828_PLCR, pll_config);
+
+	pll_freq_kbps = decode_pll_config(pll_config, reference_freq_khz);
+	lp_div = DIV_ROUND_UP(pll_freq_kbps, mipi_dsi_low_power_clk_khz * 8);
+
+	/* VC Control Register */
+	write_hw_register(cfg, SSD2828_VCR, 0);
+
+	/* Clock Control Register */
+	write_hw_register(cfg, SSD2828_CCR, SSD2828_LP_CLOCK_DIVIDER(lp_div));
+
+	/* PLL Control Register */
+	write_hw_register(cfg, SSD2828_PCR, 1); /* Enable PLL */
+
+	/* Wait for PLL lock */
+	udelay(500);
+
+	send_mipi_dcs_command(cfg, MIPI_DCS_EXIT_SLEEP_MODE);
+	mdelay(cfg->mipi_dsi_delay_after_exit_sleep_mode_ms);
+
+	send_mipi_dcs_command(cfg, MIPI_DCS_SET_DISPLAY_ON);
+	mdelay(cfg->mipi_dsi_delay_after_set_display_on_ms);
+
+	cfgr_reg |= SSD2828_CFGR_HS;    /* Enable HS mode for data lanes */
+	cfgr_reg |= SSD2828_CFGR_VEN;   /* Enable video pipeline */
+	write_hw_register(cfg, SSD2828_CFGR, cfgr_reg);
+
+	return 0;
+}
diff --git a/drivers/video/ssd2828.h b/drivers/video/ssd2828.h
new file mode 100644
index 0000000000000000000000000000000000000000..1af6fa402326b8b9a0df6be9d4247244756d2f6f
--- /dev/null
+++ b/drivers/video/ssd2828.h
@@ -0,0 +1,128 @@
+/*
+ * (C) 2015 Siarhei Siamashka <siarhei.siamashka@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Support for the SSD2828 bridge chip, which can take pixel data coming
+ * from a parallel LCD interface and translate it on the flight into MIPI DSI
+ * interface for driving a MIPI compatible TFT display.
+ *
+ * Implemented as a utility function. To be used from display drivers, which are
+ * responsible for driving parallel LCD hardware in front of the video pipeline.
+ */
+
+#ifndef _SSD2828_H
+#define _SSD2828_H
+
+struct ctfb_res_modes;
+
+struct ssd2828_config {
+	/*********************************************************************/
+	/* SSD2828 configuration                                             */
+	/*********************************************************************/
+
+	/*
+	 * The pins, which are used for SPI communication. This is only used
+	 * for configuring SSD2828, so the performance is irrelevant (only
+	 * around a hundred of bytes is moved). Also these can be any arbitrary
+	 * GPIO pins (not necessarily the pins having hardware SPI function).
+	 * Moreover, the 'sdo' pin may be even not wired up in some devices.
+	 *
+	 * These configuration variables need to be set as pin numbers for
+	 * the standard u-boot GPIO interface (gpio_get_value/gpio_set_value
+	 * functions). Note that -1 value can be used for the pins, which are
+	 * not really wired up.
+	 */
+	int csx_pin;
+	int sck_pin;
+	int sdi_pin;
+	int sdo_pin;
+	/* SSD2828 reset pin (shared with LCD panel reset) */
+	int reset_pin;
+
+	/*
+	 * The SSD2828 has its own dedicated clock source 'tx_clk' (connected
+	 * to TX_CLK_XIO/TX_CLK_XIN pins), which is necessary at least for
+	 * clocking SPI after reset. The exact clock speed is not strictly,
+	 * defined, but the datasheet says that it must be somewhere in the
+	 * 8MHz - 30MHz range (see "TX_CLK Timing" section). It can be also
+	 * used as a reference clock for PLL. If the exact clock frequency
+	 * is known, then it can be specified here. If it is unknown, or the
+	 * information is not trustworthy, then it can be set to 0.
+	 *
+	 * If unsure, set to 0.
+	 */
+	int ssd2828_tx_clk_khz;
+
+	/*
+	 * This is not a property of the used LCD panel, but more like a
+	 * property of the SSD2828 wiring. See the "SSD2828QN4 RGB data
+	 * arrangement" table in the datasheet. The SSD2828 pins are arranged
+	 * in such a way that 18bpp and 24bpp configurations are completely
+	 * incompatible with each other.
+	 *
+	 * Depending on the color depth, this must be set to 16, 18 or 24.
+	 */
+	int ssd2828_color_depth;
+
+	/*********************************************************************/
+	/* LCD panel configuration                                           */
+	/*********************************************************************/
+
+	/*
+	 * The number of lanes in the MIPI DSI interface. May vary from 1 to 4.
+	 *
+	 * This information can be found in the LCD panel datasheet.
+	 */
+	int mipi_dsi_number_of_data_lanes;
+
+	/*
+	 * Data transfer bit rate per lane. Please note that it is expected
+	 * to be higher than the pixel clock rate of the used video mode when
+	 * multiplied by the number of lanes. This is perfectly normal because
+	 * MIPI DSI handles data transfers in periodic bursts, and uses the
+	 * idle time between bursts for sending configuration information and
+	 * commands. Or just for saving power.
+	 *
+	 * The necessary Mbps/lane information can be found in the LCD panel
+	 * datasheet. Note that the transfer rate can't be always set precisely
+	 * and it may be rounded *up* (introducing no more than 10Mbps error).
+	 */
+	int mipi_dsi_bitrate_per_data_lane_mbps;
+
+	/*
+	 * Setting this to 1 enforces packing of 18bpp pixel data in 24bpp
+	 * envelope when sending it over the MIPI DSI link.
+	 *
+	 * If unsure, set to 0.
+	 */
+	int mipi_dsi_loosely_packed_pixel_format;
+
+	/*
+	 * According to the "Example for system sleep in and out" section in
+	 * the SSD2828 datasheet, some LCD panel specific delays are necessary
+	 * after MIPI DCS commands EXIT_SLEEP_MODE and SET_DISPLAY_ON.
+	 *
+	 * For example, Allwinner uses 100 milliseconds delay after
+	 * EXIT_SLEEP_MODE and 200 milliseconds delay after SET_DISPLAY_ON.
+	 */
+	int mipi_dsi_delay_after_exit_sleep_mode_ms;
+	int mipi_dsi_delay_after_set_display_on_ms;
+};
+
+/*
+ * Initialize the SSD2828 chip. It needs the 'ssd2828_config' structure
+ * and also the video mode timings.
+ *
+ * The right place to insert this function call is after the parallel LCD
+ * interface is initialized and before turning on the backlight. This is
+ * advised in the "Example for system sleep in and out" section of the
+ * SSD2828 datasheet. And also SS2828 may use 'pclk' as the clock source
+ * for PLL, which means that the input signal must be already there.
+ */
+int ssd2828_init(const struct ssd2828_config *cfg,
+		 const struct ctfb_res_modes *mode);
+
+#endif
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index d92dfa88635260560c871c92536209f18e27c194..af728b51c746783e46d3edc06b01538814dd44ea 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -20,6 +20,16 @@
 #include <fdt_support.h>
 #include <video_fb.h>
 #include "videomodes.h"
+#include "hitachi_tx18d42vm_lcd.h"
+#include "ssd2828.h"
+
+#ifdef CONFIG_VIDEO_LCD_BL_PWM_ACTIVE_LOW
+#define PWM_ON 0
+#define PWM_OFF 1
+#else
+#define PWM_ON 1
+#define PWM_OFF 0
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -270,6 +280,114 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode)
 
 #endif /* CONFIG_VIDEO_HDMI */
 
+#ifdef CONFIG_MACH_SUN4I
+/*
+ * Testing has shown that on sun4i the display backend engine does not have
+ * deep enough fifo-s causing flickering / tearing in full-hd mode due to
+ * fifo underruns. So on sun4i we use the display frontend engine to do the
+ * dma from memory, as the frontend does have deep enough fifo-s.
+ */
+
+static const u32 sun4i_vert_coef[32] = {
+	0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd,
+	0x00063efc, 0xff083dfc, 0x000a3bfb, 0xff0d39fb,
+	0xff0f37fb, 0xff1136fa, 0xfe1433fb, 0xfe1631fb,
+	0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb, 0xfc2127fc,
+	0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd,
+	0xfb2f19fd, 0xfb3116fe, 0xfb3314fe, 0xfa3611ff,
+	0xfb370fff, 0xfb390dff, 0xfb3b0a00, 0xfc3d08ff,
+	0xfc3e0600, 0xfd3f0400, 0xfe3f0300, 0xff400100,
+};
+
+static const u32 sun4i_horz_coef[64] = {
+	0x40000000, 0x00000000, 0x40fe0000, 0x0000ff03,
+	0x3ffd0000, 0x0000ff05, 0x3ffc0000, 0x0000ff06,
+	0x3efb0000, 0x0000ff08, 0x3dfb0000, 0x0000ff09,
+	0x3bfa0000, 0x0000fe0d, 0x39fa0000, 0x0000fe0f,
+	0x38fa0000, 0x0000fe10, 0x36fa0000, 0x0000fe12,
+	0x33fa0000, 0x0000fd16, 0x31fa0000, 0x0000fd18,
+	0x2ffa0000, 0x0000fd1a, 0x2cfa0000, 0x0000fc1e,
+	0x29fa0000, 0x0000fc21, 0x27fb0000, 0x0000fb23,
+	0x24fb0000, 0x0000fb26, 0x21fb0000, 0x0000fb29,
+	0x1ffc0000, 0x0000fa2b, 0x1cfc0000, 0x0000fa2e,
+	0x19fd0000, 0x0000fa30, 0x16fd0000, 0x0000fa33,
+	0x14fd0000, 0x0000fa35, 0x11fe0000, 0x0000fa37,
+	0x0ffe0000, 0x0000fa39, 0x0dfe0000, 0x0000fa3b,
+	0x0afe0000, 0x0000fa3e, 0x08ff0000, 0x0000fb3e,
+	0x06ff0000, 0x0000fb40, 0x05ff0000, 0x0000fc40,
+	0x03ff0000, 0x0000fd41, 0x01ff0000, 0x0000fe42,
+};
+
+static void sunxi_frontend_init(void)
+{
+	struct sunxi_ccm_reg * const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	struct sunxi_de_fe_reg * const de_fe =
+		(struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE;
+	int i;
+
+	/* Clocks on */
+	setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE_FE0);
+	setbits_le32(&ccm->dram_clk_gate, 1 << CCM_DRAM_GATE_OFFSET_DE_FE0);
+	clock_set_de_mod_clock(&ccm->fe0_clk_cfg, 300000000);
+
+	setbits_le32(&de_fe->enable, SUNXI_DE_FE_ENABLE_EN);
+
+	for (i = 0; i < 32; i++) {
+		writel(sun4i_horz_coef[2 * i], &de_fe->ch0_horzcoef0[i]);
+		writel(sun4i_horz_coef[2 * i + 1], &de_fe->ch0_horzcoef1[i]);
+		writel(sun4i_vert_coef[i], &de_fe->ch0_vertcoef[i]);
+		writel(sun4i_horz_coef[2 * i], &de_fe->ch1_horzcoef0[i]);
+		writel(sun4i_horz_coef[2 * i + 1], &de_fe->ch1_horzcoef1[i]);
+		writel(sun4i_vert_coef[i], &de_fe->ch1_vertcoef[i]);
+	}
+
+	setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_COEF_RDY);
+}
+
+static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode,
+				    unsigned int address)
+{
+	struct sunxi_de_fe_reg * const de_fe =
+		(struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE;
+
+	setbits_le32(&de_fe->bypass, SUNXI_DE_FE_BYPASS_CSC_BYPASS);
+	writel(CONFIG_SYS_SDRAM_BASE + address, &de_fe->ch0_addr);
+	writel(mode->xres * 4, &de_fe->ch0_stride);
+	writel(SUNXI_DE_FE_INPUT_FMT_ARGB8888, &de_fe->input_fmt);
+	writel(SUNXI_DE_FE_OUTPUT_FMT_ARGB8888, &de_fe->output_fmt);
+
+	writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
+	       &de_fe->ch0_insize);
+	writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
+	       &de_fe->ch0_outsize);
+	writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch0_horzfact);
+	writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch0_vertfact);
+
+	writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
+	       &de_fe->ch1_insize);
+	writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
+	       &de_fe->ch1_outsize);
+	writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch1_horzfact);
+	writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch1_vertfact);
+
+	setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_REG_RDY);
+}
+
+static void sunxi_frontend_enable(void)
+{
+	struct sunxi_de_fe_reg * const de_fe =
+		(struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE;
+
+	setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_FRM_START);
+}
+#else
+static void sunxi_frontend_init(void) {}
+static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode,
+				    unsigned int address) {}
+static void sunxi_frontend_enable(void) {}
+#endif
+
 /*
  * This is the entity that mixes and matches the different layers and inputs.
  * Allwinner calls it the back-end, but i like composer better.
@@ -282,6 +400,8 @@ static void sunxi_composer_init(void)
 		(struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
 	int i;
 
+	sunxi_frontend_init();
+
 #if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
 	/* Reset off */
 	setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE_BE0);
@@ -289,7 +409,9 @@ static void sunxi_composer_init(void)
 
 	/* Clocks on */
 	setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE_BE0);
+#ifndef CONFIG_MACH_SUN4I /* On sun4i the frontend does the dma */
 	setbits_le32(&ccm->dram_clk_gate, 1 << CCM_DRAM_GATE_OFFSET_DE_BE0);
+#endif
 	clock_set_de_mod_clock(&ccm->be0_clk_cfg, 300000000);
 
 	/* Engine bug, clear registers after reset */
@@ -305,13 +427,19 @@ static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
 	struct sunxi_de_be_reg * const de_be =
 		(struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
 
+	sunxi_frontend_mode_set(mode, address);
+
 	writel(SUNXI_DE_BE_HEIGHT(mode->yres) | SUNXI_DE_BE_WIDTH(mode->xres),
 	       &de_be->disp_size);
 	writel(SUNXI_DE_BE_HEIGHT(mode->yres) | SUNXI_DE_BE_WIDTH(mode->xres),
 	       &de_be->layer0_size);
+#ifndef CONFIG_MACH_SUN4I /* On sun4i the frontend does the dma */
 	writel(SUNXI_DE_BE_LAYER_STRIDE(mode->xres), &de_be->layer0_stride);
 	writel(address << 3, &de_be->layer0_addr_low32b);
 	writel(address >> 29, &de_be->layer0_addr_high4b);
+#else
+	writel(SUNXI_DE_BE_LAYER_ATTR0_SRC_FE0, &de_be->layer0_attr0_ctrl);
+#endif
 	writel(SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888, &de_be->layer0_attr1_ctrl);
 
 	setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_LAYER0_ENABLE);
@@ -322,6 +450,8 @@ static void sunxi_composer_enable(void)
 	struct sunxi_de_be_reg * const de_be =
 		(struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
 
+	sunxi_frontend_enable();
+
 	setbits_le32(&de_be->reg_ctrl, SUNXI_DE_BE_REG_CTRL_LOAD_REGS);
 	setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_START);
 }
@@ -476,8 +606,7 @@ static void sunxi_lcdc_panel_enable(void)
 	pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
 	if (pin != -1) {
 		gpio_request(pin, "lcd_backlight_pwm");
-		/* backlight pwm is inverted, set to 1 to disable backlight */
-		gpio_direction_output(pin, 1);
+		gpio_direction_output(pin, PWM_OFF);
 	}
 
 	/* Give the backlight some time to turn off and power up the panel. */
@@ -504,10 +633,8 @@ static void sunxi_lcdc_backlight_enable(void)
 		gpio_direction_output(pin, 1);
 
 	pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
-	if (pin != -1) {
-		/* backlight pwm is inverted, set to 0 to enable backlight */
-		gpio_direction_output(pin, 0);
-	}
+	if (pin != -1)
+		gpio_direction_output(pin, PWM_ON);
 }
 
 static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode)
@@ -587,12 +714,7 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode)
 		       &lcdc->tcon0_frm_ctrl);
 	}
 
-#ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
-	val = SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE0;
-#endif
-#ifdef CONFIG_VIDEO_LCD_IF_LVDS
-	val = SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE60;
-#endif
+	val = SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(CONFIG_VIDEO_LCD_DCLK_PHASE);
 	if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
 		val |= SUNXI_LCDC_TCON_HSYNC_MASK;
 	if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
@@ -826,6 +948,40 @@ static void sunxi_vga_external_dac_enable(void)
 }
 #endif /* CONFIG_VIDEO_VGA_VIA_LCD */
 
+#ifdef CONFIG_VIDEO_LCD_SSD2828
+static int sunxi_ssd2828_init(const struct ctfb_res_modes *mode)
+{
+	struct ssd2828_config cfg = {
+		.csx_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_CS),
+		.sck_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_SCLK),
+		.sdi_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MOSI),
+		.sdo_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MISO),
+		.reset_pin = name_to_gpio(CONFIG_VIDEO_LCD_SSD2828_RESET),
+		.ssd2828_tx_clk_khz  = CONFIG_VIDEO_LCD_SSD2828_TX_CLK * 1000,
+		.ssd2828_color_depth = 24,
+#ifdef CONFIG_VIDEO_LCD_PANEL_MIPI_4_LANE_513_MBPS_VIA_SSD2828
+		.mipi_dsi_number_of_data_lanes           = 4,
+		.mipi_dsi_bitrate_per_data_lane_mbps     = 513,
+		.mipi_dsi_delay_after_exit_sleep_mode_ms = 100,
+		.mipi_dsi_delay_after_set_display_on_ms  = 200
+#else
+#error MIPI LCD panel needs configuration parameters
+#endif
+	};
+
+	if (cfg.csx_pin == -1 || cfg.sck_pin == -1 || cfg.sdi_pin == -1) {
+		printf("SSD2828: SPI pins are not properly configured\n");
+		return 1;
+	}
+	if (cfg.reset_pin == -1) {
+		printf("SSD2828: Reset pin is not properly configured\n");
+		return 1;
+	}
+
+	return ssd2828_init(&cfg, mode);
+}
+#endif /* CONFIG_VIDEO_LCD_SSD2828 */
+
 static void sunxi_engines_init(void)
 {
 	sunxi_composer_init();
@@ -854,10 +1010,17 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 		break;
 	case sunxi_monitor_lcd:
 		sunxi_lcdc_panel_enable();
+		if (IS_ENABLED(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM)) {
+			mdelay(50); /* Wait for lcd controller power on */
+			hitachi_tx18d42vm_init();
+		}
 		sunxi_composer_mode_set(mode, address);
 		sunxi_lcdc_tcon0_mode_set(mode);
 		sunxi_composer_enable();
 		sunxi_lcdc_enable();
+#ifdef CONFIG_VIDEO_LCD_SSD2828
+		sunxi_ssd2828_init(mode);
+#endif
 		sunxi_lcdc_backlight_enable();
 		break;
 	case sunxi_monitor_vga:
@@ -1027,21 +1190,27 @@ int sunxi_simplefb_setup(void *blob)
 	int offset, ret;
 	const char *pipeline = NULL;
 
+#ifdef CONFIG_MACH_SUN4I
+#define PIPELINE_PREFIX "de_fe0-"
+#else
+#define PIPELINE_PREFIX
+#endif
+
 	switch (sunxi_display.monitor) {
 	case sunxi_monitor_none:
 		return 0;
 	case sunxi_monitor_dvi:
 	case sunxi_monitor_hdmi:
-		pipeline = "de_be0-lcd0-hdmi";
+		pipeline = PIPELINE_PREFIX "de_be0-lcd0-hdmi";
 		break;
 	case sunxi_monitor_lcd:
-		pipeline = "de_be0-lcd0";
+		pipeline = PIPELINE_PREFIX "de_be0-lcd0";
 		break;
 	case sunxi_monitor_vga:
 #ifdef CONFIG_VIDEO_VGA
-		pipeline = "de_be0-lcd0-tve0";
+		pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0";
 #elif defined CONFIG_VIDEO_VGA_VIA_LCD
-		pipeline = "de_be0-lcd0";
+		pipeline = PIPELINE_PREFIX "de_be0-lcd0";
 #endif
 		break;
 	}
diff --git a/include/axp221.h b/include/axp221.h
index e6639f1ffe694b12b9dbf79f0a7f9b57102c2185..6f24a617b67263f5fd43b5c10629f022cb9e5a03 100644
--- a/include/axp221.h
+++ b/include/axp221.h
@@ -26,6 +26,9 @@
 #define AXP221_OUTPUT_CTRL1_ALDO1_EN	(1 << 6)
 #define AXP221_OUTPUT_CTRL1_ALDO2_EN	(1 << 7)
 #define AXP221_OUTPUT_CTRL2	0x12
+#define AXP221_OUTPUT_CTRL2_ELDO1_EN	(1 << 0)
+#define AXP221_OUTPUT_CTRL2_ELDO2_EN	(1 << 1)
+#define AXP221_OUTPUT_CTRL2_ELDO3_EN	(1 << 2)
 #define AXP221_OUTPUT_CTRL2_DLDO1_EN	(1 << 3)
 #define AXP221_OUTPUT_CTRL2_DLDO2_EN	(1 << 4)
 #define AXP221_OUTPUT_CTRL2_DLDO3_EN	(1 << 5)
@@ -37,6 +40,9 @@
 #define AXP221_DLDO2_CTRL	0x16
 #define AXP221_DLDO3_CTRL	0x17
 #define AXP221_DLDO4_CTRL	0x18
+#define AXP221_ELDO1_CTRL	0x19
+#define AXP221_ELDO2_CTRL	0x1a
+#define AXP221_ELDO3_CTRL	0x1b
 #define AXP221_DCDC1_CTRL	0x21
 #define AXP221_DCDC2_CTRL	0x22
 #define AXP221_DCDC3_CTRL	0x23
@@ -69,6 +75,7 @@ int axp221_set_dldo4(unsigned int mvolt);
 int axp221_set_aldo1(unsigned int mvolt);
 int axp221_set_aldo2(unsigned int mvolt);
 int axp221_set_aldo3(unsigned int mvolt);
+int axp221_set_eldo(int eldo_num, unsigned int mvolt);
 int axp221_init(void);
 int axp221_get_sid(unsigned int *sid);
 int axp_drivebus_enable(void);
diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h
index 7b857405e9e7839a27a7905b136a5677ec535b08..87d269b041c00f60d3085d842598c38a89e778b7 100644
--- a/include/configs/sun4i.h
+++ b/include/configs/sun4i.h
@@ -13,7 +13,6 @@
  */
 #define CONFIG_CLK_FULL_SPEED		1008000000
 
-#define CONFIG_SYS_PROMPT		"sun4i# "
 #define CONFIG_MACH_TYPE		4104
 
 #ifdef CONFIG_USB_EHCI
diff --git a/include/configs/sun5i.h b/include/configs/sun5i.h
index 09f7533575c83518c43c040ecf944a787aab4fba..52e3a6ff01b3d6ef94400e05ca63e0a9c2ab40d8 100644
--- a/include/configs/sun5i.h
+++ b/include/configs/sun5i.h
@@ -13,7 +13,6 @@
  */
 #define CONFIG_CLK_FULL_SPEED		1008000000
 
-#define CONFIG_SYS_PROMPT		"sun5i# "
 #define CONFIG_MACH_TYPE		4138
 
 #ifdef CONFIG_USB_EHCI
diff --git a/include/configs/sun6i.h b/include/configs/sun6i.h
index 1b738527990972e112a487e9e02ab3031625a6ae..f5e11ddb691f113c32943033592133e01653a72a 100644
--- a/include/configs/sun6i.h
+++ b/include/configs/sun6i.h
@@ -16,8 +16,6 @@
  */
 #define CONFIG_CLK_FULL_SPEED		1008000000
 
-#define CONFIG_SYS_PROMPT		"sun6i# "
-
 #ifdef CONFIG_USB_EHCI
 #define CONFIG_USB_EHCI_SUNXI
 #define CONFIG_USB_MAX_CONTROLLER_COUNT	2
diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h
index ccec50c328171d9fe4f11a1a1c3f67a287f52267..7cd78903412626622713cad62b4a663ec78250bf 100644
--- a/include/configs/sun7i.h
+++ b/include/configs/sun7i.h
@@ -14,7 +14,6 @@
  */
 #define CONFIG_CLK_FULL_SPEED		912000000
 
-#define CONFIG_SYS_PROMPT		"sun7i# "
 #define CONFIG_MACH_TYPE		4283
 
 #ifdef CONFIG_USB_EHCI
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h
index f16e60b576427574eff1e2f7f26595a0912a9e18..3bdedb390c119f6cc515e6342990fbfb258c77a9 100644
--- a/include/configs/sun8i.h
+++ b/include/configs/sun8i.h
@@ -14,8 +14,6 @@
  */
 #define CONFIG_CLK_FULL_SPEED	1008000000
 
-#define CONFIG_SYS_PROMPT	"sun8i# "
-
 #ifdef CONFIG_USB_EHCI
 #define CONFIG_USB_EHCI_SUNXI
 #define CONFIG_USB_MAX_CONTROLLER_COUNT	1
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index e839053e2ba995ca3388f251fdb6e0f8bf886a9f..4a5cab25d46daceb06b4190880a02b14951c7a1b 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -40,6 +40,8 @@
  */
 #define CONFIG_DISPLAY_CPUINFO
 
+#define CONFIG_SYS_PROMPT	"sunxi# "
+
 /* Serial & console */
 #define CONFIG_SYS_NS16550
 #define CONFIG_SYS_NS16550_SERIAL
@@ -247,8 +249,16 @@
 #endif
 
 #ifdef CONFIG_USB_EHCI
-#define CONFIG_CMD_USB
 #define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1
+#endif
+
+#ifdef CONFIG_USB_MUSB_SUNXI
+#define CONFIG_MUSB_HOST
+#define CONFIG_MUSB_PIO_ONLY
+#endif
+
+#if defined CONFIG_USB_EHCI || defined CONFIG_USB_MUSB_SUNXI
+#define CONFIG_CMD_USB
 #define CONFIG_USB_STORAGE
 #endif
 
diff --git a/include/mipi_display.h b/include/mipi_display.h
new file mode 100644
index 0000000000000000000000000000000000000000..ddcc8ca7316b51695bd827d9370d9027173e3576
--- /dev/null
+++ b/include/mipi_display.h
@@ -0,0 +1,130 @@
+/*
+ * Defines for Mobile Industry Processor Interface (MIPI(R))
+ * Display Working Group standards: DSI, DCS, DBI, DPI
+ *
+ * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ * Copyright (C) 2006 Nokia Corporation
+ * Author: Imre Deak <imre.deak@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef MIPI_DISPLAY_H
+#define MIPI_DISPLAY_H
+
+/* MIPI DSI Processor-to-Peripheral transaction types */
+enum {
+	MIPI_DSI_V_SYNC_START				= 0x01,
+	MIPI_DSI_V_SYNC_END				= 0x11,
+	MIPI_DSI_H_SYNC_START				= 0x21,
+	MIPI_DSI_H_SYNC_END				= 0x31,
+
+	MIPI_DSI_COLOR_MODE_OFF				= 0x02,
+	MIPI_DSI_COLOR_MODE_ON				= 0x12,
+	MIPI_DSI_SHUTDOWN_PERIPHERAL			= 0x22,
+	MIPI_DSI_TURN_ON_PERIPHERAL			= 0x32,
+
+	MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM		= 0x03,
+	MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM		= 0x13,
+	MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM		= 0x23,
+
+	MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM		= 0x04,
+	MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM		= 0x14,
+	MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM		= 0x24,
+
+	MIPI_DSI_DCS_SHORT_WRITE			= 0x05,
+	MIPI_DSI_DCS_SHORT_WRITE_PARAM			= 0x15,
+
+	MIPI_DSI_DCS_READ				= 0x06,
+
+	MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE		= 0x37,
+
+	MIPI_DSI_END_OF_TRANSMISSION			= 0x08,
+
+	MIPI_DSI_NULL_PACKET				= 0x09,
+	MIPI_DSI_BLANKING_PACKET			= 0x19,
+	MIPI_DSI_GENERIC_LONG_WRITE			= 0x29,
+	MIPI_DSI_DCS_LONG_WRITE				= 0x39,
+
+	MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20	= 0x0c,
+	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24		= 0x1c,
+	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16		= 0x2c,
+
+	MIPI_DSI_PACKED_PIXEL_STREAM_30			= 0x0d,
+	MIPI_DSI_PACKED_PIXEL_STREAM_36			= 0x1d,
+	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12		= 0x3d,
+
+	MIPI_DSI_PACKED_PIXEL_STREAM_16			= 0x0e,
+	MIPI_DSI_PACKED_PIXEL_STREAM_18			= 0x1e,
+	MIPI_DSI_PIXEL_STREAM_3BYTE_18			= 0x2e,
+	MIPI_DSI_PACKED_PIXEL_STREAM_24			= 0x3e,
+};
+
+/* MIPI DSI Peripheral-to-Processor transaction types */
+enum {
+	MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT	= 0x02,
+	MIPI_DSI_RX_END_OF_TRANSMISSION			= 0x08,
+	MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE	= 0x11,
+	MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE	= 0x12,
+	MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE		= 0x1a,
+	MIPI_DSI_RX_DCS_LONG_READ_RESPONSE		= 0x1c,
+	MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE	= 0x21,
+	MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE	= 0x22,
+};
+
+/* MIPI DCS commands */
+enum {
+	MIPI_DCS_NOP			= 0x00,
+	MIPI_DCS_SOFT_RESET		= 0x01,
+	MIPI_DCS_GET_DISPLAY_ID		= 0x04,
+	MIPI_DCS_GET_RED_CHANNEL	= 0x06,
+	MIPI_DCS_GET_GREEN_CHANNEL	= 0x07,
+	MIPI_DCS_GET_BLUE_CHANNEL	= 0x08,
+	MIPI_DCS_GET_DISPLAY_STATUS	= 0x09,
+	MIPI_DCS_GET_POWER_MODE		= 0x0A,
+	MIPI_DCS_GET_ADDRESS_MODE	= 0x0B,
+	MIPI_DCS_GET_PIXEL_FORMAT	= 0x0C,
+	MIPI_DCS_GET_DISPLAY_MODE	= 0x0D,
+	MIPI_DCS_GET_SIGNAL_MODE	= 0x0E,
+	MIPI_DCS_GET_DIAGNOSTIC_RESULT	= 0x0F,
+	MIPI_DCS_ENTER_SLEEP_MODE	= 0x10,
+	MIPI_DCS_EXIT_SLEEP_MODE	= 0x11,
+	MIPI_DCS_ENTER_PARTIAL_MODE	= 0x12,
+	MIPI_DCS_ENTER_NORMAL_MODE	= 0x13,
+	MIPI_DCS_EXIT_INVERT_MODE	= 0x20,
+	MIPI_DCS_ENTER_INVERT_MODE	= 0x21,
+	MIPI_DCS_SET_GAMMA_CURVE	= 0x26,
+	MIPI_DCS_SET_DISPLAY_OFF	= 0x28,
+	MIPI_DCS_SET_DISPLAY_ON		= 0x29,
+	MIPI_DCS_SET_COLUMN_ADDRESS	= 0x2A,
+	MIPI_DCS_SET_PAGE_ADDRESS	= 0x2B,
+	MIPI_DCS_WRITE_MEMORY_START	= 0x2C,
+	MIPI_DCS_WRITE_LUT		= 0x2D,
+	MIPI_DCS_READ_MEMORY_START	= 0x2E,
+	MIPI_DCS_SET_PARTIAL_AREA	= 0x30,
+	MIPI_DCS_SET_SCROLL_AREA	= 0x33,
+	MIPI_DCS_SET_TEAR_OFF		= 0x34,
+	MIPI_DCS_SET_TEAR_ON		= 0x35,
+	MIPI_DCS_SET_ADDRESS_MODE	= 0x36,
+	MIPI_DCS_SET_SCROLL_START	= 0x37,
+	MIPI_DCS_EXIT_IDLE_MODE		= 0x38,
+	MIPI_DCS_ENTER_IDLE_MODE	= 0x39,
+	MIPI_DCS_SET_PIXEL_FORMAT	= 0x3A,
+	MIPI_DCS_WRITE_MEMORY_CONTINUE	= 0x3C,
+	MIPI_DCS_READ_MEMORY_CONTINUE	= 0x3E,
+	MIPI_DCS_SET_TEAR_SCANLINE	= 0x44,
+	MIPI_DCS_GET_SCANLINE		= 0x45,
+	MIPI_DCS_READ_DDB_START		= 0xA1,
+	MIPI_DCS_READ_DDB_CONTINUE	= 0xA8,
+};
+
+/* MIPI DCS pixel formats */
+#define MIPI_DCS_PIXEL_FMT_24BIT	7
+#define MIPI_DCS_PIXEL_FMT_18BIT	6
+#define MIPI_DCS_PIXEL_FMT_16BIT	5
+#define MIPI_DCS_PIXEL_FMT_12BIT	3
+#define MIPI_DCS_PIXEL_FMT_8BIT		2
+#define MIPI_DCS_PIXEL_FMT_3BIT		1
+
+#endif