diff --git a/arch/arm/cpu/armv7/sunxi/usb_phy.c b/arch/arm/cpu/armv7/sunxi/usb_phy.c
index 4d63a7449d7ced3becdd4348054047cdb5e6a9cf..b7ca5d423a9fb014de2caf6e45b4dc1839d34b0d 100644
--- a/arch/arm/cpu/armv7/sunxi/usb_phy.c
+++ b/arch/arm/cpu/armv7/sunxi/usb_phy.c
@@ -232,6 +232,13 @@ void sunxi_usb_phy_power_off(int index)
 		gpio_set_value(phy->gpio_vbus, 0);
 }
 
+int sunxi_usb_phy_power_is_on(int index)
+{
+	struct sunxi_usb_phy *phy = &sunxi_usb_phy[index];
+
+	return phy->power_on_count > 0;
+}
+
 int sunxi_usb_phy_vbus_detect(int index)
 {
 	struct sunxi_usb_phy *phy = &sunxi_usb_phy[index];
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
index 58aff1687af357eca4439d1c55243def8cc8dc56..a7e25f46c825b70026c431afaf481f2ca5c30c8d 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
@@ -267,6 +267,8 @@ struct sunxi_ccm_reg {
 #define CCM_MBUS_CTRL_CLK_SRC_PLL5 0x2
 #define CCM_MBUS_CTRL_GATE (0x1 << 31)
 
+#define CCM_NAND_CTRL_ENABLE		(0x1 << 31)
+
 #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)
@@ -289,7 +291,7 @@ struct sunxi_ccm_reg {
 #define CCM_LCD_CH0_CTRL_GATE		(0x1 << 31)
 
 #define CCM_LCD_CH1_CTRL_M(n)		((((n) - 1) & 0xf) << 0)
-/* We leave bit 11 set to 0, so sclk1 == sclk2 */
+#define CCM_LCD_CH1_CTRL_HALF_SCLK1	(1 << 11)
 #define CCM_LCD_CH1_CTRL_PLL3		(0 << 24)
 #define CCM_LCD_CH1_CTRL_PLL7		(1 << 24)
 #define CCM_LCD_CH1_CTRL_PLL3_2X	(2 << 24)
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
index 8a26b9fc51ab280f2e2870aa9419d8b070755a1f..06c6febba597129196760b949e5fac637d43b205 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
@@ -290,6 +290,7 @@ struct sunxi_ccm_reg {
 #define CCM_LCD_CH0_CTRL_GATE		(0x1 << 31)
 
 #define CCM_LCD_CH1_CTRL_M(n)		((((n) - 1) & 0xf) << 0)
+#define CCM_LCD_CH1_CTRL_HALF_SCLK1	0 /* no seperate sclk1 & 2 on sun6i */
 #define CCM_LCD_CH1_CTRL_PLL3		(0 << 24)
 #define CCM_LCD_CH1_CTRL_PLL7		(1 << 24)
 #define CCM_LCD_CH1_CTRL_PLL3_2X	(2 << 24)
diff --git a/arch/arm/include/asm/arch-sunxi/display.h b/arch/arm/include/asm/arch-sunxi/display.h
index ae954171f3bd2ab7f59ab8e7ecdcc7a5741d6246..2cc3916a01e21a2716f8d16a839a77dea58c8eed 100644
--- a/arch/arm/include/asm/arch-sunxi/display.h
+++ b/arch/arm/include/asm/arch-sunxi/display.h
@@ -151,6 +151,10 @@ struct sunxi_de_be_reg {
 	u32 layer1_attr1_ctrl;		/* 0x8a4 */
 	u32 layer2_attr1_ctrl;		/* 0x8a8 */
 	u32 layer3_attr1_ctrl;		/* 0x8ac */
+	u8 res5[0x110];			/* 0x8b0 */
+	u32 output_color_ctrl;		/* 0x9c0 */
+	u8 res6[0xc];			/* 0x9c4 */
+	u32 output_color_coef[12];	/* 0x9d0 */
 };
 
 struct sunxi_lcdc_reg {
@@ -298,7 +302,7 @@ struct sunxi_tve_reg {
 	u32 cbr_level;			/* 0x10c */
 	u32 burst_phase;		/* 0x110 */
 	u32 burst_width;		/* 0x114 */
-	u8 res2[0x04];			/* 0x118 */
+	u32 unknown2;			/* 0x118 */
 	u32 sync_vbi_level;		/* 0x11c */
 	u32 white_level;		/* 0x120 */
 	u32 active_num;			/* 0x124 */
@@ -331,11 +335,14 @@ struct sunxi_tve_reg {
 #define SUNXI_DE_BE_HEIGHT(y)			(((y) - 1) << 16)
 #define SUNXI_DE_BE_MODE_ENABLE			(1 << 0)
 #define SUNXI_DE_BE_MODE_START			(1 << 1)
+#define SUNXI_DE_BE_MODE_DEFLICKER_ENABLE	(1 << 4)
 #define SUNXI_DE_BE_MODE_LAYER0_ENABLE		(1 << 8)
+#define SUNXI_DE_BE_MODE_INTERLACE_ENABLE	(1 << 28)
 #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)
+#define SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE	1
 
 /*
  * LCDC register constants.
@@ -372,11 +379,12 @@ struct sunxi_tve_reg {
 #define SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE	(1 << 31)
 #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_INTERLACE_ENABLE	(1 << 20)
 #define SUNXI_LCDC_TCON1_CTRL_ENABLE		(1 << 31)
 #define SUNXI_LCDC_TCON1_TIMING_H_BP(n)		(((n) - 1) << 0)
 #define SUNXI_LCDC_TCON1_TIMING_H_TOTAL(n)	(((n) - 1) << 16)
 #define SUNXI_LCDC_TCON1_TIMING_V_BP(n)		(((n) - 1) << 0)
-#define SUNXI_LCDC_TCON1_TIMING_V_TOTAL(n)	(((n) * 2) << 16)
+#define SUNXI_LCDC_TCON1_TIMING_V_TOTAL(n)	((n) << 16)
 #ifdef CONFIG_SUNXI_GEN_SUN6I
 #define SUNXI_LCDC_LVDS_ANA0			0x40040320
 #define SUNXI_LCDC_LVDS_ANA0_EN_MB		(1 << 31)
@@ -494,9 +502,22 @@ struct sunxi_tve_reg {
  */
 #define SUNXI_TVE_GCTRL_DAC_INPUT_MASK(dac)	(0xf << (((dac) + 1) * 4))
 #define SUNXI_TVE_GCTRL_DAC_INPUT(dac, sel)	((sel) << (((dac) + 1) * 4))
-#define SUNXI_TVE_GCTRL_CFG0_VGA		0x20000000
-#define SUNXI_TVE_GCTRL_DAC_CFG0_VGA		0x403e1ac7
-#define SUNXI_TVE_GCTRL_UNKNOWN1_VGA		0x00000000
+#define SUNXI_TVE_CFG0_VGA			0x20000000
+#define SUNXI_TVE_CFG0_PAL			0x07030001
+#define SUNXI_TVE_CFG0_NTSC			0x07030000
+#define SUNXI_TVE_DAC_CFG0_VGA			0x403e1ac7
+#define SUNXI_TVE_DAC_CFG0_COMPOSITE		0x403f0008
+#define SUNXI_TVE_FILTER_COMPOSITE		0x00000120
+#define SUNXI_TVE_CHROMA_FREQ_PAL_M		0x21e6efe3
+#define SUNXI_TVE_CHROMA_FREQ_PAL_NC		0x21f69446
+#define SUNXI_TVE_PORCH_NUM_PAL			0x008a0018
+#define SUNXI_TVE_PORCH_NUM_NTSC		0x00760020
+#define SUNXI_TVE_LINE_NUM_PAL			0x00160271
+#define SUNXI_TVE_LINE_NUM_NTSC			0x0016020d
+#define SUNXI_TVE_BLANK_BLACK_LEVEL_PAL		0x00fc00fc
+#define SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC	0x00f0011a
+#define SUNXI_TVE_UNKNOWN1_VGA			0x00000000
+#define SUNXI_TVE_UNKNOWN1_COMPOSITE		0x18181818
 #define SUNXI_TVE_AUTO_DETECT_EN_DET_EN(dac)	(1 << ((dac) + 0))
 #define SUNXI_TVE_AUTO_DETECT_EN_INT_EN(dac)	(1 << ((dac) + 16))
 #define SUNXI_TVE_AUTO_DETECT_INT_STATUS(dac)	(1 << ((dac) + 0))
@@ -512,6 +533,20 @@ struct sunxi_tve_reg {
 #define SUNXI_TVE_CSC_REG1			0x3b6dace1
 #define SUNXI_TVE_CSC_REG2			0x0e1d13dc
 #define SUNXI_TVE_CSC_REG3			0x00108080
+#define SUNXI_TVE_COLOR_BURST_PAL_M		0x00000000
+#define SUNXI_TVE_CBR_LEVEL_PAL			0x00002828
+#define SUNXI_TVE_CBR_LEVEL_NTSC		0x0000004f
+#define SUNXI_TVE_BURST_PHASE_NTSC		0x00000000
+#define SUNXI_TVE_BURST_WIDTH_COMPOSITE		0x0016447e
+#define SUNXI_TVE_UNKNOWN2_PAL			0x0000e0e0
+#define SUNXI_TVE_UNKNOWN2_NTSC			0x0000a0a0
+#define SUNXI_TVE_SYNC_VBI_LEVEL_NTSC		0x001000f0
+#define SUNXI_TVE_ACTIVE_NUM_COMPOSITE		0x000005a0
+#define SUNXI_TVE_CHROMA_BW_GAIN_COMP		0x00000002
+#define SUNXI_TVE_NOTCH_WIDTH_COMPOSITE		0x00000101
+#define SUNXI_TVE_RESYNC_NUM_PAL		0x800d000c
+#define SUNXI_TVE_RESYNC_NUM_NTSC		0x000e000c
+#define SUNXI_TVE_SLAVE_PARA_COMPOSITE		0x00000000
 
 int sunxi_simplefb_setup(void *blob);
 
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index 8e67b3bcb87d0fe411fb95588fe85e1fbcd22f27..8382101558c8ddaffabdff1e0d602d6e5eaba00d 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -158,6 +158,7 @@ enum sunxi_gpio_number {
 #define SUN8I_GPB_UART2		2
 #define SUN8I_A33_GPB_UART0	3
 
+#define SUNXI_GPC_NAND		2
 #define SUNXI_GPC_SDC2		3
 #define SUN6I_GPC_SDC3		4
 
diff --git a/arch/arm/include/asm/arch-sunxi/usb_phy.h b/arch/arm/include/asm/arch-sunxi/usb_phy.h
index cef6c985bc8d46c74dd11cdaac712e1b45f7975f..6a14cad3ff393d4b9c0acf466e17683e82a13822 100644
--- a/arch/arm/include/asm/arch-sunxi/usb_phy.h
+++ b/arch/arm/include/asm/arch-sunxi/usb_phy.h
@@ -16,6 +16,7 @@ void sunxi_usb_phy_init(int index);
 void sunxi_usb_phy_exit(int index);
 void sunxi_usb_phy_power_on(int index);
 void sunxi_usb_phy_power_off(int index);
+int sunxi_usb_phy_power_is_on(int index);
 int sunxi_usb_phy_vbus_detect(int index);
 int sunxi_usb_phy_id_detect(int index);
 void sunxi_usb_phy_enable_squelch_detect(int index, int enable);
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index c4b5a855a5efdfc71d2874cdd9886a33cb57eefd..13f453733f1ee637c204260687adee8c90771355 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -410,6 +410,13 @@ config VIDEO_VGA_EXTERNAL_DAC_EN
 	Set the enable pin for the external VGA DAC. This takes a string in the
 	format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
 
+config VIDEO_COMPOSITE
+	boolean "Composite video output support"
+	depends on VIDEO && (MACH_SUN4I || MACH_SUN5I || MACH_SUN7I)
+	default n
+	---help---
+	Say Y here to add support for outputting composite video.
+
 config VIDEO_LCD_MODE
 	string "LCD panel timing details"
 	depends on VIDEO
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index afed6a31cab6732f334d8dba2272730ee8306ac4..f85e825891bc0dbf8009d8f77c37281917f699a9 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -107,6 +107,28 @@ int dram_init(void)
 	return 0;
 }
 
+#if defined(CONFIG_SPL_NAND_SUNXI) && defined(CONFIG_SPL_BUILD)
+static void nand_pinmux_setup(void)
+{
+	unsigned int pin;
+	for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(6); pin++)
+		sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
+
+	for (pin = SUNXI_GPC(8); pin <= SUNXI_GPC(22); pin++)
+		sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
+
+	sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_NAND);
+}
+
+static void nand_clock_setup(void)
+{
+	struct sunxi_ccm_reg *const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	setbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0));
+	setbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1);
+}
+#endif
+
 #ifdef CONFIG_GENERIC_MMC
 static void mmc_pinmux_setup(int sdc)
 {
@@ -431,6 +453,11 @@ void sunxi_board_init(void)
 	power_failed |= axp221_set_eldo(3, CONFIG_AXP221_ELDO3_VOLT);
 #endif
 
+#ifdef CONFIG_SPL_NAND_SUNXI
+	nand_pinmux_setup();
+	nand_clock_setup();
+#endif
+
 	printf("DRAM:");
 	ramsize = sunxi_dram_init();
 	printf(" %lu MiB\n", ramsize >> 20);
diff --git a/configs/Chuwi_V7_CW0825_defconfig b/configs/Chuwi_V7_CW0825_defconfig
index 401135159515427bff3f38c32ccd70bfda166cec..f44aede2896dcb9be77c93015da6116fb96154aa 100644
--- a/configs/Chuwi_V7_CW0825_defconfig
+++ b/configs/Chuwi_V7_CW0825_defconfig
@@ -5,6 +5,7 @@ CONFIG_DRAM_CLK=408
 CONFIG_DRAM_EMR1=4
 CONFIG_USB0_VBUS_PIN="PB9"
 CONFIG_USB0_VBUS_DET="PH5"
+CONFIG_USB0_ID_DET="PH4"
 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"
diff --git a/configs/Mele_M3_defconfig b/configs/Mele_M3_defconfig
index d49826982f750bf9ed4360a1885f47a6d38c5de1..5c9796a77bc246992a405981a93a506fbede6ae9 100644
--- a/configs/Mele_M3_defconfig
+++ b/configs/Mele_M3_defconfig
@@ -5,6 +5,7 @@ CONFIG_DRAM_CLK=384
 CONFIG_MMC0_CD_PIN="PH1"
 CONFIG_MMC_SUNXI_SLOT_EXTRA=2
 CONFIG_VIDEO_VGA=y
+CONFIG_VIDEO_COMPOSITE=y
 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-m3"
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL=y
diff --git a/configs/UTOO_P66_defconfig b/configs/UTOO_P66_defconfig
index 0266299f719ec2d3fde73cee8f04687085bb9f52..169c2e87c92ae56d1909755f1ea2ba0468c47c33 100644
--- a/configs/UTOO_P66_defconfig
+++ b/configs/UTOO_P66_defconfig
@@ -7,6 +7,7 @@ CONFIG_MMC0_CD_PIN="PG0"
 CONFIG_MMC_SUNXI_SLOT_EXTRA=2
 CONFIG_USB0_VBUS_PIN="PB04"
 CONFIG_USB0_VBUS_DET="PG01"
+CONFIG_USB0_ID_DET="PG2"
 CONFIG_AXP_GPIO=y
 CONFIG_VIDEO_LCD_MODE="x:480,y:800,depth:18,pclk_khz:25000,le:2,ri:93,up:2,lo:93,hs:1,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_DCLK_PHASE=0
diff --git a/configs/Wexler_TAB7200_defconfig b/configs/Wexler_TAB7200_defconfig
index eadceb2757d70f4e40b4ef9a44527e0398caefe2..02504f9ea233857b72c1df9a68e9c1038cec980f 100644
--- a/configs/Wexler_TAB7200_defconfig
+++ b/configs/Wexler_TAB7200_defconfig
@@ -2,10 +2,15 @@ CONFIG_ARM=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN7I=y
 CONFIG_DRAM_CLK=384
+CONFIG_USB0_VBUS_PIN="PB9"
+CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_USB0_ID_DET="PH4"
+CONFIG_AXP_GPIO=y
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:24,pclk_khz:33000,le:45,ri:210,up:22,lo:22,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_USB_MUSB_HOST=y
 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-wexler-tab7200"
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL=y
diff --git a/configs/jesurun_q5_defconfig b/configs/jesurun_q5_defconfig
index a2115b6d390fbb4f39269f3383e0edaf0b698e16..b0d8621c659d36e05b5da744fcddb3db3e9667c1 100644
--- a/configs/jesurun_q5_defconfig
+++ b/configs/jesurun_q5_defconfig
@@ -10,3 +10,5 @@ CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,MACPWR=SUNXI_GPH(19)"
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_FPGA is not set
 CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_MUSB_HOST=y
+CONFIG_USB0_VBUS_PIN="PB9"
diff --git a/doc/README.video b/doc/README.video
index d0a3ad6e8d455f52843778a93aa7a760f66c1b65..4f7a4b5db54b4ade757d09f252ca272cfe4ffb24 100644
--- a/doc/README.video
+++ b/doc/README.video
@@ -40,12 +40,15 @@ requires the CONFIG_VIDEO_LCD_MODE Kconfig value to be set.
 
 The sunxi u-boot driver supports the following video-mode options:
 
-- monitor=[none|dvi|hdmi|lcd] - Select the video output to use
+- monitor=[none|dvi|hdmi|lcd|vga|composite-*] - Select the video output to use
  none:     Disable video output.
  dvi/hdmi: Selects output over the hdmi connector with dvi resp. hdmi output
            format, if edid is used the format is automatically selected.
  lcd:      Selects video output to a LCD screen.
- vga:      Selects bideo output over the VGA connector.
+ vga:      Selects video output over the VGA connector.
+ composite-pal/composite-ntsc/composite-pal-m/composite-pal-nc:
+           Selects composite video output, note the specified resolution is
+           ignored with composite video output.
  Defaults to monitor=dvi.
 
 - hpd=[0|1] - Enable use of the hdmi HotPlug Detect feature
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 3024357de713de0b23fecb731b3b529caa6ec33d..41ebfea3ced1b8f0fec90837862874073c368bbc 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -85,6 +85,46 @@ config SPL_NAND_DENALI
 	  This is a small implementation of the Denali NAND controller
 	  for use on SPL.
 
+config SPL_NAND_SUNXI
+	bool "Support for NAND on Allwinner A20 in SPL"
+	depends on MACH_SUN7I
+	---help---
+	Enable support for NAND. This option allows SPL to read from
+	sunxi NAND using DMA transfers.
+	Depending on the NAND chip, values like ECC strength and page sizes
+	have to be configured.
+
+config NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END
+	hex "Size of syndrome partitions in sunxi NAND"
+	default 0x400000
+	depends on SPL_NAND_SUNXI
+	---help---
+	End address for boot partitions on NAND. Those partitions have a
+	different random seed that has to match the sunxi BROM setting.
+
+config NAND_SUNXI_SPL_ECC_STRENGTH
+	int "ECC Strength for sunxi NAND"
+	default 40
+	depends on SPL_NAND_SUNXI
+	---help---
+	ECC strength used by the sunxi NAND SPL driver. This is specific to the
+	chosen NAND chip and has to match the value used by the sunxi BROM.
+
+config NAND_SUNXI_SPL_ECC_PAGE_SIZE
+	hex "ECC page size for sunxi NAND"
+	default 0x400
+	depends on SPL_NAND_SUNXI
+	---help---
+	ECC page size used by the sunxi NAND SPL driver for syndrome partitions.
+	This setting has to match the value used by the sunxi BROM.
+
+config NAND_SUNXI_SPL_PAGE_SIZE
+	hex "Page size for sunxi NAND"
+	default 0x2000
+	depends on SPL_NAND_SUNXI
+	---help---
+	Page size of the NAND flash used by the sunxi NAND SPL driver. This is
+	specific to the chosen NAND chip.
 endif
 
 endmenu
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 347ea62e0b3d3fa5a33eb8097d01ce40d642be49..b40dda890e8fd0a9586a5213eec822815846f7c6 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -12,6 +12,7 @@ NORMAL_DRIVERS=y
 endif
 
 obj-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
+obj-$(CONFIG_SPL_NAND_SUNXI) += sunxi_nand_spl.o
 obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o
 obj-$(CONFIG_SPL_NAND_DOCG4) += docg4_spl.o
 obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c
new file mode 100644
index 0000000000000000000000000000000000000000..ac5f56d066fef5245050b4604f84e5155a064732
--- /dev/null
+++ b/drivers/mtd/nand/sunxi_nand_spl.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2014-2015, Antmicro Ltd <www.antmicro.com>
+ * Copyright (c) 2015, AW-SOM Technologies <www.aw-som.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <config.h>
+#include <asm/io.h>
+#include <nand.h>
+
+/* registers */
+#define NFC_CTL                    0x00000000
+#define NFC_ST                     0x00000004
+#define NFC_INT                    0x00000008
+#define NFC_TIMING_CTL             0x0000000C
+#define NFC_TIMING_CFG             0x00000010
+#define NFC_ADDR_LOW               0x00000014
+#define NFC_ADDR_HIGH              0x00000018
+#define NFC_SECTOR_NUM             0x0000001C
+#define NFC_CNT                    0x00000020
+#define NFC_CMD                    0x00000024
+#define NFC_RCMD_SET               0x00000028
+#define NFC_WCMD_SET               0x0000002C
+#define NFC_IO_DATA                0x00000030
+#define NFC_ECC_CTL                0x00000034
+#define NFC_ECC_ST                 0x00000038
+#define NFC_DEBUG                  0x0000003C
+#define NFC_ECC_CNT0               0x00000040
+#define NFC_ECC_CNT1               0x00000044
+#define NFC_ECC_CNT2               0x00000048
+#define NFC_ECC_CNT3               0x0000004C
+#define NFC_USER_DATA_BASE         0x00000050
+#define NFC_EFNAND_STATUS          0x00000090
+#define NFC_SPARE_AREA             0x000000A0
+#define NFC_PATTERN_ID             0x000000A4
+#define NFC_RAM0_BASE              0x00000400
+#define NFC_RAM1_BASE              0x00000800
+
+#define NFC_CTL_EN                 (1 << 0)
+#define NFC_CTL_RESET              (1 << 1)
+#define NFC_CTL_RAM_METHOD         (1 << 14)
+
+
+#define NFC_ECC_EN                 (1 << 0)
+#define NFC_ECC_PIPELINE           (1 << 3)
+#define NFC_ECC_EXCEPTION          (1 << 4)
+#define NFC_ECC_BLOCK_SIZE         (1 << 5)
+#define NFC_ECC_RANDOM_EN          (1 << 9)
+#define NFC_ECC_RANDOM_DIRECTION   (1 << 10)
+
+
+#define NFC_ADDR_NUM_OFFSET        16
+#define NFC_SEND_ADR               (1 << 19)
+#define NFC_ACCESS_DIR             (1 << 20)
+#define NFC_DATA_TRANS             (1 << 21)
+#define NFC_SEND_CMD1              (1 << 22)
+#define NFC_WAIT_FLAG              (1 << 23)
+#define NFC_SEND_CMD2              (1 << 24)
+#define NFC_SEQ                    (1 << 25)
+#define NFC_DATA_SWAP_METHOD       (1 << 26)
+#define NFC_ROW_AUTO_INC           (1 << 27)
+#define NFC_SEND_CMD3              (1 << 28)
+#define NFC_SEND_CMD4              (1 << 29)
+
+#define NFC_CMD_INT_FLAG           (1 << 1)
+
+#define NFC_READ_CMD_OFFSET         0
+#define NFC_RANDOM_READ_CMD0_OFFSET 8
+#define NFC_RANDOM_READ_CMD1_OFFSET 16
+
+#define NFC_CMD_RNDOUTSTART        0xE0
+#define NFC_CMD_RNDOUT             0x05
+#define NFC_CMD_READSTART          0x30
+
+
+#define NFC_PAGE_CMD               (2 << 30)
+
+#define SUNXI_DMA_CFG_REG0              0x300
+#define SUNXI_DMA_SRC_START_ADDR_REG0   0x304
+#define SUNXI_DMA_DEST_START_ADDRR_REG0 0x308
+#define SUNXI_DMA_DDMA_BC_REG0          0x30C
+#define SUNXI_DMA_DDMA_PARA_REG0        0x318
+
+#define SUNXI_DMA_DDMA_CFG_REG_LOADING  (1 << 31)
+#define SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 (2 << 25)
+#define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 (2 << 9)
+#define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO (1 << 5)
+#define SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC (3 << 0)
+
+#define SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC (0x0F << 0)
+#define SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE (0x7F << 8)
+
+/* minimal "boot0" style NAND support for Allwinner A20 */
+
+/* temporary buffer in internal ram */
+unsigned char temp_buf[CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE]
+	__aligned(0x10) __section(".text#");
+
+/* random seed used by linux */
+const uint16_t random_seed[128] = {
+	0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
+	0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
+	0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
+	0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
+	0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
+	0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
+	0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
+	0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
+	0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
+	0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
+	0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
+	0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
+	0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
+	0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
+	0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
+	0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
+};
+
+/* random seed used for syndrome calls */
+const uint16_t random_seed_syndrome = 0x4a80;
+
+#define MAX_RETRIES 10
+
+static int check_value_inner(int offset, int expected_bits,
+				int max_number_of_retries, int negation)
+{
+	int retries = 0;
+	do {
+		int val = readl(offset) & expected_bits;
+		if (negation ? !val : val)
+			return 1;
+		mdelay(1);
+		retries++;
+	} while (retries < max_number_of_retries);
+
+	return 0;
+}
+
+static inline int check_value(int offset, int expected_bits,
+				int max_number_of_retries)
+{
+	return check_value_inner(offset, expected_bits,
+					max_number_of_retries, 0);
+}
+
+static inline int check_value_negated(int offset, int unexpected_bits,
+					int max_number_of_retries)
+{
+	return check_value_inner(offset, unexpected_bits,
+					max_number_of_retries, 1);
+}
+
+void nand_init(void)
+{
+	uint32_t val;
+
+	val = readl(SUNXI_NFC_BASE + NFC_CTL);
+	/* enable and reset CTL */
+	writel(val | NFC_CTL_EN | NFC_CTL_RESET,
+	       SUNXI_NFC_BASE + NFC_CTL);
+
+	if (!check_value_negated(SUNXI_NFC_BASE + NFC_CTL,
+				 NFC_CTL_RESET, MAX_RETRIES)) {
+		printf("Couldn't initialize nand\n");
+	}
+}
+
+static void nand_read_page(unsigned int real_addr, int syndrome,
+			   uint32_t *ecc_errors)
+{
+	uint32_t val;
+	int ecc_off = 0;
+	uint16_t ecc_mode = 0;
+	uint16_t rand_seed;
+	uint32_t page;
+	uint16_t column;
+	uint32_t oob_offset;
+
+	switch (CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH) {
+	case 16:
+		ecc_mode = 0;
+		ecc_off = 0x20;
+		break;
+	case 24:
+		ecc_mode = 1;
+		ecc_off = 0x2e;
+		break;
+	case 28:
+		ecc_mode = 2;
+		ecc_off = 0x32;
+		break;
+	case 32:
+		ecc_mode = 3;
+		ecc_off = 0x3c;
+		break;
+	case 40:
+		ecc_mode = 4;
+		ecc_off = 0x4a;
+		break;
+	case 48:
+		ecc_mode = 4;
+		ecc_off = 0x52;
+		break;
+	case 56:
+		ecc_mode = 4;
+		ecc_off = 0x60;
+		break;
+	case 60:
+		ecc_mode = 4;
+		ecc_off = 0x0;
+		break;
+	case 64:
+		ecc_mode = 4;
+		ecc_off = 0x0;
+		break;
+	default:
+		ecc_mode = 0;
+		ecc_off = 0;
+	}
+
+	if (ecc_off == 0) {
+		printf("Unsupported ECC strength (%d)!\n",
+		       CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH);
+		return;
+	}
+
+	/* clear temp_buf */
+	memset(temp_buf, 0, CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE);
+
+	/* set CMD  */
+	writel(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET,
+	       SUNXI_NFC_BASE + NFC_CMD);
+
+	if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_CMD_INT_FLAG,
+			 MAX_RETRIES)) {
+		printf("Error while initilizing command interrupt\n");
+		return;
+	}
+
+	page = real_addr / CONFIG_NAND_SUNXI_SPL_PAGE_SIZE;
+	column = real_addr % CONFIG_NAND_SUNXI_SPL_PAGE_SIZE;
+
+	if (syndrome)
+		column += (column / CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE)
+			* ecc_off;
+
+	/* clear ecc status */
+	writel(0, SUNXI_NFC_BASE + NFC_ECC_ST);
+
+	/* Choose correct seed */
+	if (syndrome)
+		rand_seed = random_seed_syndrome;
+	else
+		rand_seed = random_seed[page % 128];
+
+	writel((rand_seed << 16) | NFC_ECC_RANDOM_EN | NFC_ECC_EN
+		| NFC_ECC_PIPELINE | (ecc_mode << 12),
+		SUNXI_NFC_BASE + NFC_ECC_CTL);
+
+	val = readl(SUNXI_NFC_BASE + NFC_CTL);
+	writel(val | NFC_CTL_RAM_METHOD, SUNXI_NFC_BASE + NFC_CTL);
+
+	if (syndrome) {
+		writel(CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE,
+		       SUNXI_NFC_BASE + NFC_SPARE_AREA);
+	} else {
+		oob_offset = CONFIG_NAND_SUNXI_SPL_PAGE_SIZE
+			+ (column / CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE)
+			* ecc_off;
+		writel(oob_offset, SUNXI_NFC_BASE + NFC_SPARE_AREA);
+	}
+
+	/* SUNXI_DMA */
+	writel(0x0, SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0); /* clr dma cmd */
+	/* read from REG_IO_DATA */
+	writel(SUNXI_NFC_BASE + NFC_IO_DATA,
+	       SUNXI_DMA_BASE + SUNXI_DMA_SRC_START_ADDR_REG0);
+	/* read to RAM */
+	writel((uint32_t)temp_buf,
+	       SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0);
+	writel(SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC
+			| SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE,
+			SUNXI_DMA_BASE + SUNXI_DMA_DDMA_PARA_REG0);
+	writel(CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE,
+	       SUNXI_DMA_BASE + SUNXI_DMA_DDMA_BC_REG0); /* 1kB */
+	writel(SUNXI_DMA_DDMA_CFG_REG_LOADING
+		| SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32
+		| SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32
+		| SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO
+		| SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC,
+		SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0);
+
+	writel((NFC_CMD_RNDOUTSTART << NFC_RANDOM_READ_CMD1_OFFSET)
+		| (NFC_CMD_RNDOUT << NFC_RANDOM_READ_CMD0_OFFSET)
+		| (NFC_CMD_READSTART | NFC_READ_CMD_OFFSET), SUNXI_NFC_BASE
+			+ NFC_RCMD_SET);
+	writel(1, SUNXI_NFC_BASE + NFC_SECTOR_NUM);
+	writel(((page & 0xFFFF) << 16) | column,
+	       SUNXI_NFC_BASE + NFC_ADDR_LOW);
+	writel((page >> 16) & 0xFF, SUNXI_NFC_BASE + NFC_ADDR_HIGH);
+	writel(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_DATA_TRANS |
+		NFC_PAGE_CMD | NFC_WAIT_FLAG | (4 << NFC_ADDR_NUM_OFFSET) |
+		NFC_SEND_ADR | NFC_DATA_SWAP_METHOD | (syndrome ? NFC_SEQ : 0),
+		SUNXI_NFC_BASE + NFC_CMD);
+
+	if (!check_value(SUNXI_NFC_BASE + NFC_ST, (1 << 2),
+			 MAX_RETRIES)) {
+		printf("Error while initializing dma interrupt\n");
+		return;
+	}
+
+	if (!check_value_negated(SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0,
+				 SUNXI_DMA_DDMA_CFG_REG_LOADING, MAX_RETRIES)) {
+		printf("Error while waiting for dma transfer to finish\n");
+		return;
+	}
+
+	if (readl(SUNXI_NFC_BASE + NFC_ECC_ST))
+		(*ecc_errors)++;
+}
+
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
+{
+	void *current_dest;
+	uint32_t count;
+	uint32_t current_count;
+	uint32_t ecc_errors = 0;
+
+	memset(dest, 0x0, size); /* clean destination memory */
+	for (current_dest = dest;
+			current_dest < (dest + size);
+			current_dest += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) {
+		nand_read_page(offs, offs
+				< CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END,
+			       &ecc_errors);
+		count = current_dest - dest;
+
+		if (size - count > CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE)
+			current_count = CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE;
+		else
+			current_count = size - count;
+
+		memcpy(current_dest,
+		       temp_buf,
+		       current_count);
+		offs += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE;
+	}
+	return ecc_errors ? -1 : 0;
+}
+
+void nand_deselect(void) {}
diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c
index 34130f8443c4bcab1567a6cfe57fd14710b6c157..38d5f92ad0fd8b86d99839a881ba8c7d758d6086 100644
--- a/drivers/usb/host/ehci-sunxi.c
+++ b/drivers/usb/host/ehci-sunxi.c
@@ -67,7 +67,6 @@ static int ehci_usb_remove(struct udevice *dev)
 	if (ret)
 		return ret;
 
-	sunxi_usb_phy_power_off(priv->phy_index);
 	sunxi_usb_phy_exit(priv->phy_index);
 
 #ifdef CONFIG_SUNXI_GEN_SUN6I
diff --git a/drivers/usb/host/ohci-sunxi.c b/drivers/usb/host/ohci-sunxi.c
index e33a8f7ec2e332fda283e5069a90c69bf62d75ad..60792726ee386c64e31cc6d104ae6030b7e6acbe 100644
--- a/drivers/usb/host/ohci-sunxi.c
+++ b/drivers/usb/host/ohci-sunxi.c
@@ -69,7 +69,6 @@ static int ohci_usb_remove(struct udevice *dev)
 	if (ret)
 		return ret;
 
-	sunxi_usb_phy_power_off(priv->phy_index);
 	sunxi_usb_phy_exit(priv->phy_index);
 
 #ifdef CONFIG_SUNXI_GEN_SUN6I
diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c
index 16a264a9dded1e6de16e1131b5042fe8c80be903..a146c0861fffd5145cc3de314c37e909b20f6cff 100644
--- a/drivers/usb/musb-new/sunxi.c
+++ b/drivers/usb/musb-new/sunxi.c
@@ -196,8 +196,6 @@ static bool enabled = false;
 
 static int sunxi_musb_enable(struct musb *musb)
 {
-	int ret;
-
 	pr_debug("%s():\n", __func__);
 
 	musb_ep_select(musb->mregs, 0);
@@ -210,17 +208,26 @@ static int sunxi_musb_enable(struct musb *musb)
 	musb_writeb(musb->mregs, USBC_REG_o_VEND0, 0);
 
 	if (is_host_enabled(musb)) {
-		ret = sunxi_usb_phy_vbus_detect(0);
-		if (ret == 1) {
-			printf("A charger is plugged into the OTG: ");
-			return -ENODEV;
+		int id = sunxi_usb_phy_id_detect(0);
+
+		if (id == 1 && sunxi_usb_phy_power_is_on(0))
+			sunxi_usb_phy_power_off(0);
+
+		if (!sunxi_usb_phy_power_is_on(0)) {
+			int vbus = sunxi_usb_phy_vbus_detect(0);
+			if (vbus == 1) {
+				printf("A charger is plugged into the OTG: ");
+				return -ENODEV;
+			}
 		}
-		ret = sunxi_usb_phy_id_detect(0);
-		if (ret == 1) {
+
+		if (id == 1) {
 			printf("No host cable detected: ");
 			return -ENODEV;
 		}
-		sunxi_usb_phy_power_on(0); /* port power on */
+
+		if (!sunxi_usb_phy_power_is_on(0))
+			sunxi_usb_phy_power_on(0);
 	}
 
 	USBC_ForceVbusValidToHigh(musb->mregs);
@@ -236,9 +243,6 @@ static void sunxi_musb_disable(struct musb *musb)
 	if (!enabled)
 		return;
 
-	if (is_host_enabled(musb))
-		sunxi_usb_phy_power_off(0); /* port power off */
-
 	USBC_ForceVbusValidToLow(musb->mregs);
 	mdelay(200); /* Wait for the current session to timeout */
 
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index 269083b6664ec4593de7d477d120ea3f7a8f860a..18681850587c61e9bddb638c8b38db520a2383c7 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -2,7 +2,7 @@
  * Display driver for Allwinner SoCs.
  *
  * (C) Copyright 2013-2014 Luc Verhaegen <libv@skynet.be>
- * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com>
+ * (C) Copyright 2014-2015 Hans de Goede <hdegoede@redhat.com>
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -40,8 +40,12 @@ enum sunxi_monitor {
 	sunxi_monitor_hdmi,
 	sunxi_monitor_lcd,
 	sunxi_monitor_vga,
+	sunxi_monitor_composite_pal,
+	sunxi_monitor_composite_ntsc,
+	sunxi_monitor_composite_pal_m,
+	sunxi_monitor_composite_pal_nc,
 };
-#define SUNXI_MONITOR_LAST sunxi_monitor_vga
+#define SUNXI_MONITOR_LAST sunxi_monitor_composite_pal_nc
 
 struct sunxi_display {
 	GraphicDevice graphic_device;
@@ -50,6 +54,12 @@ struct sunxi_display {
 	unsigned int fb_size;
 } sunxi_display;
 
+const struct ctfb_res_modes composite_video_modes[2] = {
+	/*  x     y  hz  pixclk ps/kHz   le   ri  up  lo   hs vs  s  vmode */
+	{ 720,  576, 50, 37037,  27000, 137,   5, 20, 27,   2, 2, 0, FB_VMODE_INTERLACED },
+	{ 720,  480, 60, 37037,  27000, 116,  20, 16, 27,   2, 2, 0, FB_VMODE_INTERLACED },
+};
+
 #ifdef CONFIG_VIDEO_HDMI
 
 /*
@@ -390,6 +400,25 @@ static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode,
 static void sunxi_frontend_enable(void) {}
 #endif
 
+static bool sunxi_is_composite(void)
+{
+	switch (sunxi_display.monitor) {
+	case sunxi_monitor_none:
+	case sunxi_monitor_dvi:
+	case sunxi_monitor_hdmi:
+	case sunxi_monitor_lcd:
+	case sunxi_monitor_vga:
+		return false;
+	case sunxi_monitor_composite_pal:
+	case sunxi_monitor_composite_ntsc:
+	case sunxi_monitor_composite_pal_m:
+	case sunxi_monitor_composite_pal_nc:
+		return true;
+	}
+
+	return false; /* Never reached */
+}
+
 /*
  * This is the entity that mixes and matches the different layers and inputs.
  * Allwinner calls it the back-end, but i like composer better.
@@ -423,11 +452,18 @@ static void sunxi_composer_init(void)
 	setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_ENABLE);
 }
 
+static u32 sunxi_rgb2yuv_coef[12] = {
+	0x00000107, 0x00000204, 0x00000064, 0x00000108,
+	0x00003f69, 0x00003ed6, 0x000001c1, 0x00000808,
+	0x000001c1, 0x00003e88, 0x00003fb8, 0x00000808
+};
+
 static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
 				    unsigned int address)
 {
 	struct sunxi_de_be_reg * const de_be =
 		(struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
+	int i;
 
 	sunxi_frontend_mode_set(mode, address);
 
@@ -445,6 +481,18 @@ static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
 	writel(SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888, &de_be->layer0_attr1_ctrl);
 
 	setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_LAYER0_ENABLE);
+	if (mode->vmode == FB_VMODE_INTERLACED)
+		setbits_le32(&de_be->mode,
+			     SUNXI_DE_BE_MODE_DEFLICKER_ENABLE |
+			     SUNXI_DE_BE_MODE_INTERLACE_ENABLE);
+
+	if (sunxi_is_composite()) {
+		writel(SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE,
+		       &de_be->output_color_ctrl);
+		for (i = 0; i < 12; i++)
+			writel(sunxi_rgb2yuv_coef[i],
+			       &de_be->output_color_coef[i]);
+	}
 }
 
 static void sunxi_composer_enable(void)
@@ -535,6 +583,9 @@ static void sunxi_lcdc_pll_set(int tcon, int dotclock,
 		       (best_double ? CCM_LCD_CH1_CTRL_PLL3_2X :
 				      CCM_LCD_CH1_CTRL_PLL3) |
 		       CCM_LCD_CH1_CTRL_M(best_m), &ccm->lcd0_ch1_clk_cfg);
+		if (sunxi_is_composite())
+			setbits_le32(&ccm->lcd0_ch1_clk_cfg,
+				     CCM_LCD_CH1_CTRL_HALF_SCLK1);
 	}
 
 	*clk_div = best_m;
@@ -663,11 +714,16 @@ static void sunxi_lcdc_backlight_enable(void)
 		gpio_direction_output(pin, PWM_ON);
 }
 
-static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode)
+static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode, int tcon)
 {
 	int delay;
 
-	delay = mode->lower_margin + mode->vsync_len + mode->upper_margin - 2;
+	delay = mode->lower_margin + mode->vsync_len + mode->upper_margin;
+	if (mode->vmode == FB_VMODE_INTERLACED)
+		delay /= 2;
+	if (tcon == 1)
+		delay -= 2;
+
 	return (delay > 30) ? 30 : delay;
 }
 
@@ -692,7 +748,7 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
 	clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
 			SUNXI_LCDC_CTRL_IO_MAP_TCON0);
 
-	clk_delay = sunxi_lcdc_get_clk_delay(mode);
+	clk_delay = sunxi_lcdc_get_clk_delay(mode, 0);
 	writel(SUNXI_LCDC_TCON0_CTRL_ENABLE |
 	       SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon0_ctrl);
 
@@ -757,28 +813,33 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
 	writel(0, &lcdc->tcon0_io_tristate);
 }
 
-#if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA
+#if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
 static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
 				      int *clk_div, int *clk_double,
 				      bool use_portd_hvsync)
 {
 	struct sunxi_lcdc_reg * const lcdc =
 		(struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
-	int bp, clk_delay, total, val;
+	int bp, clk_delay, total, val, yres;
 
 	/* Use tcon1 */
 	clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
 			SUNXI_LCDC_CTRL_IO_MAP_TCON1);
 
-	clk_delay = sunxi_lcdc_get_clk_delay(mode);
+	clk_delay = sunxi_lcdc_get_clk_delay(mode, 1);
 	writel(SUNXI_LCDC_TCON1_CTRL_ENABLE |
+	       ((mode->vmode == FB_VMODE_INTERLACED) ?
+			SUNXI_LCDC_TCON1_CTRL_INTERLACE_ENABLE : 0) |
 	       SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon1_ctrl);
 
-	writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres),
+	yres = mode->yres;
+	if (mode->vmode == FB_VMODE_INTERLACED)
+		yres /= 2;
+	writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
 	       &lcdc->tcon1_timing_source);
-	writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres),
+	writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
 	       &lcdc->tcon1_timing_scale);
-	writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres),
+	writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
 	       &lcdc->tcon1_timing_out);
 
 	bp = mode->hsync_len + mode->left_margin;
@@ -788,6 +849,8 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
 
 	bp = mode->vsync_len + mode->upper_margin;
 	total = mode->yres + mode->lower_margin + bp;
+	if (mode->vmode == FB_VMODE_NONINTERLACED)
+		total *= 2;
 	writel(SUNXI_LCDC_TCON1_TIMING_V_TOTAL(total) |
 	       SUNXI_LCDC_TCON1_TIMING_V_BP(bp), &lcdc->tcon1_timing_v);
 
@@ -811,7 +874,7 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
 	}
 	sunxi_lcdc_pll_set(1, mode->pixclock_khz, clk_div, clk_double);
 }
-#endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA */
+#endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || CONFIG_VIDEO_COMPOSITE */
 
 #ifdef CONFIG_VIDEO_HDMI
 
@@ -925,9 +988,9 @@ static void sunxi_hdmi_enable(void)
 
 #endif /* CONFIG_VIDEO_HDMI */
 
-#ifdef CONFIG_VIDEO_VGA
+#if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
 
-static void sunxi_vga_mode_set(void)
+static void sunxi_tvencoder_mode_set(void)
 {
 	struct sunxi_ccm_reg * const ccm =
 		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
@@ -937,16 +1000,75 @@ static void sunxi_vga_mode_set(void)
 	/* Clock on */
 	setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_TVE0);
 
-	/* Set TVE in VGA mode */
-	writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
-	       SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
-	       SUNXI_TVE_GCTRL_DAC_INPUT(2, 3), &tve->gctrl);
-	writel(SUNXI_TVE_GCTRL_CFG0_VGA, &tve->cfg0);
-	writel(SUNXI_TVE_GCTRL_DAC_CFG0_VGA, &tve->dac_cfg0);
-	writel(SUNXI_TVE_GCTRL_UNKNOWN1_VGA, &tve->unknown1);
+	switch (sunxi_display.monitor) {
+	case sunxi_monitor_vga:
+		writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
+		       SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
+		       SUNXI_TVE_GCTRL_DAC_INPUT(2, 3), &tve->gctrl);
+		writel(SUNXI_TVE_CFG0_VGA, &tve->cfg0);
+		writel(SUNXI_TVE_DAC_CFG0_VGA, &tve->dac_cfg0);
+		writel(SUNXI_TVE_UNKNOWN1_VGA, &tve->unknown1);
+		break;
+	case sunxi_monitor_composite_pal_nc:
+		writel(SUNXI_TVE_CHROMA_FREQ_PAL_NC, &tve->chroma_freq);
+		/* Fall through */
+	case sunxi_monitor_composite_pal:
+		writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
+		       SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
+		       SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
+		       SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
+		writel(SUNXI_TVE_CFG0_PAL, &tve->cfg0);
+		writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
+		writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
+		writel(SUNXI_TVE_PORCH_NUM_PAL, &tve->porch_num);
+		writel(SUNXI_TVE_LINE_NUM_PAL, &tve->line_num);
+		writel(SUNXI_TVE_BLANK_BLACK_LEVEL_PAL, &tve->blank_black_level);
+		writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
+		writel(SUNXI_TVE_CBR_LEVEL_PAL, &tve->cbr_level);
+		writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
+		writel(SUNXI_TVE_UNKNOWN2_PAL, &tve->unknown2);
+		writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
+		writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
+		writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
+		writel(SUNXI_TVE_RESYNC_NUM_PAL, &tve->resync_num);
+		writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
+		break;
+	case sunxi_monitor_composite_pal_m:
+		writel(SUNXI_TVE_CHROMA_FREQ_PAL_M, &tve->chroma_freq);
+		writel(SUNXI_TVE_COLOR_BURST_PAL_M, &tve->color_burst);
+		/* Fall through */
+	case sunxi_monitor_composite_ntsc:
+		writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
+		       SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
+		       SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
+		       SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
+		writel(SUNXI_TVE_CFG0_NTSC, &tve->cfg0);
+		writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
+		writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
+		writel(SUNXI_TVE_PORCH_NUM_NTSC, &tve->porch_num);
+		writel(SUNXI_TVE_LINE_NUM_NTSC, &tve->line_num);
+		writel(SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC, &tve->blank_black_level);
+		writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
+		writel(SUNXI_TVE_CBR_LEVEL_NTSC, &tve->cbr_level);
+		writel(SUNXI_TVE_BURST_PHASE_NTSC, &tve->burst_phase);
+		writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
+		writel(SUNXI_TVE_UNKNOWN2_NTSC, &tve->unknown2);
+		writel(SUNXI_TVE_SYNC_VBI_LEVEL_NTSC, &tve->sync_vbi_level);
+		writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
+		writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
+		writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
+		writel(SUNXI_TVE_RESYNC_NUM_NTSC, &tve->resync_num);
+		writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
+		break;
+	case sunxi_monitor_none:
+	case sunxi_monitor_dvi:
+	case sunxi_monitor_hdmi:
+	case sunxi_monitor_lcd:
+		break;
+	}
 }
 
-static void sunxi_vga_enable(void)
+static void sunxi_tvencoder_enable(void)
 {
 	struct sunxi_tve_reg * const tve =
 		(struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
@@ -954,7 +1076,7 @@ static void sunxi_vga_enable(void)
 	setbits_le32(&tve->gctrl, SUNXI_TVE_GCTRL_ENABLE);
 }
 
-#endif /* CONFIG_VIDEO_VGA */
+#endif /* CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE */
 
 static void sunxi_drc_init(void)
 {
@@ -1069,16 +1191,29 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 #ifdef CONFIG_VIDEO_VGA
 		sunxi_composer_mode_set(mode, address);
 		sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1);
-		sunxi_vga_mode_set();
+		sunxi_tvencoder_mode_set();
 		sunxi_composer_enable();
 		sunxi_lcdc_enable();
-		sunxi_vga_enable();
+		sunxi_tvencoder_enable();
 #elif defined CONFIG_VIDEO_VGA_VIA_LCD
 		sunxi_composer_mode_set(mode, address);
 		sunxi_lcdc_tcon0_mode_set(mode, true);
 		sunxi_composer_enable();
 		sunxi_lcdc_enable();
 		sunxi_vga_external_dac_enable();
+#endif
+		break;
+	case sunxi_monitor_composite_pal:
+	case sunxi_monitor_composite_ntsc:
+	case sunxi_monitor_composite_pal_m:
+	case sunxi_monitor_composite_pal_nc:
+#ifdef CONFIG_VIDEO_COMPOSITE
+		sunxi_composer_mode_set(mode, address);
+		sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
+		sunxi_tvencoder_mode_set();
+		sunxi_composer_enable();
+		sunxi_lcdc_enable();
+		sunxi_tvencoder_enable();
 #endif
 		break;
 	}
@@ -1087,11 +1222,15 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor)
 {
 	switch (monitor) {
-	case sunxi_monitor_none:	return "none";
-	case sunxi_monitor_dvi:		return "dvi";
-	case sunxi_monitor_hdmi:	return "hdmi";
-	case sunxi_monitor_lcd:		return "lcd";
-	case sunxi_monitor_vga:		return "vga";
+	case sunxi_monitor_none:		return "none";
+	case sunxi_monitor_dvi:			return "dvi";
+	case sunxi_monitor_hdmi:		return "hdmi";
+	case sunxi_monitor_lcd:			return "lcd";
+	case sunxi_monitor_vga:			return "vga";
+	case sunxi_monitor_composite_pal:	return "composite-pal";
+	case sunxi_monitor_composite_ntsc:	return "composite-ntsc";
+	case sunxi_monitor_composite_pal_m:	return "composite-pal-m";
+	case sunxi_monitor_composite_pal_nc:	return "composite-pal-nc";
 	}
 	return NULL; /* never reached */
 }
@@ -1101,6 +1240,54 @@ ulong board_get_usable_ram_top(ulong total_size)
 	return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE;
 }
 
+static bool sunxi_has_hdmi(void)
+{
+#ifdef CONFIG_VIDEO_HDMI
+	return true;
+#else
+	return false;
+#endif
+}
+
+static bool sunxi_has_lcd(void)
+{
+	char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
+
+	return lcd_mode[0] != 0;
+}
+
+static bool sunxi_has_vga(void)
+{
+#if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_VGA_VIA_LCD
+	return true;
+#else
+	return false;
+#endif
+}
+
+static bool sunxi_has_composite(void)
+{
+#ifdef CONFIG_VIDEO_COMPOSITE
+	return true;
+#else
+	return false;
+#endif
+}
+
+static enum sunxi_monitor sunxi_get_default_mon(bool allow_hdmi)
+{
+	if (allow_hdmi && sunxi_has_hdmi())
+		return sunxi_monitor_dvi;
+	else if (sunxi_has_lcd())
+		return sunxi_monitor_lcd;
+	else if (sunxi_has_vga())
+		return sunxi_monitor_vga;
+	else if (sunxi_has_composite())
+		return sunxi_monitor_composite_pal;
+	else
+		return sunxi_monitor_none;
+}
+
 void *video_hw_init(void)
 {
 	static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
@@ -1122,12 +1309,8 @@ void *video_hw_init(void)
 	hpd = video_get_option_int(options, "hpd", 1);
 	hpd_delay = video_get_option_int(options, "hpd_delay", 500);
 	edid = video_get_option_int(options, "edid", 1);
-	sunxi_display.monitor = sunxi_monitor_dvi;
-#elif defined CONFIG_VIDEO_VGA_VIA_LCD
-	sunxi_display.monitor = sunxi_monitor_vga;
-#else
-	sunxi_display.monitor = sunxi_monitor_lcd;
 #endif
+	sunxi_display.monitor = sunxi_get_default_mon(true);
 	video_get_option_string(options, "monitor", mon, sizeof(mon),
 				sunxi_get_mon_desc(sunxi_display.monitor));
 	for (i = 0; i <= SUNXI_MONITOR_LAST; i++) {
@@ -1152,16 +1335,7 @@ void *video_hw_init(void)
 				mode = &custom;
 		} else if (hpd) {
 			sunxi_hdmi_shutdown();
-			/* Fallback to lcd / vga / none */
-			if (lcd_mode[0]) {
-				sunxi_display.monitor = sunxi_monitor_lcd;
-			} else {
-#if defined CONFIG_VIDEO_VGA_VIA_LCD || defined CONFIG_VIDEO_VGA
-				sunxi_display.monitor = sunxi_monitor_vga;
-#else
-				sunxi_display.monitor = sunxi_monitor_none;
-#endif
-			}
+			sunxi_display.monitor = sunxi_get_default_mon(false);
 		} /* else continue with hdmi/dvi without a cable connected */
 	}
 #endif
@@ -1171,39 +1345,45 @@ void *video_hw_init(void)
 		return NULL;
 	case sunxi_monitor_dvi:
 	case sunxi_monitor_hdmi:
-#ifdef CONFIG_VIDEO_HDMI
+		if (!sunxi_has_hdmi()) {
+			printf("HDMI/DVI not supported on this board\n");
+			sunxi_display.monitor = sunxi_monitor_none;
+			return NULL;
+		}
 		break;
-#else
-		printf("HDMI/DVI not supported on this board\n");
-		sunxi_display.monitor = sunxi_monitor_none;
-		return NULL;
-#endif
 	case sunxi_monitor_lcd:
-		if (lcd_mode[0]) {
-			sunxi_display.depth = video_get_params(&custom, lcd_mode);
-			mode = &custom;
-			break;
+		if (!sunxi_has_lcd()) {
+			printf("LCD not supported on this board\n");
+			sunxi_display.monitor = sunxi_monitor_none;
+			return NULL;
 		}
-		printf("LCD not supported on this board\n");
-		sunxi_display.monitor = sunxi_monitor_none;
-		return NULL;
+		sunxi_display.depth = video_get_params(&custom, lcd_mode);
+		mode = &custom;
+		break;
 	case sunxi_monitor_vga:
-#if defined CONFIG_VIDEO_VGA_VIA_LCD || defined CONFIG_VIDEO_VGA
+		if (!sunxi_has_vga()) {
+			printf("VGA not supported on this board\n");
+			sunxi_display.monitor = sunxi_monitor_none;
+			return NULL;
+		}
 		sunxi_display.depth = 18;
 		break;
-#else
-		printf("VGA not supported on this board\n");
-		sunxi_display.monitor = sunxi_monitor_none;
-		return NULL;
-#endif
-	}
-
-	if (mode->vmode != FB_VMODE_NONINTERLACED) {
-		printf("Only non-interlaced modes supported, falling back to 1024x768\n");
-		mode = &res_mode_init[RES_MODE_1024x768];
-	} else {
-		printf("Setting up a %dx%d %s console\n", mode->xres,
-		       mode->yres, sunxi_get_mon_desc(sunxi_display.monitor));
+	case sunxi_monitor_composite_pal:
+	case sunxi_monitor_composite_ntsc:
+	case sunxi_monitor_composite_pal_m:
+	case sunxi_monitor_composite_pal_nc:
+		if (!sunxi_has_composite()) {
+			printf("Composite video not supported on this board\n");
+			sunxi_display.monitor = sunxi_monitor_none;
+			return NULL;
+		}
+		if (sunxi_display.monitor == sunxi_monitor_composite_pal ||
+		    sunxi_display.monitor == sunxi_monitor_composite_pal_nc)
+			mode = &composite_video_modes[0];
+		else
+			mode = &composite_video_modes[1];
+		sunxi_display.depth = 24;
+		break;
 	}
 
 	sunxi_display.fb_size =
@@ -1215,6 +1395,10 @@ void *video_hw_init(void)
 		return NULL;
 	}
 
+	printf("Setting up a %dx%d%s %s console\n", mode->xres, mode->yres,
+	       (mode->vmode == FB_VMODE_INTERLACED) ? "i" : "",
+	       sunxi_get_mon_desc(sunxi_display.monitor));
+
 	gd->fb_base = gd->bd->bi_dram[0].start +
 		      gd->bd->bi_dram[0].size - sunxi_display.fb_size;
 	sunxi_engines_init();
@@ -1268,6 +1452,12 @@ int sunxi_simplefb_setup(void *blob)
 		pipeline = PIPELINE_PREFIX "de_be0-lcd0";
 #endif
 		break;
+	case sunxi_monitor_composite_pal:
+	case sunxi_monitor_composite_ntsc:
+	case sunxi_monitor_composite_pal_m:
+	case sunxi_monitor_composite_pal_nc:
+		pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0";
+		break;
 	}
 
 	/* Find a prefilled simpefb node, matching out pipeline config */
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index edcacd5c1487db110178f0edd2e14c93f6ac277a..a2cbcf5d9541d646ca8d6c764ccca6bb2f15d1e2 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -139,6 +139,16 @@
 #define CONFIG_INITRD_TAG
 #define CONFIG_SERIAL_TAG
 
+#if defined(CONFIG_SPL_NAND_SUNXI)
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_SUPPORT
+
+#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000
+#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x008000
+
+#endif
+
+
 /* mmc config */
 #if !defined(CONFIG_UART0_PORT_F)
 #define CONFIG_MMC
@@ -252,6 +262,7 @@ extern int soft_i2c_gpio_scl;
 #define CONFIG_CONS_INDEX              1       /* UART0 */
 #endif
 
+#ifdef CONFIG_REQUIRE_SERIAL_CONSOLE
 #if CONFIG_CONS_INDEX == 1
 #ifdef CONFIG_MACH_SUN9I
 #define OF_STDOUT_PATH		"/soc/serial@07000000:115200"
@@ -267,6 +278,7 @@ extern int soft_i2c_gpio_scl;
 #else
 #error Unsupported console port nr. Please fix stdout-path in sunxi-common.h.
 #endif
+#endif /* ifdef CONFIG_REQUIRE_SERIAL_CONSOLE */
 
 /* GPIO */
 #define CONFIG_SUNXI_GPIO