[PATCH 0/3] rockchip: rk3588: Fix sdmmc clocks

Booting from sdmmc on RK3588 currently works because of a workaround in the device tree, clocks are reordered so that the driver use ciu-sample instead of ciu, and the BootRom initializes sdmmc clocks before SPL is loaded into DRAM.
The sdmmc clocks are normally controlled by TF-A using SCMI. However, there is a need to control these clocks in SPL, before TF-A has started.
This series adds a rk3588_scru driver to control the sdmmc clocks in SPL before TF-A has started, using scru regs. It also adds a small glue driver to bind the scmi clock node to the rk3588_scru driver in SPL. The SCMI agent and clk_scmi driver is used to control the clocks in U-Boot proper, after TF-A has started.
Patch 1 fixes an issue building SPL with clk_scmi driver enabled. Patch 2 adds drivers the scru and glue drivers. Patch 3 updates device tree and Kconfig options to use the new drivers.
I have tried to address some of the early feedback from [1].
This series is based on top of [2] and [3] and can also be found at [4].
[1] https://patchwork.ozlabs.org/project/uboot/cover/20230125222741.303259-1-jag... [2] https://patchwork.ozlabs.org/project/uboot/cover/20230314003755.512696-1-jon... [3] https://patchwork.ozlabs.org/project/uboot/patch/20230228213822.3583989-1-jo... [4] https://github.com/Kwiboo/u-boot-rockchip/commits/rk3588-sdmmc-v1
Jonas Karlman (3): clk: scmi: Add Kconfig option for SPL rockchip: rk3588: Add support for sdmmc clocks in SPL rockchip: rk3588: Sync sdmmc node from linux-next
.../dts/rk3588-edgeble-neu6a-io-u-boot.dtsi | 2 - arch/arm/dts/rk3588-rock-5b-u-boot.dtsi | 2 - arch/arm/dts/rk3588s-u-boot.dtsi | 27 ++-- arch/arm/dts/rk3588s.dtsi | 15 +++ arch/arm/include/asm/arch-rockchip/clock.h | 1 - .../include/asm/arch-rockchip/cru_rk3588.h | 19 ++- arch/arm/mach-rockchip/Kconfig | 2 + drivers/clk/Kconfig | 8 ++ drivers/clk/Makefile | 2 +- drivers/clk/rockchip/clk_rk3588.c | 125 ++++++++++++++++++ drivers/firmware/scmi/scmi_agent-uclass.c | 2 +- 11 files changed, 183 insertions(+), 22 deletions(-)

Building U-Boot SPL with CLK_SCMI and SCMI_FIRMWARE Kconfig options enabled and SPL_FIRMWARE disabled result in the following error.
drivers/clk/clk_scmi.o: in function `scmi_clk_gate': drivers/clk/clk_scmi.c:84: undefined reference to `devm_scmi_process_msg' drivers/clk/clk_scmi.c:88: undefined reference to `scmi_to_linux_errno' drivers/clk/clk_scmi.o: in function `scmi_clk_get_rate': drivers/clk/clk_scmi.c:113: undefined reference to `devm_scmi_process_msg' drivers/clk/clk_scmi.c:117: undefined reference to `scmi_to_linux_errno' drivers/clk/clk_scmi.o: in function `scmi_clk_set_rate': drivers/clk/clk_scmi.c:139: undefined reference to `devm_scmi_process_msg' drivers/clk/clk_scmi.c:143: undefined reference to `scmi_to_linux_errno' drivers/clk/clk_scmi.o: in function `scmi_clk_probe': drivers/clk/clk_scmi.c:157: undefined reference to `devm_scmi_of_get_channel' make[1]: *** [scripts/Makefile.spl:527: spl/u-boot-spl] Error 1 make: *** [Makefile:2043: spl/u-boot-spl] Error 2
Add Kconfig option so that CLK_SCMI can be disabled in SPL to fix this.
Signed-off-by: Jonas Karlman jonas@kwiboo.se --- drivers/clk/Kconfig | 8 ++++++++ drivers/clk/Makefile | 2 +- drivers/firmware/scmi/scmi_agent-uclass.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 09aa97ee8c0e..458dad9e844b 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -166,6 +166,14 @@ config CLK_SCMI by a SCMI agent based on SCMI clock protocol communication with a SCMI server.
+config SPL_CLK_SCMI + bool "Enable SCMI clock driver in SPL" + depends on SCMI_FIRMWARE && SPL_FIRMWARE + help + Enable this option if you want to support clock devices exposed + by a SCMI agent based on SCMI clock protocol communication + with a SCMI server in SPL. + config CLK_HSDK bool "Enable cgu clock driver for HSDK boards" depends on CLK && TARGET_HSDK diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index c274cda77c6a..c1347774b58c 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -39,7 +39,7 @@ obj-$(CONFIG_CLK_MVEBU) += mvebu/ obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o obj-$(CONFIG_CLK_OWL) += owl/ obj-$(CONFIG_CLK_RENESAS) += renesas/ -obj-$(CONFIG_CLK_SCMI) += clk_scmi.o +obj-$(CONFIG_$(SPL_TPL_)CLK_SCMI) += clk_scmi.o obj-$(CONFIG_CLK_SIFIVE) += sifive/ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/ obj-$(CONFIG_CLK_VERSACLOCK) += clk_versaclock.o diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c index 9a32678617d7..54d563d929b8 100644 --- a/drivers/firmware/scmi/scmi_agent-uclass.c +++ b/drivers/firmware/scmi/scmi_agent-uclass.c @@ -75,7 +75,7 @@ static int scmi_bind_protocols(struct udevice *dev) name = ofnode_get_name(node); switch (protocol_id) { case SCMI_PROTOCOL_ID_CLOCK: - if (IS_ENABLED(CONFIG_CLK_SCMI)) + if (CONFIG_IS_ENABLED(CLK_SCMI)) drv = DM_DRIVER_GET(scmi_clock); break; case SCMI_PROTOCOL_ID_RESET_DOMAIN:

On 2023/3/18 03:16, Jonas Karlman wrote:
Building U-Boot SPL with CLK_SCMI and SCMI_FIRMWARE Kconfig options enabled and SPL_FIRMWARE disabled result in the following error.
drivers/clk/clk_scmi.o: in function `scmi_clk_gate': drivers/clk/clk_scmi.c:84: undefined reference to `devm_scmi_process_msg' drivers/clk/clk_scmi.c:88: undefined reference to `scmi_to_linux_errno' drivers/clk/clk_scmi.o: in function `scmi_clk_get_rate': drivers/clk/clk_scmi.c:113: undefined reference to `devm_scmi_process_msg' drivers/clk/clk_scmi.c:117: undefined reference to `scmi_to_linux_errno' drivers/clk/clk_scmi.o: in function `scmi_clk_set_rate': drivers/clk/clk_scmi.c:139: undefined reference to `devm_scmi_process_msg' drivers/clk/clk_scmi.c:143: undefined reference to `scmi_to_linux_errno' drivers/clk/clk_scmi.o: in function `scmi_clk_probe': drivers/clk/clk_scmi.c:157: undefined reference to `devm_scmi_of_get_channel' make[1]: *** [scripts/Makefile.spl:527: spl/u-boot-spl] Error 1 make: *** [Makefile:2043: spl/u-boot-spl] Error 2
Add Kconfig option so that CLK_SCMI can be disabled in SPL to fix this.
Signed-off-by: Jonas Karlman jonas@kwiboo.se
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
drivers/clk/Kconfig | 8 ++++++++ drivers/clk/Makefile | 2 +- drivers/firmware/scmi/scmi_agent-uclass.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 09aa97ee8c0e..458dad9e844b 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -166,6 +166,14 @@ config CLK_SCMI by a SCMI agent based on SCMI clock protocol communication with a SCMI server.
+config SPL_CLK_SCMI
- bool "Enable SCMI clock driver in SPL"
- depends on SCMI_FIRMWARE && SPL_FIRMWARE
- help
Enable this option if you want to support clock devices exposed
by a SCMI agent based on SCMI clock protocol communication
with a SCMI server in SPL.
- config CLK_HSDK bool "Enable cgu clock driver for HSDK boards" depends on CLK && TARGET_HSDK
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index c274cda77c6a..c1347774b58c 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -39,7 +39,7 @@ obj-$(CONFIG_CLK_MVEBU) += mvebu/ obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o obj-$(CONFIG_CLK_OWL) += owl/ obj-$(CONFIG_CLK_RENESAS) += renesas/ -obj-$(CONFIG_CLK_SCMI) += clk_scmi.o +obj-$(CONFIG_$(SPL_TPL_)CLK_SCMI) += clk_scmi.o obj-$(CONFIG_CLK_SIFIVE) += sifive/ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/ obj-$(CONFIG_CLK_VERSACLOCK) += clk_versaclock.o diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c index 9a32678617d7..54d563d929b8 100644 --- a/drivers/firmware/scmi/scmi_agent-uclass.c +++ b/drivers/firmware/scmi/scmi_agent-uclass.c @@ -75,7 +75,7 @@ static int scmi_bind_protocols(struct udevice *dev) name = ofnode_get_name(node); switch (protocol_id) { case SCMI_PROTOCOL_ID_CLOCK:
if (IS_ENABLED(CONFIG_CLK_SCMI))
case SCMI_PROTOCOL_ID_RESET_DOMAIN:if (CONFIG_IS_ENABLED(CLK_SCMI)) drv = DM_DRIVER_GET(scmi_clock); break;

Booting from sdmmc on RK3588 currently works because of a workaround in the device tree, clocks are reordered so that the driver use ciu-sample instead of ciu, and the BootRom initializes sdmmc clocks before SPL is loaded into DRAM.
The sdmmc clocks are normally controlled by TF-A using SCMI. However, there is a need to control these clocks in SPL, before TF-A has started.
This adds a rk3588_scru driver to control the sdmmc clocks in SPL before TF-A has started, using scru regs. It also adds a small glue driver to bind the scmi clock node to the rk3588_scru driver in SPL.
Fixes: 7a474df74023 ("clk: rockchip: Add rk3588 clk support") Signed-off-by: Jonas Karlman jonas@kwiboo.se --- arch/arm/include/asm/arch-rockchip/clock.h | 1 - .../include/asm/arch-rockchip/cru_rk3588.h | 19 ++- drivers/clk/rockchip/clk_rk3588.c | 125 ++++++++++++++++++ 3 files changed, 143 insertions(+), 2 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/clock.h b/arch/arm/include/asm/arch-rockchip/clock.h index 90e66c7da049..f002ebcb7ac1 100644 --- a/arch/arm/include/asm/arch-rockchip/clock.h +++ b/arch/arm/include/asm/arch-rockchip/clock.h @@ -194,6 +194,5 @@ int rockchip_get_clk(struct udevice **devp); * Return: 0 success, or error value */ int rockchip_reset_bind(struct udevice *pdev, u32 reg_offset, u32 reg_number); -int rockchip_get_scmi_clk(struct udevice **devp);
#endif diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3588.h b/arch/arm/include/asm/arch-rockchip/cru_rk3588.h index 3ea59e900861..7f4a90853929 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk3588.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3588.h @@ -11,12 +11,12 @@ #define KHz 1000 #define OSC_HZ (24 * MHz)
-#define CPU_PVTPLL_HZ (1008 * MHz) #define LPLL_HZ (816 * MHz) #define GPLL_HZ (1188 * MHz) #define CPLL_HZ (1500 * MHz) #define NPLL_HZ (850 * MHz) #define PPLL_HZ (1100 * MHz) +#define SPLL_HZ (702 * MHz)
/* RK3588 pll id */ enum rk3588_pll_id { @@ -447,5 +447,22 @@ enum { CLK_I2C0_SEL_MASK = 1 << CLK_I2C0_SEL_SHIFT, CLK_I2C_SEL_200M = 0, CLK_I2C_SEL_100M, + + /* SECURECRU_CLKSEL_CON01 */ + SCMI_HCLK_SD_SEL_SHIFT = 2, + SCMI_HCLK_SD_SEL_MASK = 3 << SCMI_HCLK_SD_SEL_SHIFT, + SCMI_HCLK_SD_SEL_150M = 0, + SCMI_HCLK_SD_SEL_100M, + SCMI_HCLK_SD_SEL_50M, + SCMI_HCLK_SD_SEL_24M, + + /* SECURECRU_CLKSEL_CON03 */ + SCMI_CCLK_SD_SEL_SHIFT = 12, + SCMI_CCLK_SD_SEL_MASK = 3 << SCMI_CCLK_SD_SEL_SHIFT, + SCMI_CCLK_SD_SEL_GPLL = 0, + SCMI_CCLK_SD_SEL_SPLL, + SCMI_CCLK_SD_SEL_24M, + SCMI_CCLK_SD_DIV_SHIFT = 6, + SCMI_CCLK_SD_DIV_MASK = 0x3f << SCMI_CCLK_SD_DIV_SHIFT, }; #endif diff --git a/drivers/clk/rockchip/clk_rk3588.c b/drivers/clk/rockchip/clk_rk3588.c index a7df553e8750..41e31b61a55b 100644 --- a/drivers/clk/rockchip/clk_rk3588.c +++ b/drivers/clk/rockchip/clk_rk3588.c @@ -9,6 +9,7 @@ #include <clk-uclass.h> #include <dm.h> #include <errno.h> +#include <scmi_protocols.h> #include <syscon.h> #include <asm/arch-rockchip/cru_rk3588.h> #include <asm/arch-rockchip/clock.h> @@ -1994,3 +1995,127 @@ U_BOOT_DRIVER(rockchip_rk3588_cru) = { .bind = rk3588_clk_bind, .probe = rk3588_clk_probe, }; + +#ifdef CONFIG_SPL_BUILD +#define SCRU_BASE 0xfd7d0000 + +static ulong rk3588_scru_clk_get_rate(struct clk *clk) +{ + u32 con, div, sel, parent; + + switch (clk->id) { + case SCMI_CCLK_SD: + con = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)); + sel = (con & SCMI_CCLK_SD_SEL_MASK) >> SCMI_CCLK_SD_SEL_SHIFT; + div = (con & SCMI_CCLK_SD_DIV_MASK) >> SCMI_CCLK_SD_DIV_SHIFT; + if (sel == SCMI_CCLK_SD_SEL_GPLL) + parent = GPLL_HZ; + else if (sel == SCMI_CCLK_SD_SEL_SPLL) + parent = SPLL_HZ; + else + parent = OSC_HZ; + return DIV_TO_RATE(parent, div); + case SCMI_HCLK_SD: + con = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)); + sel = (con & SCMI_HCLK_SD_SEL_MASK) >> SCMI_HCLK_SD_SEL_SHIFT; + if (sel == SCMI_HCLK_SD_SEL_150M) + return 150 * MHz; + else if (sel == SCMI_HCLK_SD_SEL_100M) + return 100 * MHz; + else if (sel == SCMI_HCLK_SD_SEL_50M) + return 50 * MHz; + else + return OSC_HZ; + default: + return -ENOENT; + } +} + +static ulong rk3588_scru_clk_set_rate(struct clk *clk, ulong rate) +{ + u32 div, sel; + + switch (clk->id) { + case SCMI_CCLK_SD: + if ((OSC_HZ % rate) == 0) { + sel = SCMI_CCLK_SD_SEL_24M; + div = DIV_ROUND_UP(OSC_HZ, rate); + } else if ((SPLL_HZ % rate) == 0) { + sel = SCMI_CCLK_SD_SEL_SPLL; + div = DIV_ROUND_UP(SPLL_HZ, rate); + } else { + sel = SCMI_CCLK_SD_SEL_GPLL; + div = DIV_ROUND_UP(GPLL_HZ, rate); + } + rk_clrsetreg(SCRU_BASE + RK3588_CLKSEL_CON(3), + SCMI_CCLK_SD_SEL_MASK | SCMI_CCLK_SD_DIV_MASK, + sel << SCMI_CCLK_SD_SEL_SHIFT | + (div - 1) << SCMI_CCLK_SD_DIV_SHIFT); + break; + case SCMI_HCLK_SD: + if (rate >= 150 * MHz) + sel = SCMI_HCLK_SD_SEL_150M; + else if (rate >= 100 * MHz) + sel = SCMI_HCLK_SD_SEL_100M; + else if (rate >= 50 * MHz) + sel = SCMI_HCLK_SD_SEL_50M; + else + sel = SCMI_HCLK_SD_SEL_24M; + rk_clrsetreg(SCRU_BASE + RK3588_CLKSEL_CON(1), + SCMI_HCLK_SD_SEL_MASK, + sel << SCMI_HCLK_SD_SEL_SHIFT); + break; + default: + return -ENOENT; + } + + return rk3588_scru_clk_get_rate(clk); +} + +static const struct clk_ops rk3588_scru_clk_ops = { + .get_rate = rk3588_scru_clk_get_rate, + .set_rate = rk3588_scru_clk_set_rate, +}; + +U_BOOT_DRIVER(rockchip_rk3588_scru) = { + .name = "rockchip_rk3588_scru", + .id = UCLASS_CLK, + .ops = &rk3588_scru_clk_ops, +}; + +static int rk3588_scmi_spl_glue_bind(struct udevice *dev) +{ + ofnode node; + u32 protocol_id; + const char *name; + + dev_for_each_subnode(node, dev) { + if (!ofnode_is_enabled(node)) + continue; + + if (ofnode_read_u32(node, "reg", &protocol_id)) + continue; + + if (protocol_id != SCMI_PROTOCOL_ID_CLOCK) + continue; + + name = ofnode_get_name(node); + return device_bind_driver_to_node(dev, "rockchip_rk3588_scru", + name, node, NULL); + } + + return -ENOENT; +} + +static const struct udevice_id rk3588_scmi_spl_glue_ids[] = { + { .compatible = "arm,scmi-smc" }, + { } +}; + +U_BOOT_DRIVER(rk3588_scmi_spl_glue) = { + .name = "rk3588_scmi_spl_glue", + .id = UCLASS_NOP, + .of_match = rk3588_scmi_spl_glue_ids, + .bind = rk3588_scmi_spl_glue_bind, +}; +#endif

On 2023/3/18 03:16, Jonas Karlman wrote:
Booting from sdmmc on RK3588 currently works because of a workaround in the device tree, clocks are reordered so that the driver use ciu-sample instead of ciu, and the BootRom initializes sdmmc clocks before SPL is loaded into DRAM.
The sdmmc clocks are normally controlled by TF-A using SCMI. However, there is a need to control these clocks in SPL, before TF-A has started.
This adds a rk3588_scru driver to control the sdmmc clocks in SPL before TF-A has started, using scru regs. It also adds a small glue driver to bind the scmi clock node to the rk3588_scru driver in SPL.
Fixes: 7a474df74023 ("clk: rockchip: Add rk3588 clk support") Signed-off-by: Jonas Karlman jonas@kwiboo.se
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
arch/arm/include/asm/arch-rockchip/clock.h | 1 - .../include/asm/arch-rockchip/cru_rk3588.h | 19 ++- drivers/clk/rockchip/clk_rk3588.c | 125 ++++++++++++++++++ 3 files changed, 143 insertions(+), 2 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/clock.h b/arch/arm/include/asm/arch-rockchip/clock.h index 90e66c7da049..f002ebcb7ac1 100644 --- a/arch/arm/include/asm/arch-rockchip/clock.h +++ b/arch/arm/include/asm/arch-rockchip/clock.h @@ -194,6 +194,5 @@ int rockchip_get_clk(struct udevice **devp);
- Return: 0 success, or error value
*/ int rockchip_reset_bind(struct udevice *pdev, u32 reg_offset, u32 reg_number); -int rockchip_get_scmi_clk(struct udevice **devp);
#endif diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3588.h b/arch/arm/include/asm/arch-rockchip/cru_rk3588.h index 3ea59e900861..7f4a90853929 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk3588.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3588.h @@ -11,12 +11,12 @@ #define KHz 1000 #define OSC_HZ (24 * MHz)
-#define CPU_PVTPLL_HZ (1008 * MHz) #define LPLL_HZ (816 * MHz) #define GPLL_HZ (1188 * MHz) #define CPLL_HZ (1500 * MHz) #define NPLL_HZ (850 * MHz) #define PPLL_HZ (1100 * MHz) +#define SPLL_HZ (702 * MHz)
/* RK3588 pll id */ enum rk3588_pll_id { @@ -447,5 +447,22 @@ enum { CLK_I2C0_SEL_MASK = 1 << CLK_I2C0_SEL_SHIFT, CLK_I2C_SEL_200M = 0, CLK_I2C_SEL_100M,
- /* SECURECRU_CLKSEL_CON01 */
- SCMI_HCLK_SD_SEL_SHIFT = 2,
- SCMI_HCLK_SD_SEL_MASK = 3 << SCMI_HCLK_SD_SEL_SHIFT,
- SCMI_HCLK_SD_SEL_150M = 0,
- SCMI_HCLK_SD_SEL_100M,
- SCMI_HCLK_SD_SEL_50M,
- SCMI_HCLK_SD_SEL_24M,
- /* SECURECRU_CLKSEL_CON03 */
- SCMI_CCLK_SD_SEL_SHIFT = 12,
- SCMI_CCLK_SD_SEL_MASK = 3 << SCMI_CCLK_SD_SEL_SHIFT,
- SCMI_CCLK_SD_SEL_GPLL = 0,
- SCMI_CCLK_SD_SEL_SPLL,
- SCMI_CCLK_SD_SEL_24M,
- SCMI_CCLK_SD_DIV_SHIFT = 6,
- SCMI_CCLK_SD_DIV_MASK = 0x3f << SCMI_CCLK_SD_DIV_SHIFT, }; #endif
diff --git a/drivers/clk/rockchip/clk_rk3588.c b/drivers/clk/rockchip/clk_rk3588.c index a7df553e8750..41e31b61a55b 100644 --- a/drivers/clk/rockchip/clk_rk3588.c +++ b/drivers/clk/rockchip/clk_rk3588.c @@ -9,6 +9,7 @@ #include <clk-uclass.h> #include <dm.h> #include <errno.h> +#include <scmi_protocols.h> #include <syscon.h> #include <asm/arch-rockchip/cru_rk3588.h> #include <asm/arch-rockchip/clock.h> @@ -1994,3 +1995,127 @@ U_BOOT_DRIVER(rockchip_rk3588_cru) = { .bind = rk3588_clk_bind, .probe = rk3588_clk_probe, };
+#ifdef CONFIG_SPL_BUILD +#define SCRU_BASE 0xfd7d0000
+static ulong rk3588_scru_clk_get_rate(struct clk *clk) +{
- u32 con, div, sel, parent;
- switch (clk->id) {
- case SCMI_CCLK_SD:
con = readl(SCRU_BASE + RK3588_CLKSEL_CON(3));
sel = (con & SCMI_CCLK_SD_SEL_MASK) >> SCMI_CCLK_SD_SEL_SHIFT;
div = (con & SCMI_CCLK_SD_DIV_MASK) >> SCMI_CCLK_SD_DIV_SHIFT;
if (sel == SCMI_CCLK_SD_SEL_GPLL)
parent = GPLL_HZ;
else if (sel == SCMI_CCLK_SD_SEL_SPLL)
parent = SPLL_HZ;
else
parent = OSC_HZ;
return DIV_TO_RATE(parent, div);
- case SCMI_HCLK_SD:
con = readl(SCRU_BASE + RK3588_CLKSEL_CON(1));
sel = (con & SCMI_HCLK_SD_SEL_MASK) >> SCMI_HCLK_SD_SEL_SHIFT;
if (sel == SCMI_HCLK_SD_SEL_150M)
return 150 * MHz;
else if (sel == SCMI_HCLK_SD_SEL_100M)
return 100 * MHz;
else if (sel == SCMI_HCLK_SD_SEL_50M)
return 50 * MHz;
else
return OSC_HZ;
- default:
return -ENOENT;
- }
+}
+static ulong rk3588_scru_clk_set_rate(struct clk *clk, ulong rate) +{
- u32 div, sel;
- switch (clk->id) {
- case SCMI_CCLK_SD:
if ((OSC_HZ % rate) == 0) {
sel = SCMI_CCLK_SD_SEL_24M;
div = DIV_ROUND_UP(OSC_HZ, rate);
} else if ((SPLL_HZ % rate) == 0) {
sel = SCMI_CCLK_SD_SEL_SPLL;
div = DIV_ROUND_UP(SPLL_HZ, rate);
} else {
sel = SCMI_CCLK_SD_SEL_GPLL;
div = DIV_ROUND_UP(GPLL_HZ, rate);
}
rk_clrsetreg(SCRU_BASE + RK3588_CLKSEL_CON(3),
SCMI_CCLK_SD_SEL_MASK | SCMI_CCLK_SD_DIV_MASK,
sel << SCMI_CCLK_SD_SEL_SHIFT |
(div - 1) << SCMI_CCLK_SD_DIV_SHIFT);
break;
- case SCMI_HCLK_SD:
if (rate >= 150 * MHz)
sel = SCMI_HCLK_SD_SEL_150M;
else if (rate >= 100 * MHz)
sel = SCMI_HCLK_SD_SEL_100M;
else if (rate >= 50 * MHz)
sel = SCMI_HCLK_SD_SEL_50M;
else
sel = SCMI_HCLK_SD_SEL_24M;
rk_clrsetreg(SCRU_BASE + RK3588_CLKSEL_CON(1),
SCMI_HCLK_SD_SEL_MASK,
sel << SCMI_HCLK_SD_SEL_SHIFT);
break;
- default:
return -ENOENT;
- }
- return rk3588_scru_clk_get_rate(clk);
+}
+static const struct clk_ops rk3588_scru_clk_ops = {
- .get_rate = rk3588_scru_clk_get_rate,
- .set_rate = rk3588_scru_clk_set_rate,
+};
+U_BOOT_DRIVER(rockchip_rk3588_scru) = {
- .name = "rockchip_rk3588_scru",
- .id = UCLASS_CLK,
- .ops = &rk3588_scru_clk_ops,
+};
+static int rk3588_scmi_spl_glue_bind(struct udevice *dev) +{
- ofnode node;
- u32 protocol_id;
- const char *name;
- dev_for_each_subnode(node, dev) {
if (!ofnode_is_enabled(node))
continue;
if (ofnode_read_u32(node, "reg", &protocol_id))
continue;
if (protocol_id != SCMI_PROTOCOL_ID_CLOCK)
continue;
name = ofnode_get_name(node);
return device_bind_driver_to_node(dev, "rockchip_rk3588_scru",
name, node, NULL);
- }
- return -ENOENT;
+}
+static const struct udevice_id rk3588_scmi_spl_glue_ids[] = {
- { .compatible = "arm,scmi-smc" },
- { }
+};
+U_BOOT_DRIVER(rk3588_scmi_spl_glue) = {
- .name = "rk3588_scmi_spl_glue",
- .id = UCLASS_NOP,
- .of_match = rk3588_scmi_spl_glue_ids,
- .bind = rk3588_scmi_spl_glue_bind,
+}; +#endif

Sync the sdmmc node from linux-next, include required nodes in SPL and imply Kconfig options required for functional sdmmc clk in SPL and U-Boot proper.
This make it possible for both SPL and U-Boot proper to configure sdmmc clocks. In SPL, before TF-A is loaded, scru regs is configured, in U-Boot proper a SCMI message is sent to TF-A.
Fixes: 95c8656b72dc ("ARM: dts: rockchip: rk3588s-u-boot: Add sdmmc node") Signed-off-by: Jonas Karlman jonas@kwiboo.se --- .../dts/rk3588-edgeble-neu6a-io-u-boot.dtsi | 2 -- arch/arm/dts/rk3588-rock-5b-u-boot.dtsi | 2 -- arch/arm/dts/rk3588s-u-boot.dtsi | 27 +++++++++---------- arch/arm/dts/rk3588s.dtsi | 15 +++++++++++ arch/arm/mach-rockchip/Kconfig | 2 ++ 5 files changed, 30 insertions(+), 18 deletions(-)
diff --git a/arch/arm/dts/rk3588-edgeble-neu6a-io-u-boot.dtsi b/arch/arm/dts/rk3588-edgeble-neu6a-io-u-boot.dtsi index 612966492b02..373f369c6556 100644 --- a/arch/arm/dts/rk3588-edgeble-neu6a-io-u-boot.dtsi +++ b/arch/arm/dts/rk3588-edgeble-neu6a-io-u-boot.dtsi @@ -18,7 +18,5 @@
&sdmmc { bus-width = <4>; - u-boot,dm-pre-reloc; - u-boot,spl-fifo-mode; status = "okay"; }; diff --git a/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi b/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi index 36d557b4934d..4c6f0311d6a1 100644 --- a/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi +++ b/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi @@ -17,7 +17,5 @@
&sdmmc { bus-width = <4>; - u-boot,dm-spl; - u-boot,spl-fifo-mode; status = "okay"; }; diff --git a/arch/arm/dts/rk3588s-u-boot.dtsi b/arch/arm/dts/rk3588s-u-boot.dtsi index f880f4a16741..65960fa50adc 100644 --- a/arch/arm/dts/rk3588s-u-boot.dtsi +++ b/arch/arm/dts/rk3588s-u-boot.dtsi @@ -18,20 +18,6 @@ reg = <0x0 0xfd58a000 0x0 0x2000>; };
- sdmmc: mmc@fe2c0000 { - compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc"; - reg = <0x0 0xfe2c0000 0x0 0x4000>; - interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH 0>; - clocks = <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>, - <&scmi_clk SCMI_HCLK_SD>, <&scmi_clk SCMI_CCLK_SD>; - clock-names = "ciu-drive", "ciu-sample", "biu", "ciu"; - fifo-depth = <0x100>; - max-frequency = <200000000>; - pinctrl-names = "default"; - pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>; - status = "disabled"; - }; - otp: nvmem@fecc0000 { compatible = "rockchip,rk3588-otp"; reg = <0x0 0xfecc0000 0x0 0x400>; @@ -60,6 +46,19 @@ status = "okay"; };
+&scmi { + u-boot,dm-spl; +}; + +&scmi_clk { + u-boot,dm-spl; +}; + +&sdmmc { + u-boot,dm-spl; + u-boot,spl-fifo-mode; +}; + &uart2 { clock-frequency = <24000000>; u-boot,dm-spl; diff --git a/arch/arm/dts/rk3588s.dtsi b/arch/arm/dts/rk3588s.dtsi index 005cde61b4b2..fca8503aed8c 100644 --- a/arch/arm/dts/rk3588s.dtsi +++ b/arch/arm/dts/rk3588s.dtsi @@ -1099,6 +1099,21 @@ }; };
+ sdmmc: mmc@fe2c0000 { + compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xfe2c0000 0x0 0x4000>; + interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&scmi_clk SCMI_HCLK_SD>, <&scmi_clk SCMI_CCLK_SD>, + <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <200000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>; + power-domains = <&power RK3588_PD_SDMMC>; + status = "disabled"; + }; + sdhci: mmc@fe2e0000 { compatible = "rockchip,rk3588-dwcmshc"; reg = <0x0 0xfe2e0000 0x0 0x10000>; diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 5e8aacc2ea14..c10c25439112 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -318,6 +318,8 @@ config ROCKCHIP_RK3588 imply OF_LIBFDT_OVERLAY imply ROCKCHIP_OTP imply MISC_INIT_R + imply CLK_SCMI + imply SCMI_FIRMWARE help The Rockchip RK3588 is a ARM-based SoC with quad-core Cortex-A76 and quad-core Cortex-A55 including NEON and GPU, 6TOPS NPU, Mali-G610 MP4,

On 2023/3/18 03:16, Jonas Karlman wrote:
Sync the sdmmc node from linux-next, include required nodes in SPL and imply Kconfig options required for functional sdmmc clk in SPL and U-Boot proper.
This make it possible for both SPL and U-Boot proper to configure sdmmc clocks. In SPL, before TF-A is loaded, scru regs is configured, in U-Boot proper a SCMI message is sent to TF-A.
Fixes: 95c8656b72dc ("ARM: dts: rockchip: rk3588s-u-boot: Add sdmmc node") Signed-off-by: Jonas Karlman jonas@kwiboo.se
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
.../dts/rk3588-edgeble-neu6a-io-u-boot.dtsi | 2 -- arch/arm/dts/rk3588-rock-5b-u-boot.dtsi | 2 -- arch/arm/dts/rk3588s-u-boot.dtsi | 27 +++++++++---------- arch/arm/dts/rk3588s.dtsi | 15 +++++++++++ arch/arm/mach-rockchip/Kconfig | 2 ++ 5 files changed, 30 insertions(+), 18 deletions(-)
diff --git a/arch/arm/dts/rk3588-edgeble-neu6a-io-u-boot.dtsi b/arch/arm/dts/rk3588-edgeble-neu6a-io-u-boot.dtsi index 612966492b02..373f369c6556 100644 --- a/arch/arm/dts/rk3588-edgeble-neu6a-io-u-boot.dtsi +++ b/arch/arm/dts/rk3588-edgeble-neu6a-io-u-boot.dtsi @@ -18,7 +18,5 @@
&sdmmc { bus-width = <4>;
- u-boot,dm-pre-reloc;
- u-boot,spl-fifo-mode; status = "okay"; };
diff --git a/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi b/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi index 36d557b4934d..4c6f0311d6a1 100644 --- a/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi +++ b/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi @@ -17,7 +17,5 @@
&sdmmc { bus-width = <4>;
- u-boot,dm-spl;
- u-boot,spl-fifo-mode; status = "okay"; };
diff --git a/arch/arm/dts/rk3588s-u-boot.dtsi b/arch/arm/dts/rk3588s-u-boot.dtsi index f880f4a16741..65960fa50adc 100644 --- a/arch/arm/dts/rk3588s-u-boot.dtsi +++ b/arch/arm/dts/rk3588s-u-boot.dtsi @@ -18,20 +18,6 @@ reg = <0x0 0xfd58a000 0x0 0x2000>; };
- sdmmc: mmc@fe2c0000 {
compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x0 0xfe2c0000 0x0 0x4000>;
interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>,
<&scmi_clk SCMI_HCLK_SD>, <&scmi_clk SCMI_CCLK_SD>;
clock-names = "ciu-drive", "ciu-sample", "biu", "ciu";
fifo-depth = <0x100>;
max-frequency = <200000000>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
status = "disabled";
- };
- otp: nvmem@fecc0000 { compatible = "rockchip,rk3588-otp"; reg = <0x0 0xfecc0000 0x0 0x400>;
@@ -60,6 +46,19 @@ status = "okay"; };
+&scmi {
- u-boot,dm-spl;
+};
+&scmi_clk {
- u-boot,dm-spl;
+};
+&sdmmc {
- u-boot,dm-spl;
- u-boot,spl-fifo-mode;
+};
- &uart2 { clock-frequency = <24000000>; u-boot,dm-spl;
diff --git a/arch/arm/dts/rk3588s.dtsi b/arch/arm/dts/rk3588s.dtsi index 005cde61b4b2..fca8503aed8c 100644 --- a/arch/arm/dts/rk3588s.dtsi +++ b/arch/arm/dts/rk3588s.dtsi @@ -1099,6 +1099,21 @@ }; };
- sdmmc: mmc@fe2c0000 {
compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x0 0xfe2c0000 0x0 0x4000>;
interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&scmi_clk SCMI_HCLK_SD>, <&scmi_clk SCMI_CCLK_SD>,
<&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
fifo-depth = <0x100>;
max-frequency = <200000000>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
power-domains = <&power RK3588_PD_SDMMC>;
status = "disabled";
- };
- sdhci: mmc@fe2e0000 { compatible = "rockchip,rk3588-dwcmshc"; reg = <0x0 0xfe2e0000 0x0 0x10000>;
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 5e8aacc2ea14..c10c25439112 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -318,6 +318,8 @@ config ROCKCHIP_RK3588 imply OF_LIBFDT_OVERLAY imply ROCKCHIP_OTP imply MISC_INIT_R
- imply CLK_SCMI
- imply SCMI_FIRMWARE help The Rockchip RK3588 is a ARM-based SoC with quad-core Cortex-A76 and quad-core Cortex-A55 including NEON and GPU, 6TOPS NPU, Mali-G610 MP4,
participants (2)
-
Jonas Karlman
-
Kever Yang