Merge git://git.denx.de/u-boot-dm
diff --git a/MAINTAINERS b/MAINTAINERS
index 7cc3b06..fde77b2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -159,6 +159,8 @@
 F:	drivers/clk/rockchip/
 F:	drivers/gpio/rk_gpio.c
 F:	drivers/misc/rockchip-efuse.c
+F:	drivers/mmc/rockchip_sdhci.c
+F:	drivers/mmc/rockchip_dw_mmc.c
 F:	drivers/pinctrl/rockchip/
 F:	drivers/ram/rockchip/
 F:	drivers/sysreset/sysreset_rockchip.c
diff --git a/arch/arm/dts/armada-3720-db.dts b/arch/arm/dts/armada-3720-db.dts
index 5f06252..770c08a 100644
--- a/arch/arm/dts/armada-3720-db.dts
+++ b/arch/arm/dts/armada-3720-db.dts
@@ -82,7 +82,7 @@
 
 &eth0 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&rgmii_pins>;
+	pinctrl-0 = <&rgmii_pins>, <&smi_pins>;
 	status = "okay";
 	phy-mode = "rgmii";
 };
@@ -100,6 +100,8 @@
 
 &sdhci0 {
 	bus-width = <4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdio_pins>;
 	status = "okay";
 };
 
@@ -109,6 +111,8 @@
 	mmc-ddr-1_8v;
 	mmc-hs400-1_8v;
 	marvell,pad-type = "fixed-1-8v";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc_pins>;
 	status = "okay";
 
 	#address-cells = <1>;
@@ -150,3 +154,11 @@
 &usb3 {
 	status = "okay";
 };
+
+/* CON17 */
+&pcie0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie_pins>;
+	reset-gpio = <&gpiosb 3 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/armada-3720-espressobin.dts b/arch/arm/dts/armada-3720-espressobin.dts
index aa6587a..7bfccb0 100644
--- a/arch/arm/dts/armada-3720-espressobin.dts
+++ b/arch/arm/dts/armada-3720-espressobin.dts
@@ -89,6 +89,8 @@
 
 &eth0 {
 	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii_pins>, <&smi_pins>;
 	phy-mode = "rgmii";
 	phy_addr = <0x1>;
 	fixed-link {
@@ -98,6 +100,8 @@
 };
 
 &i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
 	status = "okay";
 };
 
@@ -108,6 +112,8 @@
 
 &spi0 {
 	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_quad_pins>;
 
 	spi-flash@0 {
 		#address-cells = <1>;
@@ -121,6 +127,8 @@
 
 /* Exported on the micro USB connector CON32 through an FTDI */
 &uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
 	status = "okay";
 };
 
@@ -133,3 +141,10 @@
 &usb3 {
 	status = "okay";
 };
+
+&pcie0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie_pins>;
+	reset-gpio = <&gpiosb 3 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/armada-37xx.dtsi b/arch/arm/dts/armada-37xx.dtsi
index 6902342..5400742 100644
--- a/arch/arm/dts/armada-37xx.dtsi
+++ b/arch/arm/dts/armada-37xx.dtsi
@@ -46,6 +46,7 @@
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/comphy/comphy_data.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
 	model = "Marvell Armada 37xx SoC";
@@ -154,6 +155,11 @@
 					groups = "uart2";
 					function = "uart";
 				};
+
+				mmc_pins: mmc-pins {
+					groups = "emmc_nb";
+					function = "emmc";
+				};
 			};
 
 			pinctrl_sb: pinctrl-sb@18800 {
@@ -162,7 +168,7 @@
 				reg = <0x18800 0x100>, <0x18C00 0x20>;
 				gpiosb: gpiosb {
 					#gpio-cells = <2>;
-					gpio-ranges = <&pinctrl_sb 0 0 29>;
+					gpio-ranges = <&pinctrl_sb 0 0 30>;
 					gpio-controller;
 					interrupts =
 					<GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
@@ -177,6 +183,20 @@
 					function = "mii";
 				};
 
+				smi_pins: smi-pins {
+					groups = "smi";
+					function = "smi";
+				};
+
+				sdio_pins: sdio-pins {
+					groups = "sdio_sb";
+					function = "sdio";
+				};
+
+				pcie_pins: pcie-pins {
+					groups = "pcie1";
+					function = "gpio";
+				};
 			};
 
 			usb3: usb@58000 {
@@ -266,20 +286,6 @@
 				status = "disabled";
 			};
 
-			pinctl0: pinctl@13830 { /* north bridge */
-				compatible = "marvell,armada-3700-pinctl";
-				bank-name = "armada-3700-nb";
-				reg = <0x13830 0x4>;
-				pin-count = <36>;
-			};
-
-			pinctl1: pinctl@18830 { /* south bridge */
-				compatible = "marvell,armada-3700-pinctl";
-				bank-name = "armada-3700-sb";
-				reg = <0x18830 0x4>;
-				pin-count = <30>;
-			};
-
 			comphy: comphy@18300 {
 				compatible = "marvell,mvebu-comphy", "marvell,comphy-armada-3700";
 				reg = <0x18300 0x28>,
@@ -288,5 +294,21 @@
 				max-lanes = <2>;
 			};
 		};
+
+		pcie0: pcie@d0070000 {
+			compatible = "marvell,armada-37xx-pcie";
+			reg = <0 0xd0070000 0 0x20000>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			num-lanes = <1>;
+			status = "disabled";
+
+			bus-range = <0 0xff>;
+			ranges = <0x82000000 0 0xe8000000
+				 0 0xe8000000 0 0x1000000 /* Port 0 MEM */
+				 0x81000000 0 0xe9000000
+				 0 0xe9000000 0 0x10000>; /* Port 0 IO*/
+		};
 	};
 };
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3036.h b/arch/arm/include/asm/arch-rockchip/grf_rk3036.h
index d995b7d..eaae10b 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3036.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3036.h
@@ -80,413 +80,4 @@
 };
 check_member(rk3036_grf, sdmmc_det_cnt, 0x304);
 
-/* GRF_GPIO0A_IOMUX */
-enum {
-	GPIO0A3_SHIFT		= 6,
-	GPIO0A3_MASK		= 1 << GPIO0A3_SHIFT,
-	GPIO0A3_GPIO		= 0,
-	GPIO0A3_I2C1_SDA,
-
-	GPIO0A2_SHIFT		= 4,
-	GPIO0A2_MASK		= 1 << GPIO0A2_SHIFT,
-	GPIO0A2_GPIO		= 0,
-	GPIO0A2_I2C1_SCL,
-
-	GPIO0A1_SHIFT		= 2,
-	GPIO0A1_MASK		= 3 << GPIO0A1_SHIFT,
-	GPIO0A1_GPIO		= 0,
-	GPIO0A1_I2C0_SDA,
-	GPIO0A1_PWM2,
-
-	GPIO0A0_SHIFT		= 0,
-	GPIO0A0_MASK		= 3 << GPIO0A0_SHIFT,
-	GPIO0A0_GPIO		= 0,
-	GPIO0A0_I2C0_SCL,
-	GPIO0A0_PWM1,
-};
-
-/* GRF_GPIO0B_IOMUX */
-enum {
-	GPIO0B6_SHIFT		= 12,
-	GPIO0B6_MASK		= 3 << GPIO0B6_SHIFT,
-	GPIO0B6_GPIO		= 0,
-	GPIO0B6_MMC1_D3,
-	GPIO0B6_I2S1_SCLK,
-
-	GPIO0B5_SHIFT		= 10,
-	GPIO0B5_MASK		= 3 << GPIO0B5_SHIFT,
-	GPIO0B5_GPIO		= 0,
-	GPIO0B5_MMC1_D2,
-	GPIO0B5_I2S1_SDI,
-
-	GPIO0B4_SHIFT		= 8,
-	GPIO0B4_MASK		= 3 << GPIO0B4_SHIFT,
-	GPIO0B4_GPIO		= 0,
-	GPIO0B4_MMC1_D1,
-	GPIO0B4_I2S1_LRCKTX,
-
-	GPIO0B3_SHIFT		= 6,
-	GPIO0B3_MASK		= 3 << GPIO0B3_SHIFT,
-	GPIO0B3_GPIO		= 0,
-	GPIO0B3_MMC1_D0,
-	GPIO0B3_I2S1_LRCKRX,
-
-	GPIO0B1_SHIFT		= 2,
-	GPIO0B1_MASK		= 3 << GPIO0B1_SHIFT,
-	GPIO0B1_GPIO		= 0,
-	GPIO0B1_MMC1_CLKOUT,
-	GPIO0B1_I2S1_MCLK,
-
-	GPIO0B0_SHIFT		= 0,
-	GPIO0B0_MASK		= 3,
-	GPIO0B0_GPIO		= 0,
-	GPIO0B0_MMC1_CMD,
-	GPIO0B0_I2S1_SDO,
-};
-
-/* GRF_GPIO0C_IOMUX */
-enum {
-	GPIO0C4_SHIFT		= 8,
-	GPIO0C4_MASK		= 1 << GPIO0C4_SHIFT,
-	GPIO0C4_GPIO		= 0,
-	GPIO0C4_DRIVE_VBUS,
-
-	GPIO0C3_SHIFT		= 6,
-	GPIO0C3_MASK		= 1 << GPIO0C3_SHIFT,
-	GPIO0C3_GPIO		= 0,
-	GPIO0C3_UART0_CTSN,
-
-	GPIO0C2_SHIFT		= 4,
-	GPIO0C2_MASK		= 1 << GPIO0C2_SHIFT,
-	GPIO0C2_GPIO		= 0,
-	GPIO0C2_UART0_RTSN,
-
-	GPIO0C1_SHIFT		= 2,
-	GPIO0C1_MASK		= 1 << GPIO0C1_SHIFT,
-	GPIO0C1_GPIO		= 0,
-	GPIO0C1_UART0_SIN,
-
-
-	GPIO0C0_SHIFT		= 0,
-	GPIO0C0_MASK		= 1 << GPIO0C0_SHIFT,
-	GPIO0C0_GPIO		= 0,
-	GPIO0C0_UART0_SOUT,
-};
-
-/* GRF_GPIO0D_IOMUX */
-enum {
-	GPIO0D4_SHIFT		= 8,
-	GPIO0D4_MASK		= 1 << GPIO0D4_SHIFT,
-	GPIO0D4_GPIO		= 0,
-	GPIO0D4_SPDIF,
-
-	GPIO0D3_SHIFT		= 6,
-	GPIO0D3_MASK		= 1 << GPIO0D3_SHIFT,
-	GPIO0D3_GPIO		= 0,
-	GPIO0D3_PWM3,
-
-	GPIO0D2_SHIFT		= 4,
-	GPIO0D2_MASK		= 1 << GPIO0D2_SHIFT,
-	GPIO0D2_GPIO		= 0,
-	GPIO0D2_PWM0,
-};
-
-/* GRF_GPIO1A_IOMUX */
-enum {
-	GPIO1A5_SHIFT		= 10,
-	GPIO1A5_MASK		= 1 << GPIO1A5_SHIFT,
-	GPIO1A5_GPIO		= 0,
-	GPIO1A5_I2S_SDI,
-
-	GPIO1A4_SHIFT		= 8,
-	GPIO1A4_MASK		= 1 << GPIO1A4_SHIFT,
-	GPIO1A4_GPIO		= 0,
-	GPIO1A4_I2S_SD0,
-
-	GPIO1A3_SHIFT		= 6,
-	GPIO1A3_MASK		= 1 << GPIO1A3_SHIFT,
-	GPIO1A3_GPIO		= 0,
-	GPIO1A3_I2S_LRCKTX,
-
-	GPIO1A2_SHIFT		= 4,
-	GPIO1A2_MASK		= 3 << GPIO1A2_SHIFT,
-	GPIO1A2_GPIO		= 0,
-	GPIO1A2_I2S_LRCKRX,
-	GPIO1A2_PWM1_0,
-
-	GPIO1A1_SHIFT		= 2,
-	GPIO1A1_MASK		= 1 << GPIO1A1_SHIFT,
-	GPIO1A1_GPIO		= 0,
-	GPIO1A1_I2S_SCLK,
-
-	GPIO1A0_SHIFT		= 0,
-	GPIO1A0_MASK		= 1 << GPIO1A0_SHIFT,
-	GPIO1A0_GPIO		= 0,
-	GPIO1A0_I2S_MCLK,
-
-};
-
-/* GRF_GPIO1B_IOMUX */
-enum {
-	GPIO1B7_SHIFT		= 14,
-	GPIO1B7_MASK		= 1 << GPIO1B7_SHIFT,
-	GPIO1B7_GPIO		= 0,
-	GPIO1B7_MMC0_CMD,
-
-	GPIO1B3_SHIFT		= 6,
-	GPIO1B3_MASK		= 1 << GPIO1B3_SHIFT,
-	GPIO1B3_GPIO		= 0,
-	GPIO1B3_HDMI_HPD,
-
-	GPIO1B2_SHIFT		= 4,
-	GPIO1B2_MASK		= 1 << GPIO1B2_SHIFT,
-	GPIO1B2_GPIO		= 0,
-	GPIO1B2_HDMI_SCL,
-
-	GPIO1B1_SHIFT		= 2,
-	GPIO1B1_MASK		= 1 << GPIO1B1_SHIFT,
-	GPIO1B1_GPIO		= 0,
-	GPIO1B1_HDMI_SDA,
-
-	GPIO1B0_SHIFT		= 0,
-	GPIO1B0_MASK		= 1 << GPIO1B0_SHIFT,
-	GPIO1B0_GPIO		= 0,
-	GPIO1B0_HDMI_CEC,
-};
-
-/* GRF_GPIO1C_IOMUX */
-enum {
-	GPIO1C5_SHIFT		= 10,
-	GPIO1C5_MASK		= 3 << GPIO1C5_SHIFT,
-	GPIO1C5_GPIO		= 0,
-	GPIO1C5_MMC0_D3,
-	GPIO1C5_JTAG_TMS,
-
-	GPIO1C4_SHIFT		= 8,
-	GPIO1C4_MASK		= 3 << GPIO1C4_SHIFT,
-	GPIO1C4_GPIO		= 0,
-	GPIO1C4_MMC0_D2,
-	GPIO1C4_JTAG_TCK,
-
-	GPIO1C3_SHIFT		= 6,
-	GPIO1C3_MASK		= 3 << GPIO1C3_SHIFT,
-	GPIO1C3_GPIO		= 0,
-	GPIO1C3_MMC0_D1,
-	GPIO1C3_UART2_SOUT,
-
-	GPIO1C2_SHIFT		= 4,
-	GPIO1C2_MASK		= 3 << GPIO1C2_SHIFT ,
-	GPIO1C2_GPIO		= 0,
-	GPIO1C2_MMC0_D0,
-	GPIO1C2_UART2_SIN,
-
-	GPIO1C1_SHIFT		= 2,
-	GPIO1C1_MASK		= 1 << GPIO1C1_SHIFT,
-	GPIO1C1_GPIO		= 0,
-	GPIO1C1_MMC0_DETN,
-
-	GPIO1C0_SHIFT		= 0,
-	GPIO1C0_MASK		= 1 << GPIO1C0_SHIFT,
-	GPIO1C0_GPIO		= 0,
-	GPIO1C0_MMC0_CLKOUT,
-};
-
-/* GRF_GPIO1D_IOMUX */
-enum {
-	GPIO1D7_SHIFT		= 14,
-	GPIO1D7_MASK		= 3 << GPIO1D7_SHIFT,
-	GPIO1D7_GPIO		= 0,
-	GPIO1D7_NAND_D7,
-	GPIO1D7_EMMC_D7,
-	GPIO1D7_SPI_CSN1,
-
-	GPIO1D6_SHIFT		= 12,
-	GPIO1D6_MASK		= 3 << GPIO1D6_SHIFT,
-	GPIO1D6_GPIO		= 0,
-	GPIO1D6_NAND_D6,
-	GPIO1D6_EMMC_D6,
-	GPIO1D6_SPI_CSN0,
-
-	GPIO1D5_SHIFT		= 10,
-	GPIO1D5_MASK		= 3 << GPIO1D5_SHIFT,
-	GPIO1D5_GPIO		= 0,
-	GPIO1D5_NAND_D5,
-	GPIO1D5_EMMC_D5,
-	GPIO1D5_SPI_TXD,
-
-	GPIO1D4_SHIFT		= 8,
-	GPIO1D4_MASK		= 3 << GPIO1D4_SHIFT,
-	GPIO1D4_GPIO		= 0,
-	GPIO1D4_NAND_D4,
-	GPIO1D4_EMMC_D4,
-	GPIO1D4_SPI_RXD,
-
-	GPIO1D3_SHIFT		= 6,
-	GPIO1D3_MASK		= 3 << GPIO1D3_SHIFT,
-	GPIO1D3_GPIO		= 0,
-	GPIO1D3_NAND_D3,
-	GPIO1D3_EMMC_D3,
-	GPIO1D3_SFC_SIO3,
-
-	GPIO1D2_SHIFT		= 4,
-	GPIO1D2_MASK		= 3 << GPIO1D2_SHIFT,
-	GPIO1D2_GPIO		= 0,
-	GPIO1D2_NAND_D2,
-	GPIO1D2_EMMC_D2,
-	GPIO1D2_SFC_SIO2,
-
-	GPIO1D1_SHIFT		= 2,
-	GPIO1D1_MASK		= 3 << GPIO1D1_SHIFT,
-	GPIO1D1_GPIO		= 0,
-	GPIO1D1_NAND_D1,
-	GPIO1D1_EMMC_D1,
-	GPIO1D1_SFC_SIO1,
-
-	GPIO1D0_SHIFT		= 0,
-	GPIO1D0_MASK		= 3 << GPIO1D0_SHIFT,
-	GPIO1D0_GPIO		= 0,
-	GPIO1D0_NAND_D0,
-	GPIO1D0_EMMC_D0,
-	GPIO1D0_SFC_SIO0,
-};
-
-/* GRF_GPIO2A_IOMUX */
-enum {
-	GPIO2A7_SHIFT		= 14,
-	GPIO2A7_MASK		= 1 << GPIO2A7_SHIFT,
-	GPIO2A7_GPIO		= 0,
-	GPIO2A7_TESTCLK_OUT,
-
-	GPIO2A6_SHIFT		= 12,
-	GPIO2A6_MASK		= 1 << GPIO2A6_SHIFT,
-	GPIO2A6_GPIO		= 0,
-	GPIO2A6_NAND_CS0,
-
-	GPIO2A4_SHIFT		= 8,
-	GPIO2A4_MASK		= 3 << GPIO2A4_SHIFT,
-	GPIO2A4_GPIO		= 0,
-	GPIO2A4_NAND_RDY,
-	GPIO2A4_EMMC_CMD,
-	GPIO2A3_SFC_CLK,
-
-	GPIO2A3_SHIFT		= 6,
-	GPIO2A3_MASK		= 3 << GPIO2A3_SHIFT,
-	GPIO2A3_GPIO		= 0,
-	GPIO2A3_NAND_RDN,
-	GPIO2A4_SFC_CSN1,
-
-	GPIO2A2_SHIFT		= 4,
-	GPIO2A2_MASK		= 3 << GPIO2A2_SHIFT,
-	GPIO2A2_GPIO		= 0,
-	GPIO2A2_NAND_WRN,
-	GPIO2A4_SFC_CSN0,
-
-	GPIO2A1_SHIFT		= 2,
-	GPIO2A1_MASK		= 3 << GPIO2A1_SHIFT,
-	GPIO2A1_GPIO		= 0,
-	GPIO2A1_NAND_CLE,
-	GPIO2A1_EMMC_CLKOUT,
-
-	GPIO2A0_SHIFT		= 0,
-	GPIO2A0_MASK		= 3 << GPIO2A0_SHIFT,
-	GPIO2A0_GPIO		= 0,
-	GPIO2A0_NAND_ALE,
-	GPIO2A0_SPI_CLK,
-};
-
-/* GRF_GPIO2B_IOMUX */
-enum {
-	GPIO2B7_SHIFT		= 14,
-	GPIO2B7_MASK		= 1 << GPIO2B7_SHIFT,
-	GPIO2B7_GPIO		= 0,
-	GPIO2B7_MAC_RXER,
-
-	GPIO2B6_SHIFT		= 12,
-	GPIO2B6_MASK		= 3 << GPIO2B6_SHIFT,
-	GPIO2B6_GPIO		= 0,
-	GPIO2B6_MAC_CLKOUT,
-	GPIO2B6_MAC_CLKIN,
-
-	GPIO2B5_SHIFT		= 10,
-	GPIO2B5_MASK		= 1 << GPIO2B5_SHIFT,
-	GPIO2B5_GPIO		= 0,
-	GPIO2B5_MAC_TXEN,
-
-	GPIO2B4_SHIFT		= 8,
-	GPIO2B4_MASK		= 1 << GPIO2B4_SHIFT,
-	GPIO2B4_GPIO		= 0,
-	GPIO2B4_MAC_MDIO,
-
-	GPIO2B2_SHIFT		= 4,
-	GPIO2B2_MASK		= 1 << GPIO2B2_SHIFT,
-	GPIO2B2_GPIO		= 0,
-	GPIO2B2_MAC_CRS,
-};
-
-/* GRF_GPIO2C_IOMUX */
-enum {
-	GPIO2C7_SHIFT		= 14,
-	GPIO2C7_MASK		= 3 << GPIO2C7_SHIFT,
-	GPIO2C7_GPIO		= 0,
-	GPIO2C7_UART1_SOUT,
-	GPIO2C7_TESTCLK_OUT1,
-
-	GPIO2C6_SHIFT		= 12,
-	GPIO2C6_MASK		= 1 << GPIO2C6_SHIFT,
-	GPIO2C6_GPIO		= 0,
-	GPIO2C6_UART1_SIN,
-
-	GPIO2C5_SHIFT		= 10,
-	GPIO2C5_MASK		= 1 << GPIO2C5_SHIFT,
-	GPIO2C5_GPIO		= 0,
-	GPIO2C5_I2C2_SCL,
-
-	GPIO2C4_SHIFT		= 8,
-	GPIO2C4_MASK		= 1 << GPIO2C4_SHIFT,
-	GPIO2C4_GPIO		= 0,
-	GPIO2C4_I2C2_SDA,
-
-	GPIO2C3_SHIFT		= 6,
-	GPIO2C3_MASK		= 1 << GPIO2C3_SHIFT,
-	GPIO2C3_GPIO		= 0,
-	GPIO2C3_MAC_TXD0,
-
-	GPIO2C2_SHIFT		= 4,
-	GPIO2C2_MASK		= 1 << GPIO2C2_SHIFT,
-	GPIO2C2_GPIO		= 0,
-	GPIO2C2_MAC_TXD1,
-
-	GPIO2C1_SHIFT		= 2,
-	GPIO2C1_MASK		= 1 << GPIO2C1_SHIFT,
-	GPIO2C1_GPIO		= 0,
-	GPIO2C1_MAC_RXD0,
-
-	GPIO2C0_SHIFT		= 0,
-	GPIO2C0_MASK		= 1 << GPIO2C0_SHIFT,
-	GPIO2C0_GPIO		= 0,
-	GPIO2C0_MAC_RXD1,
-};
-
-/* GRF_GPIO2D_IOMUX */
-enum {
-	GPIO2D6_SHIFT		= 12,
-	GPIO2D6_MASK		= 1 << GPIO2D6_SHIFT,
-	GPIO2D6_GPIO		= 0,
-	GPIO2D6_I2S_SDO1,
-
-	GPIO2D5_SHIFT		= 10,
-	GPIO2D5_MASK		= 1 << GPIO2D5_SHIFT,
-	GPIO2D5_GPIO		= 0,
-	GPIO2D5_I2S_SDO2,
-
-	GPIO2D4_SHIFT		= 8,
-	GPIO2D4_MASK		= 1 << GPIO2D4_SHIFT,
-	GPIO2D4_GPIO		= 0,
-	GPIO2D4_I2S_SDO3,
-
-	GPIO2D1_SHIFT		= 2,
-	GPIO2D1_MASK		= 1 << GPIO2D1_SHIFT,
-	GPIO2D1_GPIO		= 0,
-	GPIO2D1_MAC_MDC,
-};
 #endif
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3188.h b/arch/arm/include/asm/arch-rockchip/grf_rk3188.h
index ce7bac5..905288e 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3188.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3188.h
@@ -69,386 +69,6 @@
 };
 check_member(rk3188_grf, flash_cmd_p, 0x01a4);
 
-/* GRF_GPIO0D_IOMUX */
-enum {
-	GPIO0D7_SHIFT		= 14,
-	GPIO0D7_MASK		= 1,
-	GPIO0D7_GPIO		= 0,
-	GPIO0D7_SPI1_CSN0,
-
-	GPIO0D6_SHIFT		= 12,
-	GPIO0D6_MASK		= 1,
-	GPIO0D6_GPIO		= 0,
-	GPIO0D6_SPI1_CLK,
-
-	GPIO0D5_SHIFT		= 10,
-	GPIO0D5_MASK		= 1,
-	GPIO0D5_GPIO		= 0,
-	GPIO0D5_SPI1_TXD,
-
-	GPIO0D4_SHIFT		= 8,
-	GPIO0D4_MASK		= 1,
-	GPIO0D4_GPIO		= 0,
-	GPIO0D4_SPI0_RXD,
-
-	GPIO0D3_SHIFT		= 6,
-	GPIO0D3_MASK		= 3,
-	GPIO0D3_GPIO		= 0,
-	GPIO0D3_FLASH_CSN3,
-	GPIO0D3_EMMC_RSTN_OUT,
-
-	GPIO0D2_SHIFT		= 4,
-	GPIO0D2_MASK		= 3,
-	GPIO0D2_GPIO		= 0,
-	GPIO0D2_FLASH_CSN2,
-	GPIO0D2_EMMC_CMD,
-
-	GPIO0D1_SHIFT		= 2,
-	GPIO0D1_MASK		= 1,
-	GPIO0D1_GPIO		= 0,
-	GPIO0D1_FLASH_CSN1,
-
-	GPIO0D0_SHIFT		= 0,
-	GPIO0D0_MASK		= 3,
-	GPIO0D0_GPIO		= 0,
-	GPIO0D0_FLASH_DQS,
-	GPIO0D0_EMMC_CLKOUT
-};
-
-/* GRF_GPIO1A_IOMUX */
-enum {
-	GPIO1A7_SHIFT		= 14,
-	GPIO1A7_MASK		= 3,
-	GPIO1A7_GPIO		= 0,
-	GPIO1A7_UART1_RTS_N,
-	GPIO1A7_SPI0_CSN0,
-
-	GPIO1A6_SHIFT		= 12,
-	GPIO1A6_MASK		= 3,
-	GPIO1A6_GPIO		= 0,
-	GPIO1A6_UART1_CTS_N,
-	GPIO1A6_SPI0_CLK,
-
-	GPIO1A5_SHIFT		= 10,
-	GPIO1A5_MASK		= 3,
-	GPIO1A5_GPIO		= 0,
-	GPIO1A5_UART1_SOUT,
-	GPIO1A5_SPI0_TXD,
-
-	GPIO1A4_SHIFT		= 8,
-	GPIO1A4_MASK		= 3,
-	GPIO1A4_GPIO		= 0,
-	GPIO1A4_UART1_SIN,
-	GPIO1A4_SPI0_RXD,
-
-	GPIO1A3_SHIFT		= 6,
-	GPIO1A3_MASK		= 1,
-	GPIO1A3_GPIO		= 0,
-	GPIO1A3_UART0_RTS_N,
-
-	GPIO1A2_SHIFT		= 4,
-	GPIO1A2_MASK		= 1,
-	GPIO1A2_GPIO		= 0,
-	GPIO1A2_UART0_CTS_N,
-
-	GPIO1A1_SHIFT		= 2,
-	GPIO1A1_MASK		= 1,
-	GPIO1A1_GPIO		= 0,
-	GPIO1A1_UART0_SOUT,
-
-	GPIO1A0_SHIFT		= 0,
-	GPIO1A0_MASK		= 1,
-	GPIO1A0_GPIO		= 0,
-	GPIO1A0_UART0_SIN,
-};
-
-/* GRF_GPIO1B_IOMUX */
-enum {
-	GPIO1B7_SHIFT		= 14,
-	GPIO1B7_MASK		= 1,
-	GPIO1B7_GPIO		= 0,
-	GPIO1B7_SPI0_CSN1,
-
-	GPIO1B6_SHIFT		= 12,
-	GPIO1B6_MASK		= 3,
-	GPIO1B6_GPIO		= 0,
-	GPIO1B6_SPDIF_TX,
-	GPIO1B6_SPI1_CSN1,
-
-	GPIO1B5_SHIFT		= 10,
-	GPIO1B5_MASK		= 3,
-	GPIO1B5_GPIO		= 0,
-	GPIO1B5_UART3_RTS_N,
-	GPIO1B5_RESERVED,
-
-	GPIO1B4_SHIFT		= 8,
-	GPIO1B4_MASK		= 3,
-	GPIO1B4_GPIO		= 0,
-	GPIO1B4_UART3_CTS_N,
-	GPIO1B4_GPS_RFCLK,
-
-	GPIO1B3_SHIFT		= 6,
-	GPIO1B3_MASK		= 3,
-	GPIO1B3_GPIO		= 0,
-	GPIO1B3_UART3_SOUT,
-	GPIO1B3_GPS_SIG,
-
-	GPIO1B2_SHIFT		= 4,
-	GPIO1B2_MASK		= 3,
-	GPIO1B2_GPIO		= 0,
-	GPIO1B2_UART3_SIN,
-	GPIO1B2_GPS_MAG,
-
-	GPIO1B1_SHIFT		= 2,
-	GPIO1B1_MASK		= 3,
-	GPIO1B1_GPIO		= 0,
-	GPIO1B1_UART2_SOUT,
-	GPIO1B1_JTAG_TDO,
-
-	GPIO1B0_SHIFT		= 0,
-	GPIO1B0_MASK		= 3,
-	GPIO1B0_GPIO		= 0,
-	GPIO1B0_UART2_SIN,
-	GPIO1B0_JTAG_TDI,
-};
-
-/* GRF_GPIO1D_IOMUX */
-enum {
-	GPIO1D7_SHIFT		= 14,
-	GPIO1D7_MASK		= 1,
-	GPIO1D7_GPIO		= 0,
-	GPIO1D7_I2C4_SCL,
-
-	GPIO1D6_SHIFT		= 12,
-	GPIO1D6_MASK		= 1,
-	GPIO1D6_GPIO		= 0,
-	GPIO1D6_I2C4_SDA,
-
-	GPIO1D5_SHIFT		= 10,
-	GPIO1D5_MASK		= 1,
-	GPIO1D5_GPIO		= 0,
-	GPIO1D5_I2C2_SCL,
-
-	GPIO1D4_SHIFT		= 8,
-	GPIO1D4_MASK		= 1,
-	GPIO1D4_GPIO		= 0,
-	GPIO1D4_I2C2_SDA,
-
-	GPIO1D3_SHIFT		= 6,
-	GPIO1D3_MASK		= 1,
-	GPIO1D3_GPIO		= 0,
-	GPIO1D3_I2C1_SCL,
-
-	GPIO1D2_SHIFT		= 4,
-	GPIO1D2_MASK		= 1,
-	GPIO1D2_GPIO		= 0,
-	GPIO1D2_I2C1_SDA,
-
-	GPIO1D1_SHIFT		= 2,
-	GPIO1D1_MASK		= 1,
-	GPIO1D1_GPIO		= 0,
-	GPIO1D1_I2C0_SCL,
-
-	GPIO1D0_SHIFT		= 0,
-	GPIO1D0_MASK		= 1,
-	GPIO1D0_GPIO		= 0,
-	GPIO1D0_I2C0_SDA,
-};
-
-/* GRF_GPIO3A_IOMUX */
-enum {
-	GPIO3A7_SHIFT		= 14,
-	GPIO3A7_MASK		= 1,
-	GPIO3A7_GPIO		= 0,
-	GPIO3A7_SDMMC0_DATA3,
-
-	GPIO3A6_SHIFT		= 12,
-	GPIO3A6_MASK		= 1,
-	GPIO3A6_GPIO		= 0,
-	GPIO3A6_SDMMC0_DATA2,
-
-	GPIO3A5_SHIFT		= 10,
-	GPIO3A5_MASK		= 1,
-	GPIO3A5_GPIO		= 0,
-	GPIO3A5_SDMMC0_DATA1,
-
-	GPIO3A4_SHIFT		= 8,
-	GPIO3A4_MASK		= 1,
-	GPIO3A4_GPIO		= 0,
-	GPIO3A4_SDMMC0_DATA0,
-
-	GPIO3A3_SHIFT		= 6,
-	GPIO3A3_MASK		= 1,
-	GPIO3A3_GPIO		= 0,
-	GPIO3A3_SDMMC0_CMD,
-
-	GPIO3A2_SHIFT		= 4,
-	GPIO3A2_MASK		= 1,
-	GPIO3A2_GPIO		= 0,
-	GPIO3A2_SDMMC0_CLKOUT,
-
-	GPIO3A1_SHIFT		= 2,
-	GPIO3A1_MASK		= 1,
-	GPIO3A1_GPIO		= 0,
-	GPIO3A1_SDMMC0_PWREN,
-
-	GPIO3A0_SHIFT		= 0,
-	GPIO3A0_MASK		= 1,
-	GPIO3A0_GPIO		= 0,
-	GPIO3A0_SDMMC0_RSTN,
-};
-
-/* GRF_GPIO3B_IOMUX */
-enum {
-	GPIO3B7_SHIFT		= 14,
-	GPIO3B7_MASK		= 3,
-	GPIO3B7_GPIO		= 0,
-	GPIO3B7_CIF_DATA11,
-	GPIO3B7_I2C3_SCL,
-
-	GPIO3B6_SHIFT		= 12,
-	GPIO3B6_MASK		= 3,
-	GPIO3B6_GPIO		= 0,
-	GPIO3B6_CIF_DATA10,
-	GPIO3B6_I2C3_SDA,
-
-	GPIO3B5_SHIFT		= 10,
-	GPIO3B5_MASK		= 3,
-	GPIO3B5_GPIO		= 0,
-	GPIO3B5_CIF_DATA1,
-	GPIO3B5_HSADC_DATA9,
-
-	GPIO3B4_SHIFT		= 8,
-	GPIO3B4_MASK		= 3,
-	GPIO3B4_GPIO		= 0,
-	GPIO3B4_CIF_DATA0,
-	GPIO3B4_HSADC_DATA8,
-
-	GPIO3B3_SHIFT		= 6,
-	GPIO3B3_MASK		= 1,
-	GPIO3B3_GPIO		= 0,
-	GPIO3B3_CIF_CLKOUT,
-
-	GPIO3B2_SHIFT		= 4,
-	GPIO3B2_MASK		= 1,
-	GPIO3B2_GPIO		= 0,
-	/* no muxes */
-
-	GPIO3B1_SHIFT		= 2,
-	GPIO3B1_MASK		= 1,
-	GPIO3B1_GPIO		= 0,
-	GPIO3B1_SDMMC0_WRITE_PRT,
-
-	GPIO3B0_SHIFT		= 0,
-	GPIO3B0_MASK		= 1,
-	GPIO3B0_GPIO		= 0,
-	GPIO3B0_SDMMC_DETECT_N,
-};
-
-/* GRF_GPIO3C_IOMUX */
-enum {
-	GPIO3C7_SHIFT		= 14,
-	GPIO3C7_MASK		= 3,
-	GPIO3C7_GPIO		= 0,
-	GPIO3C7_SDMMC1_WRITE_PRT,
-	GPIO3C7_RMII_CRS_DVALID,
-	GPIO3C7_RESERVED,
-
-	GPIO3C6_SHIFT		= 12,
-	GPIO3C6_MASK		= 3,
-	GPIO3C6_GPIO		= 0,
-	GPIO3C6_SDMMC1_DECTN,
-	GPIO3C6_RMII_RX_ERR,
-	GPIO3C6_RESERVED,
-
-	GPIO3C5_SHIFT		= 10,
-	GPIO3C5_MASK		= 3,
-	GPIO3C5_GPIO		= 0,
-	GPIO3C5_SDMMC1_CLKOUT,
-	GPIO3C5_RMII_CLKOUT,
-	GPIO3C5_RMII_CLKIN,
-
-	GPIO3C4_SHIFT		= 8,
-	GPIO3C4_MASK		= 3,
-	GPIO3C4_GPIO		= 0,
-	GPIO3C4_SDMMC1_DATA3,
-	GPIO3C4_RMII_RXD1,
-	GPIO3C4_RESERVED,
-
-	GPIO3C3_SHIFT		= 6,
-	GPIO3C3_MASK		= 3,
-	GPIO3C3_GPIO		= 0,
-	GPIO3C3_SDMMC1_DATA2,
-	GPIO3C3_RMII_RXD0,
-	GPIO3C3_RESERVED,
-
-	GPIO3C2_SHIFT		= 4,
-	GPIO3C2_MASK		= 3,
-	GPIO3C2_GPIO		= 0,
-	GPIO3C2_SDMMC1_DATA1,
-	GPIO3C2_RMII_TXD0,
-	GPIO3C2_RESERVED,
-
-	GPIO3C1_SHIFT		= 2,
-	GPIO3C1_MASK		= 3,
-	GPIO3C1_GPIO		= 0,
-	GPIO3C1_SDMMC1_DATA0,
-	GPIO3C1_RMII_TXD1,
-	GPIO3C1_RESERVED,
-
-	GPIO3C0_SHIFT		= 0,
-	GPIO3C0_MASK		= 3,
-	GPIO3C0_GPIO		= 0,
-	GPIO3C0_SDMMC1_CMD,
-	GPIO3C0_RMII_TX_EN,
-	GPIO3C0_RESERVED,
-};
-
-/* GRF_GPIO3D_IOMUX */
-enum {
-	GPIO3D6_SHIFT		= 12,
-	GPIO3D6_MASK		= 3,
-	GPIO3D6_GPIO		= 0,
-	GPIO3D6_PWM_3,
-	GPIO3D6_JTAG_TMS,
-	GPIO3D6_HOST_DRV_VBUS,
-
-	GPIO3D5_SHIFT		= 10,
-	GPIO3D5_MASK		= 3,
-	GPIO3D5_GPIO		= 0,
-	GPIO3D5_PWM_2,
-	GPIO3D5_JTAG_TCK,
-	GPIO3D5_OTG_DRV_VBUS,
-
-	GPIO3D4_SHIFT		= 8,
-	GPIO3D4_MASK		= 3,
-	GPIO3D4_GPIO		= 0,
-	GPIO3D4_PWM_1,
-	GPIO3D4_JTAG_TRSTN,
-
-	GPIO3D3_SHIFT		= 6,
-	GPIO3D3_MASK		= 3,
-	GPIO3D3_GPIO		= 0,
-	GPIO3D3_PWM_0,
-
-	GPIO3D2_SHIFT		= 4,
-	GPIO3D2_MASK		= 3,
-	GPIO3D2_GPIO		= 0,
-	GPIO3D2_SDMMC1_INT_N,
-
-	GPIO3D1_SHIFT		= 2,
-	GPIO3D1_MASK		= 3,
-	GPIO3D1_GPIO		= 0,
-	GPIO3D1_SDMMC1_BACKEND_PWR,
-	GPIO3D1_MII_MDCLK,
-
-	GPIO3D0_SHIFT		= 0,
-	GPIO3D0_MASK		= 3,
-	GPIO3D0_GPIO		= 0,
-	GPIO3D0_SDMMC1_PWR_EN,
-	GPIO3D0_MII_MD,
-};
-
 /* GRF_SOC_CON0 */
 enum {
 	HSADC_CLK_DIR_SHIFT	= 15,
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
index b541e2c..91e8d2d 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
@@ -324,13 +324,29 @@
 check_member(rk3399_pmusgrf_regs, slv_secure_con4, 0xe3d4);
 
 enum {
+	/* GRF_GPIO2A_IOMUX */
+	GRF_GPIO2A0_SEL_SHIFT   = 0,
+	GRF_GPIO2A0_SEL_MASK    = 3 << GRF_GPIO2A0_SEL_SHIFT,
+	GRF_I2C2_SDA            = 2,
+	GRF_GPIO2A1_SEL_SHIFT   = 2,
+	GRF_GPIO2A1_SEL_MASK    = 3 << GRF_GPIO2A1_SEL_SHIFT,
+	GRF_I2C2_SCL            = 2,
+	GRF_GPIO2A7_SEL_SHIFT   = 14,
+	GRF_GPIO2A7_SEL_MASK    = 3 << GRF_GPIO2A7_SEL_SHIFT,
+	GRF_I2C7_SDA            = 2,
+
 	/* GRF_GPIO2B_IOMUX */
-	GRF_GPIO2B1_SEL_SHIFT	= 0,
+	GRF_GPIO2B0_SEL_SHIFT   = 0,
+	GRF_GPIO2B0_SEL_MASK    = 3 << GRF_GPIO2B0_SEL_SHIFT,
+	GRF_I2C7_SCL            = 2,
+	GRF_GPIO2B1_SEL_SHIFT	= 2,
 	GRF_GPIO2B1_SEL_MASK	= 3 << GRF_GPIO2B1_SEL_SHIFT,
 	GRF_SPI2TPM_RXD		= 1,
-	GRF_GPIO2B2_SEL_SHIFT	= 2,
+	GRF_I2C6_SDA            = 2,
+	GRF_GPIO2B2_SEL_SHIFT	= 4,
 	GRF_GPIO2B2_SEL_MASK	= 3 << GRF_GPIO2B2_SEL_SHIFT,
 	GRF_SPI2TPM_TXD		= 1,
+	GRF_I2C6_SCL            = 2,
 	GRF_GPIO2B3_SEL_SHIFT	= 6,
 	GRF_GPIO2B3_SEL_MASK	= 3 << GRF_GPIO2B3_SEL_SHIFT,
 	GRF_SPI2TPM_CLK		= 1,
@@ -414,6 +430,14 @@
 	GRF_GPIO3C1_SEL_MASK	= 3 << GRF_GPIO3C1_SEL_SHIFT,
 	GRF_MAC_TXCLK           = 1,
 
+	/* GRF_GPIO4A_IOMUX */
+	GRF_GPIO4A1_SEL_SHIFT   = 2,
+	GRF_GPIO4A1_SEL_MASK    = 3 << GRF_GPIO4A1_SEL_SHIFT,
+	GRF_I2C1_SDA            = 1,
+	GRF_GPIO4A2_SEL_SHIFT   = 4,
+	GRF_GPIO4A2_SEL_MASK    = 3 << GRF_GPIO4A2_SEL_SHIFT,
+	GRF_I2C1_SCL            = 1,
+
 	/* GRF_GPIO4B_IOMUX */
 	GRF_GPIO4B0_SEL_SHIFT	= 0,
 	GRF_GPIO4B0_SEL_MASK	= 3 << GRF_GPIO4B0_SEL_SHIFT,
@@ -575,6 +599,12 @@
 	PMUGRF_GPIO1B2_SEL_SHIFT        = 4,
 	PMUGRF_GPIO1B2_SEL_MASK = 3 << PMUGRF_GPIO1B2_SEL_SHIFT,
 	PMUGRF_SPI1EC_CSN0      = 2,
+	PMUGRF_GPIO1B3_SEL_SHIFT	= 6,
+	PMUGRF_GPIO1B3_SEL_MASK	= 3 << PMUGRF_GPIO1B3_SEL_SHIFT,
+	PMUGRF_I2C4_SDA         = 1,
+	PMUGRF_GPIO1B4_SEL_SHIFT        = 8,
+	PMUGRF_GPIO1B4_SEL_MASK	= 3 << PMUGRF_GPIO1B4_SEL_SHIFT,
+	PMUGRF_I2C4_SCL	        = 1,
 	PMUGRF_GPIO1B6_SEL_SHIFT        = 12,
 	PMUGRF_GPIO1B6_SEL_MASK = 3 << PMUGRF_GPIO1B6_SEL_SHIFT,
 	PMUGRF_PWM_3B           = 1,
diff --git a/arch/arm/mach-mvebu/armada3700/cpu.c b/arch/arm/mach-mvebu/armada3700/cpu.c
index b9214f7..ab4164c 100644
--- a/arch/arm/mach-mvebu/armada3700/cpu.c
+++ b/arch/arm/mach-mvebu/armada3700/cpu.c
@@ -46,6 +46,14 @@
 			 PTE_BLOCK_NON_SHARE
 	},
 	{
+		/* PCI regions */
+		.phys = 0xe8000000UL,
+		.virt = 0xe8000000UL,
+		.size = 0x02000000UL,	/* 32MiB master PCI space */
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE
+	},
+	{
 		/* List terminator */
 		0,
 	}
diff --git a/arch/nds32/dts/ag101p.dts b/arch/nds32/dts/ag101p.dts
index 19dc36f..7832efb 100644
--- a/arch/nds32/dts/ag101p.dts
+++ b/arch/nds32/dts/ag101p.dts
@@ -67,5 +67,6 @@
 		fifo-depth = <0x10>;
 		reg = <0x98e00000 0x1000>;
 		interrupts = <5 4>;
+		cap-sd-highspeed;
 	};
 };
diff --git a/arch/nds32/include/asm/arch-ae3xx/ae3xx.h b/arch/nds32/include/asm/arch-ae3xx/ae3xx.h
index b074e84..9d55c97 100644
--- a/arch/nds32/include/asm/arch-ae3xx/ae3xx.h
+++ b/arch/nds32/include/asm/arch-ae3xx/ae3xx.h
@@ -44,8 +44,6 @@
 #define CONFIG_FTGPIO010_BASE		0xf0700000
 /* I2C */
 #define CONFIG_FTIIC010_BASE		0xf0a00000
-/* SD Controller */
-#define CONFIG_FTSDC010_BASE		0xf0e00000
 
 /* The following address was not defined in Linux */
 
diff --git a/arch/nds32/include/asm/arch-ag101/ag101.h b/arch/nds32/include/asm/arch-ag101/ag101.h
index 490f28b..0f4c3ef 100644
--- a/arch/nds32/include/asm/arch-ag101/ag101.h
+++ b/arch/nds32/include/asm/arch-ag101/ag101.h
@@ -69,8 +69,6 @@
 #define CONFIG_RESERVED_04_BASE		0x98C00000
 /* Compat Flash Controller */
 #define CONFIG_FTCFC010_BASE		0x98D00000
-/* SD Controller */
-#define CONFIG_FTSDC010_BASE		0x98E00000
 
 /* Synchronous Serial Port Controller (SSP) I2S/AC97 */
 #define CONFIG_FTSSP010_02_BASE		0x99400000
diff --git a/arch/nds32/include/asm/arch-ag102/ag102.h b/arch/nds32/include/asm/arch-ag102/ag102.h
index c5ee3d9..a8aef93 100644
--- a/arch/nds32/include/asm/arch-ag102/ag102.h
+++ b/arch/nds32/include/asm/arch-ag102/ag102.h
@@ -56,8 +56,6 @@
 #define CONFIG_FTSSP010_01_BASE		0x94100000
 /* UART1 - APB STUART Controller (UART0 in Linux) */
 #define CONFIG_FTUART010_01_BASE	0x94200000
-/* FTSDC010 SD Controller */
-#define CONFIG_FTSDC010_BASE		0x94400000
 /* APB - SSP with HDA/AC97 Controller */
 #define CONFIG_FTSSP010_02_BASE		0x94500000
 /* UART2 - APB STUART Controller (UART1 in Linux) */
diff --git a/arch/riscv/cpu/nx25/start.S b/arch/riscv/cpu/nx25/start.S
index 6a07663..cd0a663 100644
--- a/arch/riscv/cpu/nx25/start.S
+++ b/arch/riscv/cpu/nx25/start.S
@@ -45,6 +45,8 @@
 
 .global trap_entry
 handle_reset:
+	li t0, CONFIG_SYS_SDRAM_BASE
+	SREG a2, 0(t0)
 	la t0, trap_entry
 	csrw mtvec, t0
 	csrwi mstatus, 0
diff --git a/arch/riscv/dts/ae250.dts b/arch/riscv/dts/ae250.dts
index 5dc4fb0..9a38345 100644
--- a/arch/riscv/dts/ae250.dts
+++ b/arch/riscv/dts/ae250.dts
@@ -74,6 +74,7 @@
 		fifo-depth = <0x10>;
 		reg = <0xf0e00000 0x1000>;
 		interrupts = <17 4>;
+		cap-sd-highspeed;
 	};
 
 	spi: spi@f0b00000 {
diff --git a/arch/riscv/include/asm/bootm.h b/arch/riscv/include/asm/bootm.h
index 0a644bb..9a90f23 100644
--- a/arch/riscv/include/asm/bootm.h
+++ b/arch/riscv/include/asm/bootm.h
@@ -13,53 +13,4 @@
 
 #include <asm/setup.h>
 
-#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
-		defined(CONFIG_CMDLINE_TAG) || \
-		defined(CONFIG_INITRD_TAG) || \
-		defined(CONFIG_SERIAL_TAG) || \
-		defined(CONFIG_REVISION_TAG)
-# define BOOTM_ENABLE_TAGS		1
-#else
-# define BOOTM_ENABLE_TAGS		0
-#endif
-
-#ifdef CONFIG_SETUP_MEMORY_TAGS
-# define BOOTM_ENABLE_MEMORY_TAGS	1
-#else
-# define BOOTM_ENABLE_MEMORY_TAGS	0
-#endif
-
-#ifdef CONFIG_CMDLINE_TAG
- #define BOOTM_ENABLE_CMDLINE_TAG	1
-#else
- #define BOOTM_ENABLE_CMDLINE_TAG	0
-#endif
-
-#ifdef CONFIG_INITRD_TAG
- #define BOOTM_ENABLE_INITRD_TAG	1
-#else
- #define BOOTM_ENABLE_INITRD_TAG	0
-#endif
-
-#ifdef CONFIG_SERIAL_TAG
- #define BOOTM_ENABLE_SERIAL_TAG	1
-void get_board_serial(struct tag_serialnr *serialnr);
-#else
- #define BOOTM_ENABLE_SERIAL_TAG	0
-static inline void get_board_serial(struct tag_serialnr *serialnr)
-{
-}
-#endif
-
-#ifdef CONFIG_REVISION_TAG
- #define BOOTM_ENABLE_REVISION_TAG	1
-u32 get_board_rev(void);
-#else
- #define BOOTM_ENABLE_REVISION_TAG	0
-static inline u32 get_board_rev(void)
-{
-	return 0;
-}
-#endif
-
 #endif
diff --git a/arch/riscv/include/asm/encoding.h b/arch/riscv/include/asm/encoding.h
index 5ff6d59..dbf8d45 100644
--- a/arch/riscv/include/asm/encoding.h
+++ b/arch/riscv/include/asm/encoding.h
@@ -121,7 +121,9 @@
 #define PTE_SW(PTE)	((0x88888880U >> ((PTE) & 0x1F)) & 1)
 #define PTE_SX(PTE)	((0xA0A0A000U >> ((PTE) & 0x1F)) & 1)
 
-#define PTE_CHECK_PERM(PTE, SUPERVISOR, STORE, FETCH) \
+#define PTE_CHECK_PERM(_PTE, _SUPERVISOR, STORE, FETCH) \
+	typeof(_PTE) (PTE) = (_PTE); \
+	typeof(_SUPERVISOR) (SUPERVISOR) = (_SUPERVISOR); \
 	((STORE) ? ((SUPERVISOR) ? PTE_SW(PTE) : PTE_UW(PTE)) : \
 	(FETCH) ? ((SUPERVISOR) ? PTE_SX(PTE) : PTE_UX(PTE)) : \
 	((SUPERVISOR) ? PTE_SR(PTE) : PTE_UR(PTE)))
@@ -151,27 +153,31 @@
 	asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
 	__tmp; })
 
-#define write_csr(reg, val) ({ \
+#define write_csr(reg, _val) ({ \
+typeof(_val) (val) = (_val); \
 if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
 	asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
 else \
 	asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
 
-#define swap_csr(reg, val) ({ unsigned long __tmp; \
+#define swap_csr(reg, _val) ({ unsigned long __tmp; \
+typeof(_val) (val) = (_val); \
 if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
 	asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \
 else \
 	asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \
 	__tmp; })
 
-#define set_csr(reg, bit) ({ unsigned long __tmp; \
+#define set_csr(reg, _bit) ({ unsigned long __tmp; \
+typeof(_bit) (bit) = (_bit); \
 if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
 	asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
 else \
 	asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
 	__tmp; })
 
-#define clear_csr(reg, bit) ({ unsigned long __tmp; \
+#define clear_csr(reg, _bit) ({ unsigned long __tmp; \
+typeof(_bit) (bit) = (_bit); \
 if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
 	asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
 else \
diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
index 0cce98a..bd352c2 100644
--- a/arch/riscv/include/asm/global_data.h
+++ b/arch/riscv/include/asm/global_data.h
@@ -17,6 +17,6 @@
 
 #include <asm-generic/global_data.h>
 
-#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("gp")
+#define DECLARE_GLOBAL_DATA_PTR register gd_t *gd asm ("gp")
 
 #endif /* __ASM_GBL_DATA_H */
diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
index e7f63ed..1df6b1b 100644
--- a/arch/riscv/include/asm/io.h
+++ b/arch/riscv/include/asm/io.h
@@ -416,19 +416,17 @@
 #define eth_io_copy_and_sum(s, c, l, b) \
 	eth_copy_and_sum((s), __mem_pci(c), (l), (b))
 
-static inline int
-check_signature(unsigned long io_addr, const unsigned char *signature,
-		  int length)
+static inline int check_signature(ulong io_addr, const uchar *s, int len)
 {
 	int retval = 0;
 
 	do {
-		if (readb(io_addr) != *signature)
+		if (readb(io_addr) != *s)
 			goto out;
 		io_addr++;
-		signature++;
-		length--;
-	} while (length);
+		s++;
+		len--;
+	} while (len);
 	retval = 1;
 out:
 	return retval;
@@ -455,18 +453,17 @@
 	eth_copy_and_sum((a), __mem_isa(b), (c), (d))
 
 static inline int
-isa_check_signature(unsigned long io_addr, const unsigned char *signature,
-		       int length)
+isa_check_signature(ulong io_addr, const uchar *s, int len)
 {
 	int retval = 0;
 
 	do {
-		if (isa_readb(io_addr) != *signature)
+		if (isa_readb(io_addr) != *s)
 			goto out;
 		io_addr++;
-		signature++;
-		length--;
-	} while (length);
+		s++;
+		len--;
+	} while (len);
 	retval = 1;
 out:
 	return retval;
diff --git a/arch/riscv/include/asm/posix_types.h b/arch/riscv/include/asm/posix_types.h
index 6892b66..7438dbe 100644
--- a/arch/riscv/include/asm/posix_types.h
+++ b/arch/riscv/include/asm/posix_types.h
@@ -69,19 +69,23 @@
 #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
 
 #undef	__FD_SET
-#define __FD_SET(fd, fdsetp) \
+#define __FD_SET(_fd, fdsetp) \
+	typeof(_fd) (fd) = (_fd); \
 	(((fd_set *)fdsetp)->fds_bits[fd >> 5] |= (1 << (fd & 31)))
 
 #undef	__FD_CLR
-#define __FD_CLR(fd, fdsetp) \
+#define __FD_CLR(_fd, fdsetp) \
+	typeof(_fd) (fd) = (_fd); \
 	(((fd_set *)fdsetp)->fds_bits[fd >> 5] &= ~(1 << (fd & 31)))
 
 #undef	__FD_ISSET
-#define __FD_ISSET(fd, fdsetp) \
+#define __FD_ISSET(_fd, fdsetp) \
+	typeof(_fd) (fd) = (_fd); \
 	((((fd_set *)fdsetp)->fds_bits[fd >> 5] & (1 << (fd & 31))) != 0)
 
 #undef	__FD_ZERO
-#define __FD_ZERO(fdsetp) \
+#define __FD_ZERO(_fdsetp) \
+	typeof(_fdsetp) (fd) = (_fdsetp); \
 	(memset(fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
 
 #endif
diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
index 76d6869..651078f 100644
--- a/arch/riscv/include/asm/ptrace.h
+++ b/arch/riscv/include/asm/ptrace.h
@@ -65,8 +65,7 @@
 	return GET_IP(regs);
 }
 
-static inline void instruction_pointer_set(struct pt_regs *regs,
-					     unsigned long val)
+static inline void instruction_pointer_set(struct pt_regs *regs, ulong val)
 {
 	SET_IP(regs, val);
 }
@@ -82,8 +81,7 @@
 	return GET_USP(regs);
 }
 
-static inline void user_stack_pointer_set(struct pt_regs *regs,
-					     unsigned long val)
+static inline void user_stack_pointer_set(struct pt_regs *regs, ulong val)
 {
 	SET_USP(regs, val);
 }
@@ -97,8 +95,7 @@
 	return GET_FP(regs);
 }
 
-static inline void frame_pointer_set(struct pt_regs *regs,
-				       unsigned long val)
+static inline void frame_pointer_set(struct pt_regs *regs, ulong val)
 {
 	SET_FP(regs, val);
 }
diff --git a/arch/riscv/include/asm/setup.h b/arch/riscv/include/asm/setup.h
index 731b0d9..4b18243 100644
--- a/arch/riscv/include/asm/setup.h
+++ b/arch/riscv/include/asm/setup.h
@@ -145,14 +145,18 @@
 	int (*parse)(const struct tag *);
 };
 
-#define tag_member_present(tag, member)				\
+#define tag_member_present(_tag, member)				\
+	typeof(_tag) (tag) = (_tag); \
 	((unsigned long)(&((struct tag *)0L)->member + 1)	\
 		<= (tag)->hdr.size * 4)
 
-#define tag_next(t)	((struct tag *)((u32 *)(t) + (t)->hdr.size))
+#define tag_next(_t)	\
+	typeof(_t) (t) = (_t); \
+	((struct tag *)((u32 *)(t) + (t)->hdr.size))
 #define tag_size(type)	((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
 
-#define for_each_tag(t, base) \
+#define for_each_tag(_t, base) \
+	typeof(_t) (t) = (_t); \
 	for (t = base; t->hdr.size; t = tag_next(t))
 
 #ifdef __KERNEL__
diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h
index 038cdae..0fc3424 100644
--- a/arch/riscv/include/asm/string.h
+++ b/arch/riscv/include/asm/string.h
@@ -26,8 +26,11 @@
 #undef __HAVE_ARCH_MEMSET
 
 #ifdef CONFIG_MARCO_MEMSET
-#define memset(p, v, n)							\
-	({								\
+#define memset(_p, _v, _n)	\
+	(typeof(_p) (p) = (_p); \
+	 typeof(_v) (v) = (_v); \
+	 typeof(_n) (n) = (_n); \
+	 {								\
 		if ((n) != 0) {						\
 			if (__builtin_constant_p((v)) && (v) == 0)	\
 				__memzero((p), (n));			\
@@ -37,7 +40,10 @@
 		(p);							\
 	})
 
-#define memzero(p, n) ({ if ((n) != 0) __memzero((p), (n)); (p); })
+#define memzero(_p, _n) \
+	(typeof(_p) (p) = (_p); \
+	 typeof(_n) (n) = (_n); \
+	 { if ((n) != 0) __memzero((p), (n)); (p); })
 #endif
 
 #endif /* __ASM_RISCV_STRING_H */
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index 44ce38b..9242fa8 100644
--- a/arch/riscv/lib/bootm.c
+++ b/arch/riscv/lib/bootm.c
@@ -21,36 +21,12 @@
 	return 0;
 }
 
-#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
-	defined(CONFIG_CMDLINE_TAG) || \
-	defined(CONFIG_INITRD_TAG) || \
-	defined(CONFIG_SERIAL_TAG) || \
-	defined(CONFIG_REVISION_TAG)
-static void setup_start_tag(bd_t *bd);
-
-# ifdef CONFIG_SETUP_MEMORY_TAGS
-static void setup_memory_tags(bd_t *bd);
-# endif
-static void setup_commandline_tag(bd_t *bd, char *commandline);
-
-# ifdef CONFIG_INITRD_TAG
-static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end);
-# endif
-static void setup_end_tag(bd_t *bd);
-
-static struct tag *params;
-#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
-
 int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
 {
 	bd_t	*bd = gd->bd;
 	char	*s;
 	int	machid = bd->bi_arch_number;
-	void	(*theKernel)(int zero, int arch, uint params);
-
-#ifdef CONFIG_CMDLINE_TAG
-	char *commandline = env_get("bootargs");
-#endif
+	void	(*theKernel)(int arch, uint params);
 
 	/*
 	 * allow the PREP bootm subcommand, it is required for bootm to work
@@ -61,7 +37,7 @@
 	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
 		return 1;
 
-	theKernel = (void (*)(int, int, uint))images->ep;
+	theKernel = (void (*)(int, uint))images->ep;
 
 	s = env_get("machid");
 	if (s) {
@@ -82,167 +58,16 @@
 			hang();
 		}
 #endif
-	} else if (BOOTM_ENABLE_TAGS) {
-#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
-	defined(CONFIG_CMDLINE_TAG) || \
-	defined(CONFIG_INITRD_TAG) || \
-	defined(CONFIG_SERIAL_TAG) || \
-	defined(CONFIG_REVISION_TAG)
-	setup_start_tag(bd);
-#ifdef CONFIG_SERIAL_TAG
-	setup_serial_tag(&params);
-#endif
-#ifdef CONFIG_REVISION_TAG
-	setup_revision_tag(&params);
-#endif
-#ifdef CONFIG_SETUP_MEMORY_TAGS
-	setup_memory_tags(bd);
-#endif
-#ifdef CONFIG_CMDLINE_TAG
-	setup_commandline_tag(bd, commandline);
-#endif
-#ifdef CONFIG_INITRD_TAG
-	if (images->rd_start && images->rd_end)
-		setup_initrd_tag(bd, images->rd_start, images->rd_end);
-#endif
-	setup_end_tag(bd);
-#endif
+	}
 
 	/* we assume that the kernel is in place */
 	printf("\nStarting kernel ...\n\n");
 
-#ifdef CONFIG_USB_DEVICE
-	{
-		extern void udc_disconnect(void);
-		udc_disconnect();
-	}
-#endif
-	}
 	cleanup_before_linux();
 	if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
-		theKernel(0, machid, (unsigned long)images->ft_addr);
-	else
-	theKernel(0, machid, bd->bi_boot_params);
+		theKernel(machid, (unsigned long)images->ft_addr);
+
 	/* does not return */
 
 	return 1;
 }
-
-#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
-	defined(CONFIG_CMDLINE_TAG) || \
-	defined(CONFIG_INITRD_TAG) || \
-	defined(CONFIG_SERIAL_TAG) || \
-	defined(CONFIG_REVISION_TAG)
-static void setup_start_tag(bd_t *bd)
-{
-	params = (struct tag *)bd->bi_boot_params;
-
-	params->hdr.tag = ATAG_CORE;
-	params->hdr.size = tag_size(tag_core);
-
-	params->u.core.flags = 0;
-	params->u.core.pagesize = 0;
-	params->u.core.rootdev = 0;
-
-	params = tag_next(params);
-}
-
-#ifdef CONFIG_SETUP_MEMORY_TAGS
-static void setup_memory_tags(bd_t *bd)
-{
-	int i;
-
-	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
-		params->hdr.tag = ATAG_MEM;
-		params->hdr.size = tag_size(tag_mem32);
-
-		params->u.mem.start = bd->bi_dram[i].start;
-		params->u.mem.size = bd->bi_dram[i].size;
-
-		params = tag_next(params);
-	}
-}
-#endif /* CONFIG_SETUP_MEMORY_TAGS */
-
-static void setup_commandline_tag(bd_t *bd, char *commandline)
-{
-	char *p;
-
-	if (!commandline)
-		return;
-
-	/* eat leading white space */
-	for (p = commandline; *p == ' '; p++)
-		;
-
-	/* skip non-existent command lines so the kernel will still
-	 * use its default command line.
-	 */
-	if (*p == '\0')
-		return;
-
-	params->hdr.tag = ATAG_CMDLINE;
-	params->hdr.size =
-		(sizeof(struct tag_header) + strlen(p) + 1 + 4) >> 2;
-
-	strcpy(params->u.cmdline.cmdline, p)
-		;
-
-	params = tag_next(params);
-}
-
-#ifdef CONFIG_INITRD_TAG
-static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end)
-{
-	/* an ATAG_INITRD node tells the kernel where the compressed
-	 * ramdisk can be found. ATAG_RDIMG is a better name, actually.
-	 */
-	params->hdr.tag = ATAG_INITRD2;
-	params->hdr.size = tag_size(tag_initrd);
-
-	params->u.initrd.start = initrd_start;
-	params->u.initrd.size = initrd_end - initrd_start;
-
-	params = tag_next(params);
-}
-#endif /* CONFIG_INITRD_TAG */
-
-#ifdef CONFIG_SERIAL_TAG
-void setup_serial_tag(struct tag **tmp)
-{
-	struct tag *params;
-	struct tag_serialnr serialnr;
-	void get_board_serial(struct tag_serialnr *serialnr);
-
-	params = *tmp;
-	get_board_serial(&serialnr);
-	params->hdr.tag = ATAG_SERIAL;
-	params->hdr.size = tag_size(tag_serialnr);
-	params->u.serialnr.low = serialnr.low;
-	params->u.serialnr.high = serialnr.high;
-	params = tag_next(params);
-	*tmp = params;
-}
-#endif
-
-#ifdef CONFIG_REVISION_TAG
-void setup_revision_tag(struct tag **in_params)
-{
-	u32 rev;
-	u32 get_board_rev(void);
-
-	rev = get_board_rev();
-	params->hdr.tag = ATAG_REVISION;
-	params->hdr.size = tag_size(tag_revision);
-	params->u.revision.rev = rev;
-	params = tag_next(params);
-}
-#endif  /* CONFIG_REVISION_TAG */
-
-static void setup_end_tag(bd_t *bd)
-{
-	params->hdr.tag = ATAG_NONE;
-	params->hdr.size = 0;
-}
-
-#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index 075db8b..923f752 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/arch/riscv/lib/interrupts.c
@@ -63,7 +63,7 @@
 
 static void _exit_trap(int code, uint epc, struct pt_regs *regs)
 {
-	static const char *exception_code[] = {
+	static const char * const exception_code[] = {
 		"Instruction address misaligned",
 		"Instruction access fault",
 		"Illegal instruction",
diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
index 90768a9..6aba614 100644
--- a/arch/x86/include/asm/bootparam.h
+++ b/arch/x86/include/asm/bootparam.h
@@ -10,8 +10,11 @@
 #include <asm/video/edid.h>
 
 /* setup data types */
-#define SETUP_NONE			0
-#define SETUP_E820_EXT			1
+enum {
+	SETUP_NONE = 0,
+	SETUP_E820_EXT,
+	SETUP_DTB,
+};
 
 /* extensible setup data list node */
 struct setup_data {
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 2a82bc8..6af1bf4 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -14,6 +14,7 @@
  */
 
 #include <common.h>
+#include <malloc.h>
 #include <asm/acpi_table.h>
 #include <asm/io.h>
 #include <asm/ptrace.h>
@@ -25,6 +26,7 @@
 #include <asm/arch/timestamp.h>
 #endif
 #include <linux/compiler.h>
+#include <linux/libfdt.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -95,6 +97,38 @@
 	}
 }
 
+static int setup_device_tree(struct setup_header *hdr, const void *fdt_blob)
+{
+	int bootproto = get_boot_protocol(hdr);
+	struct setup_data *sd;
+	int size;
+
+	if (bootproto < 0x0209)
+		return -ENOTSUPP;
+
+	if (!fdt_blob)
+		return 0;
+
+	size = fdt_totalsize(fdt_blob);
+	if (size < 0)
+		return -EINVAL;
+
+	size += sizeof(struct setup_data);
+	sd = (struct setup_data *)malloc(size);
+	if (!sd) {
+		printf("Not enough memory for DTB setup data\n");
+		return -ENOMEM;
+	}
+
+	sd->next = hdr->setup_data;
+	sd->type = SETUP_DTB;
+	sd->len = fdt_totalsize(fdt_blob);
+	memcpy(sd->data, fdt_blob, sd->len);
+	hdr->setup_data = (unsigned long)sd;
+
+	return 0;
+}
+
 struct boot_params *load_zimage(char *image, unsigned long kernel_size,
 				ulong *load_addressp)
 {
@@ -261,6 +295,7 @@
 		hdr->acpi_rsdp_addr = acpi_get_rsdp_addr();
 #endif
 
+	setup_device_tree(hdr, (const void *)env_get_hex("fdtaddr", 0));
 	setup_video(&setup_base->screen_info);
 
 	return 0;
diff --git a/board/AndesTech/adp-ae3xx/adp-ae3xx.c b/board/AndesTech/adp-ae3xx/adp-ae3xx.c
index 8cffb6b..52a89dc 100644
--- a/board/AndesTech/adp-ae3xx/adp-ae3xx.c
+++ b/board/AndesTech/adp-ae3xx/adp-ae3xx.c
@@ -12,7 +12,6 @@
 #include <netdev.h>
 #endif
 #include <linux/io.h>
-#include <faraday/ftsdc010.h>
 #include <faraday/ftsmc020.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -75,13 +74,3 @@
 		return 0;
 	}
 }
-
-int board_mmc_init(bd_t *bis)
-{
-#ifndef CONFIG_DM_MMC
-#ifdef CONFIG_FTSDC010
-	ftsdc010_mmc_init(0);
-#endif
-#endif
-	return 0;
-}
diff --git a/board/AndesTech/adp-ag101p/adp-ag101p.c b/board/AndesTech/adp-ag101p/adp-ag101p.c
index f918c63..82928e7 100644
--- a/board/AndesTech/adp-ag101p/adp-ag101p.c
+++ b/board/AndesTech/adp-ag101p/adp-ag101p.c
@@ -14,7 +14,6 @@
 #include <asm/io.h>
 #include <asm/mach-types.h>
 
-#include <faraday/ftsdc010.h>
 #include <faraday/ftsmc020.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -82,13 +81,3 @@
 		return 0;
 	}
 }
-
-int board_mmc_init(bd_t *bis)
-{
-#ifndef CONFIG_DM_MMC
-#ifdef CONFIG_FTSDC010
-	ftsdc010_mmc_init(0);
-#endif
-#endif
-	return 0;
-}
diff --git a/board/AndesTech/nx25-ae250/nx25-ae250.c b/board/AndesTech/nx25-ae250/nx25-ae250.c
index 12f2d35..6e31be3 100644
--- a/board/AndesTech/nx25-ae250/nx25-ae250.c
+++ b/board/AndesTech/nx25-ae250/nx25-ae250.c
@@ -11,7 +11,6 @@
 #include <netdev.h>
 #endif
 #include <linux/io.h>
-#include <faraday/ftsdc010.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -66,12 +65,11 @@
 	return 0;
 }
 
-int board_mmc_init(bd_t *bis)
+void *board_fdt_blob_setup(void)
 {
-#ifndef CONFIG_DM_MMC
-#ifdef CONFIG_FTSDC010
-	ftsdc010_mmc_init(0);
-#endif
-#endif
-	return 0;
+	void **ptr = (void *)CONFIG_SYS_SDRAM_BASE;
+	if (fdt_magic(*ptr) == FDT_MAGIC)
+			return (void *)*ptr;
+
+	return (void *)CONFIG_SYS_FDT_BASE;
 }
diff --git a/board/Marvell/mvebu_armada-37xx/board.c b/board/Marvell/mvebu_armada-37xx/board.c
index ac3e3a3..e205396 100644
--- a/board/Marvell/mvebu_armada-37xx/board.c
+++ b/board/Marvell/mvebu_armada-37xx/board.c
@@ -50,29 +50,6 @@
 
 int board_early_init_f(void)
 {
-	const void *blob = gd->fdt_blob;
-	const char *bank_name;
-	const char *compat = "marvell,armada-3700-pinctl";
-	int off, len;
-	void __iomem *addr;
-
-	/* FIXME
-	 * Temporary WA for setting correct pin control values
-	 * until the real pin control driver is awailable.
-	 */
-	off = fdt_node_offset_by_compatible(blob, -1, compat);
-	while (off != -FDT_ERR_NOTFOUND) {
-		bank_name = fdt_getprop(blob, off, "bank-name", &len);
-		addr = (void __iomem *)fdtdec_get_addr_size_auto_noparent(
-				blob, off, "reg", 0, NULL, true);
-		if (!strncmp(bank_name, "armada-3700-nb", len))
-			writel(PINCTRL_NB_REG_VALUE, addr);
-		else if (!strncmp(bank_name, "armada-3700-sb", len))
-			writel(PINCTRL_SB_REG_VALUE, addr);
-
-		off = fdt_node_offset_by_compatible(blob, off, compat);
-	}
-
 	return 0;
 }
 
diff --git a/common/image.c b/common/image.c
index f5278a0..e1c50eb 100644
--- a/common/image.c
+++ b/common/image.c
@@ -86,6 +86,7 @@
 	{	IH_ARCH_ARC,		"arc",		"ARC",		},
 	{	IH_ARCH_X86_64,		"x86_64",	"AMD x86_64",	},
 	{	IH_ARCH_XTENSA,		"xtensa",	"Xtensa",	},
+	{	IH_ARCH_RISCV,		"riscv",	"RISC-V",	},
 	{	-1,			"",		"",		},
 };
 
diff --git a/configs/adp-ae3xx_defconfig b/configs/adp-ae3xx_defconfig
index f3eabea..af17718 100644
--- a/configs/adp-ae3xx_defconfig
+++ b/configs/adp-ae3xx_defconfig
@@ -24,8 +24,8 @@
 CONFIG_CLK=y
 CONFIG_MMC=y
 CONFIG_DM_MMC=y
-CONFIG_MMC_NDS32=y
 CONFIG_FTSDC010=y
+CONFIG_FTSDC010_SDIO=y
 CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_CFI_FLASH=y
diff --git a/configs/adp-ag101p_defconfig b/configs/adp-ag101p_defconfig
index 742d904..481ef5b 100644
--- a/configs/adp-ag101p_defconfig
+++ b/configs/adp-ag101p_defconfig
@@ -21,8 +21,8 @@
 CONFIG_DM=y
 CONFIG_MMC=y
 CONFIG_DM_MMC=y
-CONFIG_MMC_NDS32=y
 CONFIG_FTSDC010=y
+CONFIG_FTSDC010_SDIO=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_DM_ETH=y
 CONFIG_FTMAC100=y
diff --git a/configs/clearfog_defconfig b/configs/clearfog_defconfig
index 2359ad2..ff954c7 100644
--- a/configs/clearfog_defconfig
+++ b/configs/clearfog_defconfig
@@ -30,6 +30,7 @@
 CONFIG_CMD_TIME=y
 # CONFIG_SPL_PARTITION_UUIDS is not set
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
diff --git a/configs/mvebu_db-88f3720_defconfig b/configs/mvebu_db-88f3720_defconfig
index 1d6233a..980c0df 100644
--- a/configs/mvebu_db-88f3720_defconfig
+++ b/configs/mvebu_db-88f3720_defconfig
@@ -17,6 +17,7 @@
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_USB=y
@@ -44,6 +45,10 @@
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PHYLIB=y
 CONFIG_PHY_GIGE=y
+CONFIG_E1000=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_AARDVARK=y
 CONFIG_MVEBU_COMPHY_SUPPORT=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_ARMADA_37XX=y
diff --git a/configs/mvebu_espressobin-88f3720_defconfig b/configs/mvebu_espressobin-88f3720_defconfig
index 314d405..aedb83a 100644
--- a/configs/mvebu_espressobin-88f3720_defconfig
+++ b/configs/mvebu_espressobin-88f3720_defconfig
@@ -14,8 +14,10 @@
 CONFIG_ARCH_EARLY_INIT_R=y
 CONFIG_BOARD_EARLY_INIT_F=y
 # CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_USB=y
@@ -29,6 +31,7 @@
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_SCSI_AHCI=y
 CONFIG_BLOCK_CACHE=y
+CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_MISC=y
 CONFIG_DM_MMC=y
@@ -42,7 +45,13 @@
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_PHYLIB=y
 CONFIG_PHY_GIGE=y
+CONFIG_E1000=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_AARDVARK=y
 CONFIG_MVEBU_COMPHY_SUPPORT=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_ARMADA_37XX=y
 # CONFIG_SPL_SERIAL_PRESENT is not set
 CONFIG_DEBUG_MVEBU_A3700_UART=y
 CONFIG_DEBUG_UART_BASE=0xd0012000
diff --git a/configs/nx25-ae250_defconfig b/configs/nx25-ae250_defconfig
index 47b83db..4f9bd58 100644
--- a/configs/nx25-ae250_defconfig
+++ b/configs/nx25-ae250_defconfig
@@ -16,14 +16,15 @@
 CONFIG_CMD_EXT2=y
 CONFIG_CMD_FAT=y
 CONFIG_OF_CONTROL=y
+CONFIG_OF_BOARD=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_MMC=y
 CONFIG_DM_MMC=y
-CONFIG_MMC_NDS32=y
 CONFIG_FTSDC010=y
+CONFIG_FTSDC010_SDIO=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
diff --git a/configs/puma-rk3399_defconfig b/configs/puma-rk3399_defconfig
index a8b4bac..32aa72c 100644
--- a/configs/puma-rk3399_defconfig
+++ b/configs/puma-rk3399_defconfig
@@ -56,6 +56,7 @@
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
diff --git a/doc/README.ae250 b/doc/README.ae250
index a80bb39..77c168a 100644
--- a/doc/README.ae250
+++ b/doc/README.ae250
@@ -49,8 +49,8 @@
 5. Burn this u-boot image to spi rom by spi driver
 6. Re-boot u-boot from spi flash with power off and power on.
 
-Messages
-====================
+Messages of U-Boot boot on AE250 board
+======================================
 U-Boot 2018.01-rc2-00033-g824f89a (Dec 21 2017 - 16:51:26 +0800)
 
 DRAM:  1 GiB
@@ -131,7 +131,145 @@
 eth0: mac@e0100000
 RISC-V #
 
-TODO
-====================
+
+Boot bbl and riscv-linux via U-Boot on QEMU
+===========================================
+1. Build riscv-linux
+2. Build bbl and riscv-linux with --with-payload
+3. Prepare ae250.dtb
+4. Creating OS-kernel images
+	./mkimage -A riscv -O linux -T kernel -C none -a 0x0000 -e 0x0000 -d bbl.bin bootmImage-bbl.bin
+	Image Name:
+	Created:      Tue Mar 13 10:06:42 2018
+	Image Type:   RISC-V Linux Kernel Image (uncompressed)
+	Data Size:    17901204 Bytes = 17481.64 KiB = 17.07 MiB
+	Load Address: 00000000
+	Entry Point:  00000000
+
+4. Copy bootmImage-bbl.bin and ae250.dtb to qemu sd card image
+5. Message of booting riscv-linux from bbl via u-boot on qemu
 
-Boot bbl and riscv-linux
+U-Boot 2018.03-rc4-00031-g2631273 (Mar 13 2018 - 15:02:55 +0800)
+
+DRAM:  1 GiB
+main-loop: WARNING: I/O thread spun for 1000 iterations
+MMC:   mmc@f0e00000: 0
+Loading Environment from SPI Flash... *** Warning - spi_flash_probe_bus_cs() failed, using default environment
+
+Failed (-22)
+In:    serial@f0300000
+Out:   serial@f0300000
+Err:   serial@f0300000
+Net:
+Warning: mac@e0100000 (eth0) using random MAC address - 02:00:00:00:00:00
+eth0: mac@e0100000
+RISC-V # mmc rescan
+RISC-V # mmc part
+
+Partition Map for MMC device 0  --   Partition Type: DOS
+
+Part    Start Sector    Num Sectors     UUID            Type
+RISC-V # fatls mmc 0:0
+ 17901268   bootmImage-bbl.bin
+     1954   ae2xx.dtb
+
+2 file(s), 0 dir(s)
+
+RISC-V # fatload mmc 0:0 0x00600000 bootmImage-bbl.bin
+17901268 bytes read in 4642 ms (3.7 MiB/s)
+RISC-V # fatload mmc 0:0 0x2000000 ae250.dtb
+1954 bytes read in 1 ms (1.9 MiB/s)
+RISC-V # setenv bootm_size 0x2000000
+RISC-V # setenv fdt_high 0x1f00000
+RISC-V # bootm 0x00600000 - 0x2000000
+## Booting kernel from Legacy Image at 00600000 ...
+   Image Name:
+   Image Type:   RISC-V Linux Kernel Image (uncompressed)
+   Data Size:    17901204 Bytes = 17.1 MiB
+   Load Address: 00000000
+   Entry Point:  00000000
+   Verifying Checksum ... OK
+## Flattened Device Tree blob at 02000000
+   Booting using the fdt blob at 0x2000000
+   Loading Kernel Image ... OK
+   Loading Device Tree to 0000000001efc000, end 0000000001eff7a1 ... OK
+[    0.000000] OF: fdt: Ignoring memory range 0x0 - 0x200000
+[    0.000000] Linux version 4.14.0-00046-gf3e439f-dirty (rick@atcsqa06) (gcc version 7.1.1 20170509 (GCC)) #1 Tue Jan 9 16:34:25 CST 2018
+[    0.000000] bootconsole [early0] enabled
+[    0.000000] Initial ramdisk at: 0xffffffe000016a98 (12267008 bytes)
+[    0.000000] Zone ranges:
+[    0.000000]   DMA      [mem 0x0000000000200000-0x000000007fffffff]
+[    0.000000]   Normal   empty
+[    0.000000] Movable zone start for each node
+[    0.000000] Early memory node ranges
+[    0.000000]   node   0: [mem 0x0000000000200000-0x000000007fffffff]
+[    0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x000000007fffffff]
+[    0.000000] elf_hwcap is 0x112d
+[    0.000000] random: fast init done
+[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 516615
+[    0.000000] Kernel command line: console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0xf0300000 debug loglevel=7
+[    0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
+[    0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
+[    0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
+[    0.000000] Sorting __ex_table...
+[    0.000000] Memory: 2047832K/2095104K available (1856K kernel code, 204K rwdata, 532K rodata, 12076K init, 756K bss, 47272K reserved, 0K cma-reserved)
+[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
+[    0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
+[    0.000000] riscv,cpu_intc,0: 64 local interrupts mapped
+[    0.000000] riscv,plic0,e4000000: mapped 31 interrupts to 1/2 handlers
+[    0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x24e6a1710, max_idle_ns: 440795202120 ns
+[    0.000000] Calibrating delay loop (skipped), value calculated using timer frequency.. 20.00 BogoMIPS (lpj=40000)
+[    0.000000] pid_max: default: 32768 minimum: 301
+[    0.004000] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes)
+[    0.004000] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes)
+[    0.056000] devtmpfs: initialized
+[    0.060000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
+[    0.064000] futex hash table entries: 256 (order: 0, 6144 bytes)
+[    0.068000] NET: Registered protocol family 16
+[    0.080000] vgaarb: loaded
+[    0.084000] clocksource: Switched to clocksource riscv_clocksource
+[    0.088000] NET: Registered protocol family 2
+[    0.092000] TCP established hash table entries: 16384 (order: 5, 131072 bytes)
+[    0.096000] TCP bind hash table entries: 16384 (order: 5, 131072 bytes)
+[    0.096000] TCP: Hash tables configured (established 16384 bind 16384)
+[    0.100000] UDP hash table entries: 1024 (order: 3, 32768 bytes)
+[    0.100000] UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes)
+[    0.104000] NET: Registered protocol family 1
+[    0.616000] Unpacking initramfs...
+[    1.220000] workingset: timestamp_bits=62 max_order=19 bucket_order=0
+[    1.244000] io scheduler noop registered
+[    1.244000] io scheduler cfq registered (default)
+[    1.244000] io scheduler mq-deadline registered
+[    1.248000] io scheduler kyber registered
+[    1.360000] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
+[    1.368000] console [ttyS0] disabled
+[    1.372000] f0300000.serial: ttyS0 at MMIO 0xf0300020 (irq = 10, base_baud = 1228800) is a 16550A
+[    1.392000] console [ttyS0] enabled
+[    1.392000] ftmac100: Loading version 0.2 ...
+[    1.396000] ftmac100 e0100000.mac eth0: irq 8, mapped at ffffffd002005000
+[    1.400000] ftmac100 e0100000.mac eth0: generated random MAC address 6e:ac:c3:92:36:c0
+[    1.404000] IR NEC protocol handler initialized
+[    1.404000] IR RC5(x/sz) protocol handler initialized
+[    1.404000] IR RC6 protocol handler initialized
+[    1.404000] IR JVC protocol handler initialized
+[    1.408000] IR Sony protocol handler initialized
+[    1.408000] IR SANYO protocol handler initialized
+[    1.408000] IR Sharp protocol handler initialized
+[    1.408000] IR MCE Keyboard/mouse protocol handler initialized
+[    1.412000] IR XMP protocol handler initialized
+[    1.456000] ftsdc010 f0e00000.mmc: mmc0 - using hw SDIO IRQ
+[    1.464000] bootconsole [early0] uses init memory and must be disabled even before the real one is ready
+[    1.464000] bootconsole [early0] disabled
+[    1.508000] Freeing unused kernel memory: 12076K
+[    1.512000] This architecture does not have kernel memory protection.
+[    1.520000] mmc0: new SD card at address 4567
+[    1.524000] mmcblk0: mmc0:4567 QEMU! 20.0 MiB
+[    1.844000]  mmcblk0:
+Wed Dec  1 10:00:00 CST 2010
+/ #
+
+
+
+TODO
+==================================================
+Boot bbl and riscv-linux via U-Boot on AE250 board
diff --git a/doc/device-tree-bindings/pinctrl/marvell,armada-37xx-pinctrl.txt b/doc/device-tree-bindings/pinctrl/marvell,armada-37xx-pinctrl.txt
new file mode 100644
index 0000000..86ec113
--- /dev/null
+++ b/doc/device-tree-bindings/pinctrl/marvell,armada-37xx-pinctrl.txt
@@ -0,0 +1,186 @@
+* Marvell Armada 37xx SoC pin and GPIO controller
+
+Each Armada 37xx SoC comes with two pin and GPIO controllers, one for the
+South Bridge and the other for the North Bridge.
+
+GPIO and pin controller:
+------------------------
+
+Main node:
+
+Refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning
+of the phrase "pin configuration node".
+
+Required properties for pinctrl driver:
+
+- compatible:	"marvell,armada3710-sb-pinctrl", "syscon, "simple-mfd"
+		for the South Bridge
+		"marvell,armada3710-nb-pinctrl", "syscon, "simple-mfd"
+		for the North Bridge
+- reg: The first set of registers is for pinctrl/GPIO and the second
+  set is for the interrupt controller
+- interrupts: list of interrupts used by the GPIO
+
+Available groups and functions for the North Bridge:
+
+group: jtag
+ - pins 20-24
+ - functions jtag, gpio
+
+group sdio0
+ - pins 8-10
+ - functions sdio, gpio
+
+group emmc_nb
+ - pins 27-35
+ - functions emmc, gpio
+
+group pwm0
+ - pin 11 (GPIO1-11)
+ - functions pwm, gpio
+
+group pwm1
+ - pin 12
+ - functions pwm, gpio
+
+group pwm2
+ - pin 13
+ - functions pwm, gpio
+
+group pwm3
+ - pin 14
+ - functions pwm, gpio
+
+group pmic1
+ - pin 7
+ - functions pmic, gpio
+
+group pmic0
+ - pin 6
+ - functions pmic, gpio
+
+group i2c2
+ - pins 2-3
+ - functions i2c, gpio
+
+group i2c1
+ - pins 0-1
+ - functions i2c, gpio
+
+group spi_cs1
+ - pin 17
+ - functions spi, gpio
+
+group spi_cs2
+ - pin 18
+ - functions spi, gpio
+
+group spi_cs3
+ - pin 19
+ - functions spi, gpio
+
+group onewire
+ - pin 4
+ - functions onewire, gpio
+
+group uart1
+ - pins 25-26
+ - functions uart, gpio
+
+group spi_quad
+ - pins 15-16
+ - functions spi, gpio
+
+group uart_2
+ - pins 9-10
+ - functions uart, gpio
+
+Available groups and functions for the South Bridge:
+
+group usb32_drvvbus0
+ - pin 36
+ - functions drvbus, gpio
+
+group usb2_drvvbus1
+ - pin 37
+ - functions drvbus, gpio
+
+group sdio_sb
+ - pins 60-65
+ - functions sdio, gpio
+
+group rgmii
+ - pins 42-53
+ - functions mii, gpio
+
+group pcie1
+ - pins 39-41
+ - functions pcie, gpio
+
+group smi
+ - pins 54-55
+ - functions smi, gpio
+
+group ptp
+ - pins 56-58
+ - functions ptp, gpio
+
+group ptp_clk
+ - pin 57
+ - functions ptp, mii
+
+group ptp_trig
+ - pin 58
+ - functions ptp, mii
+
+group mii_col
+ - pin 59
+ - functions mii, mii_err
+
+GPIO subnode:
+
+Please refer to gpio.txt in "gpio" directory for details of gpio-ranges property
+and the common GPIO bindings used by client devices.
+
+Required properties for the GPIO driver under the gpio subnode:
+- interrupts: List of interrupt specifiers for the controllers interrupt.
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells: Should be 2. The first cell is the GPIO number and the
+   second cell specifies GPIO flags, as defined in
+   <dt-bindings/gpio/gpio.h>. Only the GPIO_ACTIVE_HIGH and
+   GPIO_ACTIVE_LOW flags are supported.
+- gpio-ranges: Range of pins managed by the GPIO controller.
+
+Example:
+pinctrl_sb: pinctrl-sb@18800 {
+	compatible = "marvell,armada3710-sb-pinctrl",
+	"syscon", "simple-mfd";
+	reg = <0x18800 0x100>, <0x18C00 0x20>;
+	gpiosb: gpiosb {
+		#gpio-cells = <2>;
+		gpio-ranges = <&pinctrl_sb 0 0 30>;
+		gpio-controller;
+		interrupts =
+		<GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
+		<GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>,
+		<GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
+		<GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+		<GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	rgmii_pins: mii-pins {
+		groups = "rgmii";
+		function = "mii";
+	};
+
+	sdio_pins: sdio-pins {
+		groups = "sdio_sb";
+		function = "sdio";
+	};
+
+	pcie_pins: pcie-pins {
+		groups = "pcie1";
+		function = "pcie";
+	};
+};
\ No newline at end of file
diff --git a/drivers/clk/rockchip/clk_rk3188.c b/drivers/clk/rockchip/clk_rk3188.c
index ad8df5a..cfe6abe 100644
--- a/drivers/clk/rockchip/clk_rk3188.c
+++ b/drivers/clk/rockchip/clk_rk3188.c
@@ -123,7 +123,7 @@
 			       unsigned int hz, bool has_bwadj)
 {
 	static const struct pll_div dpll_cfg[] = {
-		{.nf = 25, .nr = 2, .no = 1},
+		{.nf = 75, .nr = 1, .no = 6},
 		{.nf = 400, .nr = 9, .no = 2},
 		{.nf = 500, .nr = 9, .no = 2},
 		{.nf = 100, .nr = 3, .no = 1},
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 5f67e33..3a79cbf 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -523,18 +523,18 @@
 	  If you have a board based on such a SoC and with a SD/MMC slot,
 	  say Y or M here.
 
-config MMC_NDS32
-	bool "Andestech SD/MMC controller support"
-	depends on DM_MMC && OF_CONTROL && BLK && FTSDC010
-	help
-	  This enables support for the Andestech SD/MMM controller, which is
-	  based on Faraday IP.
-
 config FTSDC010
 	bool "Ftsdc010 SD/MMC controller Support"
 	help
 	  This SD/MMC controller is present in Andestech SoCs which is based on Faraday IP.
 
+config FTSDC010_SDIO
+	bool "Support ftsdc010 sdio"
+	default n
+	depends on FTSDC010
+	help
+		This can enable ftsdc010 sdio function.
+
 endif
 
 config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 42113e2..9583410 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -42,7 +42,6 @@
 obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
 obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
 obj-$(CONFIG_STM32_SDMMC2) += stm32_sdmmc2.o
-obj-$(CONFIG_MMC_NDS32) += nds32_mmc.o
 
 # SDHCI
 obj-$(CONFIG_MMC_SDHCI)			+= sdhci.o
diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c
index 6ac4f83..9de3a15 100644
--- a/drivers/mmc/ftsdc010_mci.c
+++ b/drivers/mmc/ftsdc010_mci.c
@@ -4,23 +4,63 @@
  * (C) Copyright 2010 Faraday Technology
  * Dante Su <dantesu@faraday-tech.com>
  *
+ * Copyright 2018 Andes Technology, Inc.
+ * Author: Rick Chen (rick@andestech.com)
+ *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
 #include <common.h>
+#include <clk.h>
 #include <malloc.h>
 #include <part.h>
 #include <mmc.h>
-
 #include <linux/io.h>
 #include <linux/errno.h>
 #include <asm/byteorder.h>
 #include <faraday/ftsdc010.h>
 #include "ftsdc010_mci.h"
+#include <dm.h>
+#include <dt-structs.h>
+#include <errno.h>
+#include <mapmem.h>
+#include <pwrseq.h>
+#include <syscon.h>
+#include <linux/err.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 #define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 4) /* 250 ms */
 #define CFG_RST_TIMEOUT CONFIG_SYS_HZ /* 1 sec reset timeout */
 
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+struct ftsdc010 {
+	fdt32_t		bus_width;
+	bool		cap_mmc_highspeed;
+	bool		cap_sd_highspeed;
+	fdt32_t		clock_freq_min_max[2];
+	struct phandle_2_cell	clocks[4];
+	fdt32_t		fifo_depth;
+	fdt32_t		reg[2];
+};
+#endif
+
+struct ftsdc010_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct ftsdc010 dtplat;
+#endif
+	struct mmc_config cfg;
+	struct mmc mmc;
+};
+
+struct ftsdc_priv {
+	struct clk clk;
+	struct ftsdc010_chip chip;
+	int fifo_depth;
+	bool fifo_mode;
+	u32 minmax[2];
+};
+
 static inline int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
 {
 	struct ftsdc010_chip *chip = mmc->priv;
@@ -138,16 +178,10 @@
 /*
  * u-boot mmc api
  */
-#ifdef CONFIG_DM_MMC
 static int ftsdc010_request(struct udevice *dev, struct mmc_cmd *cmd,
 	struct mmc_data *data)
 {
 	struct mmc *mmc = mmc_get_mmc_dev(dev);
-#else
-static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd,
-	struct mmc_data *data)
-{
-#endif
 	int ret = -EOPNOTSUPP;
 	uint32_t len = 0;
 	struct ftsdc010_chip *chip = mmc->priv;
@@ -248,14 +282,9 @@
 	return ret;
 }
 
-#ifdef CONFIG_DM_MMC
 static int ftsdc010_set_ios(struct udevice *dev)
 {
 	struct mmc *mmc = mmc_get_mmc_dev(dev);
-#else
-static int ftsdc010_set_ios(struct mmc *mmc)
-{
-#endif
 	struct ftsdc010_chip *chip = mmc->priv;
 	struct ftsdc010_mmc __iomem *regs = chip->regs;
 
@@ -277,27 +306,17 @@
 	return 0;
 }
 
-#ifdef CONFIG_DM_MMC
 static int ftsdc010_get_cd(struct udevice *dev)
 {
 	struct mmc *mmc = mmc_get_mmc_dev(dev);
-#else
-static int ftsdc010_get_cd(struct mmc *mmc)
-{
-#endif
 	struct ftsdc010_chip *chip = mmc->priv;
 	struct ftsdc010_mmc __iomem *regs = chip->regs;
 	return !(readl(&regs->status) & FTSDC010_STATUS_CARD_DETECT);
 }
 
-#ifdef CONFIG_DM_MMC
 static int ftsdc010_get_wp(struct udevice *dev)
 {
 	struct mmc *mmc = mmc_get_mmc_dev(dev);
-#else
-static int ftsdc010_get_wp(struct mmc *mmc)
-{
-#endif
 	struct ftsdc010_chip *chip = mmc->priv;
 	struct ftsdc010_mmc __iomem *regs = chip->regs;
 	if (readl(&regs->status) & FTSDC010_STATUS_WRITE_PROT) {
@@ -337,31 +356,20 @@
 	return 0;
 }
 
-#ifdef CONFIG_DM_MMC
-int ftsdc010_probe(struct udevice *dev)
+static int ftsdc010_probe(struct udevice *dev)
 {
 	struct mmc *mmc = mmc_get_mmc_dev(dev);
 	return ftsdc010_init(mmc);
 }
 
-const struct dm_mmc_ops dm_ftsdc010_ops = {
+const struct dm_mmc_ops dm_ftsdc010_mmc_ops = {
 	.send_cmd	= ftsdc010_request,
 	.set_ios	= ftsdc010_set_ios,
 	.get_cd		= ftsdc010_get_cd,
 	.get_wp		= ftsdc010_get_wp,
 };
-
-#else
-static const struct mmc_ops ftsdc010_ops = {
-	.send_cmd	= ftsdc010_request,
-	.set_ios	= ftsdc010_set_ios,
-	.getcd		= ftsdc010_get_cd,
-	.getwp		= ftsdc010_get_wp,
-	.init		= ftsdc010_init,
-};
-#endif
 
-void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
+static void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
 		     uint caps, u32 max_clk, u32 min_clk)
 {
 	cfg->name = name;
@@ -380,73 +388,94 @@
 	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 }
 
-void set_bus_width(struct ftsdc010_mmc __iomem *regs, struct mmc_config *cfg)
+static int ftsdc010_mmc_ofdata_to_platdata(struct udevice *dev)
 {
-	switch (readl(&regs->bwr) & FTSDC010_BWR_CAPS_MASK) {
-	case FTSDC010_BWR_CAPS_4BIT:
-		cfg->host_caps |= MMC_MODE_4BIT;
-		break;
-	case FTSDC010_BWR_CAPS_8BIT:
-		cfg->host_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
-		break;
-	default:
-		break;
-	}
-}
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct ftsdc_priv *priv = dev_get_priv(dev);
+	struct ftsdc010_chip *chip = &priv->chip;
+	chip->name = dev->name;
+	chip->ioaddr = (void *)devfdt_get_addr(dev);
+	chip->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+					"bus-width", 4);
+	chip->priv = dev;
+	priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+				    "fifo-depth", 0);
+	priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
+					  "fifo-mode");
+	if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
+			 "clock-freq-min-max", priv->minmax, 2)) {
+		int val = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+				  "max-frequency", -EINVAL);
+		if (val < 0)
+			return val;
 
-#ifdef CONFIG_BLK
-int ftsdc010_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg)
-{
-	return mmc_bind(dev, mmc, cfg);
+		priv->minmax[0] = 400000;  /* 400 kHz */
+		priv->minmax[1] = val;
+	} else {
+		debug("%s: 'clock-freq-min-max' property was deprecated.\n",
+		__func__);
+	}
+#endif
+	chip->sclk = priv->minmax[1];
+	chip->regs = chip->ioaddr;
+	return 0;
 }
-#else
 
-int ftsdc010_mmc_init(int devid)
+static int ftsdc010_mmc_probe(struct udevice *dev)
 {
-	struct mmc *mmc;
-	struct ftsdc010_chip *chip;
-	struct ftsdc010_mmc __iomem *regs;
-#ifdef CONFIG_FTSDC010_BASE_LIST
-	uint32_t base_list[] = CONFIG_FTSDC010_BASE_LIST;
+	struct ftsdc010_plat *plat = dev_get_platdata(dev);
+	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+	struct ftsdc_priv *priv = dev_get_priv(dev);
+	struct ftsdc010_chip *chip = &priv->chip;
+	struct udevice *pwr_dev __maybe_unused;
 
-	if (devid < 0 || devid >= ARRAY_SIZE(base_list))
-		return -1;
-	regs = (void __iomem *)base_list[devid];
-#else
-	regs = (void __iomem *)(CONFIG_FTSDC010_BASE + (devid << 20));
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	int ret;
+	struct ftsdc010 *dtplat = &plat->dtplat;
+	chip->name = dev->name;
+	chip->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
+	chip->buswidth = dtplat->bus_width;
+	chip->priv = dev;
+	chip->dev_index = 1;
+	memcpy(priv->minmax, dtplat->clock_freq_min_max, sizeof(priv->minmax));
+	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+	if (ret < 0)
+		return ret;
 #endif
 
-	chip = malloc(sizeof(struct ftsdc010_chip));
-	if (!chip)
-		return -ENOMEM;
-	memset(chip, 0, sizeof(struct ftsdc010_chip));
+	if (dev_read_bool(dev, "cap-mmc-highspeed") || \
+		  dev_read_bool(dev, "cap-sd-highspeed"))
+		chip->caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
 
-	chip->regs = regs;
-#ifdef CONFIG_SYS_CLK_FREQ
-	chip->sclk = CONFIG_SYS_CLK_FREQ;
-#else
-	chip->sclk = clk_get_rate("SDC");
-#endif
+	ftsdc_setup_cfg(&plat->cfg, dev->name, chip->buswidth, chip->caps,
+			priv->minmax[1] , priv->minmax[0]);
+	chip->mmc = &plat->mmc;
+	chip->mmc->priv = &priv->chip;
+	chip->mmc->dev = dev;
+	upriv->mmc = chip->mmc;
+	return ftsdc010_probe(dev);
+}
 
-	chip->cfg.name = "ftsdc010";
-#ifndef CONFIG_DM_MMC
-	chip->cfg.ops = &ftsdc010_ops;
-#endif
-	chip->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz;
-	set_bus_width(regs , &chip->cfg);
-	chip->cfg.voltages  = MMC_VDD_32_33 | MMC_VDD_33_34;
-	chip->cfg.f_max     = chip->sclk / 2;
-	chip->cfg.f_min     = chip->sclk / 0x100;
+int ftsdc010_mmc_bind(struct udevice *dev)
+{
+	struct ftsdc010_plat *plat = dev_get_platdata(dev);
 
-	chip->cfg.part_type = PART_TYPE_DOS;
-	chip->cfg.b_max	    = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+	return mmc_bind(dev, &plat->mmc, &plat->cfg);
+}
 
-	mmc = mmc_create(&chip->cfg, chip);
-	if (mmc == NULL) {
-		free(chip);
-		return -ENOMEM;
-	}
+static const struct udevice_id ftsdc010_mmc_ids[] = {
+	{ .compatible = "andestech,atsdc010" },
+	{ }
+};
 
-	return 0;
-}
-#endif
+U_BOOT_DRIVER(ftsdc010_mmc) = {
+	.name		= "ftsdc010_mmc",
+	.id		= UCLASS_MMC,
+	.of_match	= ftsdc010_mmc_ids,
+	.ofdata_to_platdata = ftsdc010_mmc_ofdata_to_platdata,
+	.ops		= &dm_ftsdc010_mmc_ops,
+	.bind		= ftsdc010_mmc_bind,
+	.probe		= ftsdc010_mmc_probe,
+	.priv_auto_alloc_size = sizeof(struct ftsdc_priv),
+	.platdata_auto_alloc_size = sizeof(struct ftsdc010_plat),
+};
diff --git a/drivers/mmc/ftsdc010_mci.h b/drivers/mmc/ftsdc010_mci.h
index 31a27fd..e417360 100644
--- a/drivers/mmc/ftsdc010_mci.h
+++ b/drivers/mmc/ftsdc010_mci.h
@@ -35,19 +35,4 @@
 	bool fifo_mode;
 };
 
-
-#ifdef CONFIG_DM_MMC
-/* Export the operations to drivers */
-int ftsdc010_probe(struct udevice *dev);
-extern const struct dm_mmc_ops dm_ftsdc010_ops;
-#endif
-void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
-		     uint caps, u32 max_clk, u32 min_clk);
-void set_bus_width(struct ftsdc010_mmc __iomem *regs, struct mmc_config *cfg);
-
-#ifdef CONFIG_BLK
-int ftsdc010_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
-#endif
-
-
 #endif /* __FTSDC010_MCI_H */
diff --git a/drivers/mmc/nds32_mmc.c b/drivers/mmc/nds32_mmc.c
deleted file mode 100644
index 6d3c857..0000000
--- a/drivers/mmc/nds32_mmc.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Andestech ATFSDC010 SD/MMC driver
- *
- * (C) Copyright 2017
- * Rick Chen, NDS32 Software Engineering, rick@andestech.com
-
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <clk.h>
-#include <dm.h>
-#include <dt-structs.h>
-#include <errno.h>
-#include <mapmem.h>
-#include <mmc.h>
-#include <pwrseq.h>
-#include <syscon.h>
-#include <linux/err.h>
-#include <faraday/ftsdc010.h>
-#include "ftsdc010_mci.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
-struct nds_mmc {
-	fdt32_t		bus_width;
-	bool		cap_mmc_highspeed;
-	bool		cap_sd_highspeed;
-	fdt32_t		clock_freq_min_max[2];
-	struct phandle_2_cell	clocks[4];
-	fdt32_t		fifo_depth;
-	fdt32_t		reg[2];
-};
-#endif
-
-struct nds_mmc_plat {
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
-	struct nds_mmc dtplat;
-#endif
-	struct mmc_config cfg;
-	struct mmc mmc;
-};
-
-struct ftsdc_priv {
-	struct clk clk;
-	struct ftsdc010_chip chip;
-	int fifo_depth;
-	bool fifo_mode;
-	u32 minmax[2];
-};
-
-static int nds32_mmc_ofdata_to_platdata(struct udevice *dev)
-{
-#if !CONFIG_IS_ENABLED(OF_PLATDATA)
-	struct ftsdc_priv *priv = dev_get_priv(dev);
-	struct ftsdc010_chip *chip = &priv->chip;
-	chip->name = dev->name;
-	chip->ioaddr = (void *)devfdt_get_addr(dev);
-	chip->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-					"bus-width", 4);
-	chip->priv = dev;
-	priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-				    "fifo-depth", 0);
-	priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
-					  "fifo-mode");
-	if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
-			 "clock-freq-min-max", priv->minmax, 2)) {
-		int val = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-				  "max-frequency", -EINVAL);
-		if (val < 0)
-			return val;
-
-		priv->minmax[0] = 400000;  /* 400 kHz */
-		priv->minmax[1] = val;
-	} else {
-		debug("%s: 'clock-freq-min-max' property was deprecated.\n",
-		__func__);
-	}
-#endif
-	chip->sclk = priv->minmax[1];
-	chip->regs = chip->ioaddr;
-	return 0;
-}
-
-static int nds32_mmc_probe(struct udevice *dev)
-{
-	struct nds_mmc_plat *plat = dev_get_platdata(dev);
-	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
-	struct ftsdc_priv *priv = dev_get_priv(dev);
-	struct ftsdc010_chip *chip = &priv->chip;
-	struct udevice *pwr_dev __maybe_unused;
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
-	int ret;
-	struct nds_mmc *dtplat = &plat->dtplat;
-	chip->name = dev->name;
-	chip->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
-	chip->buswidth = dtplat->bus_width;
-	chip->priv = dev;
-	chip->dev_index = 1;
-	memcpy(priv->minmax, dtplat->clock_freq_min_max, sizeof(priv->minmax));
-	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
-	if (ret < 0)
-		return ret;
-#endif
-	ftsdc_setup_cfg(&plat->cfg, dev->name, chip->buswidth, chip->caps,
-			priv->minmax[1] , priv->minmax[0]);
-	chip->mmc = &plat->mmc;
-	chip->mmc->priv = &priv->chip;
-	chip->mmc->dev = dev;
-	upriv->mmc = chip->mmc;
-	return ftsdc010_probe(dev);
-}
-
-static int nds32_mmc_bind(struct udevice *dev)
-{
-	struct nds_mmc_plat *plat = dev_get_platdata(dev);
-	return ftsdc010_bind(dev, &plat->mmc, &plat->cfg);
-}
-
-static const struct udevice_id nds32_mmc_ids[] = {
-	{ .compatible = "andestech,atsdc010" },
-	{ }
-};
-
-U_BOOT_DRIVER(nds32_mmc_drv) = {
-	.name		= "nds32_mmc",
-	.id		= UCLASS_MMC,
-	.of_match	= nds32_mmc_ids,
-	.ofdata_to_platdata = nds32_mmc_ofdata_to_platdata,
-	.ops		= &dm_ftsdc010_ops,
-	.bind		= nds32_mmc_bind,
-	.probe		= nds32_mmc_probe,
-	.priv_auto_alloc_size = sizeof(struct ftsdc_priv),
-	.platdata_auto_alloc_size = sizeof(struct nds_mmc_plat),
-};
diff --git a/drivers/mmc/pci_mmc.c b/drivers/mmc/pci_mmc.c
index 05c0044..b7a2ebf 100644
--- a/drivers/mmc/pci_mmc.c
+++ b/drivers/mmc/pci_mmc.c
@@ -29,11 +29,10 @@
 	struct pci_mmc_plat *plat = dev_get_platdata(dev);
 	struct pci_mmc_priv *priv = dev_get_priv(dev);
 	struct sdhci_host *host = &priv->host;
-	u32 ioaddr;
 	int ret;
 
-	dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, &ioaddr);
-	host->ioaddr = map_sysmem(ioaddr, 0);
+	host->ioaddr = (void *)dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
+					      PCI_REGION_MEM);
 	host->name = dev->name;
 	ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0);
 	if (ret)
diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index be6edb2..ab89be4 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -62,6 +62,13 @@
 
 	host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD;
 	host->max_clk = max_frequency;
+	/*
+	 * The sdhci-driver only supports 4bit and 8bit, as sdhci_setup_cfg
+	 * doesn't allow us to clear MMC_MODE_4BIT.  Consequently, we don't
+	 * check for other bus-width values.
+	 */
+	if (host->bus_width == 8)
+		host->host_caps |= MMC_MODE_8BIT;
 
 	ret = sdhci_setup_cfg(&plat->cfg, host, 0, EMMC_MIN_FREQ);
 
@@ -82,6 +89,7 @@
 
 	host->name = dev->name;
 	host->ioaddr = dev_read_addr_ptr(dev);
+	host->bus_width = dev_read_u32_default(dev, "bus-width", 4);
 #endif
 
 	return 0;
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index da6421f..c20a0cc 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -26,6 +26,16 @@
 	  measure when porting a board to use driver model for PCI. Once the
 	  board is fully supported, this option should be disabled.
 
+config PCI_AARDVARK
+	bool "Enable Aardvark PCIe driver"
+	default n
+	depends on DM_PCI
+	depends on ARMADA_3700
+	help
+	  Say Y here if you want to enable PCIe controller support on
+	  Armada37x0 SoCs. The PCIe controller on Armada37x0 is based on
+	  Aardvark hardware.
+
 config PCI_PNP
 	bool "Enable Plug & Play support for PCI"
 	depends on PCI || DM_PCI
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 8fbab46..40ebc06 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -30,6 +30,7 @@
 obj-$(CONFIG_SH7751_PCI) +=pci_sh7751.o
 obj-$(CONFIG_SH7780_PCI) +=pci_sh7780.o
 obj-$(CONFIG_PCI_TEGRA) += pci_tegra.o
+obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
 obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o
 obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o
 obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape_fixup.o
diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c
new file mode 100644
index 0000000..69a4d81
--- /dev/null
+++ b/drivers/pci/pci-aardvark.c
@@ -0,0 +1,690 @@
+/*
+ * ***************************************************************************
+ * Copyright (C) 2015 Marvell International Ltd.
+ * ***************************************************************************
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 2 of the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * ***************************************************************************
+ */
+/* pcie_advk.c
+ *
+ * Ported from Linux driver - driver/pci/host/pci-aardvark.c
+ *
+ * Author: Victor Gu <xigu@marvell.com>
+ *         Hezi Shahmoon <hezi.shahmoon@marvell.com>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <pci.h>
+#include <asm/io.h>
+#include <asm-generic/gpio.h>
+#include <linux/ioport.h>
+
+/* PCIe core registers */
+#define PCIE_CORE_CMD_STATUS_REG				0x4
+#define     PCIE_CORE_CMD_IO_ACCESS_EN				BIT(0)
+#define     PCIE_CORE_CMD_MEM_ACCESS_EN				BIT(1)
+#define     PCIE_CORE_CMD_MEM_IO_REQ_EN				BIT(2)
+#define PCIE_CORE_DEV_CTRL_STATS_REG				0xc8
+#define     PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE	(0 << 4)
+#define     PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE		(0 << 11)
+#define PCIE_CORE_LINK_CTRL_STAT_REG				0xd0
+#define     PCIE_CORE_LINK_TRAINING				BIT(5)
+#define PCIE_CORE_ERR_CAPCTL_REG				0x118
+#define     PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX			BIT(5)
+#define     PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN			BIT(6)
+#define     PCIE_CORE_ERR_CAPCTL_ECRC_CHECK			BIT(7)
+#define     PCIE_CORE_ERR_CAPCTL_ECRC_CHECK_RCV			BIT(8)
+
+/* PIO registers base address and register offsets */
+#define PIO_BASE_ADDR				0x4000
+#define PIO_CTRL				(PIO_BASE_ADDR + 0x0)
+#define   PIO_CTRL_TYPE_MASK			GENMASK(3, 0)
+#define   PIO_CTRL_ADDR_WIN_DISABLE		BIT(24)
+#define PIO_STAT				(PIO_BASE_ADDR + 0x4)
+#define   PIO_COMPLETION_STATUS_SHIFT		7
+#define   PIO_COMPLETION_STATUS_MASK		GENMASK(9, 7)
+#define   PIO_COMPLETION_STATUS_OK		0
+#define   PIO_COMPLETION_STATUS_UR		1
+#define   PIO_COMPLETION_STATUS_CRS		2
+#define   PIO_COMPLETION_STATUS_CA		4
+#define   PIO_NON_POSTED_REQ			BIT(10)
+#define   PIO_ERR_STATUS			BIT(11)
+#define PIO_ADDR_LS				(PIO_BASE_ADDR + 0x8)
+#define PIO_ADDR_MS				(PIO_BASE_ADDR + 0xc)
+#define PIO_WR_DATA				(PIO_BASE_ADDR + 0x10)
+#define PIO_WR_DATA_STRB			(PIO_BASE_ADDR + 0x14)
+#define PIO_RD_DATA				(PIO_BASE_ADDR + 0x18)
+#define PIO_START				(PIO_BASE_ADDR + 0x1c)
+#define PIO_ISR					(PIO_BASE_ADDR + 0x20)
+
+/* Aardvark Control registers */
+#define CONTROL_BASE_ADDR			0x4800
+#define PCIE_CORE_CTRL0_REG			(CONTROL_BASE_ADDR + 0x0)
+#define     PCIE_GEN_SEL_MSK			0x3
+#define     PCIE_GEN_SEL_SHIFT			0x0
+#define     SPEED_GEN_1				0
+#define     SPEED_GEN_2				1
+#define     SPEED_GEN_3				2
+#define     IS_RC_MSK				1
+#define     IS_RC_SHIFT				2
+#define     LANE_CNT_MSK			0x18
+#define     LANE_CNT_SHIFT			0x3
+#define     LANE_COUNT_1			(0 << LANE_CNT_SHIFT)
+#define     LANE_COUNT_2			(1 << LANE_CNT_SHIFT)
+#define     LANE_COUNT_4			(2 << LANE_CNT_SHIFT)
+#define     LANE_COUNT_8			(3 << LANE_CNT_SHIFT)
+#define     LINK_TRAINING_EN			BIT(6)
+#define PCIE_CORE_CTRL2_REG			(CONTROL_BASE_ADDR + 0x8)
+#define     PCIE_CORE_CTRL2_RESERVED		0x7
+#define     PCIE_CORE_CTRL2_TD_ENABLE		BIT(4)
+#define     PCIE_CORE_CTRL2_STRICT_ORDER_ENABLE	BIT(5)
+#define     PCIE_CORE_CTRL2_ADDRWIN_MAP_ENABLE	BIT(6)
+
+/* LMI registers base address and register offsets */
+#define LMI_BASE_ADDR				0x6000
+#define CFG_REG					(LMI_BASE_ADDR + 0x0)
+#define     LTSSM_SHIFT				24
+#define     LTSSM_MASK				0x3f
+#define     LTSSM_L0				0x10
+
+/* PCIe core controller registers */
+#define CTRL_CORE_BASE_ADDR			0x18000
+#define CTRL_CONFIG_REG				(CTRL_CORE_BASE_ADDR + 0x0)
+#define     CTRL_MODE_SHIFT			0x0
+#define     CTRL_MODE_MASK			0x1
+#define     PCIE_CORE_MODE_DIRECT		0x0
+#define     PCIE_CORE_MODE_COMMAND		0x1
+
+/* Transaction types */
+#define PCIE_CONFIG_RD_TYPE0			0x8
+#define PCIE_CONFIG_RD_TYPE1			0x9
+#define PCIE_CONFIG_WR_TYPE0			0xa
+#define PCIE_CONFIG_WR_TYPE1			0xb
+
+/* PCI_BDF shifts 8bit, so we need extra 4bit shift */
+#define PCIE_BDF(dev)				(dev << 4)
+#define PCIE_CONF_BUS(bus)			(((bus) & 0xff) << 20)
+#define PCIE_CONF_DEV(dev)			(((dev) & 0x1f) << 15)
+#define PCIE_CONF_FUNC(fun)			(((fun) & 0x7)	<< 12)
+#define PCIE_CONF_REG(reg)			((reg) & 0xffc)
+#define PCIE_CONF_ADDR(bus, devfn, where)	\
+	(PCIE_CONF_BUS(bus) | PCIE_CONF_DEV(PCI_SLOT(devfn))	| \
+	 PCIE_CONF_FUNC(PCI_FUNC(devfn)) | PCIE_CONF_REG(where))
+
+/* PCIe Retries & Timeout definitions */
+#define MAX_RETRIES				10
+#define PIO_WAIT_TIMEOUT			100
+#define LINK_WAIT_TIMEOUT			100000
+
+#define CFG_RD_UR_VAL			0xFFFFFFFF
+#define CFG_RD_CRS_VAL			0xFFFF0001
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * struct pcie_advk - Advk PCIe controller state
+ *
+ * @reg_base:    The base address of the register space.
+ * @first_busno: This driver supports multiple PCIe controllers.
+ *               first_busno stores the bus number of the PCIe root-port
+ *               number which may vary depending on the PCIe setup
+ *               (PEX switches etc).
+ * @device:      The pointer to PCI uclass device.
+ */
+struct pcie_advk {
+	void           *base;
+	int            first_busno;
+	struct udevice *dev;
+};
+
+static inline void advk_writel(struct pcie_advk *pcie, uint val, uint reg)
+{
+	writel(val, pcie->base + reg);
+}
+
+static inline uint advk_readl(struct pcie_advk *pcie, uint reg)
+{
+	return readl(pcie->base + reg);
+}
+
+/**
+ * pcie_advk_addr_valid() - Check for valid bus address
+ *
+ * @bdf: The PCI device to access
+ * @first_busno: Bus number of the PCIe controller root complex
+ *
+ * Return: 1 on valid, 0 on invalid
+ */
+static int pcie_advk_addr_valid(pci_dev_t bdf, int first_busno)
+{
+	/*
+	 * In PCIE-E only a single device (0) can exist
+	 * on the local bus. Beyound the local bus, there might be
+	 * a Switch and everything is possible.
+	 */
+	if ((PCI_BUS(bdf) == first_busno) && (PCI_DEV(bdf) > 0))
+		return 0;
+
+	return 1;
+}
+
+/**
+ * pcie_advk_wait_pio() - Wait for PIO access to be accomplished
+ *
+ * @pcie: The PCI device to access
+ *
+ * Wait up to 1 micro second for PIO access to be accomplished.
+ *
+ * Return 1 (true) if PIO access is accomplished.
+ * Return 0 (false) if PIO access is timed out.
+ */
+static int pcie_advk_wait_pio(struct pcie_advk *pcie)
+{
+	uint start, isr;
+	uint count;
+
+	for (count = 0; count < MAX_RETRIES; count++) {
+		start = advk_readl(pcie, PIO_START);
+		isr = advk_readl(pcie, PIO_ISR);
+		if (!start && isr)
+			return 1;
+		/*
+		 * Do not check the PIO state too frequently,
+		 * 100us delay is appropriate.
+		 */
+		udelay(PIO_WAIT_TIMEOUT);
+	}
+
+	dev_err(pcie->dev, "config read/write timed out\n");
+	return 0;
+}
+
+/**
+ * pcie_advk_check_pio_status() - Validate PIO status and get the read result
+ *
+ * @pcie: Pointer to the PCI bus
+ * @read: Read from or write to configuration space - true(read) false(write)
+ * @read_val: Pointer to the read result, only valid when read is true
+ *
+ */
+static int pcie_advk_check_pio_status(struct pcie_advk *pcie,
+				      bool read,
+				      uint *read_val)
+{
+	uint reg;
+	unsigned int status;
+	char *strcomp_status, *str_posted;
+
+	reg = advk_readl(pcie, PIO_STAT);
+	status = (reg & PIO_COMPLETION_STATUS_MASK) >>
+		PIO_COMPLETION_STATUS_SHIFT;
+
+	switch (status) {
+	case PIO_COMPLETION_STATUS_OK:
+		if (reg & PIO_ERR_STATUS) {
+			strcomp_status = "COMP_ERR";
+			break;
+		}
+		/* Get the read result */
+		if (read)
+			*read_val = advk_readl(pcie, PIO_RD_DATA);
+		/* No error */
+		strcomp_status = NULL;
+		break;
+	case PIO_COMPLETION_STATUS_UR:
+		if (read) {
+			/* For reading, UR is not an error status. */
+			*read_val = CFG_RD_UR_VAL;
+			strcomp_status = NULL;
+		} else {
+			strcomp_status = "UR";
+		}
+		break;
+	case PIO_COMPLETION_STATUS_CRS:
+		if (read) {
+			/* For reading, CRS is not an error status. */
+			*read_val = CFG_RD_CRS_VAL;
+			strcomp_status = NULL;
+		} else {
+			strcomp_status = "CRS";
+		}
+		break;
+	case PIO_COMPLETION_STATUS_CA:
+		strcomp_status = "CA";
+		break;
+	default:
+		strcomp_status = "Unknown";
+		break;
+	}
+
+	if (!strcomp_status)
+		return 0;
+
+	if (reg & PIO_NON_POSTED_REQ)
+		str_posted = "Non-posted";
+	else
+		str_posted = "Posted";
+
+	dev_err(pcie->dev, "%s PIO Response Status: %s, %#x @ %#x\n",
+		str_posted, strcomp_status, reg,
+		advk_readl(pcie, PIO_ADDR_LS));
+
+	return -EFAULT;
+}
+
+/**
+ * pcie_advk_read_config() - Read from configuration space
+ *
+ * @bus: Pointer to the PCI bus
+ * @bdf: Identifies the PCIe device to access
+ * @offset: The offset into the device's configuration space
+ * @valuep: A pointer at which to store the read value
+ * @size: Indicates the size of access to perform
+ *
+ * Read a value of size @size from offset @offset within the configuration
+ * space of the device identified by the bus, device & function numbers in @bdf
+ * on the PCI bus @bus.
+ *
+ * Return: 0 on success
+ */
+static int pcie_advk_read_config(struct udevice *bus, pci_dev_t bdf,
+				 uint offset, ulong *valuep,
+				 enum pci_size_t size)
+{
+	struct pcie_advk *pcie = dev_get_priv(bus);
+	uint reg;
+	int ret;
+
+	dev_dbg(pcie->dev, "PCIE CFG read:  (b,d,f)=(%2d,%2d,%2d) ",
+		PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
+
+	if (!pcie_advk_addr_valid(bdf, pcie->first_busno)) {
+		dev_dbg(pcie->dev, "- out of range\n");
+		*valuep = pci_get_ff(size);
+		return 0;
+	}
+
+	/* Start PIO */
+	advk_writel(pcie, 0, PIO_START);
+	advk_writel(pcie, 1, PIO_ISR);
+
+	/* Program the control register */
+	reg = advk_readl(pcie, PIO_CTRL);
+	reg &= ~PIO_CTRL_TYPE_MASK;
+	if (PCI_BUS(bdf) == pcie->first_busno)
+		reg |= PCIE_CONFIG_RD_TYPE0;
+	else
+		reg |= PCIE_CONFIG_RD_TYPE1;
+	advk_writel(pcie, reg, PIO_CTRL);
+
+	/* Program the address registers */
+	reg = PCIE_BDF(bdf) | PCIE_CONF_REG(offset);
+	advk_writel(pcie, reg, PIO_ADDR_LS);
+	advk_writel(pcie, 0, PIO_ADDR_MS);
+
+	/* Start the transfer */
+	advk_writel(pcie, 1, PIO_START);
+
+	if (!pcie_advk_wait_pio(pcie))
+		return -EINVAL;
+
+	/* Check PIO status and get the read result */
+	ret = pcie_advk_check_pio_status(pcie, true, &reg);
+	if (ret)
+		return ret;
+
+	dev_dbg(pcie->dev, "(addr,size,val)=(0x%04x, %d, 0x%08x)\n",
+		offset, size, reg);
+	*valuep = pci_conv_32_to_size(reg, offset, size);
+
+	return 0;
+}
+
+/**
+ * pcie_calc_datastrobe() - Calculate data strobe
+ *
+ * @offset: The offset into the device's configuration space
+ * @size: Indicates the size of access to perform
+ *
+ * Calculate data strobe according to offset and size
+ *
+ */
+static uint pcie_calc_datastrobe(uint offset, enum pci_size_t size)
+{
+	uint bytes, data_strobe;
+
+	switch (size) {
+	case PCI_SIZE_8:
+		bytes = 1;
+		break;
+	case PCI_SIZE_16:
+		bytes = 2;
+		break;
+	default:
+		bytes = 4;
+	}
+
+	data_strobe = GENMASK(bytes - 1, 0) << (offset & 0x3);
+
+	return data_strobe;
+}
+
+/**
+ * pcie_advk_write_config() - Write to configuration space
+ *
+ * @bus: Pointer to the PCI bus
+ * @bdf: Identifies the PCIe device to access
+ * @offset: The offset into the device's configuration space
+ * @value: The value to write
+ * @size: Indicates the size of access to perform
+ *
+ * Write the value @value of size @size from offset @offset within the
+ * configuration space of the device identified by the bus, device & function
+ * numbers in @bdf on the PCI bus @bus.
+ *
+ * Return: 0 on success
+ */
+static int pcie_advk_write_config(struct udevice *bus, pci_dev_t bdf,
+				  uint offset, ulong value,
+				  enum pci_size_t size)
+{
+	struct pcie_advk *pcie = dev_get_priv(bus);
+	uint reg;
+
+	dev_dbg(pcie->dev, "PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ",
+		PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
+	dev_dbg(pcie->dev, "(addr,size,val)=(0x%04x, %d, 0x%08lx)\n",
+		offset, size, value);
+
+	if (!pcie_advk_addr_valid(bdf, pcie->first_busno)) {
+		dev_dbg(pcie->dev, "- out of range\n");
+		return 0;
+	}
+
+	/* Start PIO */
+	advk_writel(pcie, 0, PIO_START);
+	advk_writel(pcie, 1, PIO_ISR);
+
+	/* Program the control register */
+	reg = advk_readl(pcie, PIO_CTRL);
+	reg &= ~PIO_CTRL_TYPE_MASK;
+	if (PCI_BUS(bdf) == pcie->first_busno)
+		reg |= PCIE_CONFIG_WR_TYPE0;
+	else
+		reg |= PCIE_CONFIG_WR_TYPE1;
+	advk_writel(pcie, reg, PIO_CTRL);
+
+	/* Program the address registers */
+	reg = PCIE_BDF(bdf) | PCIE_CONF_REG(offset);
+	advk_writel(pcie, reg, PIO_ADDR_LS);
+	advk_writel(pcie, 0, PIO_ADDR_MS);
+	dev_dbg(pcie->dev, "\tPIO req. - addr = 0x%08x\n", reg);
+
+	/* Program the data register */
+	reg = pci_conv_size_to_32(0, value, offset, size);
+	advk_writel(pcie, reg, PIO_WR_DATA);
+	dev_dbg(pcie->dev, "\tPIO req. - val  = 0x%08x\n", reg);
+
+	/* Program the data strobe */
+	reg = pcie_calc_datastrobe(offset, size);
+	advk_writel(pcie, reg, PIO_WR_DATA_STRB);
+	dev_dbg(pcie->dev, "\tPIO req. - strb = 0x%02x\n", reg);
+
+	/* Start the transfer */
+	advk_writel(pcie, 1, PIO_START);
+
+	if (!pcie_advk_wait_pio(pcie)) {
+		dev_dbg(pcie->dev, "- wait pio timeout\n");
+		return -EINVAL;
+	}
+
+	/* Check PIO status */
+	pcie_advk_check_pio_status(pcie, false, &reg);
+
+	return 0;
+}
+
+/**
+ * pcie_advk_link_up() - Check if PCIe link is up or not
+ *
+ * @pcie: The PCI device to access
+ *
+ * Return 1 (true) on link up.
+ * Return 0 (false) on link down.
+ */
+static int pcie_advk_link_up(struct pcie_advk *pcie)
+{
+	u32 val, ltssm_state;
+
+	val = advk_readl(pcie, CFG_REG);
+	ltssm_state = (val >> LTSSM_SHIFT) & LTSSM_MASK;
+	return ltssm_state >= LTSSM_L0;
+}
+
+/**
+ * pcie_advk_wait_for_link() - Wait for link training to be accomplished
+ *
+ * @pcie: The PCI device to access
+ *
+ * Wait up to 1 second for link training to be accomplished.
+ *
+ * Return 1 (true) if link training ends up with link up success.
+ * Return 0 (false) if link training ends up with link up failure.
+ */
+static int pcie_advk_wait_for_link(struct pcie_advk *pcie)
+{
+	int retries;
+
+	/* check if the link is up or not */
+	for (retries = 0; retries < MAX_RETRIES; retries++) {
+		if (pcie_advk_link_up(pcie)) {
+			printf("PCIE-%d: Link up\n", pcie->first_busno);
+			return 0;
+		}
+
+		udelay(LINK_WAIT_TIMEOUT);
+	}
+
+	printf("PCIE-%d: Link down\n", pcie->first_busno);
+
+	return -ETIMEDOUT;
+}
+
+/**
+ * pcie_advk_setup_hw() - PCIe initailzation
+ *
+ * @pcie: The PCI device to access
+ *
+ * Return: 0 on success
+ */
+static int pcie_advk_setup_hw(struct pcie_advk *pcie)
+{
+	u32 reg;
+
+	/* Set to Direct mode */
+	reg = advk_readl(pcie, CTRL_CONFIG_REG);
+	reg &= ~(CTRL_MODE_MASK << CTRL_MODE_SHIFT);
+	reg |= ((PCIE_CORE_MODE_DIRECT & CTRL_MODE_MASK) << CTRL_MODE_SHIFT);
+	advk_writel(pcie, reg, CTRL_CONFIG_REG);
+
+	/* Set PCI global control register to RC mode */
+	reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
+	reg |= (IS_RC_MSK << IS_RC_SHIFT);
+	advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
+
+	/* Set Advanced Error Capabilities and Control PF0 register */
+	reg = PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX |
+		PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN |
+		PCIE_CORE_ERR_CAPCTL_ECRC_CHECK |
+		PCIE_CORE_ERR_CAPCTL_ECRC_CHECK_RCV;
+	advk_writel(pcie, reg, PCIE_CORE_ERR_CAPCTL_REG);
+
+	/* Set PCIe Device Control and Status 1 PF0 register */
+	reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE |
+		PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE;
+	advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG);
+
+	/* Program PCIe Control 2 to disable strict ordering */
+	reg = PCIE_CORE_CTRL2_RESERVED |
+		PCIE_CORE_CTRL2_TD_ENABLE;
+	advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG);
+
+	/* Set GEN2 */
+	reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
+	reg &= ~PCIE_GEN_SEL_MSK;
+	reg |= SPEED_GEN_2;
+	advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
+
+	/* Set lane X1 */
+	reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
+	reg &= ~LANE_CNT_MSK;
+	reg |= LANE_COUNT_1;
+	advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
+
+	/* Enable link training */
+	reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
+	reg |= LINK_TRAINING_EN;
+	advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
+
+	/*
+	 * Enable AXI address window location generation:
+	 * When it is enabled, the default outbound window
+	 * configurations (Default User Field: 0xD0074CFC)
+	 * are used to transparent address translation for
+	 * the outbound transactions. Thus, PCIe address
+	 * windows are not required.
+	 */
+	reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG);
+	reg |= PCIE_CORE_CTRL2_ADDRWIN_MAP_ENABLE;
+	advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG);
+
+	/*
+	 * Bypass the address window mapping for PIO:
+	 * Since PIO access already contains all required
+	 * info over AXI interface by PIO registers, the
+	 * address window is not required.
+	 */
+	reg = advk_readl(pcie, PIO_CTRL);
+	reg |= PIO_CTRL_ADDR_WIN_DISABLE;
+	advk_writel(pcie, reg, PIO_CTRL);
+
+	/* Start link training */
+	reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG);
+	reg |= PCIE_CORE_LINK_TRAINING;
+	advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG);
+
+	/* Wait for PCIe link up */
+	if (pcie_advk_wait_for_link(pcie))
+		return -ENXIO;
+
+	reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG);
+	reg |= PCIE_CORE_CMD_MEM_ACCESS_EN |
+		PCIE_CORE_CMD_IO_ACCESS_EN |
+		PCIE_CORE_CMD_MEM_IO_REQ_EN;
+	advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG);
+
+	return 0;
+}
+
+/**
+ * pcie_advk_probe() - Probe the PCIe bus for active link
+ *
+ * @dev: A pointer to the device being operated on
+ *
+ * Probe for an active link on the PCIe bus and configure the controller
+ * to enable this port.
+ *
+ * Return: 0 on success, else -ENODEV
+ */
+static int pcie_advk_probe(struct udevice *dev)
+{
+	struct pcie_advk *pcie = dev_get_priv(dev);
+
+#ifdef CONFIG_DM_GPIO
+	struct gpio_desc reset_gpio;
+
+	gpio_request_by_name(dev, "reset-gpio", 0, &reset_gpio,
+			     GPIOD_IS_OUT);
+	/*
+	 * Issue reset to add-in card through the dedicated GPIO.
+	 * Some boards are connecting the card reset pin to common system
+	 * reset wire and others are using separate GPIO port.
+	 * In the last case we have to release a reset of the addon card
+	 * using this GPIO.
+	 *
+	 * FIX-ME:
+	 *     The PCIe RESET signal is not supposed to be released along
+	 *     with the SOC RESET signal. It should be lowered as early as
+	 *     possible before PCIe PHY initialization. Moreover, the PCIe
+	 *     clock should be gated as well.
+	 */
+	if (dm_gpio_is_valid(&reset_gpio)) {
+		dev_dbg(pcie->dev, "Toggle PCIE Reset GPIO ...\n");
+		dm_gpio_set_value(&reset_gpio, 0);
+		mdelay(200);
+		dm_gpio_set_value(&reset_gpio, 1);
+	}
+#else
+	dev_dbg(pcie->dev, "PCIE Reset on GPIO support is missing\n");
+#endif /* CONFIG_DM_GPIO */
+
+	pcie->first_busno = dev->seq;
+	pcie->dev = pci_get_controller(dev);
+
+	return pcie_advk_setup_hw(pcie);
+}
+
+/**
+ * pcie_advk_ofdata_to_platdata() - Translate from DT to device state
+ *
+ * @dev: A pointer to the device being operated on
+ *
+ * Translate relevant data from the device tree pertaining to device @dev into
+ * state that the driver will later make use of. This state is stored in the
+ * device's private data structure.
+ *
+ * Return: 0 on success, else -EINVAL
+ */
+static int pcie_advk_ofdata_to_platdata(struct udevice *dev)
+{
+	struct pcie_advk *pcie = dev_get_priv(dev);
+
+	/* Get the register base address */
+	pcie->base = (void *)dev_read_addr_index(dev, 0);
+	if ((fdt_addr_t)pcie->base == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	return 0;
+}
+
+static const struct dm_pci_ops pcie_advk_ops = {
+	.read_config	= pcie_advk_read_config,
+	.write_config	= pcie_advk_write_config,
+};
+
+static const struct udevice_id pcie_advk_ids[] = {
+	{ .compatible = "marvell,armada-37xx-pcie" },
+	{ }
+};
+
+U_BOOT_DRIVER(pcie_advk) = {
+	.name			= "pcie_advk",
+	.id			= UCLASS_PCI,
+	.of_match		= pcie_advk_ids,
+	.ops			= &pcie_advk_ops,
+	.ofdata_to_platdata	= pcie_advk_ofdata_to_platdata,
+	.probe			= pcie_advk_probe,
+	.priv_auto_alloc_size	= sizeof(struct pcie_advk),
+};
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index ad43e8a..a2e8296 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -876,6 +876,9 @@
 #ifdef CONFIG_NR_DRAM_BANKS
 	bd_t *bd = gd->bd;
 
+	if (!bd)
+		return 0;
+
 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) {
 		if (bd->bi_dram[i].size) {
 			pci_set_region(hose->regions + hose->region_count++,
@@ -894,8 +897,9 @@
 #endif
 	if (gd->pci_ram_top && gd->pci_ram_top < base + size)
 		size = gd->pci_ram_top - base;
-	pci_set_region(hose->regions + hose->region_count++, base, base,
-		       size, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+	if (size)
+		pci_set_region(hose->regions + hose->region_count++, base,
+			base, size, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
 #endif
 
 	return 0;
diff --git a/drivers/pci/pcie_dw_mvebu.c b/drivers/pci/pcie_dw_mvebu.c
index a198855..a0032b7 100644
--- a/drivers/pci/pcie_dw_mvebu.c
+++ b/drivers/pci/pcie_dw_mvebu.c
@@ -111,6 +111,10 @@
 	void *cfg_base;
 	fdt_size_t cfg_size;
 	int first_busno;
+
+	/* IO and MEM PCI regions */
+	struct pci_region io;
+	struct pci_region mem;
 };
 
 static int pcie_dw_get_link_speed(const void *regs_base)
@@ -126,6 +130,34 @@
 }
 
 /**
+ * pcie_dw_prog_outbound_atu() - Configure ATU for outbound accesses
+ *
+ * @pcie: Pointer to the PCI controller state
+ * @index: ATU region index
+ * @type: ATU accsess type
+ * @cpu_addr: the physical address for the translation entry
+ * @pci_addr: the pcie bus address for the translation entry
+ * @size: the size of the translation entry
+ */
+static void pcie_dw_prog_outbound_atu(struct pcie_dw_mvebu *pcie, int index,
+				      int type, u64 cpu_addr, u64 pci_addr,
+				      u32 size)
+{
+	writel(PCIE_ATU_REGION_OUTBOUND | index,
+	       pcie->ctrl_base + PCIE_ATU_VIEWPORT);
+	writel(lower_32_bits(cpu_addr), pcie->ctrl_base + PCIE_ATU_LOWER_BASE);
+	writel(upper_32_bits(cpu_addr), pcie->ctrl_base + PCIE_ATU_UPPER_BASE);
+	writel(lower_32_bits(cpu_addr + size - 1),
+	       pcie->ctrl_base + PCIE_ATU_LIMIT);
+	writel(lower_32_bits(pci_addr),
+	       pcie->ctrl_base + PCIE_ATU_LOWER_TARGET);
+	writel(upper_32_bits(pci_addr),
+	       pcie->ctrl_base + PCIE_ATU_UPPER_TARGET);
+	writel(type, pcie->ctrl_base + PCIE_ATU_CR1);
+	writel(PCIE_ATU_ENABLE, pcie->ctrl_base + PCIE_ATU_CR2);
+}
+
+/**
  * set_cfg_address() - Configure the PCIe controller config space access
  *
  * @pcie: Pointer to the PCI controller state
@@ -143,27 +175,29 @@
 				 pci_dev_t d, uint where)
 {
 	uintptr_t va_address;
+	u32 atu_type;
 
 	/*
 	 * Region #0 is used for Outbound CFG space access.
 	 * Direction = Outbound
 	 * Region Index = 0
 	 */
-	writel(0, pcie->ctrl_base + PCIE_ATU_VIEWPORT);
 
 	if (PCI_BUS(d) == (pcie->first_busno + 1))
 		/* For local bus, change TLP Type field to 4. */
-		writel(PCIE_ATU_TYPE_CFG0, pcie->ctrl_base + PCIE_ATU_CR1);
+		atu_type = PCIE_ATU_TYPE_CFG0;
 	else
 		/* Otherwise, change TLP Type field to 5. */
-		writel(PCIE_ATU_TYPE_CFG1, pcie->ctrl_base + PCIE_ATU_CR1);
+		atu_type = PCIE_ATU_TYPE_CFG1;
 
 	if (PCI_BUS(d) == pcie->first_busno) {
 		/* Accessing root port configuration space. */
 		va_address = (uintptr_t)pcie->ctrl_base;
 	} else {
 		d = PCI_MASK_BUS(d) | (PCI_BUS(d) - pcie->first_busno);
-		writel(d << 8, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET);
+		pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX0,
+					  atu_type, (u64)pcie->cfg_base,
+					  d << 8, pcie->cfg_size);
 		va_address = (uintptr_t)pcie->cfg_base;
 	}
 
@@ -231,6 +265,10 @@
 	debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);
 	*valuep = pci_conv_32_to_size(value, offset, size);
 
+	pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX0,
+				  PCIE_ATU_TYPE_IO, pcie->io.phys_start,
+				  pcie->io.bus_start, pcie->io.size);
+
 	return 0;
 }
 
@@ -272,6 +310,10 @@
 	value = pci_conv_size_to_32(old, value, offset, size);
 	writel(value, va_address);
 
+	pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX0,
+				  PCIE_ATU_TYPE_IO, pcie->io.phys_start,
+				  pcie->io.bus_start, pcie->io.size);
+
 	return 0;
 }
 
@@ -388,34 +430,6 @@
 }
 
 /**
- * pcie_dw_regions_setup() - iATU region setup
- *
- * @pcie: Pointer to the PCI controller state
- *
- * Configure the iATU regions in the PCIe controller for outbound access.
- */
-static void pcie_dw_regions_setup(struct pcie_dw_mvebu *pcie)
-{
-	/*
-	 * Region #0 is used for Outbound CFG space access.
-	 * Direction = Outbound
-	 * Region Index = 0
-	 */
-	writel(0, pcie->ctrl_base + PCIE_ATU_VIEWPORT);
-
-	writel((u32)(uintptr_t)pcie->cfg_base, pcie->ctrl_base
-	       + PCIE_ATU_LOWER_BASE);
-	writel(0, pcie->ctrl_base + PCIE_ATU_UPPER_BASE);
-	writel((u32)(uintptr_t)pcie->cfg_base + pcie->cfg_size,
-	       pcie->ctrl_base + PCIE_ATU_LIMIT);
-
-	writel(0, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET);
-	writel(0, pcie->ctrl_base + PCIE_ATU_UPPER_TARGET);
-	writel(PCIE_ATU_TYPE_CFG0, pcie->ctrl_base + PCIE_ATU_CR1);
-	writel(PCIE_ATU_ENABLE, pcie->ctrl_base + PCIE_ATU_CR2);
-}
-
-/**
  * pcie_dw_set_host_bars() - Configure the host BARs
  *
  * @regs_base: A pointer to the PCIe controller registers
@@ -495,7 +509,18 @@
 		       hose->first_busno);
 	}
 
+	/* Store the IO and MEM windows settings for future use by the ATU */
+	pcie->io.phys_start = hose->regions[0].phys_start; /* IO base */
+	pcie->io.bus_start  = hose->regions[0].bus_start;  /* IO_bus_addr */
+	pcie->io.size	    = hose->regions[0].size;	   /* IO size */
+
+	pcie->mem.phys_start = hose->regions[1].phys_start; /* MEM base */
+	pcie->mem.bus_start  = hose->regions[1].bus_start;  /* MEM_bus_addr */
+	pcie->mem.size	     = hose->regions[1].size;	    /* MEM size */
+
-	pcie_dw_regions_setup(pcie);
+	pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX1,
+				  PCIE_ATU_TYPE_MEM, pcie->mem.phys_start,
+				  pcie->mem.bus_start, pcie->mem.size);
 
 	/* Set the CLASS_REV of RC CFG header to PCI_CLASS_BRIDGE_PCI */
 	clrsetbits_le32(pcie->ctrl_base + PCI_CLASS_REVISION,
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
index 2bf853e..010eb20 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -44,7 +44,7 @@
 #define IRQ_STATUS	0x10
 #define IRQ_WKUP	0x18
 
-#define NB_FUNCS 2
+#define NB_FUNCS 3
 #define GPIO_PER_REG	32
 
 /**
@@ -128,6 +128,16 @@
 		.funcs = {_func1, "gpio"}	\
 	}
 
+#define PIN_GRP_GPIO_3(_name, _start, _nr, _mask, _v1, _v2, _v3, _f1, _f2) \
+	{					\
+		.name = _name,			\
+		.start_pin = _start,		\
+		.npins = _nr,			\
+		.reg_mask = _mask,		\
+		.val = {_v1, _v2, _v3},	\
+		.funcs = {_f1, _f2, "gpio"}	\
+	}
+
 #define PIN_GRP_EXTRA(_name, _start, _nr, _mask, _v1, _v2, _start2, _nr2, \
 		      _f1, _f2)				\
 	{						\
@@ -149,8 +159,8 @@
 	PIN_GRP_GPIO("pwm1", 12, 1, BIT(4), "pwm"),
 	PIN_GRP_GPIO("pwm2", 13, 1, BIT(5), "pwm"),
 	PIN_GRP_GPIO("pwm3", 14, 1, BIT(6), "pwm"),
-	PIN_GRP_GPIO("pmic1", 17, 1, BIT(7), "pmic"),
-	PIN_GRP_GPIO("pmic0", 16, 1, BIT(8), "pmic"),
+	PIN_GRP_GPIO("pmic1", 7, 1, BIT(7), "pmic"),
+	PIN_GRP_GPIO("pmic0", 6, 1, BIT(8), "pmic"),
 	PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"),
 	PIN_GRP_GPIO("i2c1", 0, 2, BIT(10), "i2c"),
 	PIN_GRP_GPIO("spi_cs1", 17, 1, BIT(12), "spi"),
@@ -172,13 +182,15 @@
 static struct armada_37xx_pin_group armada_37xx_sb_groups[] = {
 	PIN_GRP_GPIO("usb32_drvvbus0", 0, 1, BIT(0), "drvbus"),
 	PIN_GRP_GPIO("usb2_drvvbus1", 1, 1, BIT(1), "drvbus"),
-	PIN_GRP_GPIO("sdio_sb", 24, 5, BIT(2), "sdio"),
-	PIN_GRP_EXTRA("rgmii", 6, 14, BIT(3), 0, BIT(3), 23, 1, "mii", "gpio"),
-	PIN_GRP_GPIO("pcie1", 3, 2, BIT(4), "pcie"),
-	PIN_GRP_GPIO("ptp", 20, 3, BIT(5), "ptp"),
+	PIN_GRP_GPIO("sdio_sb", 24, 6, BIT(2), "sdio"),
+	PIN_GRP_GPIO("rgmii", 6, 12, BIT(3), "mii"),
+	PIN_GRP_GPIO("smi", 18, 2, BIT(4), "smi"),
+	PIN_GRP_GPIO("pcie1", 3, 3, BIT(5) | BIT(9) | BIT(10), "pcie"),
+	PIN_GRP_GPIO("ptp", 20, 3, BIT(11) | BIT(12) | BIT(13), "ptp"),
 	PIN_GRP("ptp_clk", 21, 1, BIT(6), "ptp", "mii"),
 	PIN_GRP("ptp_trig", 22, 1, BIT(7), "ptp", "mii"),
-	PIN_GRP("mii_col", 23, 1, BIT(8), "mii", "mii_err"),
+	PIN_GRP_GPIO_3("mii_col", 23, 1, BIT(8) | BIT(14), 0, BIT(8), BIT(14),
+		       "mii", "mii_err"),
 };
 
 const struct armada_37xx_pin_data armada_37xx_pin_nb = {
@@ -189,18 +201,18 @@
 };
 
 const struct armada_37xx_pin_data armada_37xx_pin_sb = {
-	.nr_pins = 29,
+	.nr_pins = 30,
 	.name = "GPIO2",
 	.groups = armada_37xx_sb_groups,
 	.ngroups = ARRAY_SIZE(armada_37xx_sb_groups),
 };
 
 static inline void armada_37xx_update_reg(unsigned int *reg,
-					  unsigned int offset)
+					  unsigned int *offset)
 {
 	/* We never have more than 2 registers */
-	if (offset >= GPIO_PER_REG) {
-		offset -= GPIO_PER_REG;
+	if (*offset >= GPIO_PER_REG) {
+		*offset -= GPIO_PER_REG;
 		*reg += sizeof(u32);
 	}
 }
@@ -210,7 +222,7 @@
 {
 	int f;
 
-	for (f = 0; f < NB_FUNCS; f++)
+	for (f = 0; (f < NB_FUNCS) && grp->funcs[f]; f++)
 		if (!strcmp(grp->funcs[f], func))
 			return f;
 
@@ -352,7 +364,7 @@
 		for (j = 0; j < grp->extra_npins; j++)
 			grp->pins[i+j] = grp->extra_pin + j;
 
-		for (f = 0; f < NB_FUNCS; f++) {
+		for (f = 0; (f < NB_FUNCS) && grp->funcs[f]; f++) {
 			int ret;
 			/* check for unique functions and count groups */
 			ret = armada_37xx_add_function(info->funcs, &funcsize,
@@ -404,7 +416,7 @@
 			struct armada_37xx_pin_group *gp = &info->groups[g];
 			int f;
 
-			for (f = 0; f < NB_FUNCS; f++) {
+			for (f = 0; (f < NB_FUNCS) && gp->funcs[f]; f++) {
 				if (strcmp(gp->funcs[f], name) == 0) {
 					*groups = gp->name;
 					groups++;
@@ -421,7 +433,7 @@
 	unsigned int reg = INPUT_VAL;
 	unsigned int val, mask;
 
-	armada_37xx_update_reg(&reg, offset);
+	armada_37xx_update_reg(&reg, &offset);
 	mask = BIT(offset);
 
 	val = readl(info->base + reg);
@@ -436,7 +448,7 @@
 	unsigned int reg = OUTPUT_VAL;
 	unsigned int mask, val;
 
-	armada_37xx_update_reg(&reg, offset);
+	armada_37xx_update_reg(&reg, &offset);
 	mask = BIT(offset);
 	val = value ? mask : 0;
 
@@ -452,7 +464,7 @@
 	unsigned int reg = OUTPUT_EN;
 	unsigned int val, mask;
 
-	armada_37xx_update_reg(&reg, offset);
+	armada_37xx_update_reg(&reg, &offset);
 	mask = BIT(offset);
 	val = readl(info->base + reg);
 
@@ -469,7 +481,7 @@
 	unsigned int reg = OUTPUT_EN;
 	unsigned int mask;
 
-	armada_37xx_update_reg(&reg, offset);
+	armada_37xx_update_reg(&reg, &offset);
 	mask = BIT(offset);
 
 	clrbits_le32(info->base + reg, mask);
@@ -484,7 +496,7 @@
 	unsigned int reg = OUTPUT_EN;
 	unsigned int mask;
 
-	armada_37xx_update_reg(&reg, offset);
+	armada_37xx_update_reg(&reg, &offset);
 	mask = BIT(offset);
 
 	setbits_le32(info->base + reg, mask);
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3036.c b/drivers/pinctrl/rockchip/pinctrl_rk3036.c
index 94f6d7a..7e93d85 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3036.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3036.c
@@ -18,6 +18,416 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/* GRF_GPIO0A_IOMUX */
+enum {
+	GPIO0A3_SHIFT		= 6,
+	GPIO0A3_MASK		= 1 << GPIO0A3_SHIFT,
+	GPIO0A3_GPIO		= 0,
+	GPIO0A3_I2C1_SDA,
+
+	GPIO0A2_SHIFT		= 4,
+	GPIO0A2_MASK		= 1 << GPIO0A2_SHIFT,
+	GPIO0A2_GPIO		= 0,
+	GPIO0A2_I2C1_SCL,
+
+	GPIO0A1_SHIFT		= 2,
+	GPIO0A1_MASK		= 3 << GPIO0A1_SHIFT,
+	GPIO0A1_GPIO		= 0,
+	GPIO0A1_I2C0_SDA,
+	GPIO0A1_PWM2,
+
+	GPIO0A0_SHIFT		= 0,
+	GPIO0A0_MASK		= 3 << GPIO0A0_SHIFT,
+	GPIO0A0_GPIO		= 0,
+	GPIO0A0_I2C0_SCL,
+	GPIO0A0_PWM1,
+};
+
+/* GRF_GPIO0B_IOMUX */
+enum {
+	GPIO0B6_SHIFT		= 12,
+	GPIO0B6_MASK		= 3 << GPIO0B6_SHIFT,
+	GPIO0B6_GPIO		= 0,
+	GPIO0B6_MMC1_D3,
+	GPIO0B6_I2S1_SCLK,
+
+	GPIO0B5_SHIFT		= 10,
+	GPIO0B5_MASK		= 3 << GPIO0B5_SHIFT,
+	GPIO0B5_GPIO		= 0,
+	GPIO0B5_MMC1_D2,
+	GPIO0B5_I2S1_SDI,
+
+	GPIO0B4_SHIFT		= 8,
+	GPIO0B4_MASK		= 3 << GPIO0B4_SHIFT,
+	GPIO0B4_GPIO		= 0,
+	GPIO0B4_MMC1_D1,
+	GPIO0B4_I2S1_LRCKTX,
+
+	GPIO0B3_SHIFT		= 6,
+	GPIO0B3_MASK		= 3 << GPIO0B3_SHIFT,
+	GPIO0B3_GPIO		= 0,
+	GPIO0B3_MMC1_D0,
+	GPIO0B3_I2S1_LRCKRX,
+
+	GPIO0B1_SHIFT		= 2,
+	GPIO0B1_MASK		= 3 << GPIO0B1_SHIFT,
+	GPIO0B1_GPIO		= 0,
+	GPIO0B1_MMC1_CLKOUT,
+	GPIO0B1_I2S1_MCLK,
+
+	GPIO0B0_SHIFT		= 0,
+	GPIO0B0_MASK		= 3,
+	GPIO0B0_GPIO		= 0,
+	GPIO0B0_MMC1_CMD,
+	GPIO0B0_I2S1_SDO,
+};
+
+/* GRF_GPIO0C_IOMUX */
+enum {
+	GPIO0C4_SHIFT		= 8,
+	GPIO0C4_MASK		= 1 << GPIO0C4_SHIFT,
+	GPIO0C4_GPIO		= 0,
+	GPIO0C4_DRIVE_VBUS,
+
+	GPIO0C3_SHIFT		= 6,
+	GPIO0C3_MASK		= 1 << GPIO0C3_SHIFT,
+	GPIO0C3_GPIO		= 0,
+	GPIO0C3_UART0_CTSN,
+
+	GPIO0C2_SHIFT		= 4,
+	GPIO0C2_MASK		= 1 << GPIO0C2_SHIFT,
+	GPIO0C2_GPIO		= 0,
+	GPIO0C2_UART0_RTSN,
+
+	GPIO0C1_SHIFT		= 2,
+	GPIO0C1_MASK		= 1 << GPIO0C1_SHIFT,
+	GPIO0C1_GPIO		= 0,
+	GPIO0C1_UART0_SIN,
+
+
+	GPIO0C0_SHIFT		= 0,
+	GPIO0C0_MASK		= 1 << GPIO0C0_SHIFT,
+	GPIO0C0_GPIO		= 0,
+	GPIO0C0_UART0_SOUT,
+};
+
+/* GRF_GPIO0D_IOMUX */
+enum {
+	GPIO0D4_SHIFT		= 8,
+	GPIO0D4_MASK		= 1 << GPIO0D4_SHIFT,
+	GPIO0D4_GPIO		= 0,
+	GPIO0D4_SPDIF,
+
+	GPIO0D3_SHIFT		= 6,
+	GPIO0D3_MASK		= 1 << GPIO0D3_SHIFT,
+	GPIO0D3_GPIO		= 0,
+	GPIO0D3_PWM3,
+
+	GPIO0D2_SHIFT		= 4,
+	GPIO0D2_MASK		= 1 << GPIO0D2_SHIFT,
+	GPIO0D2_GPIO		= 0,
+	GPIO0D2_PWM0,
+};
+
+/* GRF_GPIO1A_IOMUX */
+enum {
+	GPIO1A5_SHIFT		= 10,
+	GPIO1A5_MASK		= 1 << GPIO1A5_SHIFT,
+	GPIO1A5_GPIO		= 0,
+	GPIO1A5_I2S_SDI,
+
+	GPIO1A4_SHIFT		= 8,
+	GPIO1A4_MASK		= 1 << GPIO1A4_SHIFT,
+	GPIO1A4_GPIO		= 0,
+	GPIO1A4_I2S_SD0,
+
+	GPIO1A3_SHIFT		= 6,
+	GPIO1A3_MASK		= 1 << GPIO1A3_SHIFT,
+	GPIO1A3_GPIO		= 0,
+	GPIO1A3_I2S_LRCKTX,
+
+	GPIO1A2_SHIFT		= 4,
+	GPIO1A2_MASK		= 3 << GPIO1A2_SHIFT,
+	GPIO1A2_GPIO		= 0,
+	GPIO1A2_I2S_LRCKRX,
+	GPIO1A2_PWM1_0,
+
+	GPIO1A1_SHIFT		= 2,
+	GPIO1A1_MASK		= 1 << GPIO1A1_SHIFT,
+	GPIO1A1_GPIO		= 0,
+	GPIO1A1_I2S_SCLK,
+
+	GPIO1A0_SHIFT		= 0,
+	GPIO1A0_MASK		= 1 << GPIO1A0_SHIFT,
+	GPIO1A0_GPIO		= 0,
+	GPIO1A0_I2S_MCLK,
+
+};
+
+/* GRF_GPIO1B_IOMUX */
+enum {
+	GPIO1B7_SHIFT		= 14,
+	GPIO1B7_MASK		= 1 << GPIO1B7_SHIFT,
+	GPIO1B7_GPIO		= 0,
+	GPIO1B7_MMC0_CMD,
+
+	GPIO1B3_SHIFT		= 6,
+	GPIO1B3_MASK		= 1 << GPIO1B3_SHIFT,
+	GPIO1B3_GPIO		= 0,
+	GPIO1B3_HDMI_HPD,
+
+	GPIO1B2_SHIFT		= 4,
+	GPIO1B2_MASK		= 1 << GPIO1B2_SHIFT,
+	GPIO1B2_GPIO		= 0,
+	GPIO1B2_HDMI_SCL,
+
+	GPIO1B1_SHIFT		= 2,
+	GPIO1B1_MASK		= 1 << GPIO1B1_SHIFT,
+	GPIO1B1_GPIO		= 0,
+	GPIO1B1_HDMI_SDA,
+
+	GPIO1B0_SHIFT		= 0,
+	GPIO1B0_MASK		= 1 << GPIO1B0_SHIFT,
+	GPIO1B0_GPIO		= 0,
+	GPIO1B0_HDMI_CEC,
+};
+
+/* GRF_GPIO1C_IOMUX */
+enum {
+	GPIO1C5_SHIFT		= 10,
+	GPIO1C5_MASK		= 3 << GPIO1C5_SHIFT,
+	GPIO1C5_GPIO		= 0,
+	GPIO1C5_MMC0_D3,
+	GPIO1C5_JTAG_TMS,
+
+	GPIO1C4_SHIFT		= 8,
+	GPIO1C4_MASK		= 3 << GPIO1C4_SHIFT,
+	GPIO1C4_GPIO		= 0,
+	GPIO1C4_MMC0_D2,
+	GPIO1C4_JTAG_TCK,
+
+	GPIO1C3_SHIFT		= 6,
+	GPIO1C3_MASK		= 3 << GPIO1C3_SHIFT,
+	GPIO1C3_GPIO		= 0,
+	GPIO1C3_MMC0_D1,
+	GPIO1C3_UART2_SOUT,
+
+	GPIO1C2_SHIFT		= 4,
+	GPIO1C2_MASK		= 3 << GPIO1C2_SHIFT ,
+	GPIO1C2_GPIO		= 0,
+	GPIO1C2_MMC0_D0,
+	GPIO1C2_UART2_SIN,
+
+	GPIO1C1_SHIFT		= 2,
+	GPIO1C1_MASK		= 1 << GPIO1C1_SHIFT,
+	GPIO1C1_GPIO		= 0,
+	GPIO1C1_MMC0_DETN,
+
+	GPIO1C0_SHIFT		= 0,
+	GPIO1C0_MASK		= 1 << GPIO1C0_SHIFT,
+	GPIO1C0_GPIO		= 0,
+	GPIO1C0_MMC0_CLKOUT,
+};
+
+/* GRF_GPIO1D_IOMUX */
+enum {
+	GPIO1D7_SHIFT		= 14,
+	GPIO1D7_MASK		= 3 << GPIO1D7_SHIFT,
+	GPIO1D7_GPIO		= 0,
+	GPIO1D7_NAND_D7,
+	GPIO1D7_EMMC_D7,
+	GPIO1D7_SPI_CSN1,
+
+	GPIO1D6_SHIFT		= 12,
+	GPIO1D6_MASK		= 3 << GPIO1D6_SHIFT,
+	GPIO1D6_GPIO		= 0,
+	GPIO1D6_NAND_D6,
+	GPIO1D6_EMMC_D6,
+	GPIO1D6_SPI_CSN0,
+
+	GPIO1D5_SHIFT		= 10,
+	GPIO1D5_MASK		= 3 << GPIO1D5_SHIFT,
+	GPIO1D5_GPIO		= 0,
+	GPIO1D5_NAND_D5,
+	GPIO1D5_EMMC_D5,
+	GPIO1D5_SPI_TXD,
+
+	GPIO1D4_SHIFT		= 8,
+	GPIO1D4_MASK		= 3 << GPIO1D4_SHIFT,
+	GPIO1D4_GPIO		= 0,
+	GPIO1D4_NAND_D4,
+	GPIO1D4_EMMC_D4,
+	GPIO1D4_SPI_RXD,
+
+	GPIO1D3_SHIFT		= 6,
+	GPIO1D3_MASK		= 3 << GPIO1D3_SHIFT,
+	GPIO1D3_GPIO		= 0,
+	GPIO1D3_NAND_D3,
+	GPIO1D3_EMMC_D3,
+	GPIO1D3_SFC_SIO3,
+
+	GPIO1D2_SHIFT		= 4,
+	GPIO1D2_MASK		= 3 << GPIO1D2_SHIFT,
+	GPIO1D2_GPIO		= 0,
+	GPIO1D2_NAND_D2,
+	GPIO1D2_EMMC_D2,
+	GPIO1D2_SFC_SIO2,
+
+	GPIO1D1_SHIFT		= 2,
+	GPIO1D1_MASK		= 3 << GPIO1D1_SHIFT,
+	GPIO1D1_GPIO		= 0,
+	GPIO1D1_NAND_D1,
+	GPIO1D1_EMMC_D1,
+	GPIO1D1_SFC_SIO1,
+
+	GPIO1D0_SHIFT		= 0,
+	GPIO1D0_MASK		= 3 << GPIO1D0_SHIFT,
+	GPIO1D0_GPIO		= 0,
+	GPIO1D0_NAND_D0,
+	GPIO1D0_EMMC_D0,
+	GPIO1D0_SFC_SIO0,
+};
+
+/* GRF_GPIO2A_IOMUX */
+enum {
+	GPIO2A7_SHIFT		= 14,
+	GPIO2A7_MASK		= 1 << GPIO2A7_SHIFT,
+	GPIO2A7_GPIO		= 0,
+	GPIO2A7_TESTCLK_OUT,
+
+	GPIO2A6_SHIFT		= 12,
+	GPIO2A6_MASK		= 1 << GPIO2A6_SHIFT,
+	GPIO2A6_GPIO		= 0,
+	GPIO2A6_NAND_CS0,
+
+	GPIO2A4_SHIFT		= 8,
+	GPIO2A4_MASK		= 3 << GPIO2A4_SHIFT,
+	GPIO2A4_GPIO		= 0,
+	GPIO2A4_NAND_RDY,
+	GPIO2A4_EMMC_CMD,
+	GPIO2A3_SFC_CLK,
+
+	GPIO2A3_SHIFT		= 6,
+	GPIO2A3_MASK		= 3 << GPIO2A3_SHIFT,
+	GPIO2A3_GPIO		= 0,
+	GPIO2A3_NAND_RDN,
+	GPIO2A4_SFC_CSN1,
+
+	GPIO2A2_SHIFT		= 4,
+	GPIO2A2_MASK		= 3 << GPIO2A2_SHIFT,
+	GPIO2A2_GPIO		= 0,
+	GPIO2A2_NAND_WRN,
+	GPIO2A4_SFC_CSN0,
+
+	GPIO2A1_SHIFT		= 2,
+	GPIO2A1_MASK		= 3 << GPIO2A1_SHIFT,
+	GPIO2A1_GPIO		= 0,
+	GPIO2A1_NAND_CLE,
+	GPIO2A1_EMMC_CLKOUT,
+
+	GPIO2A0_SHIFT		= 0,
+	GPIO2A0_MASK		= 3 << GPIO2A0_SHIFT,
+	GPIO2A0_GPIO		= 0,
+	GPIO2A0_NAND_ALE,
+	GPIO2A0_SPI_CLK,
+};
+
+/* GRF_GPIO2B_IOMUX */
+enum {
+	GPIO2B7_SHIFT		= 14,
+	GPIO2B7_MASK		= 1 << GPIO2B7_SHIFT,
+	GPIO2B7_GPIO		= 0,
+	GPIO2B7_MAC_RXER,
+
+	GPIO2B6_SHIFT		= 12,
+	GPIO2B6_MASK		= 3 << GPIO2B6_SHIFT,
+	GPIO2B6_GPIO		= 0,
+	GPIO2B6_MAC_CLKOUT,
+	GPIO2B6_MAC_CLKIN,
+
+	GPIO2B5_SHIFT		= 10,
+	GPIO2B5_MASK		= 1 << GPIO2B5_SHIFT,
+	GPIO2B5_GPIO		= 0,
+	GPIO2B5_MAC_TXEN,
+
+	GPIO2B4_SHIFT		= 8,
+	GPIO2B4_MASK		= 1 << GPIO2B4_SHIFT,
+	GPIO2B4_GPIO		= 0,
+	GPIO2B4_MAC_MDIO,
+
+	GPIO2B2_SHIFT		= 4,
+	GPIO2B2_MASK		= 1 << GPIO2B2_SHIFT,
+	GPIO2B2_GPIO		= 0,
+	GPIO2B2_MAC_CRS,
+};
+
+/* GRF_GPIO2C_IOMUX */
+enum {
+	GPIO2C7_SHIFT		= 14,
+	GPIO2C7_MASK		= 3 << GPIO2C7_SHIFT,
+	GPIO2C7_GPIO		= 0,
+	GPIO2C7_UART1_SOUT,
+	GPIO2C7_TESTCLK_OUT1,
+
+	GPIO2C6_SHIFT		= 12,
+	GPIO2C6_MASK		= 1 << GPIO2C6_SHIFT,
+	GPIO2C6_GPIO		= 0,
+	GPIO2C6_UART1_SIN,
+
+	GPIO2C5_SHIFT		= 10,
+	GPIO2C5_MASK		= 1 << GPIO2C5_SHIFT,
+	GPIO2C5_GPIO		= 0,
+	GPIO2C5_I2C2_SCL,
+
+	GPIO2C4_SHIFT		= 8,
+	GPIO2C4_MASK		= 1 << GPIO2C4_SHIFT,
+	GPIO2C4_GPIO		= 0,
+	GPIO2C4_I2C2_SDA,
+
+	GPIO2C3_SHIFT		= 6,
+	GPIO2C3_MASK		= 1 << GPIO2C3_SHIFT,
+	GPIO2C3_GPIO		= 0,
+	GPIO2C3_MAC_TXD0,
+
+	GPIO2C2_SHIFT		= 4,
+	GPIO2C2_MASK		= 1 << GPIO2C2_SHIFT,
+	GPIO2C2_GPIO		= 0,
+	GPIO2C2_MAC_TXD1,
+
+	GPIO2C1_SHIFT		= 2,
+	GPIO2C1_MASK		= 1 << GPIO2C1_SHIFT,
+	GPIO2C1_GPIO		= 0,
+	GPIO2C1_MAC_RXD0,
+
+	GPIO2C0_SHIFT		= 0,
+	GPIO2C0_MASK		= 1 << GPIO2C0_SHIFT,
+	GPIO2C0_GPIO		= 0,
+	GPIO2C0_MAC_RXD1,
+};
+
+/* GRF_GPIO2D_IOMUX */
+enum {
+	GPIO2D6_SHIFT		= 12,
+	GPIO2D6_MASK		= 1 << GPIO2D6_SHIFT,
+	GPIO2D6_GPIO		= 0,
+	GPIO2D6_I2S_SDO1,
+
+	GPIO2D5_SHIFT		= 10,
+	GPIO2D5_MASK		= 1 << GPIO2D5_SHIFT,
+	GPIO2D5_GPIO		= 0,
+	GPIO2D5_I2S_SDO2,
+
+	GPIO2D4_SHIFT		= 8,
+	GPIO2D4_MASK		= 1 << GPIO2D4_SHIFT,
+	GPIO2D4_GPIO		= 0,
+	GPIO2D4_I2S_SDO3,
+
+	GPIO2D1_SHIFT		= 2,
+	GPIO2D1_MASK		= 1 << GPIO2D1_SHIFT,
+	GPIO2D1_GPIO		= 0,
+	GPIO2D1_MAC_MDC,
+};
+
 struct rk3036_pinctrl_priv {
 	struct rk3036_grf *grf;
 };
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3188.c b/drivers/pinctrl/rockchip/pinctrl_rk3188.c
index 692d8e2..fdab836 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3188.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3188.c
@@ -20,6 +20,386 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/* GRF_GPIO0D_IOMUX */
+enum {
+	GPIO0D7_SHIFT		= 14,
+	GPIO0D7_MASK		= 1,
+	GPIO0D7_GPIO		= 0,
+	GPIO0D7_SPI1_CSN0,
+
+	GPIO0D6_SHIFT		= 12,
+	GPIO0D6_MASK		= 1,
+	GPIO0D6_GPIO		= 0,
+	GPIO0D6_SPI1_CLK,
+
+	GPIO0D5_SHIFT		= 10,
+	GPIO0D5_MASK		= 1,
+	GPIO0D5_GPIO		= 0,
+	GPIO0D5_SPI1_TXD,
+
+	GPIO0D4_SHIFT		= 8,
+	GPIO0D4_MASK		= 1,
+	GPIO0D4_GPIO		= 0,
+	GPIO0D4_SPI0_RXD,
+
+	GPIO0D3_SHIFT		= 6,
+	GPIO0D3_MASK		= 3,
+	GPIO0D3_GPIO		= 0,
+	GPIO0D3_FLASH_CSN3,
+	GPIO0D3_EMMC_RSTN_OUT,
+
+	GPIO0D2_SHIFT		= 4,
+	GPIO0D2_MASK		= 3,
+	GPIO0D2_GPIO		= 0,
+	GPIO0D2_FLASH_CSN2,
+	GPIO0D2_EMMC_CMD,
+
+	GPIO0D1_SHIFT		= 2,
+	GPIO0D1_MASK		= 1,
+	GPIO0D1_GPIO		= 0,
+	GPIO0D1_FLASH_CSN1,
+
+	GPIO0D0_SHIFT		= 0,
+	GPIO0D0_MASK		= 3,
+	GPIO0D0_GPIO		= 0,
+	GPIO0D0_FLASH_DQS,
+	GPIO0D0_EMMC_CLKOUT
+};
+
+/* GRF_GPIO1A_IOMUX */
+enum {
+	GPIO1A7_SHIFT		= 14,
+	GPIO1A7_MASK		= 3,
+	GPIO1A7_GPIO		= 0,
+	GPIO1A7_UART1_RTS_N,
+	GPIO1A7_SPI0_CSN0,
+
+	GPIO1A6_SHIFT		= 12,
+	GPIO1A6_MASK		= 3,
+	GPIO1A6_GPIO		= 0,
+	GPIO1A6_UART1_CTS_N,
+	GPIO1A6_SPI0_CLK,
+
+	GPIO1A5_SHIFT		= 10,
+	GPIO1A5_MASK		= 3,
+	GPIO1A5_GPIO		= 0,
+	GPIO1A5_UART1_SOUT,
+	GPIO1A5_SPI0_TXD,
+
+	GPIO1A4_SHIFT		= 8,
+	GPIO1A4_MASK		= 3,
+	GPIO1A4_GPIO		= 0,
+	GPIO1A4_UART1_SIN,
+	GPIO1A4_SPI0_RXD,
+
+	GPIO1A3_SHIFT		= 6,
+	GPIO1A3_MASK		= 1,
+	GPIO1A3_GPIO		= 0,
+	GPIO1A3_UART0_RTS_N,
+
+	GPIO1A2_SHIFT		= 4,
+	GPIO1A2_MASK		= 1,
+	GPIO1A2_GPIO		= 0,
+	GPIO1A2_UART0_CTS_N,
+
+	GPIO1A1_SHIFT		= 2,
+	GPIO1A1_MASK		= 1,
+	GPIO1A1_GPIO		= 0,
+	GPIO1A1_UART0_SOUT,
+
+	GPIO1A0_SHIFT		= 0,
+	GPIO1A0_MASK		= 1,
+	GPIO1A0_GPIO		= 0,
+	GPIO1A0_UART0_SIN,
+};
+
+/* GRF_GPIO1B_IOMUX */
+enum {
+	GPIO1B7_SHIFT		= 14,
+	GPIO1B7_MASK		= 1,
+	GPIO1B7_GPIO		= 0,
+	GPIO1B7_SPI0_CSN1,
+
+	GPIO1B6_SHIFT		= 12,
+	GPIO1B6_MASK		= 3,
+	GPIO1B6_GPIO		= 0,
+	GPIO1B6_SPDIF_TX,
+	GPIO1B6_SPI1_CSN1,
+
+	GPIO1B5_SHIFT		= 10,
+	GPIO1B5_MASK		= 3,
+	GPIO1B5_GPIO		= 0,
+	GPIO1B5_UART3_RTS_N,
+	GPIO1B5_RESERVED,
+
+	GPIO1B4_SHIFT		= 8,
+	GPIO1B4_MASK		= 3,
+	GPIO1B4_GPIO		= 0,
+	GPIO1B4_UART3_CTS_N,
+	GPIO1B4_GPS_RFCLK,
+
+	GPIO1B3_SHIFT		= 6,
+	GPIO1B3_MASK		= 3,
+	GPIO1B3_GPIO		= 0,
+	GPIO1B3_UART3_SOUT,
+	GPIO1B3_GPS_SIG,
+
+	GPIO1B2_SHIFT		= 4,
+	GPIO1B2_MASK		= 3,
+	GPIO1B2_GPIO		= 0,
+	GPIO1B2_UART3_SIN,
+	GPIO1B2_GPS_MAG,
+
+	GPIO1B1_SHIFT		= 2,
+	GPIO1B1_MASK		= 3,
+	GPIO1B1_GPIO		= 0,
+	GPIO1B1_UART2_SOUT,
+	GPIO1B1_JTAG_TDO,
+
+	GPIO1B0_SHIFT		= 0,
+	GPIO1B0_MASK		= 3,
+	GPIO1B0_GPIO		= 0,
+	GPIO1B0_UART2_SIN,
+	GPIO1B0_JTAG_TDI,
+};
+
+/* GRF_GPIO1D_IOMUX */
+enum {
+	GPIO1D7_SHIFT		= 14,
+	GPIO1D7_MASK		= 1,
+	GPIO1D7_GPIO		= 0,
+	GPIO1D7_I2C4_SCL,
+
+	GPIO1D6_SHIFT		= 12,
+	GPIO1D6_MASK		= 1,
+	GPIO1D6_GPIO		= 0,
+	GPIO1D6_I2C4_SDA,
+
+	GPIO1D5_SHIFT		= 10,
+	GPIO1D5_MASK		= 1,
+	GPIO1D5_GPIO		= 0,
+	GPIO1D5_I2C2_SCL,
+
+	GPIO1D4_SHIFT		= 8,
+	GPIO1D4_MASK		= 1,
+	GPIO1D4_GPIO		= 0,
+	GPIO1D4_I2C2_SDA,
+
+	GPIO1D3_SHIFT		= 6,
+	GPIO1D3_MASK		= 1,
+	GPIO1D3_GPIO		= 0,
+	GPIO1D3_I2C1_SCL,
+
+	GPIO1D2_SHIFT		= 4,
+	GPIO1D2_MASK		= 1,
+	GPIO1D2_GPIO		= 0,
+	GPIO1D2_I2C1_SDA,
+
+	GPIO1D1_SHIFT		= 2,
+	GPIO1D1_MASK		= 1,
+	GPIO1D1_GPIO		= 0,
+	GPIO1D1_I2C0_SCL,
+
+	GPIO1D0_SHIFT		= 0,
+	GPIO1D0_MASK		= 1,
+	GPIO1D0_GPIO		= 0,
+	GPIO1D0_I2C0_SDA,
+};
+
+/* GRF_GPIO3A_IOMUX */
+enum {
+	GPIO3A7_SHIFT		= 14,
+	GPIO3A7_MASK		= 1,
+	GPIO3A7_GPIO		= 0,
+	GPIO3A7_SDMMC0_DATA3,
+
+	GPIO3A6_SHIFT		= 12,
+	GPIO3A6_MASK		= 1,
+	GPIO3A6_GPIO		= 0,
+	GPIO3A6_SDMMC0_DATA2,
+
+	GPIO3A5_SHIFT		= 10,
+	GPIO3A5_MASK		= 1,
+	GPIO3A5_GPIO		= 0,
+	GPIO3A5_SDMMC0_DATA1,
+
+	GPIO3A4_SHIFT		= 8,
+	GPIO3A4_MASK		= 1,
+	GPIO3A4_GPIO		= 0,
+	GPIO3A4_SDMMC0_DATA0,
+
+	GPIO3A3_SHIFT		= 6,
+	GPIO3A3_MASK		= 1,
+	GPIO3A3_GPIO		= 0,
+	GPIO3A3_SDMMC0_CMD,
+
+	GPIO3A2_SHIFT		= 4,
+	GPIO3A2_MASK		= 1,
+	GPIO3A2_GPIO		= 0,
+	GPIO3A2_SDMMC0_CLKOUT,
+
+	GPIO3A1_SHIFT		= 2,
+	GPIO3A1_MASK		= 1,
+	GPIO3A1_GPIO		= 0,
+	GPIO3A1_SDMMC0_PWREN,
+
+	GPIO3A0_SHIFT		= 0,
+	GPIO3A0_MASK		= 1,
+	GPIO3A0_GPIO		= 0,
+	GPIO3A0_SDMMC0_RSTN,
+};
+
+/* GRF_GPIO3B_IOMUX */
+enum {
+	GPIO3B7_SHIFT		= 14,
+	GPIO3B7_MASK		= 3,
+	GPIO3B7_GPIO		= 0,
+	GPIO3B7_CIF_DATA11,
+	GPIO3B7_I2C3_SCL,
+
+	GPIO3B6_SHIFT		= 12,
+	GPIO3B6_MASK		= 3,
+	GPIO3B6_GPIO		= 0,
+	GPIO3B6_CIF_DATA10,
+	GPIO3B6_I2C3_SDA,
+
+	GPIO3B5_SHIFT		= 10,
+	GPIO3B5_MASK		= 3,
+	GPIO3B5_GPIO		= 0,
+	GPIO3B5_CIF_DATA1,
+	GPIO3B5_HSADC_DATA9,
+
+	GPIO3B4_SHIFT		= 8,
+	GPIO3B4_MASK		= 3,
+	GPIO3B4_GPIO		= 0,
+	GPIO3B4_CIF_DATA0,
+	GPIO3B4_HSADC_DATA8,
+
+	GPIO3B3_SHIFT		= 6,
+	GPIO3B3_MASK		= 1,
+	GPIO3B3_GPIO		= 0,
+	GPIO3B3_CIF_CLKOUT,
+
+	GPIO3B2_SHIFT		= 4,
+	GPIO3B2_MASK		= 1,
+	GPIO3B2_GPIO		= 0,
+	/* no muxes */
+
+	GPIO3B1_SHIFT		= 2,
+	GPIO3B1_MASK		= 1,
+	GPIO3B1_GPIO		= 0,
+	GPIO3B1_SDMMC0_WRITE_PRT,
+
+	GPIO3B0_SHIFT		= 0,
+	GPIO3B0_MASK		= 1,
+	GPIO3B0_GPIO		= 0,
+	GPIO3B0_SDMMC_DETECT_N,
+};
+
+/* GRF_GPIO3C_IOMUX */
+enum {
+	GPIO3C7_SHIFT		= 14,
+	GPIO3C7_MASK		= 3,
+	GPIO3C7_GPIO		= 0,
+	GPIO3C7_SDMMC1_WRITE_PRT,
+	GPIO3C7_RMII_CRS_DVALID,
+	GPIO3C7_RESERVED,
+
+	GPIO3C6_SHIFT		= 12,
+	GPIO3C6_MASK		= 3,
+	GPIO3C6_GPIO		= 0,
+	GPIO3C6_SDMMC1_DECTN,
+	GPIO3C6_RMII_RX_ERR,
+	GPIO3C6_RESERVED,
+
+	GPIO3C5_SHIFT		= 10,
+	GPIO3C5_MASK		= 3,
+	GPIO3C5_GPIO		= 0,
+	GPIO3C5_SDMMC1_CLKOUT,
+	GPIO3C5_RMII_CLKOUT,
+	GPIO3C5_RMII_CLKIN,
+
+	GPIO3C4_SHIFT		= 8,
+	GPIO3C4_MASK		= 3,
+	GPIO3C4_GPIO		= 0,
+	GPIO3C4_SDMMC1_DATA3,
+	GPIO3C4_RMII_RXD1,
+	GPIO3C4_RESERVED,
+
+	GPIO3C3_SHIFT		= 6,
+	GPIO3C3_MASK		= 3,
+	GPIO3C3_GPIO		= 0,
+	GPIO3C3_SDMMC1_DATA2,
+	GPIO3C3_RMII_RXD0,
+	GPIO3C3_RESERVED,
+
+	GPIO3C2_SHIFT		= 4,
+	GPIO3C2_MASK		= 3,
+	GPIO3C2_GPIO		= 0,
+	GPIO3C2_SDMMC1_DATA1,
+	GPIO3C2_RMII_TXD0,
+	GPIO3C2_RESERVED,
+
+	GPIO3C1_SHIFT		= 2,
+	GPIO3C1_MASK		= 3,
+	GPIO3C1_GPIO		= 0,
+	GPIO3C1_SDMMC1_DATA0,
+	GPIO3C1_RMII_TXD1,
+	GPIO3C1_RESERVED,
+
+	GPIO3C0_SHIFT		= 0,
+	GPIO3C0_MASK		= 3,
+	GPIO3C0_GPIO		= 0,
+	GPIO3C0_SDMMC1_CMD,
+	GPIO3C0_RMII_TX_EN,
+	GPIO3C0_RESERVED,
+};
+
+/* GRF_GPIO3D_IOMUX */
+enum {
+	GPIO3D6_SHIFT		= 12,
+	GPIO3D6_MASK		= 3,
+	GPIO3D6_GPIO		= 0,
+	GPIO3D6_PWM_3,
+	GPIO3D6_JTAG_TMS,
+	GPIO3D6_HOST_DRV_VBUS,
+
+	GPIO3D5_SHIFT		= 10,
+	GPIO3D5_MASK		= 3,
+	GPIO3D5_GPIO		= 0,
+	GPIO3D5_PWM_2,
+	GPIO3D5_JTAG_TCK,
+	GPIO3D5_OTG_DRV_VBUS,
+
+	GPIO3D4_SHIFT		= 8,
+	GPIO3D4_MASK		= 3,
+	GPIO3D4_GPIO		= 0,
+	GPIO3D4_PWM_1,
+	GPIO3D4_JTAG_TRSTN,
+
+	GPIO3D3_SHIFT		= 6,
+	GPIO3D3_MASK		= 3,
+	GPIO3D3_GPIO		= 0,
+	GPIO3D3_PWM_0,
+
+	GPIO3D2_SHIFT		= 4,
+	GPIO3D2_MASK		= 3,
+	GPIO3D2_GPIO		= 0,
+	GPIO3D2_SDMMC1_INT_N,
+
+	GPIO3D1_SHIFT		= 2,
+	GPIO3D1_MASK		= 3,
+	GPIO3D1_GPIO		= 0,
+	GPIO3D1_SDMMC1_BACKEND_PWR,
+	GPIO3D1_MII_MDCLK,
+
+	GPIO3D0_SHIFT		= 0,
+	GPIO3D0_MASK		= 3,
+	GPIO3D0_GPIO		= 0,
+	GPIO3D0_SDMMC1_PWR_EN,
+	GPIO3D0_MII_MD,
+};
+
 struct rk3188_pinctrl_priv {
 	struct rk3188_grf *grf;
 	struct rk3188_pmu *pmu;
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3399.c b/drivers/pinctrl/rockchip/pinctrl_rk3399.c
index 19a7415..c705225 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3399.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3399.c
@@ -70,6 +70,60 @@
 			     PMUGRF_GPIO1C0_SEL_MASK,
 			     PMUGRF_I2C0PMU_SCL << PMUGRF_GPIO1C0_SEL_SHIFT);
 		break;
+
+	case PERIPH_ID_I2C1:
+		rk_clrsetreg(&grf->gpio4a_iomux,
+			     GRF_GPIO4A1_SEL_MASK,
+			     GRF_I2C1_SDA << GRF_GPIO4A1_SEL_SHIFT);
+		rk_clrsetreg(&grf->gpio4a_iomux,
+			     GRF_GPIO4A2_SEL_MASK,
+			     GRF_I2C1_SCL << GRF_GPIO4A2_SEL_SHIFT);
+		break;
+
+	case PERIPH_ID_I2C2:
+		rk_clrsetreg(&grf->gpio2a_iomux,
+			     GRF_GPIO2A0_SEL_MASK,
+			     GRF_I2C2_SDA << GRF_GPIO2A0_SEL_SHIFT);
+		rk_clrsetreg(&grf->gpio2a_iomux,
+			     GRF_GPIO2A1_SEL_MASK,
+			     GRF_I2C2_SCL << GRF_GPIO2A1_SEL_SHIFT);
+		break;
+	case PERIPH_ID_I2C3:
+		rk_clrsetreg(&grf->gpio4c_iomux,
+			     GRF_GPIO4C0_SEL_MASK,
+			     GRF_HDMII2C_SCL << GRF_GPIO4C0_SEL_SHIFT);
+		rk_clrsetreg(&grf->gpio4c_iomux,
+			     GRF_GPIO4C1_SEL_MASK,
+			     GRF_HDMII2C_SDA << GRF_GPIO4C1_SEL_SHIFT);
+		break;
+
+	case PERIPH_ID_I2C4:
+		rk_clrsetreg(&pmugrf->gpio1b_iomux,
+			     PMUGRF_GPIO1B3_SEL_MASK,
+			     PMUGRF_I2C4_SDA << PMUGRF_GPIO1B3_SEL_SHIFT);
+		rk_clrsetreg(&pmugrf->gpio1b_iomux,
+			     PMUGRF_GPIO1B4_SEL_MASK,
+			     PMUGRF_I2C4_SCL << PMUGRF_GPIO1B4_SEL_SHIFT);
+		break;
+
+	case PERIPH_ID_I2C7:
+		rk_clrsetreg(&grf->gpio2a_iomux,
+			     GRF_GPIO2A7_SEL_MASK,
+			     GRF_I2C7_SDA << GRF_GPIO2A7_SEL_SHIFT);
+		rk_clrsetreg(&grf->gpio2b_iomux,
+			     GRF_GPIO2B0_SEL_MASK,
+			     GRF_I2C7_SCL << GRF_GPIO2B0_SEL_SHIFT);
+		break;
+
+	case PERIPH_ID_I2C6:
+		rk_clrsetreg(&grf->gpio2b_iomux,
+			     GRF_GPIO2B1_SEL_MASK,
+			     GRF_I2C6_SDA << GRF_GPIO2B1_SEL_SHIFT);
+		rk_clrsetreg(&grf->gpio2b_iomux,
+			     GRF_GPIO2B2_SEL_MASK,
+			     GRF_I2C6_SDA << GRF_GPIO2B2_SEL_SHIFT);
+		break;
+
 	case PERIPH_ID_I2C8:
 		rk_clrsetreg(&pmugrf->gpio1c_iomux,
 			     PMUGRF_GPIO1C4_SEL_MASK,
@@ -78,13 +132,8 @@
 			     PMUGRF_GPIO1C5_SEL_MASK,
 			     PMUGRF_I2C8PMU_SCL << PMUGRF_GPIO1C5_SEL_SHIFT);
 		break;
-	case PERIPH_ID_I2C1:
-	case PERIPH_ID_I2C2:
-	case PERIPH_ID_I2C3:
-	case PERIPH_ID_I2C4:
+
 	case PERIPH_ID_I2C5:
-	case PERIPH_ID_I2C6:
-	case PERIPH_ID_I2C7:
 	default:
 		debug("i2c id = %d iomux error!\n", i2c_id);
 		break;
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 76c1fe8..5cb470c 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -1015,6 +1015,7 @@
 	writel(RK_CLRSETBITS(1 << 1, 1 << 1), &dram->cic->cic_ctrl0);
 	while (!(readl(&dram->cic->cic_status0) & (1 << 0))) {
 		mdelay(10);
+		i++;
 		if (i > 10) {
 			debug("index1 frequency done overtime\n");
 			return -ETIME;
diff --git a/drivers/usb/gadget/f_rockusb.c b/drivers/usb/gadget/f_rockusb.c
index d5a10f1..ad3ae91 100644
--- a/drivers/usb/gadget/f_rockusb.c
+++ b/drivers/usb/gadget/f_rockusb.c
@@ -552,7 +552,6 @@
 				 sizeof(struct fsg_bulk_cb_wrap));
 	struct f_rockusb *f_rkusb = get_rkusb();
 
-	f_rkusb->reboot_flag = 0;
 	memcpy((char *)cbw, req->buf, USB_BULK_CB_WRAP_LEN);
 	f_rkusb->reboot_flag = cbw->CDB[1];
 	rockusb_func->in_req->complete = compl_do_reset;
diff --git a/drivers/video/rockchip/rk3288_mipi.c b/drivers/video/rockchip/rk3288_mipi.c
index 953b47f..a7fa9c5 100644
--- a/drivers/video/rockchip/rk3288_mipi.c
+++ b/drivers/video/rockchip/rk3288_mipi.c
@@ -136,7 +136,7 @@
 	struct rk_mipi_priv *priv = dev_get_priv(dev);
 
 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
-	if (IS_ERR(priv->grf)) {
+	if (IS_ERR_OR_NULL(priv->grf)) {
 		debug("%s: Get syscon grf failed (ret=%p)\n",
 		      __func__, priv->grf);
 		return  -ENXIO;
diff --git a/drivers/video/rockchip/rk3399_mipi.c b/drivers/video/rockchip/rk3399_mipi.c
index 9ef202b..b936fce 100644
--- a/drivers/video/rockchip/rk3399_mipi.c
+++ b/drivers/video/rockchip/rk3399_mipi.c
@@ -128,7 +128,7 @@
 	struct rk_mipi_priv *priv = dev_get_priv(dev);
 
 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
-	if (priv->grf <= 0) {
+	if (IS_ERR_OR_NULL(priv->grf)) {
 		debug("%s: Get syscon grf failed (ret=%p)\n",
 		      __func__, priv->grf);
 		return  -ENXIO;
diff --git a/include/configs/adp-ae3xx.h b/include/configs/adp-ae3xx.h
index f5a8dec..1ebbc4c 100644
--- a/include/configs/adp-ae3xx.h
+++ b/include/configs/adp-ae3xx.h
@@ -81,12 +81,6 @@
 #define CONFIG_SYS_NS16550_CLK		((18432000 * 20) / 25)	/* AG101P */
 
 /*
- * SD (MMC) controller
- */
-#define CONFIG_FTSDC010_NUMBER		1
-#define CONFIG_FTSDC010_SDIO
-
-/*
  * Miscellaneous configurable options
  */
 
diff --git a/include/configs/adp-ag101p.h b/include/configs/adp-ag101p.h
index 6ae6fb4..ff365c4 100644
--- a/include/configs/adp-ag101p.h
+++ b/include/configs/adp-ag101p.h
@@ -83,12 +83,6 @@
 #define CONFIG_SYS_NS16550_CLK		((18432000 * 20) / 25)	/* AG101P */
 
 /*
- * SD (MMC) controller
- */
-#define CONFIG_FTSDC010_NUMBER		1
-#define CONFIG_FTSDC010_SDIO
-
-/*
  * Miscellaneous configurable options
  */
 
diff --git a/include/configs/mvebu_armada-8k.h b/include/configs/mvebu_armada-8k.h
index f288cf5..1cd0fa9 100644
--- a/include/configs/mvebu_armada-8k.h
+++ b/include/configs/mvebu_armada-8k.h
@@ -106,4 +106,23 @@
 #define CONFIG_E1000
 #endif
 
+#define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 1) \
+	func(MMC, mmc, 0) \
+	func(USB, usb, 0) \
+	func(SCSI, scsi, 0) \
+	func(PXE, pxe, na) \
+	func(DHCP, dhcp, na)
+
+#include <config_distro_bootcmd.h>
+
+#define CONFIG_EXTRA_ENV_SETTINGS	\
+	"scriptaddr=0x4d00000\0"	\
+	"pxefile_addr_r=0x4e00000\0"	\
+	"fdt_addr_r=0x4f00000\0"	\
+	"kernel_addr_r=0x5000000\0"	\
+	"ramdisk_addr_r=0x8000000\0"	\
+	"fdtfile=marvell/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
+	BOOTENV
+
 #endif /* _CONFIG_MVEBU_ARMADA_8K_H */
diff --git a/include/configs/nx25-ae250.h b/include/configs/nx25-ae250.h
index 73c3c33..0e4c431 100644
--- a/include/configs/nx25-ae250.h
+++ b/include/configs/nx25-ae250.h
@@ -11,18 +11,9 @@
 /*
  * CPU and Board Configuration Options
  */
-#define CONFIG_SKIP_LOWLEVEL_INIT
-
 #define CONFIG_BOOTP_SEND_HOSTNAME
 #define CONFIG_BOOTP_SERVERIP
 
-#ifdef CONFIG_SKIP_LOWLEVEL_INIT
-#ifdef CONFIG_OF_CONTROL
-#undef CONFIG_OF_SEPARATE
-#define CONFIG_OF_EMBED
-#endif
-#endif
-
 /*
  * Miscellaneous configurable options
  */
@@ -50,6 +41,9 @@
  */
 #define CONFIG_SYS_MALLOC_LEN   (512 << 10)
 
+/* DT blob (fdt) address */
+#define CONFIG_SYS_FDT_BASE		0x000f0000
+
 /*
  * Physical Memory Map
  */
@@ -70,12 +64,6 @@
 #endif
 #define CONFIG_SYS_NS16550_CLK		19660800
 
-/*
- * SD (MMC) controller
- */
-#define CONFIG_FTSDC010_NUMBER		1
-#define CONFIG_FTSDC010_SDIO
-
 /* Init Stack Pointer */
 #define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x1000000 - \
 					GENERATED_GBL_DATA_SIZE)
diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
index 8582252..f0e550d 100644
--- a/include/configs/rk3399_common.h
+++ b/include/configs/rk3399_common.h
@@ -59,6 +59,7 @@
 #include <config_distro_bootcmd.h>
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	ENV_MEM_LAYOUT_SETTINGS \
+	"fdtfile=rockchip/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
 	"partitions=" PARTS_DEFAULT \
 	BOOTENV
 
diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c
index 2e8d409..205aa19 100644
--- a/lib/efi/efi_stub.c
+++ b/lib/efi/efi_stub.c
@@ -182,7 +182,7 @@
 				<< 16;
 		base <<= 12;	/* 4KB granularity */
 		limit <<= 12;
-		if ((desc & GDT_PRESENT) && (desc && GDT_NOTSYS) &&
+		if ((desc & GDT_PRESENT) && (desc & GDT_NOTSYS) &&
 		    !(desc & GDT_LONG) && (desc & GDT_4KB) &&
 		    (desc & GDT_32BIT) && (desc & GDT_CODE) &&
 		    CONFIG_SYS_TEXT_BASE > base &&
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 0c7db05..2c26d34 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -741,10 +741,6 @@
 CONFIG_FTRTC010_BASE
 CONFIG_FTRTC010_EXTCLK
 CONFIG_FTRTC010_PCLK
-CONFIG_FTSDC010_BASE
-CONFIG_FTSDC010_BASE_LIST
-CONFIG_FTSDC010_NUMBER
-CONFIG_FTSDC010_SDIO
 CONFIG_FTSDMC021
 CONFIG_FTSDMC021_BASE
 CONFIG_FTSMC020
diff --git a/tools/kwbimage.c b/tools/kwbimage.c
index 3ca3b3b..26686ad 100644
--- a/tools/kwbimage.c
+++ b/tools/kwbimage.c
@@ -1616,6 +1616,10 @@
 				  struct image_tool_params *params)
 {
 	uint8_t checksum;
+	size_t header_size = kwbimage_header_size(ptr);
+
+	if (header_size > image_size)
+		return -FDT_ERR_BADSTRUCTURE;
 
 	if (!main_hdr_checksum_ok(ptr))
 		return -FDT_ERR_BADSTRUCTURE;