Merge tag 'u-boot-rockchip-20211015' of https://source.denx.de/u-boot/custodians/u-boot-rockchip

- Fix for Rockchip mmc HS400 mode;
- Fix for px30 board Odroid Go;
- rockchip_sfc update;
- rk3568 clk update;
- doc fix;
diff --git a/arch/arm/dts/px30.dtsi b/arch/arm/dts/px30.dtsi
index aaa8ae2..ef70648 100644
--- a/arch/arm/dts/px30.dtsi
+++ b/arch/arm/dts/px30.dtsi
@@ -967,7 +967,7 @@
 		clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
 		clock-names = "clk_sfc", "hclk_sfc";
 		pinctrl-names = "default";
-		pinctrl-0 = <&sfc_clk &sfc_cs &sfc_bus4>;
+		pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus4>;
 		power-domains = <&power PX30_PD_MMC_NAND>;
 		status = "disabled";
 	};
@@ -1953,7 +1953,7 @@
 					<1 RK_PA1 3 &pcfg_pull_none>;
 			};
 
-			sfc_cs: sfc-cs {
+			sfc_cs0: sfc-cs0 {
 				rockchip,pins =
 					<1 RK_PA4 3 &pcfg_pull_none>;
 			};
diff --git a/arch/arm/dts/rk3326-odroid-go2-u-boot.dtsi b/arch/arm/dts/rk3326-odroid-go2-u-boot.dtsi
index 741e8dd..bffaa3e 100644
--- a/arch/arm/dts/rk3326-odroid-go2-u-boot.dtsi
+++ b/arch/arm/dts/rk3326-odroid-go2-u-boot.dtsi
@@ -18,8 +18,18 @@
 	};
 };
 
+/* U-Boot clk driver for px30 cannot set GPU_CLK */
 &cru {
 	u-boot,dm-pre-reloc;
+	assigned-clocks = <&cru PLL_NPLL>,
+		<&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>,
+		<&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>,
+		<&cru PCLK_BUS_PRE>, <&cru PLL_CPLL>;
+
+	assigned-clock-rates = <1188000000>,
+		<200000000>, <200000000>,
+		<150000000>, <150000000>,
+		<100000000>, <17000000>;
 };
 
 &dmc {
@@ -70,7 +80,7 @@
 	u-boot,dm-pre-reloc;
 };
 
-&spi_flash {
+&{/sfc@ff3a0000/flash@0} {
 	u-boot,dm-pre-reloc;
 };
 
diff --git a/arch/arm/dts/rk3326-odroid-go2.dts b/arch/arm/dts/rk3326-odroid-go2.dts
index 6f91f50..4e3dcee 100644
--- a/arch/arm/dts/rk3326-odroid-go2.dts
+++ b/arch/arm/dts/rk3326-odroid-go2.dts
@@ -618,18 +618,18 @@
 };
 
 &sfc {
+	pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus2>;
+	pinctrl-names = "default";
 	#address-cells = <1>;
 	#size-cells = <0>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&sfc_clk &sfc_cs &sfc_bus2>;
 	status = "okay";
 
-	spi_flash: xt25f128b@0 {
+	flash@0 {
 		compatible = "jedec,spi-nor";
 		reg = <0>;
 		spi-max-frequency = <108000000>;
 		spi-rx-bus-width = <2>;
-		spi-tx-bus-width = <2>;
+		spi-tx-bus-width = <1>;
 	};
 };
 
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3568.h b/arch/arm/include/asm/arch-rockchip/cru_rk3568.h
index 6c59033..399f19a 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rk3568.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3568.h
@@ -14,7 +14,7 @@
 #define APLL_HZ		(816 * MHz)
 #define GPLL_HZ		(1188 * MHz)
 #define CPLL_HZ		(1000 * MHz)
-#define PPLL_HZ		(100 * MHz)
+#define PPLL_HZ		(200 * MHz)
 
 /* RK3568 pll id */
 enum rk3568_pll_id {
diff --git a/configs/lion-rk3368_defconfig b/configs/lion-rk3368_defconfig
index e214cf5..7f62811 100644
--- a/configs/lion-rk3368_defconfig
+++ b/configs/lion-rk3368_defconfig
@@ -96,7 +96,6 @@
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_DWC2=y
-CONFIG_ROCKCHIP_USB2_PHY=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DWC2_OTG=y
 CONFIG_SPL_TINY_MEMSET=y
diff --git a/configs/nanopc-t4-rk3399_defconfig b/configs/nanopc-t4-rk3399_defconfig
index d86faf1..f31668c 100644
--- a/configs/nanopc-t4-rk3399_defconfig
+++ b/configs/nanopc-t4-rk3399_defconfig
@@ -53,7 +53,6 @@
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_DWC3=y
-CONFIG_ROCKCHIP_USB2_PHY=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
diff --git a/configs/roc-pc-mezzanine-rk3399_defconfig b/configs/roc-pc-mezzanine-rk3399_defconfig
index 199624f..ca2fb9e 100644
--- a/configs/roc-pc-mezzanine-rk3399_defconfig
+++ b/configs/roc-pc-mezzanine-rk3399_defconfig
@@ -71,7 +71,6 @@
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3_GENERIC=y
-CONFIG_ROCKCHIP_USB2_PHY=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
diff --git a/configs/roc-pc-rk3399_defconfig b/configs/roc-pc-rk3399_defconfig
index bc124c8..de35a62 100644
--- a/configs/roc-pc-rk3399_defconfig
+++ b/configs/roc-pc-rk3399_defconfig
@@ -68,7 +68,6 @@
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3_GENERIC=y
-CONFIG_ROCKCHIP_USB2_PHY=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
diff --git a/configs/rock-pi-n10-rk3399pro_defconfig b/configs/rock-pi-n10-rk3399pro_defconfig
index 0b89ae9..bd8b120 100644
--- a/configs/rock-pi-n10-rk3399pro_defconfig
+++ b/configs/rock-pi-n10-rk3399pro_defconfig
@@ -62,7 +62,6 @@
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3_GENERIC=y
-CONFIG_ROCKCHIP_USB2_PHY=y
 CONFIG_USB_KEYBOARD=y
 # CONFIG_USB_KEYBOARD_FN_KEYS is not set
 CONFIG_USB_GADGET=y
diff --git a/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst
index fbb9983..144cb98 100644
--- a/doc/board/rockchip/rockchip.rst
+++ b/doc/board/rockchip/rockchip.rst
@@ -16,16 +16,18 @@
 Rockchip is SoC solutions provider for tablets & PCs, streaming media
 TV boxes, AI audio & vision, IoT hardware.
 
-A wide range of Rockchip SoCs with associated boardsare supported in
+A wide range of Rockchip SoCs with associated boards are supported in
 mainline U-Boot.
 
-List of mainline supported rockchip boards:
+List of mainline supported Rockchip boards:
 
 * rk3036
      - Rockchip Evb-RK3036 (evb-rk3036)
      - Kylin (kylin_rk3036)
 * rk3128
      - Rockchip Evb-RK3128 (evb-rk3128)
+* rk3188
+     - Radxa Rock (rock)
 * rk3229
      - Rockchip Evb-RK3229 (evb-rk3229)
 * rk3288
@@ -75,8 +77,6 @@
 * rv1108
      - Rockchip Evb-rv1108 (evb-rv1108)
      - Elgin-R1 (elgin-rv1108)
-* rv3188
-     - Radxa Rock (rock)
 
 Building
 --------
@@ -93,7 +93,7 @@
         make realclean
         make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3399
 
-Specify the PLAT= with desired rockchip platform to build TF-A for.
+Specify the PLAT= with desired Rockchip platform to build TF-A for.
 
 U-Boot
 ^^^^^^
@@ -130,7 +130,7 @@
 SD Card
 ^^^^^^^
 
-All rockchip platforms, except rk3128 (which doesn't use SPL) are now
+All Rockchip platforms, except rk3128 (which doesn't use SPL) are now
 supporting single boot image using binman and pad_cat.
 
 To write an image that boots from an SD card (assumed to be /dev/sda)::
@@ -141,7 +141,7 @@
 eMMC
 ^^^^
 
-eMMC flash would probe on mmc0 in most of the rockchip platforms.
+eMMC flash would probe on mmc0 in most of the Rockchip platforms.
 
 Create GPT partition layout as defined in configurations::
 
@@ -164,7 +164,7 @@
         sudo fastboot -i 0x2207 flash loader1 idbloader.img
         sudo fastboot -i 0x2207 flash loader2 u-boot.itb
 
-Note: for rockchip 32-bit platforms the U-Boot proper image
+Note: for Rockchip 32-bit platforms the U-Boot proper image
 is u-boot-dtb.img
 
 SPI
@@ -227,8 +227,8 @@
 TODO
 ----
 
-- Add rockchip idbloader image building
-- Add rockchip TPL image building
+- Add Rockchip idbloader image building
+- Add Rockchip TPL image building
 - Document SPI flash boot
 - Add missing SoC's with it boards list
 
diff --git a/drivers/clk/rockchip/clk_px30.c b/drivers/clk/rockchip/clk_px30.c
index 617ce0d..ea874e3 100644
--- a/drivers/clk/rockchip/clk_px30.c
+++ b/drivers/clk/rockchip/clk_px30.c
@@ -1291,6 +1291,9 @@
 	case PLL_NPLL:
 		ret = px30_clk_set_pll_rate(priv, NPLL, rate);
 		break;
+	case PLL_CPLL:
+		ret = px30_clk_set_pll_rate(priv, CPLL, rate);
+		break;
 	case ARMCLK:
 		ret = px30_armclk_set_clk(priv, rate);
 		break;
diff --git a/drivers/clk/rockchip/clk_rk3568.c b/drivers/clk/rockchip/clk_rk3568.c
index 553c6c0..d5e45e7 100644
--- a/drivers/clk/rockchip/clk_rk3568.c
+++ b/drivers/clk/rockchip/clk_rk3568.c
@@ -1441,6 +1441,7 @@
 
 	switch (rate) {
 	case OSC_HZ:
+	case 26 * MHz:
 		src_clk = CLK_SDMMC_SEL_24M;
 		break;
 	case 400 * MHz:
@@ -1507,7 +1508,7 @@
 	case SCLK_SFC_SEL_125M:
 		return 125 * MHz;
 	case SCLK_SFC_SEL_150M:
-		return 150 * KHz;
+		return 150 * MHz;
 	default:
 		return -ENOENT;
 	}
@@ -1534,7 +1535,7 @@
 	case 125 * MHz:
 		src_clk = SCLK_SFC_SEL_125M;
 		break;
-	case 150 * KHz:
+	case 150 * MHz:
 		src_clk = SCLK_SFC_SEL_150M;
 		break;
 	default:
@@ -2406,6 +2407,9 @@
 	case BCLK_EMMC:
 		rate = rk3568_emmc_get_bclk(priv);
 		break;
+	case TCLK_EMMC:
+		rate = OSC_HZ;
+		break;
 #ifndef CONFIG_SPL_BUILD
 	case ACLK_VOP:
 		rate = rk3568_aclk_vop_get_clk(priv);
@@ -2582,6 +2586,9 @@
 	case BCLK_EMMC:
 		ret = rk3568_emmc_set_bclk(priv, rate);
 		break;
+	case TCLK_EMMC:
+		ret = OSC_HZ;
+		break;
 #ifndef CONFIG_SPL_BUILD
 	case ACLK_VOP:
 		ret = rk3568_aclk_vop_set_clk(priv, rate);
diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index 1ac0058..2784738 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -143,6 +143,9 @@
 	writel(RK_CLRSETBITS(3 << 12, freqsel << 12), &phy->emmcphy_con[0]);
 	writel(RK_CLRSETBITS(1 << 1, 1 << 1), &phy->emmcphy_con[6]);
 
+	/* REN Enable on STRB Line for HS400 */
+	writel(RK_CLRSETBITS(0, 1 << 9), &phy->emmcphy_con[2]);
+
 	read_poll_timeout(readl, &phy->emmcphy_status, dllrdy,
 			  PHYCTRL_DLL_LOCK_WO_TMOUT(dllrdy), 1, 5000);
 }
diff --git a/drivers/spi/rockchip_sfc.c b/drivers/spi/rockchip_sfc.c
index 4e2b861..e098add 100644
--- a/drivers/spi/rockchip_sfc.c
+++ b/drivers/spi/rockchip_sfc.c
@@ -116,6 +116,7 @@
 
 /* Master trigger */
 #define SFC_DMA_TRIGGER			0x80
+#define SFC_DMA_TRIGGER_START		1
 
 /* Src or Dst addr for master */
 #define SFC_DMA_ADDR			0x84
@@ -163,14 +164,12 @@
 #define SFC_DMA_TRANS_THRETHOLD		(0x40)
 
 /* Maximum clock values from datasheet suggest keeping clock value under
- * 150MHz. No minimum or average value is suggested, but the U-boot BSP driver
- * has a minimum of 10MHz and a default of 80MHz which seems reasonable.
+ * 150MHz. No minimum or average value is suggested.
  */
-#define SFC_MIN_SPEED_HZ		(10 * 1000 * 1000)
-#define SFC_DEFAULT_SPEED_HZ		(80 * 1000 * 1000)
-#define SFC_MAX_SPEED_HZ		(150 * 1000 * 1000)
+#define SFC_MAX_SPEED		(150 * 1000 * 1000)
 
 struct rockchip_sfc {
+	struct udevice *dev;
 	void __iomem *regbase;
 	struct clk hclk;
 	struct clk clk;
@@ -197,8 +196,6 @@
 	/* Still need to clear the masked interrupt from RISR */
 	writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
 
-	debug("reset\n");
-
 	return err;
 }
 
@@ -261,15 +258,11 @@
 #if CONFIG_IS_ENABLED(CLK)
 	ret = clk_enable(&sfc->hclk);
 	if (ret)
-		debug("Enable ahb clock fail %s: %d\n", bus->name, ret);
+		dev_dbg(sfc->dev, "sfc Enable ahb clock fail %s: %d\n", bus->name, ret);
 
 	ret = clk_enable(&sfc->clk);
 	if (ret)
-		debug("Enable clock fail for %s: %d\n", bus->name, ret);
-
-	ret = clk_set_rate(&sfc->clk, SFC_DEFAULT_SPEED_HZ);
-	if (ret)
-		debug("Could not set sfc clock for %s: %d\n", bus->name, ret);
+		dev_dbg(sfc->dev, "sfc Enable clock fail for %s: %d\n", bus->name, ret);
 #endif
 
 	ret = rockchip_sfc_init(sfc);
@@ -278,7 +271,8 @@
 
 	sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc);
 	sfc->version = rockchip_sfc_get_version(sfc);
-	sfc->speed = SFC_DEFAULT_SPEED_HZ;
+	sfc->max_freq = SFC_MAX_SPEED;
+	sfc->dev = bus;
 
 	return 0;
 
@@ -291,33 +285,38 @@
 	return ret;
 }
 
-static inline int rockchip_sfc_get_fifo_level(struct rockchip_sfc *sfc, int wr)
+static int rockchip_sfc_wait_txfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
 {
-	u32 fsr = readl(sfc->regbase + SFC_FSR);
-	int level;
+	int ret = 0;
+	u32 status;
 
-	if (wr)
-		level = (fsr & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
-	else
-		level = (fsr & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;
+	ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
+				 status & SFC_FSR_TXLV_MASK,
+				 timeout_us);
+	if (ret) {
+		dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n");
+
+		return -ETIMEDOUT;
+	}
 
-	return level;
+	return (status & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
 }
 
-static int rockchip_sfc_wait_fifo_ready(struct rockchip_sfc *sfc, int wr, u32 timeout)
+static int rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
 {
-	unsigned long tbase = get_timer(0);
-	int level;
+	int ret = 0;
+	u32 status;
 
-	while (!(level = rockchip_sfc_get_fifo_level(sfc, wr))) {
-		if (get_timer(tbase) > timeout) {
-			debug("%s fifo timeout\n", wr ? "write" : "read");
-			return -ETIMEDOUT;
-		}
-		udelay(1);
+	ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
+				 status & SFC_FSR_RXLV_MASK,
+				 timeout_us);
+	if (ret) {
+		dev_dbg(sfc->dev, "sfc wait rx fifo timeout\n");
+
+		return -ETIMEDOUT;
 	}
 
-	return level;
+	return (status & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;
 }
 
 static void rockchip_sfc_adjust_op_work(struct spi_mem_op *op)
@@ -411,11 +410,11 @@
 	ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE;
 	cmd |= plat->cs << SFC_CMD_CS_SHIFT;
 
-	debug("addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n",
-	      op->addr.nbytes, op->addr.buswidth,
-	      op->dummy.nbytes, op->dummy.buswidth);
-	debug("ctrl=%x cmd=%x addr=%llx len=%x\n",
-	      ctrl, cmd, op->addr.val, len);
+	dev_dbg(sfc->dev, "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n",
+		op->addr.nbytes, op->addr.buswidth,
+		op->dummy.nbytes, op->dummy.buswidth);
+	dev_dbg(sfc->dev, "sfc ctrl=%x cmd=%x addr=%llx len=%x\n",
+		ctrl, cmd, op->addr.val, len);
 
 	writel(ctrl, sfc->regbase + SFC_CTRL);
 	writel(cmd, sfc->regbase + SFC_CMD);
@@ -435,7 +434,7 @@
 
 	dwords = len >> 2;
 	while (dwords) {
-		tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_WR, 1000);
+		tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);
 		if (tx_level < 0)
 			return tx_level;
 		write_words = min_t(u32, tx_level, dwords);
@@ -446,7 +445,7 @@
 
 	/* write the rest non word aligned bytes */
 	if (bytes) {
-		tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_WR, 1000);
+		tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);
 		if (tx_level < 0)
 			return tx_level;
 		memcpy(&tmp, buf, bytes);
@@ -467,7 +466,7 @@
 	/* word aligned access only */
 	dwords = len >> 2;
 	while (dwords) {
-		rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_RD, 1000);
+		rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);
 		if (rx_level < 0)
 			return rx_level;
 		read_words = min_t(u32, rx_level, dwords);
@@ -478,7 +477,7 @@
 
 	/* read the rest non word aligned bytes */
 	if (bytes) {
-		rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_RD, 1000);
+		rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);
 		if (rx_level < 0)
 			return rx_level;
 		tmp = readl(sfc->regbase + SFC_DATA);
@@ -492,7 +491,7 @@
 {
 	writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
 	writel((u32)dma_buf, sfc->regbase + SFC_DMA_ADDR);
-	writel(0x1, sfc->regbase + SFC_DMA_TRIGGER);
+	writel(SFC_DMA_TRIGGER_START, sfc->regbase + SFC_DMA_TRIGGER);
 
 	return len;
 }
@@ -500,7 +499,7 @@
 static int rockchip_sfc_xfer_data_poll(struct rockchip_sfc *sfc,
 				       const struct spi_mem_op *op, u32 len)
 {
-	debug("xfer_poll len=%x\n", len);
+	dev_dbg(sfc->dev, "sfc xfer_poll len=%x\n", len);
 
 	if (op->data.dir == SPI_MEM_DATA_OUT)
 		return rockchip_sfc_write_fifo(sfc, op->data.buf.out, len);
@@ -516,7 +515,7 @@
 	void *dma_buf;
 	int ret;
 
-	debug("xfer_dma len=%x\n", len);
+	dev_dbg(sfc->dev, "sfc xfer_dma len=%x\n", len);
 
 	if (op->data.dir == SPI_MEM_DATA_OUT) {
 		dma_buf = (void *)op->data.buf.out;
@@ -539,19 +538,17 @@
 
 static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us)
 {
-	unsigned long tbase = get_timer(0);
 	int ret = 0;
-	u32 timeout = timeout_us;
-
-	while (readl(sfc->regbase + SFC_SR) & SFC_SR_IS_BUSY) {
-		if (get_timer(tbase) > timeout) {
-			printf("wait sfc idle timeout\n");
-			rockchip_sfc_reset(sfc);
+	u32 status;
 
-			return -ETIMEDOUT;
-		}
+	ret = readl_poll_timeout(sfc->regbase + SFC_SR, status,
+				 !(status & SFC_SR_IS_BUSY),
+				 timeout_us);
+	if (ret) {
+		dev_err(sfc->dev, "wait sfc idle timeout\n");
+		rockchip_sfc_reset(sfc);
 
-		udelay(1);
+		ret = -EIO;
 	}
 
 	return ret;
@@ -564,33 +561,16 @@
 	u32 len = min_t(u32, op->data.nbytes, sfc->max_iosize);
 	int ret;
 
-#if CONFIG_IS_ENABLED(CLK)
-	if (unlikely(mem->max_hz != sfc->speed)) {
-		ret = clk_set_rate(&sfc->clk, clamp(mem->max_hz, (uint)SFC_MIN_SPEED_HZ,
-						    (uint)SFC_MAX_SPEED_HZ));
-		if (ret < 0) {
-			printf("set_freq=%dHz fail, check if it's the cru support level\n",
-			       mem->max_hz);
-			return ret;
-		}
-
-		sfc->max_freq = mem->max_hz;
-		sfc->speed = mem->max_hz;
-		debug("set_freq=%dHz real_freq=%dHz\n", sfc->max_freq, sfc->speed);
-	}
-#endif
-
 	rockchip_sfc_adjust_op_work((struct spi_mem_op *)op);
-
 	rockchip_sfc_xfer_setup(sfc, mem, op, len);
 	if (len) {
-		if (likely(sfc->use_dma) && !(len & 0x3) && len >= SFC_DMA_TRANS_THRETHOLD)
+		if (likely(sfc->use_dma) && len >= SFC_DMA_TRANS_THRETHOLD)
 			ret = rockchip_sfc_xfer_data_dma(sfc, op, len);
 		else
 			ret = rockchip_sfc_xfer_data_poll(sfc, op, len);
 
 		if (ret != len) {
-			printf("xfer data failed ret %d dir %d\n", ret, op->data.dir);
+			dev_err(sfc->dev, "xfer data failed ret %d dir %d\n", ret, op->data.dir);
 
 			return -EIO;
 		}
@@ -604,13 +584,32 @@
 	struct rockchip_sfc *sfc = dev_get_plat(mem->dev->parent);
 
 	op->data.nbytes = min(op->data.nbytes, sfc->max_iosize);
+
 	return 0;
 }
 
 static int rockchip_sfc_set_speed(struct udevice *bus, uint speed)
 {
-	/* We set up speed later for each transmission.
-	 */
+	struct rockchip_sfc *sfc = dev_get_plat(bus);
+
+	if (speed > sfc->max_freq)
+		speed = sfc->max_freq;
+
+	if (speed == sfc->speed)
+		return 0;
+
+#if CONFIG_IS_ENABLED(CLK)
+	int ret = clk_set_rate(&sfc->clk, speed);
+
+	if (ret < 0) {
+		dev_err(sfc->dev, "set_freq=%dHz fail, check if it's the cru support level\n",
+			speed);
+		return ret;
+	}
+	sfc->speed = speed;
+#else
+	dev_dbg(sfc->dev, "sfc failed, CLK not support\n");
+#endif
 	return 0;
 }