[PATCH 0/8] arm: mach-snapdragon: Qualcomm clock driver cleanup

This series begins making some headway towards cleaning up Qualcomm platform support in u-boot. The following is a rough overview of the changes:
* Move the Qualcomm clock drivers out of mach-snapdragon and into clk/qcom * Introduce per-platform clock driver configs to decouple Qualcomm platform support from mach-snapdragon targets. * Add the IPQ4019 clock driver, removing it from mach-ipq40xx and introducing the reset map. * Merge the qcom reset driver is into clk/qcom and rework it to be compatible with upstream devicetrees. * A callback model is added so that multiple clock drivers can be compiled in at once. * SDM845 gains support for enabling/disabling all gate clocks (CBC's) by way of a new "gate_clk" abstraction. * Preperatory cleanup work is done to simplify the bringup process for new platforms.
Further details are included in each commit.
The primary goal of this series is to prepare for enabling several new Qualcomm platforms in u-boot as well as additional peripherals, while minimising the amount of copy/pasted board-specific code.
This series conflicts with a previous series introducing support for the Qualcomm RB2 board [1], I plan to resend this initial support pending acceptance of this series and several other cleanups.
[1]: https://lore.kernel.org/u-boot/20230324080418.3856409-1-bhupesh.sharma@linar...
--- Caleb Connolly (7): clk/qcom: move from mach-snapdragon clk/qcom: add per-platform configs clk/qcom: move ipq4019 driver from mach-ipq40xx clk/qcom: sdm845: add register map for simple gate clocks clk/qcom: use function pointers for enable and set_rate clk/qcom: add mnd_width to clk_rcg_set_rate_mnd() clk/qcom: fix rcg divider value
Konrad Dybcio (1): clk/qcom: handle resets and clocks in one device
arch/arm/Kconfig | 2 + arch/arm/dts/qcom-ipq4019.dtsi | 14 +- arch/arm/dts/qcs404-evb.dts | 19 +- arch/arm/mach-ipq40xx/Makefile | 1 - arch/arm/mach-ipq40xx/clock-ipq4019.c | 88 ------ arch/arm/mach-snapdragon/Kconfig | 4 + arch/arm/mach-snapdragon/Makefile | 5 - arch/arm/mach-snapdragon/clock-sdm845.c | 98 ------- arch/arm/mach-snapdragon/clock-snapdragon.c | 181 ------------ arch/arm/mach-snapdragon/clock-snapdragon.h | 48 ---- .../mach-snapdragon/include/mach/sysmap-sdm845.h | 3 + drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/qcom/Kconfig | 52 ++++ drivers/clk/qcom/Makefile | 10 + .../clk/qcom}/clock-apq8016.c | 41 ++- .../clk/qcom}/clock-apq8096.c | 41 ++- .../reset-qcom.c => clk/qcom/clock-ipq4019.c} | 165 ++++------- drivers/clk/qcom/clock-qcom.c | 303 +++++++++++++++++++++ drivers/clk/qcom/clock-qcom.h | 96 +++++++ .../clk/qcom}/clock-qcs404.c | 97 +++++-- drivers/clk/qcom/clock-sdm845.c | 265 ++++++++++++++++++ drivers/reset/Kconfig | 7 - drivers/reset/Makefile | 1 - 24 files changed, 938 insertions(+), 605 deletions(-) --- base-commit: 30d01b582f2274eb8c808026c5fb4c33e9f2210d
// Caleb (they/them)

Clock drivers don't belong here, move them to the right place and declutter mach-snapdragon a bit.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- arch/arm/mach-snapdragon/Makefile | 5 ----- drivers/clk/Makefile | 1 + drivers/clk/qcom/Makefile | 9 +++++++++ {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-apq8016.c | 2 +- {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-apq8096.c | 3 ++- .../clock-snapdragon.c => drivers/clk/qcom/clock-qcom.c | 2 +- .../clock-snapdragon.h => drivers/clk/qcom/clock-qcom.h | 0 {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-qcs404.c | 2 +- {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-sdm845.c | 2 +- 9 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile index cbaaf23f6b56..497ee35cf7d3 100644 --- a/arch/arm/mach-snapdragon/Makefile +++ b/arch/arm/mach-snapdragon/Makefile @@ -2,20 +2,15 @@ # # (C) Copyright 2015 Mateusz Kulikowski mateusz.kulikowski@gmail.com
-obj-$(CONFIG_SDM845) += clock-sdm845.o obj-$(CONFIG_SDM845) += sysmap-sdm845.o obj-$(CONFIG_SDM845) += init_sdm845.o -obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o obj-$(CONFIG_TARGET_DRAGONBOARD820C) += sysmap-apq8096.o -obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o obj-$(CONFIG_TARGET_DRAGONBOARD410C) += sysmap-apq8016.o obj-y += misc.o -obj-y += clock-snapdragon.o obj-y += dram.o obj-y += pinctrl-snapdragon.o obj-y += pinctrl-apq8016.o obj-y += pinctrl-apq8096.o obj-y += pinctrl-qcs404.o obj-y += pinctrl-sdm845.o -obj-$(CONFIG_TARGET_QCS404EVB) += clock-qcs404.o obj-$(CONFIG_TARGET_QCS404EVB) += sysmap-qcs404.o diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 26bf429acbc0..dd90c7672e1b 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_CLK_MPFS) += microchip/ obj-$(CONFIG_CLK_MVEBU) += mvebu/ obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o obj-$(CONFIG_CLK_OWL) += owl/ +obj-$(CONFIG_ARCH_SNAPDRAGON) += qcom/ obj-$(CONFIG_CLK_RENESAS) += renesas/ obj-$(CONFIG_$(SPL_TPL_)CLK_SCMI) += clk_scmi.o obj-$(CONFIG_CLK_SIFIVE) += sifive/ diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile new file mode 100644 index 000000000000..5f0c7a79d2ab --- /dev/null +++ b/drivers/clk/qcom/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2023 Linaro + +obj-y += clock-qcom.o +obj-$(CONFIG_SDM845) += clock-sdm845.o +obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o +obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o +obj-$(CONFIG_TARGET_QCS404EVB) += clock-qcs404.o diff --git a/arch/arm/mach-snapdragon/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c similarity index 98% rename from arch/arm/mach-snapdragon/clock-apq8016.c rename to drivers/clk/qcom/clock-apq8016.c index 23a37a1714dc..90f2a93d9ed5 100644 --- a/arch/arm/mach-snapdragon/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -13,7 +13,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
/* GPLL0 clock control registers */ #define GPLL0_STATUS_ACTIVE BIT(17) diff --git a/arch/arm/mach-snapdragon/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c similarity index 98% rename from arch/arm/mach-snapdragon/clock-apq8096.c rename to drivers/clk/qcom/clock-apq8096.c index 66184596d562..d5388c69aefe 100644 --- a/arch/arm/mach-snapdragon/clock-apq8096.c +++ b/drivers/clk/qcom/clock-apq8096.c @@ -13,7 +13,8 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" + +#include "clock-qcom.h"
/* GPLL0 clock control registers */ #define GPLL0_STATUS_ACTIVE BIT(30) diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.c b/drivers/clk/qcom/clock-qcom.c similarity index 99% rename from arch/arm/mach-snapdragon/clock-snapdragon.c rename to drivers/clk/qcom/clock-qcom.c index 0ac45dce9a92..5667abeb89a4 100644 --- a/arch/arm/mach-snapdragon/clock-snapdragon.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -13,7 +13,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
/* CBCR register fields */ #define CBCR_BRANCH_ENABLE_BIT BIT(0) diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.h b/drivers/clk/qcom/clock-qcom.h similarity index 100% rename from arch/arm/mach-snapdragon/clock-snapdragon.h rename to drivers/clk/qcom/clock-qcom.h diff --git a/arch/arm/mach-snapdragon/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c similarity index 99% rename from arch/arm/mach-snapdragon/clock-qcs404.c rename to drivers/clk/qcom/clock-qcs404.c index 3357b54c30c0..80218af73ef6 100644 --- a/arch/arm/mach-snapdragon/clock-qcs404.c +++ b/drivers/clk/qcom/clock-qcs404.c @@ -11,7 +11,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
#include <dt-bindings/clock/qcom,gcc-qcs404.h>
diff --git a/arch/arm/mach-snapdragon/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c similarity index 98% rename from arch/arm/mach-snapdragon/clock-sdm845.c rename to drivers/clk/qcom/clock-sdm845.c index d6df0365afca..95a057b82986 100644 --- a/arch/arm/mach-snapdragon/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -15,7 +15,7 @@ #include <asm/io.h> #include <linux/bitops.h> #include <dt-bindings/clock/qcom,gcc-sdm845.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }

On Wed, 25 Oct 2023 at 01:54, Caleb Connolly caleb.connolly@linaro.org wrote:
Clock drivers don't belong here, move them to the right place and declutter mach-snapdragon a bit.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org
arch/arm/mach-snapdragon/Makefile | 5 ----- drivers/clk/Makefile | 1 + drivers/clk/qcom/Makefile | 9 +++++++++ {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-apq8016.c | 2 +- {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-apq8096.c | 3 ++- .../clock-snapdragon.c => drivers/clk/qcom/clock-qcom.c | 2 +- .../clock-snapdragon.h => drivers/clk/qcom/clock-qcom.h | 0 {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-qcs404.c | 2 +- {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-sdm845.c | 2 +- 9 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile index cbaaf23f6b56..497ee35cf7d3 100644 --- a/arch/arm/mach-snapdragon/Makefile +++ b/arch/arm/mach-snapdragon/Makefile @@ -2,20 +2,15 @@ # # (C) Copyright 2015 Mateusz Kulikowski mateusz.kulikowski@gmail.com
-obj-$(CONFIG_SDM845) += clock-sdm845.o obj-$(CONFIG_SDM845) += sysmap-sdm845.o obj-$(CONFIG_SDM845) += init_sdm845.o -obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o obj-$(CONFIG_TARGET_DRAGONBOARD820C) += sysmap-apq8096.o -obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o obj-$(CONFIG_TARGET_DRAGONBOARD410C) += sysmap-apq8016.o obj-y += misc.o -obj-y += clock-snapdragon.o obj-y += dram.o obj-y += pinctrl-snapdragon.o obj-y += pinctrl-apq8016.o obj-y += pinctrl-apq8096.o obj-y += pinctrl-qcs404.o obj-y += pinctrl-sdm845.o -obj-$(CONFIG_TARGET_QCS404EVB) += clock-qcs404.o obj-$(CONFIG_TARGET_QCS404EVB) += sysmap-qcs404.o diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 26bf429acbc0..dd90c7672e1b 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_CLK_MPFS) += microchip/ obj-$(CONFIG_CLK_MVEBU) += mvebu/ obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o obj-$(CONFIG_CLK_OWL) += owl/ +obj-$(CONFIG_ARCH_SNAPDRAGON) += qcom/
CONFIG_CLK_QCOM is better suited here. You should introduce that here instead.
-Sumit
obj-$(CONFIG_CLK_RENESAS) += renesas/ obj-$(CONFIG_$(SPL_TPL_)CLK_SCMI) += clk_scmi.o obj-$(CONFIG_CLK_SIFIVE) += sifive/ diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile new file mode 100644 index 000000000000..5f0c7a79d2ab --- /dev/null +++ b/drivers/clk/qcom/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2023 Linaro
+obj-y += clock-qcom.o +obj-$(CONFIG_SDM845) += clock-sdm845.o +obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o +obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o +obj-$(CONFIG_TARGET_QCS404EVB) += clock-qcs404.o diff --git a/arch/arm/mach-snapdragon/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c similarity index 98% rename from arch/arm/mach-snapdragon/clock-apq8016.c rename to drivers/clk/qcom/clock-apq8016.c index 23a37a1714dc..90f2a93d9ed5 100644 --- a/arch/arm/mach-snapdragon/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -13,7 +13,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
/* GPLL0 clock control registers */ #define GPLL0_STATUS_ACTIVE BIT(17) diff --git a/arch/arm/mach-snapdragon/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c similarity index 98% rename from arch/arm/mach-snapdragon/clock-apq8096.c rename to drivers/clk/qcom/clock-apq8096.c index 66184596d562..d5388c69aefe 100644 --- a/arch/arm/mach-snapdragon/clock-apq8096.c +++ b/drivers/clk/qcom/clock-apq8096.c @@ -13,7 +13,8 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h"
+#include "clock-qcom.h"
/* GPLL0 clock control registers */ #define GPLL0_STATUS_ACTIVE BIT(30) diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.c b/drivers/clk/qcom/clock-qcom.c similarity index 99% rename from arch/arm/mach-snapdragon/clock-snapdragon.c rename to drivers/clk/qcom/clock-qcom.c index 0ac45dce9a92..5667abeb89a4 100644 --- a/arch/arm/mach-snapdragon/clock-snapdragon.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -13,7 +13,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
/* CBCR register fields */ #define CBCR_BRANCH_ENABLE_BIT BIT(0) diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.h b/drivers/clk/qcom/clock-qcom.h similarity index 100% rename from arch/arm/mach-snapdragon/clock-snapdragon.h rename to drivers/clk/qcom/clock-qcom.h diff --git a/arch/arm/mach-snapdragon/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c similarity index 99% rename from arch/arm/mach-snapdragon/clock-qcs404.c rename to drivers/clk/qcom/clock-qcs404.c index 3357b54c30c0..80218af73ef6 100644 --- a/arch/arm/mach-snapdragon/clock-qcs404.c +++ b/drivers/clk/qcom/clock-qcs404.c @@ -11,7 +11,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
#include <dt-bindings/clock/qcom,gcc-qcs404.h>
diff --git a/arch/arm/mach-snapdragon/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c similarity index 98% rename from arch/arm/mach-snapdragon/clock-sdm845.c rename to drivers/clk/qcom/clock-sdm845.c index d6df0365afca..95a057b82986 100644 --- a/arch/arm/mach-snapdragon/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -15,7 +15,7 @@ #include <asm/io.h> #include <linux/bitops.h> #include <dt-bindings/clock/qcom,gcc-sdm845.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-- 2.42.0

On Wed, 25 Oct 2023 at 01:54, Caleb Connolly caleb.connolly@linaro.org wrote:
Clock drivers don't belong here, move them to the right place and declutter mach-snapdragon a bit.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org
arch/arm/mach-snapdragon/Makefile | 5 ----- drivers/clk/Makefile | 1 + drivers/clk/qcom/Makefile | 9 +++++++++ {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-apq8016.c | 2 +- {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-apq8096.c | 3 ++- .../clock-snapdragon.c => drivers/clk/qcom/clock-qcom.c | 2 +- .../clock-snapdragon.h => drivers/clk/qcom/clock-qcom.h | 0 {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-qcs404.c | 2 +- {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-sdm845.c | 2 +- 9 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile index cbaaf23f6b56..497ee35cf7d3 100644 --- a/arch/arm/mach-snapdragon/Makefile +++ b/arch/arm/mach-snapdragon/Makefile @@ -2,20 +2,15 @@ # # (C) Copyright 2015 Mateusz Kulikowski mateusz.kulikowski@gmail.com
-obj-$(CONFIG_SDM845) += clock-sdm845.o obj-$(CONFIG_SDM845) += sysmap-sdm845.o obj-$(CONFIG_SDM845) += init_sdm845.o -obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o obj-$(CONFIG_TARGET_DRAGONBOARD820C) += sysmap-apq8096.o -obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o obj-$(CONFIG_TARGET_DRAGONBOARD410C) += sysmap-apq8016.o obj-y += misc.o -obj-y += clock-snapdragon.o obj-y += dram.o obj-y += pinctrl-snapdragon.o obj-y += pinctrl-apq8016.o obj-y += pinctrl-apq8096.o obj-y += pinctrl-qcs404.o obj-y += pinctrl-sdm845.o -obj-$(CONFIG_TARGET_QCS404EVB) += clock-qcs404.o obj-$(CONFIG_TARGET_QCS404EVB) += sysmap-qcs404.o diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 26bf429acbc0..dd90c7672e1b 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_CLK_MPFS) += microchip/ obj-$(CONFIG_CLK_MVEBU) += mvebu/ obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o obj-$(CONFIG_CLK_OWL) += owl/ +obj-$(CONFIG_ARCH_SNAPDRAGON) += qcom/ obj-$(CONFIG_CLK_RENESAS) += renesas/ obj-$(CONFIG_$(SPL_TPL_)CLK_SCMI) += clk_scmi.o obj-$(CONFIG_CLK_SIFIVE) += sifive/ diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile new file mode 100644 index 000000000000..5f0c7a79d2ab --- /dev/null +++ b/drivers/clk/qcom/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2023 Linaro
+obj-y += clock-qcom.o +obj-$(CONFIG_SDM845) += clock-sdm845.o +obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o +obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o +obj-$(CONFIG_TARGET_QCS404EVB) += clock-qcs404.o
Similarly, I think here we should introduce here SoC specific config options like:
CONFIG_CLK_SDM845 CONFIG_CLK_APQ8016 CONFIG_CLK_APQ8096 CONFIG_CLK_QCS404
-Sumit
diff --git a/arch/arm/mach-snapdragon/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c similarity index 98% rename from arch/arm/mach-snapdragon/clock-apq8016.c rename to drivers/clk/qcom/clock-apq8016.c index 23a37a1714dc..90f2a93d9ed5 100644 --- a/arch/arm/mach-snapdragon/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -13,7 +13,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
/* GPLL0 clock control registers */ #define GPLL0_STATUS_ACTIVE BIT(17) diff --git a/arch/arm/mach-snapdragon/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c similarity index 98% rename from arch/arm/mach-snapdragon/clock-apq8096.c rename to drivers/clk/qcom/clock-apq8096.c index 66184596d562..d5388c69aefe 100644 --- a/arch/arm/mach-snapdragon/clock-apq8096.c +++ b/drivers/clk/qcom/clock-apq8096.c @@ -13,7 +13,8 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h"
+#include "clock-qcom.h"
/* GPLL0 clock control registers */ #define GPLL0_STATUS_ACTIVE BIT(30) diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.c b/drivers/clk/qcom/clock-qcom.c similarity index 99% rename from arch/arm/mach-snapdragon/clock-snapdragon.c rename to drivers/clk/qcom/clock-qcom.c index 0ac45dce9a92..5667abeb89a4 100644 --- a/arch/arm/mach-snapdragon/clock-snapdragon.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -13,7 +13,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
/* CBCR register fields */ #define CBCR_BRANCH_ENABLE_BIT BIT(0) diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.h b/drivers/clk/qcom/clock-qcom.h similarity index 100% rename from arch/arm/mach-snapdragon/clock-snapdragon.h rename to drivers/clk/qcom/clock-qcom.h diff --git a/arch/arm/mach-snapdragon/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c similarity index 99% rename from arch/arm/mach-snapdragon/clock-qcs404.c rename to drivers/clk/qcom/clock-qcs404.c index 3357b54c30c0..80218af73ef6 100644 --- a/arch/arm/mach-snapdragon/clock-qcs404.c +++ b/drivers/clk/qcom/clock-qcs404.c @@ -11,7 +11,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
#include <dt-bindings/clock/qcom,gcc-qcs404.h>
diff --git a/arch/arm/mach-snapdragon/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c similarity index 98% rename from arch/arm/mach-snapdragon/clock-sdm845.c rename to drivers/clk/qcom/clock-sdm845.c index d6df0365afca..95a057b82986 100644 --- a/arch/arm/mach-snapdragon/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -15,7 +15,7 @@ #include <asm/io.h> #include <linux/bitops.h> #include <dt-bindings/clock/qcom,gcc-sdm845.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-- 2.42.0

On Thu, 26 Oct 2023 at 15:45, Sumit Garg sumit.garg@linaro.org wrote:
On Wed, 25 Oct 2023 at 01:54, Caleb Connolly caleb.connolly@linaro.org wrote:
Clock drivers don't belong here, move them to the right place and declutter mach-snapdragon a bit.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org
arch/arm/mach-snapdragon/Makefile | 5 ----- drivers/clk/Makefile | 1 + drivers/clk/qcom/Makefile | 9 +++++++++ {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-apq8016.c | 2 +- {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-apq8096.c | 3 ++- .../clock-snapdragon.c => drivers/clk/qcom/clock-qcom.c | 2 +- .../clock-snapdragon.h => drivers/clk/qcom/clock-qcom.h | 0 {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-qcs404.c | 2 +- {arch/arm/mach-snapdragon => drivers/clk/qcom}/clock-sdm845.c | 2 +- 9 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile index cbaaf23f6b56..497ee35cf7d3 100644 --- a/arch/arm/mach-snapdragon/Makefile +++ b/arch/arm/mach-snapdragon/Makefile @@ -2,20 +2,15 @@ # # (C) Copyright 2015 Mateusz Kulikowski mateusz.kulikowski@gmail.com
-obj-$(CONFIG_SDM845) += clock-sdm845.o obj-$(CONFIG_SDM845) += sysmap-sdm845.o obj-$(CONFIG_SDM845) += init_sdm845.o -obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o obj-$(CONFIG_TARGET_DRAGONBOARD820C) += sysmap-apq8096.o -obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o obj-$(CONFIG_TARGET_DRAGONBOARD410C) += sysmap-apq8016.o obj-y += misc.o -obj-y += clock-snapdragon.o obj-y += dram.o obj-y += pinctrl-snapdragon.o obj-y += pinctrl-apq8016.o obj-y += pinctrl-apq8096.o obj-y += pinctrl-qcs404.o obj-y += pinctrl-sdm845.o -obj-$(CONFIG_TARGET_QCS404EVB) += clock-qcs404.o obj-$(CONFIG_TARGET_QCS404EVB) += sysmap-qcs404.o diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 26bf429acbc0..dd90c7672e1b 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_CLK_MPFS) += microchip/ obj-$(CONFIG_CLK_MVEBU) += mvebu/ obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o obj-$(CONFIG_CLK_OWL) += owl/ +obj-$(CONFIG_ARCH_SNAPDRAGON) += qcom/ obj-$(CONFIG_CLK_RENESAS) += renesas/ obj-$(CONFIG_$(SPL_TPL_)CLK_SCMI) += clk_scmi.o obj-$(CONFIG_CLK_SIFIVE) += sifive/ diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile new file mode 100644 index 000000000000..5f0c7a79d2ab --- /dev/null +++ b/drivers/clk/qcom/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2023 Linaro
+obj-y += clock-qcom.o +obj-$(CONFIG_SDM845) += clock-sdm845.o +obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o +obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o +obj-$(CONFIG_TARGET_QCS404EVB) += clock-qcs404.o
Similarly, I think here we should introduce here SoC specific config options like:
CONFIG_CLK_SDM845 CONFIG_CLK_APQ8016 CONFIG_CLK_APQ8096 CONFIG_CLK_QCS404
Please ignore these comments as I see the second patch doing that exactly. Although, I would have preferred to merge the two patches but I am fine either way.
-Sumit
diff --git a/arch/arm/mach-snapdragon/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c similarity index 98% rename from arch/arm/mach-snapdragon/clock-apq8016.c rename to drivers/clk/qcom/clock-apq8016.c index 23a37a1714dc..90f2a93d9ed5 100644 --- a/arch/arm/mach-snapdragon/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -13,7 +13,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
/* GPLL0 clock control registers */ #define GPLL0_STATUS_ACTIVE BIT(17) diff --git a/arch/arm/mach-snapdragon/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c similarity index 98% rename from arch/arm/mach-snapdragon/clock-apq8096.c rename to drivers/clk/qcom/clock-apq8096.c index 66184596d562..d5388c69aefe 100644 --- a/arch/arm/mach-snapdragon/clock-apq8096.c +++ b/drivers/clk/qcom/clock-apq8096.c @@ -13,7 +13,8 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h"
+#include "clock-qcom.h"
/* GPLL0 clock control registers */ #define GPLL0_STATUS_ACTIVE BIT(30) diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.c b/drivers/clk/qcom/clock-qcom.c similarity index 99% rename from arch/arm/mach-snapdragon/clock-snapdragon.c rename to drivers/clk/qcom/clock-qcom.c index 0ac45dce9a92..5667abeb89a4 100644 --- a/arch/arm/mach-snapdragon/clock-snapdragon.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -13,7 +13,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
/* CBCR register fields */ #define CBCR_BRANCH_ENABLE_BIT BIT(0) diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.h b/drivers/clk/qcom/clock-qcom.h similarity index 100% rename from arch/arm/mach-snapdragon/clock-snapdragon.h rename to drivers/clk/qcom/clock-qcom.h diff --git a/arch/arm/mach-snapdragon/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c similarity index 99% rename from arch/arm/mach-snapdragon/clock-qcs404.c rename to drivers/clk/qcom/clock-qcs404.c index 3357b54c30c0..80218af73ef6 100644 --- a/arch/arm/mach-snapdragon/clock-qcs404.c +++ b/drivers/clk/qcom/clock-qcs404.c @@ -11,7 +11,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
#include <dt-bindings/clock/qcom,gcc-qcs404.h>
diff --git a/arch/arm/mach-snapdragon/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c similarity index 98% rename from arch/arm/mach-snapdragon/clock-sdm845.c rename to drivers/clk/qcom/clock-sdm845.c index d6df0365afca..95a057b82986 100644 --- a/arch/arm/mach-snapdragon/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -15,7 +15,7 @@ #include <asm/io.h> #include <linux/bitops.h> #include <dt-bindings/clock/qcom,gcc-sdm845.h> -#include "clock-snapdragon.h" +#include "clock-qcom.h"
#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-- 2.42.0

Decouple the clock drivers from the mach-snapdragon TARGET configs by introducing CONFIG_CLK_QCOM and associated options to build each SoC.
This will make future cleanup easier as we move towards a generic Qualcomm target.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- arch/arm/mach-snapdragon/Kconfig | 4 ++++ drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 2 +- drivers/clk/qcom/Kconfig | 44 ++++++++++++++++++++++++++++++++++++++++ drivers/clk/qcom/Makefile | 8 ++++---- 5 files changed, 54 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig index 0e073045be54..eaf75abf4bd5 100644 --- a/arch/arm/mach-snapdragon/Kconfig +++ b/arch/arm/mach-snapdragon/Kconfig @@ -16,6 +16,7 @@ config SDM845 bool "Qualcomm Snapdragon 845 SoC" default n select LINUX_KERNEL_IMAGE_HEADER + imply CLK_QCOM_SDM845
config LNX_KRNL_IMG_TEXT_OFFSET_BASE default 0x80000000 @@ -27,6 +28,7 @@ config TARGET_DRAGONBOARD410C bool "96Boards Dragonboard 410C" select BOARD_LATE_INIT select ENABLE_ARM_SOC_BOOT0_HOOK + imply CLK_QCOM_APQ8016 help Support for 96Boards Dragonboard 410C. This board complies with 96Board Open Platform Specifications. Features: @@ -40,6 +42,7 @@ config TARGET_DRAGONBOARD410C
config TARGET_DRAGONBOARD820C bool "96Boards Dragonboard 820C" + imply CLK_QCOM_APQ8096 help Support for 96Boards Dragonboard 820C. This board complies with 96Board Open Platform Specifications. Features: @@ -73,6 +76,7 @@ config TARGET_STARQLTECHN config TARGET_QCS404EVB bool "Qualcomm Technologies, Inc. QCS404 EVB" select LINUX_KERNEL_IMAGE_HEADER + imply CLK_QCOM_QCS404 help Support for Qualcomm Technologies, Inc. QCS404 evaluation board. Features: diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index bfd23a990469..017dd260a544 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -254,6 +254,7 @@ source "drivers/clk/meson/Kconfig" source "drivers/clk/microchip/Kconfig" source "drivers/clk/mvebu/Kconfig" source "drivers/clk/owl/Kconfig" +source "drivers/clk/qcom/Kconfig" source "drivers/clk/renesas/Kconfig" source "drivers/clk/sunxi/Kconfig" source "drivers/clk/sifive/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index dd90c7672e1b..dd974742b6c8 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -40,7 +40,7 @@ obj-$(CONFIG_CLK_MPFS) += microchip/ obj-$(CONFIG_CLK_MVEBU) += mvebu/ obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o obj-$(CONFIG_CLK_OWL) += owl/ -obj-$(CONFIG_ARCH_SNAPDRAGON) += qcom/ +obj-$(CONFIG_CLK_QCOM) += qcom/ obj-$(CONFIG_CLK_RENESAS) += renesas/ obj-$(CONFIG_$(SPL_TPL_)CLK_SCMI) += clk_scmi.o obj-$(CONFIG_CLK_SIFIVE) += sifive/ diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig new file mode 100644 index 000000000000..a884f077d9b9 --- /dev/null +++ b/drivers/clk/qcom/Kconfig @@ -0,0 +1,44 @@ +if ARCH_SNAPDRAGON || ARCH_IPQ40XX + +config CLK_QCOM + bool + depends on CLK && DM_RESET + def_bool n + +menu "Qualcomm clock drivers" + +config CLK_QCOM_APQ8016 + bool "Qualcomm APQ8016 GCC" + select CLK_QCOM + help + Say Y here to enable support for the Global Clock Controller + on the Snapdragon APQ8016 SoC. This driver supports the clocks + and resets exposed by the GCC hardware block. + +config CLK_QCOM_APQ8096 + bool "Qualcomm APQ8096 GCC" + select CLK_QCOM + help + Say Y here to enable support for the Global Clock Controller + on the Snapdragon APQ8096 SoC. This driver supports the clocks + and resets exposed by the GCC hardware block. + +config CLK_QCOM_QCS404 + bool "Qualcomm QCS404 GCC" + select CLK_QCOM + help + Say Y here to enable support for the Global Clock Controller + on the Snapdragon QCS404 SoC. This driver supports the clocks + and resets exposed by the GCC hardware block. + +config CLK_QCOM_SDM845 + bool "Qualcomm SDM845 GCC" + select CLK_QCOM + help + Say Y here to enable support for the Global Clock Controller + on the Snapdragon 845 SoC. This driver supports the clocks + and resets exposed by the GCC hardware block. + +endmenu + +endif diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 5f0c7a79d2ab..44d55583596d 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -3,7 +3,7 @@ # (C) Copyright 2023 Linaro
obj-y += clock-qcom.o -obj-$(CONFIG_SDM845) += clock-sdm845.o -obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o -obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o -obj-$(CONFIG_TARGET_QCS404EVB) += clock-qcs404.o +obj-$(CONFIG_CLK_QCOM_SDM845) += clock-sdm845.o +obj-$(CONFIG_CLK_QCOM_APQ8016) += clock-apq8016.o +obj-$(CONFIG_CLK_QCOM_APQ8096) += clock-apq8096.o +obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o

This driver is just a stub, but it's necessary to support the upcoming reset driver changes.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- arch/arm/Kconfig | 1 + arch/arm/mach-ipq40xx/Makefile | 1 - drivers/clk/qcom/Kconfig | 8 +++++ drivers/clk/qcom/Makefile | 1 + .../clk/qcom}/clock-ipq4019.c | 41 ++-------------------- 5 files changed, 12 insertions(+), 40 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 531b081de996..5aaf7e5e32af 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -766,6 +766,7 @@ config ARCH_IPQ40XX select CLK select SMEM select OF_CONTROL + select CLK_QCOM_IPQ4019 imply CMD_DM
config ARCH_KEYSTONE diff --git a/arch/arm/mach-ipq40xx/Makefile b/arch/arm/mach-ipq40xx/Makefile index 08a65b8854d3..b36a935c6f9f 100644 --- a/arch/arm/mach-ipq40xx/Makefile +++ b/arch/arm/mach-ipq40xx/Makefile @@ -4,6 +4,5 @@ # # Author: Robert Marko robert.marko@sartura.hr
-obj-y += clock-ipq4019.o obj-y += pinctrl-snapdragon.o obj-y += pinctrl-ipq4019.o diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index a884f077d9b9..0df0d1881a49 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -23,6 +23,14 @@ config CLK_QCOM_APQ8096 on the Snapdragon APQ8096 SoC. This driver supports the clocks and resets exposed by the GCC hardware block.
+config CLK_QCOM_IPQ4019 + bool "Qualcomm IPQ4019 GCC" + select CLK_QCOM + help + Say Y here to enable support for the Global Clock Controller + on the Snapdragon IPQ4019 SoC. This driver supports the clocks + and resets exposed by the GCC hardware block. + config CLK_QCOM_QCS404 bool "Qualcomm QCS404 GCC" select CLK_QCOM diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 44d55583596d..25bd2e1e8bb1 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -6,4 +6,5 @@ obj-y += clock-qcom.o obj-$(CONFIG_CLK_QCOM_SDM845) += clock-sdm845.o obj-$(CONFIG_CLK_QCOM_APQ8016) += clock-apq8016.o obj-$(CONFIG_CLK_QCOM_APQ8096) += clock-apq8096.o +obj-$(CONFIG_CLK_QCOM_IPQ4019) += clock-ipa4019.o obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o diff --git a/arch/arm/mach-ipq40xx/clock-ipq4019.c b/drivers/clk/qcom/clock-ipq4019.c similarity index 56% rename from arch/arm/mach-ipq40xx/clock-ipq4019.c rename to drivers/clk/qcom/clock-ipq4019.c index c1d5c4ecdd81..04c99964df15 100644 --- a/arch/arm/mach-ipq40xx/clock-ipq4019.c +++ b/drivers/clk/qcom/clock-ipq4019.c @@ -12,12 +12,9 @@ #include <common.h> #include <dm.h> #include <errno.h> - #include <dt-bindings/clock/qcom,ipq4019-gcc.h>
-struct msm_clk_priv { - phys_addr_t base; -}; +#include "clock-qcom.h"
ulong msm_set_rate(struct clk *clk, ulong rate) { @@ -30,23 +27,7 @@ ulong msm_set_rate(struct clk *clk, ulong rate) } }
-static int msm_clk_probe(struct udevice *dev) -{ - struct msm_clk_priv *priv = dev_get_priv(dev); - - priv->base = dev_read_addr(dev); - if (priv->base == FDT_ADDR_T_NONE) - return -EINVAL; - - return 0; -} - -static ulong msm_clk_set_rate(struct clk *clk, ulong rate) -{ - return msm_set_rate(clk, rate); -} - -static int msm_enable(struct clk *clk) +int msm_enable(struct clk *clk) { switch (clk->id) { case GCC_BLSP1_QUP1_SPI_APPS_CLK: /*SPI1*/ @@ -68,21 +49,3 @@ static int msm_enable(struct clk *clk) } }
-static struct clk_ops msm_clk_ops = { - .set_rate = msm_clk_set_rate, - .enable = msm_enable, -}; - -static const struct udevice_id msm_clk_ids[] = { - { .compatible = "qcom,gcc-ipq4019" }, - { } -}; - -U_BOOT_DRIVER(clk_msm) = { - .name = "clk_msm", - .id = UCLASS_CLK, - .of_match = msm_clk_ids, - .ops = &msm_clk_ops, - .priv_auto = sizeof(struct msm_clk_priv), - .probe = msm_clk_probe, -};

On Wed, 25 Oct 2023 at 01:54, Caleb Connolly caleb.connolly@linaro.org wrote:
This driver is just a stub, but it's necessary to support the upcoming reset driver changes.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org
arch/arm/Kconfig | 1 + arch/arm/mach-ipq40xx/Makefile | 1 - drivers/clk/qcom/Kconfig | 8 +++++ drivers/clk/qcom/Makefile | 1 + .../clk/qcom}/clock-ipq4019.c | 41 ++-------------------- 5 files changed, 12 insertions(+), 40 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 531b081de996..5aaf7e5e32af 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -766,6 +766,7 @@ config ARCH_IPQ40XX select CLK select SMEM select OF_CONTROL
select CLK_QCOM_IPQ4019 imply CMD_DM
config ARCH_KEYSTONE diff --git a/arch/arm/mach-ipq40xx/Makefile b/arch/arm/mach-ipq40xx/Makefile index 08a65b8854d3..b36a935c6f9f 100644 --- a/arch/arm/mach-ipq40xx/Makefile +++ b/arch/arm/mach-ipq40xx/Makefile @@ -4,6 +4,5 @@ # # Author: Robert Marko robert.marko@sartura.hr
-obj-y += clock-ipq4019.o obj-y += pinctrl-snapdragon.o obj-y += pinctrl-ipq4019.o diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index a884f077d9b9..0df0d1881a49 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -23,6 +23,14 @@ config CLK_QCOM_APQ8096 on the Snapdragon APQ8096 SoC. This driver supports the clocks and resets exposed by the GCC hardware block.
+config CLK_QCOM_IPQ4019
bool "Qualcomm IPQ4019 GCC"
select CLK_QCOM
help
Say Y here to enable support for the Global Clock Controller
on the Snapdragon IPQ4019 SoC. This driver supports the clocks
and resets exposed by the GCC hardware block.
config CLK_QCOM_QCS404 bool "Qualcomm QCS404 GCC" select CLK_QCOM diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 44d55583596d..25bd2e1e8bb1 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -6,4 +6,5 @@ obj-y += clock-qcom.o obj-$(CONFIG_CLK_QCOM_SDM845) += clock-sdm845.o obj-$(CONFIG_CLK_QCOM_APQ8016) += clock-apq8016.o obj-$(CONFIG_CLK_QCOM_APQ8096) += clock-apq8096.o +obj-$(CONFIG_CLK_QCOM_IPQ4019) += clock-ipa4019.o obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o diff --git a/arch/arm/mach-ipq40xx/clock-ipq4019.c b/drivers/clk/qcom/clock-ipq4019.c similarity index 56% rename from arch/arm/mach-ipq40xx/clock-ipq4019.c rename to drivers/clk/qcom/clock-ipq4019.c index c1d5c4ecdd81..04c99964df15 100644 --- a/arch/arm/mach-ipq40xx/clock-ipq4019.c +++ b/drivers/clk/qcom/clock-ipq4019.c @@ -12,12 +12,9 @@ #include <common.h> #include <dm.h> #include <errno.h>
#include <dt-bindings/clock/qcom,ipq4019-gcc.h>
-struct msm_clk_priv {
phys_addr_t base;
-}; +#include "clock-qcom.h"
ulong msm_set_rate(struct clk *clk, ulong rate) { @@ -30,23 +27,7 @@ ulong msm_set_rate(struct clk *clk, ulong rate) } }
-static int msm_clk_probe(struct udevice *dev) -{
struct msm_clk_priv *priv = dev_get_priv(dev);
priv->base = dev_read_addr(dev);
if (priv->base == FDT_ADDR_T_NONE)
return -EINVAL;
return 0;
-}
-static ulong msm_clk_set_rate(struct clk *clk, ulong rate) -{
return msm_set_rate(clk, rate);
-}
-static int msm_enable(struct clk *clk) +int msm_enable(struct clk *clk) { switch (clk->id) { case GCC_BLSP1_QUP1_SPI_APPS_CLK: /*SPI1*/ @@ -68,21 +49,3 @@ static int msm_enable(struct clk *clk) } }
-static struct clk_ops msm_clk_ops = {
.set_rate = msm_clk_set_rate,
.enable = msm_enable,
-};
-static const struct udevice_id msm_clk_ids[] = {
{ .compatible = "qcom,gcc-ipq4019" },
This compatible should be moved to "clock-qcom.c".
-Sumit
{ }
-};
-U_BOOT_DRIVER(clk_msm) = {
.name = "clk_msm",
.id = UCLASS_CLK,
.of_match = msm_clk_ids,
.ops = &msm_clk_ops,
.priv_auto = sizeof(struct msm_clk_priv),
.probe = msm_clk_probe,
-};
-- 2.42.0

[...]
diff --git a/arch/arm/mach-ipq40xx/clock-ipq4019.c b/drivers/clk/qcom/clock-ipq4019.c similarity index 56% rename from arch/arm/mach-ipq40xx/clock-ipq4019.c rename to drivers/clk/qcom/clock-ipq4019.c index c1d5c4ecdd81..04c99964df15 100644 --- a/arch/arm/mach-ipq40xx/clock-ipq4019.c +++ b/drivers/clk/qcom/clock-ipq4019.c @@ -12,12 +12,9 @@
[...]
-static const struct udevice_id msm_clk_ids[] = {
{ .compatible = "qcom,gcc-ipq4019" },
This compatible should be moved to "clock-qcom.c".
Should all of the clock drivers have their udevice_id tables in clock-qcom.c or just this one?
I'll note that I forgot to adjust the U_BOOT_DRIVER definition below to be apq4019 specific, it shouldn't say "clk_msm".
-Sumit
{ }
-};
-U_BOOT_DRIVER(clk_msm) = {
.name = "clk_msm",
.id = UCLASS_CLK,
.of_match = msm_clk_ids,
.ops = &msm_clk_ops,
.priv_auto = sizeof(struct msm_clk_priv),
.probe = msm_clk_probe,
-};
-- 2.42.0

On Fri, 27 Oct 2023 at 18:27, Caleb Connolly caleb.connolly@linaro.org wrote:
[...]
diff --git a/arch/arm/mach-ipq40xx/clock-ipq4019.c b/drivers/clk/qcom/clock-ipq4019.c similarity index 56% rename from arch/arm/mach-ipq40xx/clock-ipq4019.c rename to drivers/clk/qcom/clock-ipq4019.c index c1d5c4ecdd81..04c99964df15 100644 --- a/arch/arm/mach-ipq40xx/clock-ipq4019.c +++ b/drivers/clk/qcom/clock-ipq4019.c @@ -12,12 +12,9 @@
[...]
-static const struct udevice_id msm_clk_ids[] = {
{ .compatible = "qcom,gcc-ipq4019" },
This compatible should be moved to "clock-qcom.c".
Should all of the clock drivers have their udevice_id tables in clock-qcom.c or just this one?
Actually this comment was with respect to this patch only being incomplete in itself. You are trying to reuse compatibles defined in clock-qcom.c while moving this driver to drivers/clk/qcom/.
I am fine with the later patch to have udevice_id table in corresponding SoC specific driver. There are lots of moving parts in this series :).
-Sumit
I'll note that I forgot to adjust the U_BOOT_DRIVER definition below to be apq4019 specific, it shouldn't say "clk_msm".
-Sumit
{ }
-};
-U_BOOT_DRIVER(clk_msm) = {
.name = "clk_msm",
.id = UCLASS_CLK,
.of_match = msm_clk_ids,
.ops = &msm_clk_ops,
.priv_auto = sizeof(struct msm_clk_priv),
.probe = msm_clk_probe,
-};
-- 2.42.0
-- // Caleb (they/them)

On 27/10/2023 14:03, Sumit Garg wrote:
On Fri, 27 Oct 2023 at 18:27, Caleb Connolly caleb.connolly@linaro.org wrote:
[...]
diff --git a/arch/arm/mach-ipq40xx/clock-ipq4019.c b/drivers/clk/qcom/clock-ipq4019.c similarity index 56% rename from arch/arm/mach-ipq40xx/clock-ipq4019.c rename to drivers/clk/qcom/clock-ipq4019.c index c1d5c4ecdd81..04c99964df15 100644 --- a/arch/arm/mach-ipq40xx/clock-ipq4019.c +++ b/drivers/clk/qcom/clock-ipq4019.c @@ -12,12 +12,9 @@
[...]
-static const struct udevice_id msm_clk_ids[] = {
{ .compatible = "qcom,gcc-ipq4019" },
This compatible should be moved to "clock-qcom.c".
Should all of the clock drivers have their udevice_id tables in clock-qcom.c or just this one?
Actually this comment was with respect to this patch only being incomplete in itself. You are trying to reuse compatibles defined in clock-qcom.c while moving this driver to drivers/clk/qcom/.
Ah! You're right, thanks for catching that.
I am fine with the later patch to have udevice_id table in corresponding SoC specific driver. There are lots of moving parts in this series :).
Yes, it's a lot to keep track of. I appreciate your feedback :)
-Sumit
I'll note that I forgot to adjust the U_BOOT_DRIVER definition below to be apq4019 specific, it shouldn't say "clk_msm".
-Sumit
{ }
-};
-U_BOOT_DRIVER(clk_msm) = {
.name = "clk_msm",
.id = UCLASS_CLK,
.of_match = msm_clk_ids,
.ops = &msm_clk_ops,
.priv_auto = sizeof(struct msm_clk_priv),
.probe = msm_clk_probe,
-};
-- 2.42.0
-- // Caleb (they/them)

From: Konrad Dybcio konrad.dybcio@linaro.org
Qualcomm's clock controller blocks are actually do much more than it says on the tin.. They provide clocks, resets and power domains. Currently, U-Boot required one to spawn 2 separate devices for controlling clocks and resets, both spanning the same register space. Refactor the code to make it work with just a single DT node, making it compatible with upstream Linux bindings and dropping the dedicated reset driver in favour of including it in the clock driver.
While at it, take the liberty of slowly renaming 'msm' and 'snapdragon' to 'qcom' and drop unused compatibles.
Heavily inspired by Renesas code for a similar hw block.
Signed-off-by: Konrad Dybcio konrad.dybcio@linaro.org [caleb: moved drivers to clk/qcom, added reset driver and adjusted bind logic] Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- arch/arm/Kconfig | 1 + arch/arm/dts/qcom-ipq4019.dtsi | 14 +-- arch/arm/dts/qcs404-evb.dts | 19 ++-- drivers/clk/qcom/clock-apq8016.c | 23 ++++- drivers/clk/qcom/clock-apq8096.c | 22 ++++- drivers/clk/qcom/clock-ipq4019.c | 95 +++++++++++++++++++ drivers/clk/qcom/clock-qcom.c | 122 ++++++++++++++++++++---- drivers/clk/qcom/clock-qcom.h | 22 +++-- drivers/clk/qcom/clock-qcs404.c | 54 ++++++++++- drivers/clk/qcom/clock-sdm845.c | 55 ++++++++++- drivers/reset/Kconfig | 7 -- drivers/reset/Makefile | 1 - drivers/reset/reset-qcom.c | 195 --------------------------------------- 13 files changed, 370 insertions(+), 260 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5aaf7e5e32af..faccfaf720a8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1067,6 +1067,7 @@ config ARCH_SNAPDRAGON select DM select DM_GPIO select DM_SERIAL + select DM_RESET select GPIO_EXTRA_HEADER select MSM_SMEM select OF_CONTROL diff --git a/arch/arm/dts/qcom-ipq4019.dtsi b/arch/arm/dts/qcom-ipq4019.dtsi index 0850ae56e9a8..f9489e42ea2c 100644 --- a/arch/arm/dts/qcom-ipq4019.dtsi +++ b/arch/arm/dts/qcom-ipq4019.dtsi @@ -66,14 +66,6 @@ status = "disabled"; };
- reset: gcc-reset@1800000 { - compatible = "qcom,gcc-reset-ipq4019"; - reg = <0x1800000 0x60000>; - #clock-cells = <1>; - #reset-cells = <1>; - bootph-all; - }; - soc_gpios: pinctrl@1000000 { compatible = "qcom,ipq4019-pinctrl"; reg = <0x1000000 0x300000>; @@ -136,7 +128,7 @@ #phy-cells = <0>; reg = <0x9a000 0x800>; reg-names = "phy_base"; - resets = <&reset USB3_UNIPHY_PHY_ARES>; + resets = <&gcc USB3_UNIPHY_PHY_ARES>; reset-names = "por_rst"; status = "disabled"; }; @@ -146,7 +138,7 @@ #phy-cells = <0>; reg = <0xa6000 0x40>; reg-names = "phy_base"; - resets = <&reset USB3_HSPHY_POR_ARES>, <&reset USB3_HSPHY_S_ARES>; + resets = <&gcc USB3_HSPHY_POR_ARES>, <&gcc USB3_HSPHY_S_ARES>; reset-names = "por_rst", "srif_rst"; status = "disabled"; }; @@ -179,7 +171,7 @@ #phy-cells = <0>; reg = <0xa8000 0x40>; reg-names = "phy_base"; - resets = <&reset USB2_HSPHY_POR_ARES>, <&reset USB2_HSPHY_S_ARES>; + resets = <&gcc USB2_HSPHY_POR_ARES>, <&gcc USB2_HSPHY_S_ARES>; reset-names = "por_rst", "srif_rst"; status = "disabled"; }; diff --git a/arch/arm/dts/qcs404-evb.dts b/arch/arm/dts/qcs404-evb.dts index 8d7893c11695..84224a8a3d39 100644 --- a/arch/arm/dts/qcs404-evb.dts +++ b/arch/arm/dts/qcs404-evb.dts @@ -208,11 +208,6 @@ #address-cells = <0x1>; #size-cells = <0x0>; #clock-cells = <1>; - }; - - reset: gcc-reset@1800000 { - compatible = "qcom,gcc-reset-qcs404"; - reg = <0x1800000 0x80000>; #reset-cells = <1>; };
@@ -245,8 +240,8 @@ clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, <&gcc GCC_USB3_PHY_PIPE_CLK>; clock-names = "ahb", "pipe"; - resets = <&reset GCC_USB3_PHY_BCR>, - <&reset GCC_USB3PHY_PHY_BCR>; + resets = <&gcc GCC_USB3_PHY_BCR>, + <&gcc GCC_USB3PHY_PHY_BCR>; reset-names = "com", "phy"; };
@@ -257,8 +252,8 @@ clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>; clock-names = "ahb", "sleep"; - resets = <&reset GCC_USB_HS_PHY_CFG_AHB_BCR>, - <&reset GCC_USB2A_PHY_BCR>; + resets = <&gcc GCC_USB_HS_PHY_CFG_AHB_BCR>, + <&gcc GCC_USB2A_PHY_BCR>; reset-names = "phy", "por"; };
@@ -269,8 +264,8 @@ clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>; clock-names = "ahb", "sleep"; - resets = <&reset GCC_QUSB2_PHY_BCR>, - <&reset GCC_USB2_HS_PHY_ONLY_BCR>; + resets = <&gcc GCC_QUSB2_PHY_BCR>, + <&gcc GCC_USB2_HS_PHY_ONLY_BCR>; reset-names = "phy", "por"; };
@@ -335,7 +330,7 @@ <&gcc GCC_ETH_PTP_CLK>, <&gcc GCC_ETH_RGMII_CLK>;
- resets = <&reset GCC_EMAC_BCR>; + resets = <&gcc GCC_EMAC_BCR>; reset-names = "emac";
snps,tso; diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c index 90f2a93d9ed5..e3b9b8c1b91b 100644 --- a/drivers/clk/qcom/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -13,6 +13,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> + #include "clock-qcom.h"
/* GPLL0 clock control registers */ @@ -49,7 +50,7 @@ static struct vote_clk gcc_blsp1_ahb_clk = { };
/* SDHCI */ -static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate) +static int clk_init_sdc(struct qcom_cc_priv *priv, int slot, uint rate) { int div = 8; /* 100MHz default */
@@ -75,7 +76,7 @@ static const struct bcr_regs uart2_regs = { };
/* UART: 115200 */ -static int clk_init_uart(struct msm_clk_priv *priv) +static int clk_init_uart(struct qcom_cc_priv *priv) { /* Enable AHB clock */ clk_enable_vote_clk(priv->base, &gcc_blsp1_ahb_clk); @@ -95,7 +96,7 @@ static int clk_init_uart(struct msm_clk_priv *priv)
ulong msm_set_rate(struct clk *clk, ulong rate) { - struct msm_clk_priv *priv = dev_get_priv(clk->dev); + struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
switch (clk->id) { case 0: /* SDC1 */ @@ -116,3 +117,19 @@ int msm_enable(struct clk *clk) { return 0; } + +static const struct udevice_id gcc_apq8016_of_match[] = { + { + .compatible = "qcom,gcc-apq8016", + /* TODO: add reset map */ + }, + { } +}; + +U_BOOT_DRIVER(gcc_apq8016) = { + .name = "gcc_apq8016", + .id = UCLASS_NOP, + .of_match = gcc_apq8016_of_match, + .bind = qcom_cc_bind, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/qcom/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c index d5388c69aefe..dc64d11ca979 100644 --- a/drivers/clk/qcom/clock-apq8096.c +++ b/drivers/clk/qcom/clock-apq8096.c @@ -41,7 +41,7 @@ static struct vote_clk gcc_blsp2_ahb_clk = { .vote_bit = BIT(15), };
-static int clk_init_sdc(struct msm_clk_priv *priv, uint rate) +static int clk_init_sdc(struct qcom_cc_priv *priv, uint rate) { int div = 3;
@@ -62,7 +62,7 @@ static const struct bcr_regs uart2_regs = { .D = BLSP2_UART2_APPS_D, };
-static int clk_init_uart(struct msm_clk_priv *priv) +static int clk_init_uart(struct qcom_cc_priv *priv) { /* Enable AHB clock */ clk_enable_vote_clk(priv->base, &gcc_blsp2_ahb_clk); @@ -82,7 +82,7 @@ static int clk_init_uart(struct msm_clk_priv *priv)
ulong msm_set_rate(struct clk *clk, ulong rate) { - struct msm_clk_priv *priv = dev_get_priv(clk->dev); + struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
switch (clk->id) { case 0: /* SDC1 */ @@ -99,3 +99,19 @@ int msm_enable(struct clk *clk) { return 0; } + +static const struct udevice_id gcc_apq8096_of_match[] = { + { + .compatible = "qcom,gcc-apq8096", + /* TODO: add reset map */ + }, + { } +}; + +U_BOOT_DRIVER(gcc_apq8096) = { + .name = "gcc_apq8096", + .id = UCLASS_NOP, + .of_match = gcc_apq8096_of_match, + .bind = qcom_cc_bind, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/qcom/clock-ipq4019.c b/drivers/clk/qcom/clock-ipq4019.c index 04c99964df15..6636af98132d 100644 --- a/drivers/clk/qcom/clock-ipq4019.c +++ b/drivers/clk/qcom/clock-ipq4019.c @@ -13,6 +13,7 @@ #include <dm.h> #include <errno.h> #include <dt-bindings/clock/qcom,ipq4019-gcc.h> +#include <dt-bindings/reset/qcom,ipq4019-reset.h>
#include "clock-qcom.h"
@@ -49,3 +50,97 @@ int msm_enable(struct clk *clk) } }
+static const struct qcom_reset_map gcc_ipq4019_resets[] = { + [WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 }, + [WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 }, + [WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 }, + [WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 }, + [WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 }, + [WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 }, + [WIFI1_CPU_INIT_RESET] = { 0x20008, 5 }, + [WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 }, + [WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 }, + [WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 }, + [WIFI1_CORE_WARM_RESET] = { 0x20008, 1 }, + [WIFI1_CORE_COLD_RESET] = { 0x20008, 0 }, + [USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 }, + [USB3_HSPHY_POR_ARES] = { 0x1e038, 4 }, + [USB3_HSPHY_S_ARES] = { 0x1e038, 2 }, + [USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 }, + [USB2_HSPHY_S_ARES] = { 0x1e01c, 2 }, + [PCIE_PHY_AHB_ARES] = { 0x1d010, 11 }, + [PCIE_AHB_ARES] = { 0x1d010, 10 }, + [PCIE_PWR_ARES] = { 0x1d010, 9 }, + [PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 }, + [PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 }, + [PCIE_PHY_ARES] = { 0x1d010, 6 }, + [PCIE_PARF_XPU_ARES] = { 0x1d010, 5 }, + [PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 }, + [PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 }, + [PCIE_PIPE_ARES] = { 0x1d010, 2 }, + [PCIE_AXI_S_ARES] = { 0x1d010, 1 }, + [PCIE_AXI_M_ARES] = { 0x1d010, 0 }, + [ESS_RESET] = { 0x12008, 0}, + [GCC_BLSP1_BCR] = {0x01000, 0}, + [GCC_BLSP1_QUP1_BCR] = {0x02000, 0}, + [GCC_BLSP1_UART1_BCR] = {0x02038, 0}, + [GCC_BLSP1_QUP2_BCR] = {0x03008, 0}, + [GCC_BLSP1_UART2_BCR] = {0x03028, 0}, + [GCC_BIMC_BCR] = {0x04000, 0}, + [GCC_TLMM_BCR] = {0x05000, 0}, + [GCC_IMEM_BCR] = {0x0E000, 0}, + [GCC_ESS_BCR] = {0x12008, 0}, + [GCC_PRNG_BCR] = {0x13000, 0}, + [GCC_BOOT_ROM_BCR] = {0x13008, 0}, + [GCC_CRYPTO_BCR] = {0x16000, 0}, + [GCC_SDCC1_BCR] = {0x18000, 0}, + [GCC_SEC_CTRL_BCR] = {0x1A000, 0}, + [GCC_AUDIO_BCR] = {0x1B008, 0}, + [GCC_QPIC_BCR] = {0x1C000, 0}, + [GCC_PCIE_BCR] = {0x1D000, 0}, + [GCC_USB2_BCR] = {0x1E008, 0}, + [GCC_USB2_PHY_BCR] = {0x1E018, 0}, + [GCC_USB3_BCR] = {0x1E024, 0}, + [GCC_USB3_PHY_BCR] = {0x1E034, 0}, + [GCC_SYSTEM_NOC_BCR] = {0x21000, 0}, + [GCC_PCNOC_BCR] = {0x2102C, 0}, + [GCC_DCD_BCR] = {0x21038, 0}, + [GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0}, + [GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0}, + [GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0}, + [GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0}, + [GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0}, + [GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0}, + [GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0}, + [GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0}, + [GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0}, + [GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0}, + [GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0}, + [GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0}, + [GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0}, + [GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0}, + [GCC_TCSR_BCR] = {0x22000, 0}, + [GCC_MPM_BCR] = {0x24000, 0}, + [GCC_SPDM_BCR] = {0x25000, 0}, +}; + +static struct qcom_cc_data ipq4019_data = { + .resets = gcc_ipq4019_resets, + .num_resets = ARRAY_SIZE(gcc_ipq4019_resets), +}; + +static const struct udevice_id gcc_ipq4019_of_match[] = { + { + .compatible = "qcom,gcc-ipq4019", + .data = (ulong)&ipq4019_data, + }, + { } +}; + +U_BOOT_DRIVER(gcc_ipq4019) = { + .name = "gcc_ipq4019", + .id = UCLASS_NOP, + .of_match = gcc_ipq4019_of_match, + .bind = qcom_cc_bind, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c index 5667abeb89a4..b0416a05789d 100644 --- a/drivers/clk/qcom/clock-qcom.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -1,8 +1,13 @@ -// SPDX-License-Identifier: BSD-3-Clause +// SPDX-License-Identifier: BSD-3-Clause AND GPL-2.0 /* - * Clock drivers for Qualcomm APQ8016, APQ8096 + * Clock and reset drivers for Qualcomm platforms Global Clock + * Controller (GCC). * * (C) Copyright 2015 Mateusz Kulikowski mateusz.kulikowski@gmail.com + * (C) Copyright 2020 Sartura Ltd. (reset driver) + * Author: Robert Marko robert.marko@sartura.hr + * (C) Copyright 2022 Linaro Ltd. (reset driver) + * Author: Sumit Garg sumit.garg@linaro.org * * Based on Little Kernel driver, simplified */ @@ -10,9 +15,13 @@ #include <common.h> #include <clk-uclass.h> #include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> +#include <reset-uclass.h> + #include "clock-qcom.h"
/* CBCR register fields */ @@ -137,12 +146,15 @@ void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
static int msm_clk_probe(struct udevice *dev) { - struct msm_clk_priv *priv = dev_get_priv(dev); + struct qcom_cc_data *data = (struct qcom_cc_data *)dev_get_driver_data(dev); + struct qcom_cc_priv *priv = dev_get_priv(dev);
priv->base = dev_read_addr(dev); if (priv->base == FDT_ADDR_T_NONE) return -EINVAL;
+ priv->data = data; + return 0; }
@@ -161,21 +173,97 @@ static struct clk_ops msm_clk_ops = { .enable = msm_clk_enable, };
-static const struct udevice_id msm_clk_ids[] = { - { .compatible = "qcom,gcc-msm8916" }, - { .compatible = "qcom,gcc-apq8016" }, - { .compatible = "qcom,gcc-msm8996" }, - { .compatible = "qcom,gcc-apq8096" }, - { .compatible = "qcom,gcc-sdm845" }, - { .compatible = "qcom,gcc-qcs404" }, - { } -}; - -U_BOOT_DRIVER(clk_msm) = { - .name = "clk_msm", +U_BOOT_DRIVER(qcom_clk) = { + .name = "qcom_clk", .id = UCLASS_CLK, - .of_match = msm_clk_ids, .ops = &msm_clk_ops, - .priv_auto = sizeof(struct msm_clk_priv), + .priv_auto = sizeof(struct qcom_cc_priv), .probe = msm_clk_probe, }; + +int qcom_cc_bind(struct udevice *parent) +{ + struct qcom_cc_data *data = (struct qcom_cc_data *)dev_get_driver_data(parent); + struct udevice *clkdev, *rstdev; + struct driver *drv; + int ret; + + /* Get a handle to the common clk handler */ + drv = lists_driver_lookup_name("qcom_clk"); + if (!drv) + return -ENOENT; + + /* Register the clock controller */ + ret = device_bind_with_driver_data(parent, drv, "qcom_clk", (ulong)data, + dev_ofnode(parent), &clkdev); + if (ret) + return ret; + + /* Bail out early if resets are not specified for this platform */ + if (!data->resets) + return ret; + + /* Get a handle to the common reset handler */ + drv = lists_driver_lookup_name("qcom_reset"); + if (!drv) + return -ENOENT; + + /* Register the reset controller */ + ret = device_bind_with_driver_data(parent, drv, "qcom_reset", (ulong)data, + dev_ofnode(parent), &rstdev); + if (ret) + device_unbind(clkdev); + + return ret; +} + +static int qcom_reset_set(struct reset_ctl *rst, bool assert) +{ + struct qcom_cc_data *data = (struct qcom_cc_data *)dev_get_driver_data(rst->dev); + void __iomem *base = dev_get_priv(rst->dev); + const struct qcom_reset_map *map; + u32 value; + + map = &data->resets[rst->id]; + + value = readl(base + map->reg); + + if (assert) + value |= BIT(map->bit); + else + value &= ~BIT(map->bit); + + writel(value, base + map->reg); + + return 0; +} + +static int qcom_reset_assert(struct reset_ctl *rst) +{ + return qcom_reset_set(rst, true); +} + +static int qcom_reset_deassert(struct reset_ctl *rst) +{ + return qcom_reset_set(rst, false); +} + +static const struct reset_ops qcom_reset_ops = { + .rst_assert = qcom_reset_assert, + .rst_deassert = qcom_reset_deassert, +}; + +static int qcom_reset_probe(struct udevice *dev) +{ + /* Set our priv pointer to the base address */ + dev_set_priv(dev, (void *)dev_read_addr(dev)); + + return 0; +} + +U_BOOT_DRIVER(qcom_reset) = { + .name = "qcom_reset", + .id = UCLASS_RESET, + .ops = &qcom_reset_ops, + .probe = qcom_reset_probe, +}; diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h index c90bbefa5881..a77a94b6ea06 100644 --- a/drivers/clk/qcom/clock-qcom.h +++ b/drivers/clk/qcom/clock-qcom.h @@ -1,11 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* - * Qualcomm APQ8016, APQ8096, SDM845 - * * (C) Copyright 2017 Jorge Ramirez-Ortiz jorge.ramirez-ortiz@linaro.org */ -#ifndef _CLOCK_SNAPDRAGON_H -#define _CLOCK_SNAPDRAGON_H +#ifndef _CLOCK_QCOM_H +#define _CLOCK_QCOM_H
#define CFG_CLK_SRC_CXO (0 << 8) #define CFG_CLK_SRC_GPLL0 (1 << 8) @@ -32,10 +30,22 @@ struct bcr_regs { uintptr_t D; };
-struct msm_clk_priv { - phys_addr_t base; +struct qcom_reset_map { + unsigned int reg; + u8 bit; };
+struct qcom_cc_data { + const struct qcom_reset_map *resets; + unsigned long num_resets; +}; + +struct qcom_cc_priv { + phys_addr_t base; + struct qcom_cc_data *data; +}; + +int qcom_cc_bind(struct udevice *parent); void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0); void clk_bcr_update(phys_addr_t apps_cmd_rgcr); void clk_enable_cbc(phys_addr_t cbcr); diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c index 80218af73ef6..e622309b6747 100644 --- a/drivers/clk/qcom/clock-qcs404.c +++ b/drivers/clk/qcom/clock-qcs404.c @@ -11,9 +11,10 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> +#include <dt-bindings/clock/qcom,gcc-qcs404.h> + #include "clock-qcom.h"
-#include <dt-bindings/clock/qcom,gcc-qcs404.h>
/* GPLL0 clock control registers */ #define GPLL0_STATUS_ACTIVE BIT(31) @@ -113,7 +114,7 @@ static const struct bcr_regs blsp1_qup4_i2c_apps_regs = {
ulong msm_set_rate(struct clk *clk, ulong rate) { - struct msm_clk_priv *priv = dev_get_priv(clk->dev); + struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
switch (clk->id) { case GCC_BLSP1_UART2_APPS_CLK: @@ -158,7 +159,7 @@ ulong msm_set_rate(struct clk *clk, ulong rate)
int msm_enable(struct clk *clk) { - struct msm_clk_priv *priv = dev_get_priv(clk->dev); + struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
switch (clk->id) { case GCC_USB30_MASTER_CLK: @@ -235,3 +236,50 @@ int msm_enable(struct clk *clk)
return 0; } + +static const struct qcom_reset_map qcs404_gcc_resets[] = { + [GCC_GENI_IR_BCR] = { 0x0F000 }, + [GCC_CDSP_RESTART] = { 0x18000 }, + [GCC_USB_HS_BCR] = { 0x41000 }, + [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 }, + [GCC_QUSB2_PHY_BCR] = { 0x4103c }, + [GCC_USB_HS_PHY_CFG_AHB_BCR] = { 0x0000c, 1 }, + [GCC_USB2A_PHY_BCR] = { 0x0000c, 0 }, + [GCC_USB3_PHY_BCR] = { 0x39004 }, + [GCC_USB_30_BCR] = { 0x39000 }, + [GCC_USB3PHY_PHY_BCR] = { 0x39008 }, + [GCC_PCIE_0_BCR] = { 0x3e000 }, + [GCC_PCIE_0_PHY_BCR] = { 0x3e004 }, + [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 }, + [GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c }, + [GCC_PCIE_0_AXI_MASTER_STICKY_ARES] = { 0x3e040, 6}, + [GCC_PCIE_0_AHB_ARES] = { 0x3e040, 5 }, + [GCC_PCIE_0_AXI_SLAVE_ARES] = { 0x3e040, 4 }, + [GCC_PCIE_0_AXI_MASTER_ARES] = { 0x3e040, 3 }, + [GCC_PCIE_0_CORE_STICKY_ARES] = { 0x3e040, 2 }, + [GCC_PCIE_0_SLEEP_ARES] = { 0x3e040, 1 }, + [GCC_PCIE_0_PIPE_ARES] = { 0x3e040, 0 }, + [GCC_EMAC_BCR] = { 0x4e000 }, + [GCC_WDSP_RESTART] = {0x19000}, +}; + +static const struct qcom_cc_data qcs404_gcc_data = { + .resets = qcs404_gcc_resets, + .num_resets = ARRAY_SIZE(qcs404_gcc_resets), +}; + +static const struct udevice_id gcc_qcs404_of_match[] = { + { + .compatible = "qcom,gcc-qcs404", + .data = (ulong)&qcs404_gcc_data + }, + { } +}; + +U_BOOT_DRIVER(gcc_qcs404) = { + .name = "gcc_qcs404", + .id = UCLASS_NOP, + .of_match = gcc_qcs404_of_match, + .bind = qcom_cc_bind, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c index 95a057b82986..eab88a40c09d 100644 --- a/drivers/clk/qcom/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -15,6 +15,7 @@ #include <asm/io.h> #include <linux/bitops.h> #include <dt-bindings/clock/qcom,gcc-sdm845.h> + #include "clock-qcom.h"
#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } @@ -70,7 +71,7 @@ const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate) return f - 1; }
-static int clk_init_uart(struct msm_clk_priv *priv, uint rate) +static int clk_init_uart(struct qcom_cc_priv *priv, uint rate) { const struct freq_tbl *freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
@@ -82,7 +83,7 @@ static int clk_init_uart(struct msm_clk_priv *priv, uint rate)
ulong msm_set_rate(struct clk *clk, ulong rate) { - struct msm_clk_priv *priv = dev_get_priv(clk->dev); + struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
switch (clk->id) { case GCC_QUPV3_WRAP1_S1_CLK: /*UART2*/ @@ -96,3 +97,53 @@ int msm_enable(struct clk *clk) { return 0; } + +static const struct qcom_reset_map sdm845_gcc_resets[] = { + [GCC_MMSS_BCR] = { 0xb000 }, + [GCC_PCIE_0_BCR] = { 0x6b000 }, + [GCC_PCIE_1_BCR] = { 0x8d000 }, + [GCC_PCIE_PHY_BCR] = { 0x6f000 }, + [GCC_PDM_BCR] = { 0x33000 }, + [GCC_PRNG_BCR] = { 0x34000 }, + [GCC_QUPV3_WRAPPER_0_BCR] = { 0x17000 }, + [GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 }, + [GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x12004 }, + [GCC_SDCC2_BCR] = { 0x14000 }, + [GCC_SDCC4_BCR] = { 0x16000 }, + [GCC_TSIF_BCR] = { 0x36000 }, + [GCC_UFS_CARD_BCR] = { 0x75000 }, + [GCC_UFS_PHY_BCR] = { 0x77000 }, + [GCC_USB30_PRIM_BCR] = { 0xf000 }, + [GCC_USB30_SEC_BCR] = { 0x10000 }, + [GCC_USB3_PHY_PRIM_BCR] = { 0x50000 }, + [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 }, + [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 }, + [GCC_USB3_PHY_SEC_BCR] = { 0x5000c }, + [GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 }, + [GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 }, + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 }, + [GCC_PCIE_0_PHY_BCR] = { 0x6c01c }, + [GCC_PCIE_1_PHY_BCR] = { 0x8e01c }, +}; + +static const struct qcom_cc_data qcs404_gcc_data = { + .resets = sdm845_gcc_resets, + .num_resets = ARRAY_SIZE(sdm845_gcc_resets), +}; + +static const struct udevice_id gcc_sdm845_of_match[] = { + { + .compatible = "qcom,gcc-sdm845", + .data = (ulong)&qcs404_gcc_data, + }, + { } +}; + +U_BOOT_DRIVER(gcc_sdm845) = { + .name = "gcc_sdm845", + .id = UCLASS_NOP, + .of_match = gcc_sdm845_of_match, + .bind = qcom_cc_bind, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 73bbd3069258..88e04d93f2a0 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -156,13 +156,6 @@ config RESET_IMX7 help Support for reset controller on i.MX7/8 SoCs.
-config RESET_QCOM - bool "Reset driver for Qualcomm SoCs" - depends on DM_RESET && (ARCH_SNAPDRAGON || ARCH_IPQ40XX) - default y - help - Support for reset controller on Qualcomm SoCs. - config RESET_SIFIVE bool "Reset Driver for SiFive SoC's" depends on DM_RESET && CLK_SIFIVE_PRCI && (TARGET_SIFIVE_UNLEASHED || TARGET_SIFIVE_UNMATCHED) diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index e2239a250a3a..7b0066f80188 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -24,7 +24,6 @@ obj-$(CONFIG_RESET_MTMIPS) += reset-mtmips.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o obj-$(CONFIG_RESET_IMX7) += reset-imx7.o -obj-$(CONFIG_RESET_QCOM) += reset-qcom.o obj-$(CONFIG_RESET_SIFIVE) += reset-sifive.o obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o diff --git a/drivers/reset/reset-qcom.c b/drivers/reset/reset-qcom.c deleted file mode 100644 index 94315e76d545..000000000000 --- a/drivers/reset/reset-qcom.c +++ /dev/null @@ -1,195 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (c) 2020 Sartura Ltd. - * Copyright (c) 2022 Linaro Ltd. - * - * Author: Robert Marko robert.marko@sartura.hr - * Sumit Garg sumit.garg@linaro.org - * - * Based on Linux driver - */ - -#include <asm/io.h> -#include <common.h> -#include <dm.h> -#include <reset-uclass.h> -#include <linux/bitops.h> -#include <malloc.h> - -struct qcom_reset_priv { - phys_addr_t base; -}; - -struct qcom_reset_map { - unsigned int reg; - u8 bit; -}; - -#ifdef CONFIG_ARCH_IPQ40XX -#include <dt-bindings/reset/qcom,ipq4019-reset.h> -static const struct qcom_reset_map gcc_qcom_resets[] = { - [WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 }, - [WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 }, - [WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 }, - [WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 }, - [WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 }, - [WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 }, - [WIFI1_CPU_INIT_RESET] = { 0x20008, 5 }, - [WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 }, - [WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 }, - [WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 }, - [WIFI1_CORE_WARM_RESET] = { 0x20008, 1 }, - [WIFI1_CORE_COLD_RESET] = { 0x20008, 0 }, - [USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 }, - [USB3_HSPHY_POR_ARES] = { 0x1e038, 4 }, - [USB3_HSPHY_S_ARES] = { 0x1e038, 2 }, - [USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 }, - [USB2_HSPHY_S_ARES] = { 0x1e01c, 2 }, - [PCIE_PHY_AHB_ARES] = { 0x1d010, 11 }, - [PCIE_AHB_ARES] = { 0x1d010, 10 }, - [PCIE_PWR_ARES] = { 0x1d010, 9 }, - [PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 }, - [PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 }, - [PCIE_PHY_ARES] = { 0x1d010, 6 }, - [PCIE_PARF_XPU_ARES] = { 0x1d010, 5 }, - [PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 }, - [PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 }, - [PCIE_PIPE_ARES] = { 0x1d010, 2 }, - [PCIE_AXI_S_ARES] = { 0x1d010, 1 }, - [PCIE_AXI_M_ARES] = { 0x1d010, 0 }, - [ESS_RESET] = { 0x12008, 0}, - [GCC_BLSP1_BCR] = {0x01000, 0}, - [GCC_BLSP1_QUP1_BCR] = {0x02000, 0}, - [GCC_BLSP1_UART1_BCR] = {0x02038, 0}, - [GCC_BLSP1_QUP2_BCR] = {0x03008, 0}, - [GCC_BLSP1_UART2_BCR] = {0x03028, 0}, - [GCC_BIMC_BCR] = {0x04000, 0}, - [GCC_TLMM_BCR] = {0x05000, 0}, - [GCC_IMEM_BCR] = {0x0E000, 0}, - [GCC_ESS_BCR] = {0x12008, 0}, - [GCC_PRNG_BCR] = {0x13000, 0}, - [GCC_BOOT_ROM_BCR] = {0x13008, 0}, - [GCC_CRYPTO_BCR] = {0x16000, 0}, - [GCC_SDCC1_BCR] = {0x18000, 0}, - [GCC_SEC_CTRL_BCR] = {0x1A000, 0}, - [GCC_AUDIO_BCR] = {0x1B008, 0}, - [GCC_QPIC_BCR] = {0x1C000, 0}, - [GCC_PCIE_BCR] = {0x1D000, 0}, - [GCC_USB2_BCR] = {0x1E008, 0}, - [GCC_USB2_PHY_BCR] = {0x1E018, 0}, - [GCC_USB3_BCR] = {0x1E024, 0}, - [GCC_USB3_PHY_BCR] = {0x1E034, 0}, - [GCC_SYSTEM_NOC_BCR] = {0x21000, 0}, - [GCC_PCNOC_BCR] = {0x2102C, 0}, - [GCC_DCD_BCR] = {0x21038, 0}, - [GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0}, - [GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0}, - [GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0}, - [GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0}, - [GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0}, - [GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0}, - [GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0}, - [GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0}, - [GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0}, - [GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0}, - [GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0}, - [GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0}, - [GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0}, - [GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0}, - [GCC_TCSR_BCR] = {0x22000, 0}, - [GCC_MPM_BCR] = {0x24000, 0}, - [GCC_SPDM_BCR] = {0x25000, 0}, -}; -#endif - -#ifdef CONFIG_TARGET_QCS404EVB -#include <dt-bindings/clock/qcom,gcc-qcs404.h> -static const struct qcom_reset_map gcc_qcom_resets[] = { - [GCC_GENI_IR_BCR] = { 0x0F000 }, - [GCC_CDSP_RESTART] = { 0x18000 }, - [GCC_USB_HS_BCR] = { 0x41000 }, - [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 }, - [GCC_QUSB2_PHY_BCR] = { 0x4103c }, - [GCC_USB_HS_PHY_CFG_AHB_BCR] = { 0x0000c, 1 }, - [GCC_USB2A_PHY_BCR] = { 0x0000c, 0 }, - [GCC_USB3_PHY_BCR] = { 0x39004 }, - [GCC_USB_30_BCR] = { 0x39000 }, - [GCC_USB3PHY_PHY_BCR] = { 0x39008 }, - [GCC_PCIE_0_BCR] = { 0x3e000 }, - [GCC_PCIE_0_PHY_BCR] = { 0x3e004 }, - [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 }, - [GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c }, - [GCC_PCIE_0_AXI_MASTER_STICKY_ARES] = { 0x3e040, 6}, - [GCC_PCIE_0_AHB_ARES] = { 0x3e040, 5 }, - [GCC_PCIE_0_AXI_SLAVE_ARES] = { 0x3e040, 4 }, - [GCC_PCIE_0_AXI_MASTER_ARES] = { 0x3e040, 3 }, - [GCC_PCIE_0_CORE_STICKY_ARES] = { 0x3e040, 2 }, - [GCC_PCIE_0_SLEEP_ARES] = { 0x3e040, 1 }, - [GCC_PCIE_0_PIPE_ARES] = { 0x3e040, 0 }, - [GCC_EMAC_BCR] = { 0x4e000 }, - [GCC_WDSP_RESTART] = {0x19000}, -}; -#endif - -static int qcom_reset_assert(struct reset_ctl *rst) -{ - struct qcom_reset_priv *priv = dev_get_priv(rst->dev); - const struct qcom_reset_map *reset_map = gcc_qcom_resets; - const struct qcom_reset_map *map; - u32 value; - - map = &reset_map[rst->id]; - - value = readl(priv->base + map->reg); - value |= BIT(map->bit); - writel(value, priv->base + map->reg); - - return 0; -} - -static int qcom_reset_deassert(struct reset_ctl *rst) -{ - struct qcom_reset_priv *priv = dev_get_priv(rst->dev); - const struct qcom_reset_map *reset_map = gcc_qcom_resets; - const struct qcom_reset_map *map; - u32 value; - - map = &reset_map[rst->id]; - - value = readl(priv->base + map->reg); - value &= ~BIT(map->bit); - writel(value, priv->base + map->reg); - - return 0; -} - -static const struct reset_ops qcom_reset_ops = { - .rst_assert = qcom_reset_assert, - .rst_deassert = qcom_reset_deassert, -}; - -static const struct udevice_id qcom_reset_ids[] = { - { .compatible = "qcom,gcc-reset-ipq4019" }, - { .compatible = "qcom,gcc-reset-qcs404" }, - { } -}; - -static int qcom_reset_probe(struct udevice *dev) -{ - struct qcom_reset_priv *priv = dev_get_priv(dev); - - priv->base = dev_read_addr(dev); - if (priv->base == FDT_ADDR_T_NONE) - return -EINVAL; - - return 0; -} - -U_BOOT_DRIVER(qcom_reset) = { - .name = "qcom_reset", - .id = UCLASS_RESET, - .of_match = qcom_reset_ids, - .ops = &qcom_reset_ops, - .probe = qcom_reset_probe, - .priv_auto = sizeof(struct qcom_reset_priv), -};

On Wed, 25 Oct 2023 at 01:54, Caleb Connolly caleb.connolly@linaro.org wrote:
From: Konrad Dybcio konrad.dybcio@linaro.org
Qualcomm's clock controller blocks are actually do much more than it
s/do/doing/
says on the tin.. They provide clocks, resets and power domains. Currently, U-Boot required one to spawn 2 separate devices for
s/required/requires/
controlling clocks and resets, both spanning the same register space. Refactor the code to make it work with just a single DT node, making it compatible with upstream Linux bindings and dropping the dedicated reset driver in favour of including it in the clock driver.
While at it, take the liberty of slowly renaming 'msm' and 'snapdragon' to 'qcom' and drop unused compatibles.
Heavily inspired by Renesas code for a similar hw block.
Signed-off-by: Konrad Dybcio konrad.dybcio@linaro.org [caleb: moved drivers to clk/qcom, added reset driver and adjusted bind logic] Signed-off-by: Caleb Connolly caleb.connolly@linaro.org
arch/arm/Kconfig | 1 + arch/arm/dts/qcom-ipq4019.dtsi | 14 +-- arch/arm/dts/qcs404-evb.dts | 19 ++-- drivers/clk/qcom/clock-apq8016.c | 23 ++++- drivers/clk/qcom/clock-apq8096.c | 22 ++++- drivers/clk/qcom/clock-ipq4019.c | 95 +++++++++++++++++++ drivers/clk/qcom/clock-qcom.c | 122 ++++++++++++++++++++---- drivers/clk/qcom/clock-qcom.h | 22 +++-- drivers/clk/qcom/clock-qcs404.c | 54 ++++++++++- drivers/clk/qcom/clock-sdm845.c | 55 ++++++++++- drivers/reset/Kconfig | 7 -- drivers/reset/Makefile | 1 - drivers/reset/reset-qcom.c | 195 --------------------------------------- 13 files changed, 370 insertions(+), 260 deletions(-)
Overall the code looks more scalable after this patch but I have some comments below.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5aaf7e5e32af..faccfaf720a8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1067,6 +1067,7 @@ config ARCH_SNAPDRAGON select DM select DM_GPIO select DM_SERIAL
select DM_RESET select GPIO_EXTRA_HEADER select MSM_SMEM select OF_CONTROL
diff --git a/arch/arm/dts/qcom-ipq4019.dtsi b/arch/arm/dts/qcom-ipq4019.dtsi index 0850ae56e9a8..f9489e42ea2c 100644 --- a/arch/arm/dts/qcom-ipq4019.dtsi +++ b/arch/arm/dts/qcom-ipq4019.dtsi @@ -66,14 +66,6 @@ status = "disabled"; };
reset: gcc-reset@1800000 {
compatible = "qcom,gcc-reset-ipq4019";
reg = <0x1800000 0x60000>;
#clock-cells = <1>;
#reset-cells = <1>;
bootph-all;
};
soc_gpios: pinctrl@1000000 { compatible = "qcom,ipq4019-pinctrl"; reg = <0x1000000 0x300000>;
@@ -136,7 +128,7 @@ #phy-cells = <0>; reg = <0x9a000 0x800>; reg-names = "phy_base";
resets = <&reset USB3_UNIPHY_PHY_ARES>;
resets = <&gcc USB3_UNIPHY_PHY_ARES>; reset-names = "por_rst"; status = "disabled"; };
@@ -146,7 +138,7 @@ #phy-cells = <0>; reg = <0xa6000 0x40>; reg-names = "phy_base";
resets = <&reset USB3_HSPHY_POR_ARES>, <&reset USB3_HSPHY_S_ARES>;
resets = <&gcc USB3_HSPHY_POR_ARES>, <&gcc USB3_HSPHY_S_ARES>; reset-names = "por_rst", "srif_rst"; status = "disabled"; };
@@ -179,7 +171,7 @@ #phy-cells = <0>; reg = <0xa8000 0x40>; reg-names = "phy_base";
resets = <&reset USB2_HSPHY_POR_ARES>, <&reset USB2_HSPHY_S_ARES>;
resets = <&gcc USB2_HSPHY_POR_ARES>, <&gcc USB2_HSPHY_S_ARES>; reset-names = "por_rst", "srif_rst"; status = "disabled"; };
diff --git a/arch/arm/dts/qcs404-evb.dts b/arch/arm/dts/qcs404-evb.dts index 8d7893c11695..84224a8a3d39 100644 --- a/arch/arm/dts/qcs404-evb.dts +++ b/arch/arm/dts/qcs404-evb.dts @@ -208,11 +208,6 @@ #address-cells = <0x1>; #size-cells = <0x0>; #clock-cells = <1>;
};
reset: gcc-reset@1800000 {
compatible = "qcom,gcc-reset-qcs404";
reg = <0x1800000 0x80000>; #reset-cells = <1>; };
@@ -245,8 +240,8 @@ clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, <&gcc GCC_USB3_PHY_PIPE_CLK>; clock-names = "ahb", "pipe";
resets = <&reset GCC_USB3_PHY_BCR>,
<&reset GCC_USB3PHY_PHY_BCR>;
resets = <&gcc GCC_USB3_PHY_BCR>,
<&gcc GCC_USB3PHY_PHY_BCR>; reset-names = "com", "phy"; };
@@ -257,8 +252,8 @@ clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>; clock-names = "ahb", "sleep";
resets = <&reset GCC_USB_HS_PHY_CFG_AHB_BCR>,
<&reset GCC_USB2A_PHY_BCR>;
resets = <&gcc GCC_USB_HS_PHY_CFG_AHB_BCR>,
<&gcc GCC_USB2A_PHY_BCR>; reset-names = "phy", "por"; };
@@ -269,8 +264,8 @@ clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>; clock-names = "ahb", "sleep";
resets = <&reset GCC_QUSB2_PHY_BCR>,
<&reset GCC_USB2_HS_PHY_ONLY_BCR>;
resets = <&gcc GCC_QUSB2_PHY_BCR>,
<&gcc GCC_USB2_HS_PHY_ONLY_BCR>; reset-names = "phy", "por"; };
@@ -335,7 +330,7 @@ <&gcc GCC_ETH_PTP_CLK>, <&gcc GCC_ETH_RGMII_CLK>;
resets = <&reset GCC_EMAC_BCR>;
resets = <&gcc GCC_EMAC_BCR>; reset-names = "emac"; snps,tso;
diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c index 90f2a93d9ed5..e3b9b8c1b91b 100644 --- a/drivers/clk/qcom/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -13,6 +13,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h>
#include "clock-qcom.h"
/* GPLL0 clock control registers */ @@ -49,7 +50,7 @@ static struct vote_clk gcc_blsp1_ahb_clk = { };
/* SDHCI */ -static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate) +static int clk_init_sdc(struct qcom_cc_priv *priv, int slot, uint rate) { int div = 8; /* 100MHz default */
@@ -75,7 +76,7 @@ static const struct bcr_regs uart2_regs = { };
/* UART: 115200 */ -static int clk_init_uart(struct msm_clk_priv *priv) +static int clk_init_uart(struct qcom_cc_priv *priv) { /* Enable AHB clock */ clk_enable_vote_clk(priv->base, &gcc_blsp1_ahb_clk); @@ -95,7 +96,7 @@ static int clk_init_uart(struct msm_clk_priv *priv)
ulong msm_set_rate(struct clk *clk, ulong rate) {
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
struct qcom_cc_priv *priv = dev_get_priv(clk->dev); switch (clk->id) { case 0: /* SDC1 */
@@ -116,3 +117,19 @@ int msm_enable(struct clk *clk) { return 0; }
+static const struct udevice_id gcc_apq8016_of_match[] = {
{
.compatible = "qcom,gcc-apq8016",
/* TODO: add reset map */
},
{ }
+};
+U_BOOT_DRIVER(gcc_apq8016) = {
.name = "gcc_apq8016",
.id = UCLASS_NOP,
.of_match = gcc_apq8016_of_match,
.bind = qcom_cc_bind,
.flags = DM_FLAG_PRE_RELOC,
+}; diff --git a/drivers/clk/qcom/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c index d5388c69aefe..dc64d11ca979 100644 --- a/drivers/clk/qcom/clock-apq8096.c +++ b/drivers/clk/qcom/clock-apq8096.c @@ -41,7 +41,7 @@ static struct vote_clk gcc_blsp2_ahb_clk = { .vote_bit = BIT(15), };
-static int clk_init_sdc(struct msm_clk_priv *priv, uint rate) +static int clk_init_sdc(struct qcom_cc_priv *priv, uint rate) { int div = 3;
@@ -62,7 +62,7 @@ static const struct bcr_regs uart2_regs = { .D = BLSP2_UART2_APPS_D, };
-static int clk_init_uart(struct msm_clk_priv *priv) +static int clk_init_uart(struct qcom_cc_priv *priv) { /* Enable AHB clock */ clk_enable_vote_clk(priv->base, &gcc_blsp2_ahb_clk); @@ -82,7 +82,7 @@ static int clk_init_uart(struct msm_clk_priv *priv)
ulong msm_set_rate(struct clk *clk, ulong rate) {
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
struct qcom_cc_priv *priv = dev_get_priv(clk->dev); switch (clk->id) { case 0: /* SDC1 */
@@ -99,3 +99,19 @@ int msm_enable(struct clk *clk) { return 0; }
+static const struct udevice_id gcc_apq8096_of_match[] = {
{
.compatible = "qcom,gcc-apq8096",
/* TODO: add reset map */
},
{ }
+};
+U_BOOT_DRIVER(gcc_apq8096) = {
.name = "gcc_apq8096",
.id = UCLASS_NOP,
.of_match = gcc_apq8096_of_match,
.bind = qcom_cc_bind,
.flags = DM_FLAG_PRE_RELOC,
+}; diff --git a/drivers/clk/qcom/clock-ipq4019.c b/drivers/clk/qcom/clock-ipq4019.c index 04c99964df15..6636af98132d 100644 --- a/drivers/clk/qcom/clock-ipq4019.c +++ b/drivers/clk/qcom/clock-ipq4019.c @@ -13,6 +13,7 @@ #include <dm.h> #include <errno.h> #include <dt-bindings/clock/qcom,ipq4019-gcc.h> +#include <dt-bindings/reset/qcom,ipq4019-reset.h>
With this unification, we should directly import qcom,gcc-ipq4019.h from Linux tree and use that instead of u-boot specific headers.
#include "clock-qcom.h"
@@ -49,3 +50,97 @@ int msm_enable(struct clk *clk) } }
+static const struct qcom_reset_map gcc_ipq4019_resets[] = {
[WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 },
[WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 },
[WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 },
[WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 },
[WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 },
[WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 },
[WIFI1_CPU_INIT_RESET] = { 0x20008, 5 },
[WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 },
[WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 },
[WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 },
[WIFI1_CORE_WARM_RESET] = { 0x20008, 1 },
[WIFI1_CORE_COLD_RESET] = { 0x20008, 0 },
[USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 },
[USB3_HSPHY_POR_ARES] = { 0x1e038, 4 },
[USB3_HSPHY_S_ARES] = { 0x1e038, 2 },
[USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 },
[USB2_HSPHY_S_ARES] = { 0x1e01c, 2 },
[PCIE_PHY_AHB_ARES] = { 0x1d010, 11 },
[PCIE_AHB_ARES] = { 0x1d010, 10 },
[PCIE_PWR_ARES] = { 0x1d010, 9 },
[PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 },
[PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 },
[PCIE_PHY_ARES] = { 0x1d010, 6 },
[PCIE_PARF_XPU_ARES] = { 0x1d010, 5 },
[PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 },
[PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 },
[PCIE_PIPE_ARES] = { 0x1d010, 2 },
[PCIE_AXI_S_ARES] = { 0x1d010, 1 },
[PCIE_AXI_M_ARES] = { 0x1d010, 0 },
[ESS_RESET] = { 0x12008, 0},
[GCC_BLSP1_BCR] = {0x01000, 0},
[GCC_BLSP1_QUP1_BCR] = {0x02000, 0},
[GCC_BLSP1_UART1_BCR] = {0x02038, 0},
[GCC_BLSP1_QUP2_BCR] = {0x03008, 0},
[GCC_BLSP1_UART2_BCR] = {0x03028, 0},
[GCC_BIMC_BCR] = {0x04000, 0},
[GCC_TLMM_BCR] = {0x05000, 0},
[GCC_IMEM_BCR] = {0x0E000, 0},
[GCC_ESS_BCR] = {0x12008, 0},
[GCC_PRNG_BCR] = {0x13000, 0},
[GCC_BOOT_ROM_BCR] = {0x13008, 0},
[GCC_CRYPTO_BCR] = {0x16000, 0},
[GCC_SDCC1_BCR] = {0x18000, 0},
[GCC_SEC_CTRL_BCR] = {0x1A000, 0},
[GCC_AUDIO_BCR] = {0x1B008, 0},
[GCC_QPIC_BCR] = {0x1C000, 0},
[GCC_PCIE_BCR] = {0x1D000, 0},
[GCC_USB2_BCR] = {0x1E008, 0},
[GCC_USB2_PHY_BCR] = {0x1E018, 0},
[GCC_USB3_BCR] = {0x1E024, 0},
[GCC_USB3_PHY_BCR] = {0x1E034, 0},
[GCC_SYSTEM_NOC_BCR] = {0x21000, 0},
[GCC_PCNOC_BCR] = {0x2102C, 0},
[GCC_DCD_BCR] = {0x21038, 0},
[GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0},
[GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0},
[GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0},
[GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0},
[GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0},
[GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0},
[GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0},
[GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0},
[GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0},
[GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0},
[GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0},
[GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0},
[GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0},
[GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0},
[GCC_TCSR_BCR] = {0x22000, 0},
[GCC_MPM_BCR] = {0x24000, 0},
[GCC_SPDM_BCR] = {0x25000, 0},
+};
+static struct qcom_cc_data ipq4019_data = {
.resets = gcc_ipq4019_resets,
.num_resets = ARRAY_SIZE(gcc_ipq4019_resets),
+};
+static const struct udevice_id gcc_ipq4019_of_match[] = {
{
.compatible = "qcom,gcc-ipq4019",
.data = (ulong)&ipq4019_data,
},
{ }
+};
+U_BOOT_DRIVER(gcc_ipq4019) = {
.name = "gcc_ipq4019",
.id = UCLASS_NOP,
.of_match = gcc_ipq4019_of_match,
.bind = qcom_cc_bind,
.flags = DM_FLAG_PRE_RELOC,
+}; diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c index 5667abeb89a4..b0416a05789d 100644 --- a/drivers/clk/qcom/clock-qcom.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -1,8 +1,13 @@ -// SPDX-License-Identifier: BSD-3-Clause +// SPDX-License-Identifier: BSD-3-Clause AND GPL-2.0 /*
- Clock drivers for Qualcomm APQ8016, APQ8096
- Clock and reset drivers for Qualcomm platforms Global Clock
- Controller (GCC).
- (C) Copyright 2015 Mateusz Kulikowski mateusz.kulikowski@gmail.com
- (C) Copyright 2020 Sartura Ltd. (reset driver)
Author: Robert Marko <robert.marko@sartura.hr>
- (C) Copyright 2022 Linaro Ltd. (reset driver)
*/
Author: Sumit Garg <sumit.garg@linaro.org>
- Based on Little Kernel driver, simplified
@@ -10,9 +15,13 @@ #include <common.h> #include <clk-uclass.h> #include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> +#include <reset-uclass.h>
#include "clock-qcom.h"
/* CBCR register fields */ @@ -137,12 +146,15 @@ void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
static int msm_clk_probe(struct udevice *dev)
Renaming msm_* to qcom_* here too? I would prefer the rename to be a separate patch as it would make the review process easier.
-Sumit
{
struct msm_clk_priv *priv = dev_get_priv(dev);
struct qcom_cc_data *data = (struct qcom_cc_data *)dev_get_driver_data(dev);
struct qcom_cc_priv *priv = dev_get_priv(dev); priv->base = dev_read_addr(dev); if (priv->base == FDT_ADDR_T_NONE) return -EINVAL;
priv->data = data;
return 0;
}
@@ -161,21 +173,97 @@ static struct clk_ops msm_clk_ops = { .enable = msm_clk_enable, };
-static const struct udevice_id msm_clk_ids[] = {
{ .compatible = "qcom,gcc-msm8916" },
{ .compatible = "qcom,gcc-apq8016" },
{ .compatible = "qcom,gcc-msm8996" },
{ .compatible = "qcom,gcc-apq8096" },
{ .compatible = "qcom,gcc-sdm845" },
{ .compatible = "qcom,gcc-qcs404" },
{ }
-};
-U_BOOT_DRIVER(clk_msm) = {
.name = "clk_msm",
+U_BOOT_DRIVER(qcom_clk) = {
.name = "qcom_clk", .id = UCLASS_CLK,
.of_match = msm_clk_ids, .ops = &msm_clk_ops,
.priv_auto = sizeof(struct msm_clk_priv),
.priv_auto = sizeof(struct qcom_cc_priv), .probe = msm_clk_probe,
};
+int qcom_cc_bind(struct udevice *parent) +{
struct qcom_cc_data *data = (struct qcom_cc_data *)dev_get_driver_data(parent);
struct udevice *clkdev, *rstdev;
struct driver *drv;
int ret;
/* Get a handle to the common clk handler */
drv = lists_driver_lookup_name("qcom_clk");
if (!drv)
return -ENOENT;
/* Register the clock controller */
ret = device_bind_with_driver_data(parent, drv, "qcom_clk", (ulong)data,
dev_ofnode(parent), &clkdev);
if (ret)
return ret;
/* Bail out early if resets are not specified for this platform */
if (!data->resets)
return ret;
/* Get a handle to the common reset handler */
drv = lists_driver_lookup_name("qcom_reset");
if (!drv)
return -ENOENT;
/* Register the reset controller */
ret = device_bind_with_driver_data(parent, drv, "qcom_reset", (ulong)data,
dev_ofnode(parent), &rstdev);
if (ret)
device_unbind(clkdev);
return ret;
+}
+static int qcom_reset_set(struct reset_ctl *rst, bool assert) +{
struct qcom_cc_data *data = (struct qcom_cc_data *)dev_get_driver_data(rst->dev);
void __iomem *base = dev_get_priv(rst->dev);
const struct qcom_reset_map *map;
u32 value;
map = &data->resets[rst->id];
value = readl(base + map->reg);
if (assert)
value |= BIT(map->bit);
else
value &= ~BIT(map->bit);
writel(value, base + map->reg);
return 0;
+}
+static int qcom_reset_assert(struct reset_ctl *rst) +{
return qcom_reset_set(rst, true);
+}
+static int qcom_reset_deassert(struct reset_ctl *rst) +{
return qcom_reset_set(rst, false);
+}
+static const struct reset_ops qcom_reset_ops = {
.rst_assert = qcom_reset_assert,
.rst_deassert = qcom_reset_deassert,
+};
+static int qcom_reset_probe(struct udevice *dev) +{
/* Set our priv pointer to the base address */
dev_set_priv(dev, (void *)dev_read_addr(dev));
return 0;
+}
+U_BOOT_DRIVER(qcom_reset) = {
.name = "qcom_reset",
.id = UCLASS_RESET,
.ops = &qcom_reset_ops,
.probe = qcom_reset_probe,
+}; diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h index c90bbefa5881..a77a94b6ea06 100644 --- a/drivers/clk/qcom/clock-qcom.h +++ b/drivers/clk/qcom/clock-qcom.h @@ -1,11 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /*
- Qualcomm APQ8016, APQ8096, SDM845
*/
- (C) Copyright 2017 Jorge Ramirez-Ortiz jorge.ramirez-ortiz@linaro.org
-#ifndef _CLOCK_SNAPDRAGON_H -#define _CLOCK_SNAPDRAGON_H +#ifndef _CLOCK_QCOM_H +#define _CLOCK_QCOM_H
#define CFG_CLK_SRC_CXO (0 << 8) #define CFG_CLK_SRC_GPLL0 (1 << 8) @@ -32,10 +30,22 @@ struct bcr_regs { uintptr_t D; };
-struct msm_clk_priv {
phys_addr_t base;
+struct qcom_reset_map {
unsigned int reg;
u8 bit;
};
+struct qcom_cc_data {
const struct qcom_reset_map *resets;
unsigned long num_resets;
+};
+struct qcom_cc_priv {
phys_addr_t base;
struct qcom_cc_data *data;
+};
+int qcom_cc_bind(struct udevice *parent); void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0); void clk_bcr_update(phys_addr_t apps_cmd_rgcr); void clk_enable_cbc(phys_addr_t cbcr); diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c index 80218af73ef6..e622309b6747 100644 --- a/drivers/clk/qcom/clock-qcs404.c +++ b/drivers/clk/qcom/clock-qcs404.c @@ -11,9 +11,10 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> +#include <dt-bindings/clock/qcom,gcc-qcs404.h>
#include "clock-qcom.h"
-#include <dt-bindings/clock/qcom,gcc-qcs404.h>
/* GPLL0 clock control registers */ #define GPLL0_STATUS_ACTIVE BIT(31) @@ -113,7 +114,7 @@ static const struct bcr_regs blsp1_qup4_i2c_apps_regs = {
ulong msm_set_rate(struct clk *clk, ulong rate) {
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
struct qcom_cc_priv *priv = dev_get_priv(clk->dev); switch (clk->id) { case GCC_BLSP1_UART2_APPS_CLK:
@@ -158,7 +159,7 @@ ulong msm_set_rate(struct clk *clk, ulong rate)
int msm_enable(struct clk *clk) {
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
struct qcom_cc_priv *priv = dev_get_priv(clk->dev); switch (clk->id) { case GCC_USB30_MASTER_CLK:
@@ -235,3 +236,50 @@ int msm_enable(struct clk *clk)
return 0;
}
+static const struct qcom_reset_map qcs404_gcc_resets[] = {
[GCC_GENI_IR_BCR] = { 0x0F000 },
[GCC_CDSP_RESTART] = { 0x18000 },
[GCC_USB_HS_BCR] = { 0x41000 },
[GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 },
[GCC_QUSB2_PHY_BCR] = { 0x4103c },
[GCC_USB_HS_PHY_CFG_AHB_BCR] = { 0x0000c, 1 },
[GCC_USB2A_PHY_BCR] = { 0x0000c, 0 },
[GCC_USB3_PHY_BCR] = { 0x39004 },
[GCC_USB_30_BCR] = { 0x39000 },
[GCC_USB3PHY_PHY_BCR] = { 0x39008 },
[GCC_PCIE_0_BCR] = { 0x3e000 },
[GCC_PCIE_0_PHY_BCR] = { 0x3e004 },
[GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 },
[GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c },
[GCC_PCIE_0_AXI_MASTER_STICKY_ARES] = { 0x3e040, 6},
[GCC_PCIE_0_AHB_ARES] = { 0x3e040, 5 },
[GCC_PCIE_0_AXI_SLAVE_ARES] = { 0x3e040, 4 },
[GCC_PCIE_0_AXI_MASTER_ARES] = { 0x3e040, 3 },
[GCC_PCIE_0_CORE_STICKY_ARES] = { 0x3e040, 2 },
[GCC_PCIE_0_SLEEP_ARES] = { 0x3e040, 1 },
[GCC_PCIE_0_PIPE_ARES] = { 0x3e040, 0 },
[GCC_EMAC_BCR] = { 0x4e000 },
[GCC_WDSP_RESTART] = {0x19000},
+};
+static const struct qcom_cc_data qcs404_gcc_data = {
.resets = qcs404_gcc_resets,
.num_resets = ARRAY_SIZE(qcs404_gcc_resets),
+};
+static const struct udevice_id gcc_qcs404_of_match[] = {
{
.compatible = "qcom,gcc-qcs404",
.data = (ulong)&qcs404_gcc_data
},
{ }
+};
+U_BOOT_DRIVER(gcc_qcs404) = {
.name = "gcc_qcs404",
.id = UCLASS_NOP,
.of_match = gcc_qcs404_of_match,
.bind = qcom_cc_bind,
.flags = DM_FLAG_PRE_RELOC,
+}; diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c index 95a057b82986..eab88a40c09d 100644 --- a/drivers/clk/qcom/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -15,6 +15,7 @@ #include <asm/io.h> #include <linux/bitops.h> #include <dt-bindings/clock/qcom,gcc-sdm845.h>
#include "clock-qcom.h"
#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } @@ -70,7 +71,7 @@ const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate) return f - 1; }
-static int clk_init_uart(struct msm_clk_priv *priv, uint rate) +static int clk_init_uart(struct qcom_cc_priv *priv, uint rate) { const struct freq_tbl *freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
@@ -82,7 +83,7 @@ static int clk_init_uart(struct msm_clk_priv *priv, uint rate)
ulong msm_set_rate(struct clk *clk, ulong rate) {
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
struct qcom_cc_priv *priv = dev_get_priv(clk->dev); switch (clk->id) { case GCC_QUPV3_WRAP1_S1_CLK: /*UART2*/
@@ -96,3 +97,53 @@ int msm_enable(struct clk *clk) { return 0; }
+static const struct qcom_reset_map sdm845_gcc_resets[] = {
[GCC_MMSS_BCR] = { 0xb000 },
[GCC_PCIE_0_BCR] = { 0x6b000 },
[GCC_PCIE_1_BCR] = { 0x8d000 },
[GCC_PCIE_PHY_BCR] = { 0x6f000 },
[GCC_PDM_BCR] = { 0x33000 },
[GCC_PRNG_BCR] = { 0x34000 },
[GCC_QUPV3_WRAPPER_0_BCR] = { 0x17000 },
[GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 },
[GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 },
[GCC_QUSB2PHY_SEC_BCR] = { 0x12004 },
[GCC_SDCC2_BCR] = { 0x14000 },
[GCC_SDCC4_BCR] = { 0x16000 },
[GCC_TSIF_BCR] = { 0x36000 },
[GCC_UFS_CARD_BCR] = { 0x75000 },
[GCC_UFS_PHY_BCR] = { 0x77000 },
[GCC_USB30_PRIM_BCR] = { 0xf000 },
[GCC_USB30_SEC_BCR] = { 0x10000 },
[GCC_USB3_PHY_PRIM_BCR] = { 0x50000 },
[GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 },
[GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 },
[GCC_USB3_PHY_SEC_BCR] = { 0x5000c },
[GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 },
[GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 },
[GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 },
[GCC_PCIE_0_PHY_BCR] = { 0x6c01c },
[GCC_PCIE_1_PHY_BCR] = { 0x8e01c },
+};
+static const struct qcom_cc_data qcs404_gcc_data = {
.resets = sdm845_gcc_resets,
.num_resets = ARRAY_SIZE(sdm845_gcc_resets),
+};
+static const struct udevice_id gcc_sdm845_of_match[] = {
{
.compatible = "qcom,gcc-sdm845",
.data = (ulong)&qcs404_gcc_data,
},
{ }
+};
+U_BOOT_DRIVER(gcc_sdm845) = {
.name = "gcc_sdm845",
.id = UCLASS_NOP,
.of_match = gcc_sdm845_of_match,
.bind = qcom_cc_bind,
.flags = DM_FLAG_PRE_RELOC,
+}; diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 73bbd3069258..88e04d93f2a0 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -156,13 +156,6 @@ config RESET_IMX7 help Support for reset controller on i.MX7/8 SoCs.
-config RESET_QCOM
bool "Reset driver for Qualcomm SoCs"
depends on DM_RESET && (ARCH_SNAPDRAGON || ARCH_IPQ40XX)
default y
help
Support for reset controller on Qualcomm SoCs.
config RESET_SIFIVE bool "Reset Driver for SiFive SoC's" depends on DM_RESET && CLK_SIFIVE_PRCI && (TARGET_SIFIVE_UNLEASHED || TARGET_SIFIVE_UNMATCHED) diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index e2239a250a3a..7b0066f80188 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -24,7 +24,6 @@ obj-$(CONFIG_RESET_MTMIPS) += reset-mtmips.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o obj-$(CONFIG_RESET_IMX7) += reset-imx7.o -obj-$(CONFIG_RESET_QCOM) += reset-qcom.o obj-$(CONFIG_RESET_SIFIVE) += reset-sifive.o obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o diff --git a/drivers/reset/reset-qcom.c b/drivers/reset/reset-qcom.c deleted file mode 100644 index 94315e76d545..000000000000 --- a/drivers/reset/reset-qcom.c +++ /dev/null @@ -1,195 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/*
- Copyright (c) 2020 Sartura Ltd.
- Copyright (c) 2022 Linaro Ltd.
- Author: Robert Marko robert.marko@sartura.hr
Sumit Garg <sumit.garg@linaro.org>
- Based on Linux driver
- */
-#include <asm/io.h> -#include <common.h> -#include <dm.h> -#include <reset-uclass.h> -#include <linux/bitops.h> -#include <malloc.h>
-struct qcom_reset_priv {
phys_addr_t base;
-};
-struct qcom_reset_map {
unsigned int reg;
u8 bit;
-};
-#ifdef CONFIG_ARCH_IPQ40XX -#include <dt-bindings/reset/qcom,ipq4019-reset.h> -static const struct qcom_reset_map gcc_qcom_resets[] = {
[WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 },
[WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 },
[WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 },
[WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 },
[WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 },
[WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 },
[WIFI1_CPU_INIT_RESET] = { 0x20008, 5 },
[WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 },
[WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 },
[WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 },
[WIFI1_CORE_WARM_RESET] = { 0x20008, 1 },
[WIFI1_CORE_COLD_RESET] = { 0x20008, 0 },
[USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 },
[USB3_HSPHY_POR_ARES] = { 0x1e038, 4 },
[USB3_HSPHY_S_ARES] = { 0x1e038, 2 },
[USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 },
[USB2_HSPHY_S_ARES] = { 0x1e01c, 2 },
[PCIE_PHY_AHB_ARES] = { 0x1d010, 11 },
[PCIE_AHB_ARES] = { 0x1d010, 10 },
[PCIE_PWR_ARES] = { 0x1d010, 9 },
[PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 },
[PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 },
[PCIE_PHY_ARES] = { 0x1d010, 6 },
[PCIE_PARF_XPU_ARES] = { 0x1d010, 5 },
[PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 },
[PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 },
[PCIE_PIPE_ARES] = { 0x1d010, 2 },
[PCIE_AXI_S_ARES] = { 0x1d010, 1 },
[PCIE_AXI_M_ARES] = { 0x1d010, 0 },
[ESS_RESET] = { 0x12008, 0},
[GCC_BLSP1_BCR] = {0x01000, 0},
[GCC_BLSP1_QUP1_BCR] = {0x02000, 0},
[GCC_BLSP1_UART1_BCR] = {0x02038, 0},
[GCC_BLSP1_QUP2_BCR] = {0x03008, 0},
[GCC_BLSP1_UART2_BCR] = {0x03028, 0},
[GCC_BIMC_BCR] = {0x04000, 0},
[GCC_TLMM_BCR] = {0x05000, 0},
[GCC_IMEM_BCR] = {0x0E000, 0},
[GCC_ESS_BCR] = {0x12008, 0},
[GCC_PRNG_BCR] = {0x13000, 0},
[GCC_BOOT_ROM_BCR] = {0x13008, 0},
[GCC_CRYPTO_BCR] = {0x16000, 0},
[GCC_SDCC1_BCR] = {0x18000, 0},
[GCC_SEC_CTRL_BCR] = {0x1A000, 0},
[GCC_AUDIO_BCR] = {0x1B008, 0},
[GCC_QPIC_BCR] = {0x1C000, 0},
[GCC_PCIE_BCR] = {0x1D000, 0},
[GCC_USB2_BCR] = {0x1E008, 0},
[GCC_USB2_PHY_BCR] = {0x1E018, 0},
[GCC_USB3_BCR] = {0x1E024, 0},
[GCC_USB3_PHY_BCR] = {0x1E034, 0},
[GCC_SYSTEM_NOC_BCR] = {0x21000, 0},
[GCC_PCNOC_BCR] = {0x2102C, 0},
[GCC_DCD_BCR] = {0x21038, 0},
[GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0},
[GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0},
[GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0},
[GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0},
[GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0},
[GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0},
[GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0},
[GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0},
[GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0},
[GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0},
[GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0},
[GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0},
[GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0},
[GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0},
[GCC_TCSR_BCR] = {0x22000, 0},
[GCC_MPM_BCR] = {0x24000, 0},
[GCC_SPDM_BCR] = {0x25000, 0},
-}; -#endif
-#ifdef CONFIG_TARGET_QCS404EVB -#include <dt-bindings/clock/qcom,gcc-qcs404.h> -static const struct qcom_reset_map gcc_qcom_resets[] = {
[GCC_GENI_IR_BCR] = { 0x0F000 },
[GCC_CDSP_RESTART] = { 0x18000 },
[GCC_USB_HS_BCR] = { 0x41000 },
[GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 },
[GCC_QUSB2_PHY_BCR] = { 0x4103c },
[GCC_USB_HS_PHY_CFG_AHB_BCR] = { 0x0000c, 1 },
[GCC_USB2A_PHY_BCR] = { 0x0000c, 0 },
[GCC_USB3_PHY_BCR] = { 0x39004 },
[GCC_USB_30_BCR] = { 0x39000 },
[GCC_USB3PHY_PHY_BCR] = { 0x39008 },
[GCC_PCIE_0_BCR] = { 0x3e000 },
[GCC_PCIE_0_PHY_BCR] = { 0x3e004 },
[GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 },
[GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c },
[GCC_PCIE_0_AXI_MASTER_STICKY_ARES] = { 0x3e040, 6},
[GCC_PCIE_0_AHB_ARES] = { 0x3e040, 5 },
[GCC_PCIE_0_AXI_SLAVE_ARES] = { 0x3e040, 4 },
[GCC_PCIE_0_AXI_MASTER_ARES] = { 0x3e040, 3 },
[GCC_PCIE_0_CORE_STICKY_ARES] = { 0x3e040, 2 },
[GCC_PCIE_0_SLEEP_ARES] = { 0x3e040, 1 },
[GCC_PCIE_0_PIPE_ARES] = { 0x3e040, 0 },
[GCC_EMAC_BCR] = { 0x4e000 },
[GCC_WDSP_RESTART] = {0x19000},
-}; -#endif
-static int qcom_reset_assert(struct reset_ctl *rst) -{
struct qcom_reset_priv *priv = dev_get_priv(rst->dev);
const struct qcom_reset_map *reset_map = gcc_qcom_resets;
const struct qcom_reset_map *map;
u32 value;
map = &reset_map[rst->id];
value = readl(priv->base + map->reg);
value |= BIT(map->bit);
writel(value, priv->base + map->reg);
return 0;
-}
-static int qcom_reset_deassert(struct reset_ctl *rst) -{
struct qcom_reset_priv *priv = dev_get_priv(rst->dev);
const struct qcom_reset_map *reset_map = gcc_qcom_resets;
const struct qcom_reset_map *map;
u32 value;
map = &reset_map[rst->id];
value = readl(priv->base + map->reg);
value &= ~BIT(map->bit);
writel(value, priv->base + map->reg);
return 0;
-}
-static const struct reset_ops qcom_reset_ops = {
.rst_assert = qcom_reset_assert,
.rst_deassert = qcom_reset_deassert,
-};
-static const struct udevice_id qcom_reset_ids[] = {
{ .compatible = "qcom,gcc-reset-ipq4019" },
{ .compatible = "qcom,gcc-reset-qcs404" },
{ }
-};
-static int qcom_reset_probe(struct udevice *dev) -{
struct qcom_reset_priv *priv = dev_get_priv(dev);
priv->base = dev_read_addr(dev);
if (priv->base == FDT_ADDR_T_NONE)
return -EINVAL;
return 0;
-}
-U_BOOT_DRIVER(qcom_reset) = {
.name = "qcom_reset",
.id = UCLASS_RESET,
.of_match = qcom_reset_ids,
.ops = &qcom_reset_ops,
.probe = qcom_reset_probe,
.priv_auto = sizeof(struct qcom_reset_priv),
-};
-- 2.42.0

Many gate clocks can be enabled with a single register write, add support for defining these simple gate clocks and add the ones found on SDM845.
While we're here, inline clk_init_uart() into msm_set_rate().
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- .../mach-snapdragon/include/mach/sysmap-sdm845.h | 3 + drivers/clk/qcom/clock-qcom.h | 22 +++ drivers/clk/qcom/clock-sdm845.c | 163 +++++++++++++++++++-- 3 files changed, 176 insertions(+), 12 deletions(-)
diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h b/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h index 7165985bcd1e..a0010d71594e 100644 --- a/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h +++ b/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h @@ -39,4 +39,7 @@ #define SE9_UART_APPS_N (0x18154) #define SE9_UART_APPS_D (0x18158)
+#define USB30_SEC_GDSCR (0x10004) +#define USB30_PRIM_GDSCR (0xf004) + #endif diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h index a77a94b6ea06..7b3bcf41f421 100644 --- a/drivers/clk/qcom/clock-qcom.h +++ b/drivers/clk/qcom/clock-qcom.h @@ -30,6 +30,18 @@ struct bcr_regs { uintptr_t D; };
+struct gate_clk { + uintptr_t reg; + u32 en_val; + const char *name; +}; + +#ifdef DEBUG +#define GATE_CLK(clk, reg, val) [clk] = { reg, val, #clk } +#else +#define GATE_CLK(clk, reg, val) [clk] = { reg, val, NULL } +#endif + struct qcom_reset_map { unsigned int reg; u8 bit; @@ -38,6 +50,8 @@ struct qcom_reset_map { struct qcom_cc_data { const struct qcom_reset_map *resets; unsigned long num_resets; + const struct gate_clk *clks; + unsigned long num_clks; };
struct qcom_cc_priv { @@ -55,4 +69,12 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div, int source);
+static inline void qcom_gate_clk_en(const struct qcom_cc_priv *priv, unsigned long id) +{ + if (id >= priv->data->num_clks || priv->data->clks[id].reg == 0) + return; + + setbits_le32(priv->base + priv->data->clks[id].reg, priv->data->clks[id].en_val); +} + #endif diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c index eab88a40c09d..ccad73b6ff15 100644 --- a/drivers/clk/qcom/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -11,6 +11,7 @@ #include <common.h> #include <clk-uclass.h> #include <dm.h> +#include <linux/delay.h> #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> @@ -71,30 +72,166 @@ const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate) return f - 1; }
-static int clk_init_uart(struct qcom_cc_priv *priv, uint rate) -{ - const struct freq_tbl *freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate); - - clk_rcg_set_rate_mnd(priv->base, &uart2_regs, - freq->pre_div, freq->m, freq->n, freq->src); - - return 0; -} - ulong msm_set_rate(struct clk *clk, ulong rate) { struct qcom_cc_priv *priv = dev_get_priv(clk->dev); + const struct freq_tbl *freq;
switch (clk->id) { - case GCC_QUPV3_WRAP1_S1_CLK: /*UART2*/ - return clk_init_uart(priv, rate); + case GCC_QUPV3_WRAP1_S1_CLK: /* UART9 */ + freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate); + clk_rcg_set_rate_mnd(priv->base, &uart2_regs, + freq->pre_div, freq->m, freq->n, freq->src); + + return freq->freq; default: return 0; } }
+static const struct gate_clk sdm845_clks[] = { + GATE_CLK(GCC_AGGRE_NOC_PCIE_TBU_CLK, 0x90014, 0x00000001), + GATE_CLK(GCC_AGGRE_UFS_CARD_AXI_CLK, 0x82028, 0x00000001), + GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x82024, 0x00000001), + GATE_CLK(GCC_AGGRE_USB3_PRIM_AXI_CLK, 0x8201c, 0x00000001), + GATE_CLK(GCC_AGGRE_USB3_SEC_AXI_CLK, 0x82020, 0x00000001), + GATE_CLK(GCC_BOOT_ROM_AHB_CLK, 0x52004, 0x00000400), + GATE_CLK(GCC_CAMERA_AHB_CLK, 0x0b008, 0x00000001), + GATE_CLK(GCC_CAMERA_AXI_CLK, 0x0b020, 0x00000001), + GATE_CLK(GCC_CAMERA_XO_CLK, 0x0b02c, 0x00000001), + GATE_CLK(GCC_CE1_AHB_CLK, 0x52004, 0x00000008), + GATE_CLK(GCC_CE1_AXI_CLK, 0x52004, 0x00000010), + GATE_CLK(GCC_CE1_CLK, 0x52004, 0x00000020), + GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x0502c, 0x00000001), + GATE_CLK(GCC_CFG_NOC_USB3_SEC_AXI_CLK, 0x05030, 0x00000001), + GATE_CLK(GCC_CPUSS_AHB_CLK, 0x52004, 0x00200000), + GATE_CLK(GCC_CPUSS_RBCPR_CLK, 0x48008, 0x00000001), + GATE_CLK(GCC_DDRSS_GPU_AXI_CLK, 0x44038, 0x00000001), + GATE_CLK(GCC_DISP_AHB_CLK, 0x0b00c, 0x00000001), + GATE_CLK(GCC_DISP_AXI_CLK, 0x0b024, 0x00000001), + GATE_CLK(GCC_DISP_GPLL0_CLK_SRC, 0x52004, 0x00040000), + GATE_CLK(GCC_DISP_GPLL0_DIV_CLK_SRC, 0x52004, 0x00080000), + GATE_CLK(GCC_DISP_XO_CLK, 0x0b030, 0x00000001), + GATE_CLK(GCC_GP1_CLK, 0x64000, 0x00000001), + GATE_CLK(GCC_GP2_CLK, 0x65000, 0x00000001), + GATE_CLK(GCC_GP3_CLK, 0x66000, 0x00000001), + GATE_CLK(GCC_GPU_CFG_AHB_CLK, 0x71004, 0x00000001), + GATE_CLK(GCC_GPU_GPLL0_CLK_SRC, 0x52004, 0x00008000), + GATE_CLK(GCC_GPU_GPLL0_DIV_CLK_SRC, 0x52004, 0x00010000), + GATE_CLK(GCC_GPU_MEMNOC_GFX_CLK, 0x7100c, 0x00000001), + GATE_CLK(GCC_GPU_SNOC_DVM_GFX_CLK, 0x71018, 0x00000001), + GATE_CLK(GCC_MSS_AXIS2_CLK, 0x8a008, 0x00000001), + GATE_CLK(GCC_MSS_CFG_AHB_CLK, 0x8a000, 0x00000001), + GATE_CLK(GCC_MSS_GPLL0_DIV_CLK_SRC, 0x52004, 0x00020000), + GATE_CLK(GCC_MSS_MFAB_AXIS_CLK, 0x8a004, 0x00000001), + GATE_CLK(GCC_MSS_Q6_MEMNOC_AXI_CLK, 0x8a154, 0x00000001), + GATE_CLK(GCC_MSS_SNOC_AXI_CLK, 0x8a150, 0x00000001), + GATE_CLK(GCC_PCIE_0_AUX_CLK, 0x5200c, 0x00000008), + GATE_CLK(GCC_PCIE_0_CFG_AHB_CLK, 0x5200c, 0x00000004), + GATE_CLK(GCC_PCIE_0_CLKREF_CLK, 0x8c00c, 0x00000001), + GATE_CLK(GCC_PCIE_0_MSTR_AXI_CLK, 0x5200c, 0x00000002), + GATE_CLK(GCC_PCIE_0_PIPE_CLK, 0x5200c, 0x00000010), + GATE_CLK(GCC_PCIE_0_SLV_AXI_CLK, 0x5200c, 0x00000001), + GATE_CLK(GCC_PCIE_0_SLV_Q2A_AXI_CLK, 0x5200c, 0x00000020), + GATE_CLK(GCC_PCIE_1_AUX_CLK, 0x52004, 0x20000000), + GATE_CLK(GCC_PCIE_1_CFG_AHB_CLK, 0x52004, 0x10000000), + GATE_CLK(GCC_PCIE_1_CLKREF_CLK, 0x8c02c, 0x00000001), + GATE_CLK(GCC_PCIE_1_MSTR_AXI_CLK, 0x52004, 0x08000000), + GATE_CLK(GCC_PCIE_1_PIPE_CLK, 0x52004, 0x40000000), + GATE_CLK(GCC_PCIE_1_SLV_AXI_CLK, 0x52004, 0x04000000), + GATE_CLK(GCC_PCIE_1_SLV_Q2A_AXI_CLK, 0x52004, 0x02000000), + GATE_CLK(GCC_PCIE_PHY_AUX_CLK, 0x6f004, 0x00000001), + GATE_CLK(GCC_PCIE_PHY_REFGEN_CLK, 0x6f02c, 0x00000001), + GATE_CLK(GCC_PDM2_CLK, 0x3300c, 0x00000001), + GATE_CLK(GCC_PDM_AHB_CLK, 0x33004, 0x00000001), + GATE_CLK(GCC_PDM_XO4_CLK, 0x33008, 0x00000001), + GATE_CLK(GCC_PRNG_AHB_CLK, 0x52004, 0x00002000), + GATE_CLK(GCC_QMIP_CAMERA_AHB_CLK, 0x0b014, 0x00000001), + GATE_CLK(GCC_QMIP_DISP_AHB_CLK, 0x0b018, 0x00000001), + GATE_CLK(GCC_QMIP_VIDEO_AHB_CLK, 0x0b010, 0x00000001), + GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x5200c, 0x00000400), + GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x5200c, 0x00000800), + GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK, 0x5200c, 0x00001000), + GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x5200c, 0x00002000), + GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK, 0x5200c, 0x00004000), + GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK, 0x5200c, 0x00008000), + GATE_CLK(GCC_QUPV3_WRAP0_S6_CLK, 0x5200c, 0x00010000), + GATE_CLK(GCC_QUPV3_WRAP0_S7_CLK, 0x5200c, 0x00020000), + GATE_CLK(GCC_QUPV3_WRAP1_S0_CLK, 0x5200c, 0x00400000), + GATE_CLK(GCC_QUPV3_WRAP1_S1_CLK, 0x5200c, 0x00800000), + GATE_CLK(GCC_QUPV3_WRAP1_S3_CLK, 0x5200c, 0x02000000), + GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK, 0x5200c, 0x04000000), + GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK, 0x5200c, 0x08000000), + GATE_CLK(GCC_QUPV3_WRAP1_S6_CLK, 0x5200c, 0x10000000), + GATE_CLK(GCC_QUPV3_WRAP1_S7_CLK, 0x5200c, 0x20000000), + GATE_CLK(GCC_QUPV3_WRAP_0_M_AHB_CLK, 0x5200c, 0x00000040), + GATE_CLK(GCC_QUPV3_WRAP_0_S_AHB_CLK, 0x5200c, 0x00000080), + GATE_CLK(GCC_QUPV3_WRAP_1_M_AHB_CLK, 0x5200c, 0x00100000), + GATE_CLK(GCC_QUPV3_WRAP_1_S_AHB_CLK, 0x5200c, 0x00200000), + GATE_CLK(GCC_SDCC2_AHB_CLK, 0x14008, 0x00000001), + GATE_CLK(GCC_SDCC2_APPS_CLK, 0x14004, 0x00000001), + GATE_CLK(GCC_SDCC4_AHB_CLK, 0x16008, 0x00000001), + GATE_CLK(GCC_SDCC4_APPS_CLK, 0x16004, 0x00000001), + GATE_CLK(GCC_SYS_NOC_CPUSS_AHB_CLK, 0x52004, 0x00000001), + GATE_CLK(GCC_TSIF_AHB_CLK, 0x36004, 0x00000001), + GATE_CLK(GCC_TSIF_INACTIVITY_TIMERS_CLK, 0x3600c, 0x00000001), + GATE_CLK(GCC_TSIF_REF_CLK, 0x36008, 0x00000001), + GATE_CLK(GCC_UFS_CARD_AHB_CLK, 0x75010, 0x00000001), + GATE_CLK(GCC_UFS_CARD_AXI_CLK, 0x7500c, 0x00000001), + GATE_CLK(GCC_UFS_CARD_CLKREF_CLK, 0x8c004, 0x00000001), + GATE_CLK(GCC_UFS_CARD_ICE_CORE_CLK, 0x75058, 0x00000001), + GATE_CLK(GCC_UFS_CARD_PHY_AUX_CLK, 0x7508c, 0x00000001), + GATE_CLK(GCC_UFS_CARD_RX_SYMBOL_0_CLK, 0x75018, 0x00000001), + GATE_CLK(GCC_UFS_CARD_RX_SYMBOL_1_CLK, 0x750a8, 0x00000001), + GATE_CLK(GCC_UFS_CARD_TX_SYMBOL_0_CLK, 0x75014, 0x00000001), + GATE_CLK(GCC_UFS_CARD_UNIPRO_CORE_CLK, 0x75054, 0x00000001), + GATE_CLK(GCC_UFS_MEM_CLKREF_CLK, 0x8c000, 0x00000001), + GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77010, 0x00000001), + GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x7700c, 0x00000001), + GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77058, 0x00000001), + GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x7708c, 0x00000001), + GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x77018, 0x00000001), + GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x770a8, 0x00000001), + GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x77014, 0x00000001), + GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x77054, 0x00000001), + GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0x0f00c, 0x00000001), + GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x0f014, 0x00000001), + GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0x0f010, 0x00000001), + GATE_CLK(GCC_USB30_SEC_MASTER_CLK, 0x1000c, 0x00000001), + GATE_CLK(GCC_USB30_SEC_MOCK_UTMI_CLK, 0x10014, 0x00000001), + GATE_CLK(GCC_USB30_SEC_SLEEP_CLK, 0x10010, 0x00000001), + GATE_CLK(GCC_USB3_PRIM_CLKREF_CLK, 0x8c008, 0x00000001), + GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK, 0x0f04c, 0x00000001), + GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0x0f050, 0x00000001), + GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0x0f054, 0x00000001), + GATE_CLK(GCC_USB3_SEC_CLKREF_CLK, 0x8c028, 0x00000001), + GATE_CLK(GCC_USB3_SEC_PHY_AUX_CLK, 0x1004c, 0x00000001), + GATE_CLK(GCC_USB3_SEC_PHY_PIPE_CLK, 0x10054, 0x00000001), + GATE_CLK(GCC_USB3_SEC_PHY_COM_AUX_CLK, 0x10050, 0x00000001), + GATE_CLK(GCC_USB_PHY_CFG_AHB2PHY_CLK, 0x6a004, 0x00000001), + GATE_CLK(GCC_VIDEO_AHB_CLK, 0x0b004, 0x00000001), + GATE_CLK(GCC_VIDEO_AXI_CLK, 0x0b01c, 0x00000001), + GATE_CLK(GCC_VIDEO_XO_CLK, 0x0b028, 0x00000001), + GATE_CLK(GCC_GPU_IREF_CLK, 0x8c010, 0x00000001), + GATE_CLK(GCC_APC_VS_CLK, 0x7a050, 0x00000001), + GATE_CLK(GCC_GPU_VS_CLK, 0x7a04c, 0x00000001), + GATE_CLK(GCC_MSS_VS_CLK, 0x7a048, 0x00000001), + GATE_CLK(GCC_VDDA_VS_CLK, 0x7a00c, 0x00000001), + GATE_CLK(GCC_VDDCX_VS_CLK, 0x7a004, 0x00000001), + GATE_CLK(GCC_VDDMX_VS_CLK, 0x7a008, 0x00000001), + GATE_CLK(GCC_VS_CTRL_AHB_CLK, 0x7a014, 0x00000001), + GATE_CLK(GCC_VS_CTRL_CLK, 0x7a010, 0x00000001), + GATE_CLK(GCC_CPUSS_DVM_BUS_CLK, 0x48190, 0x00000001), +}; + int msm_enable(struct clk *clk) { + struct qcom_cc_priv *priv = dev_get_priv(clk->dev); + + debug("%s: clk %s\n", __func__, sdm845_clks[clk->id].name); + + qcom_gate_clk_en(priv, clk->id); + return 0; }
@@ -130,6 +267,8 @@ static const struct qcom_reset_map sdm845_gcc_resets[] = { static const struct qcom_cc_data qcs404_gcc_data = { .resets = sdm845_gcc_resets, .num_resets = ARRAY_SIZE(sdm845_gcc_resets), + .clks = sdm845_clks, + .num_clks = ARRAY_SIZE(sdm845_clks), };
static const struct udevice_id gcc_sdm845_of_match[] = {

On Wed, 25 Oct 2023 at 01:54, Caleb Connolly caleb.connolly@linaro.org wrote:
Many gate clocks can be enabled with a single register write, add support for defining these simple gate clocks and add the ones found on SDM845.
While we're here, inline clk_init_uart() into msm_set_rate().
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org
.../mach-snapdragon/include/mach/sysmap-sdm845.h | 3 + drivers/clk/qcom/clock-qcom.h | 22 +++ drivers/clk/qcom/clock-sdm845.c | 163 +++++++++++++++++++-- 3 files changed, 176 insertions(+), 12 deletions(-)
diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h b/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h index 7165985bcd1e..a0010d71594e 100644 --- a/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h +++ b/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h @@ -39,4 +39,7 @@ #define SE9_UART_APPS_N (0x18154) #define SE9_UART_APPS_D (0x18158)
+#define USB30_SEC_GDSCR (0x10004) +#define USB30_PRIM_GDSCR (0xf004)
#endif diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h index a77a94b6ea06..7b3bcf41f421 100644 --- a/drivers/clk/qcom/clock-qcom.h +++ b/drivers/clk/qcom/clock-qcom.h @@ -30,6 +30,18 @@ struct bcr_regs { uintptr_t D; };
+struct gate_clk {
uintptr_t reg;
u32 en_val;
const char *name;
+};
+#ifdef DEBUG +#define GATE_CLK(clk, reg, val) [clk] = { reg, val, #clk } +#else +#define GATE_CLK(clk, reg, val) [clk] = { reg, val, NULL } +#endif
struct qcom_reset_map { unsigned int reg; u8 bit; @@ -38,6 +50,8 @@ struct qcom_reset_map { struct qcom_cc_data { const struct qcom_reset_map *resets; unsigned long num_resets;
const struct gate_clk *clks;
unsigned long num_clks;
};
struct qcom_cc_priv { @@ -55,4 +69,12 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div, int source);
+static inline void qcom_gate_clk_en(const struct qcom_cc_priv *priv, unsigned long id) +{
if (id >= priv->data->num_clks || priv->data->clks[id].reg == 0)
return;
setbits_le32(priv->base + priv->data->clks[id].reg, priv->data->clks[id].en_val);
+}
#endif diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c index eab88a40c09d..ccad73b6ff15 100644 --- a/drivers/clk/qcom/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -11,6 +11,7 @@ #include <common.h> #include <clk-uclass.h> #include <dm.h> +#include <linux/delay.h> #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> @@ -71,30 +72,166 @@ const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate) return f - 1; }
-static int clk_init_uart(struct qcom_cc_priv *priv, uint rate) -{
const struct freq_tbl *freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
clk_rcg_set_rate_mnd(priv->base, &uart2_regs,
freq->pre_div, freq->m, freq->n, freq->src);
return 0;
-}
ulong msm_set_rate(struct clk *clk, ulong rate) { struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
const struct freq_tbl *freq; switch (clk->id) {
case GCC_QUPV3_WRAP1_S1_CLK: /*UART2*/
return clk_init_uart(priv, rate);
case GCC_QUPV3_WRAP1_S1_CLK: /* UART9 */
freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
clk_rcg_set_rate_mnd(priv->base, &uart2_regs,
freq->pre_div, freq->m, freq->n, freq->src);
return freq->freq; default: return 0; }
}
+static const struct gate_clk sdm845_clks[] = {
GATE_CLK(GCC_AGGRE_NOC_PCIE_TBU_CLK, 0x90014, 0x00000001),
GATE_CLK(GCC_AGGRE_UFS_CARD_AXI_CLK, 0x82028, 0x00000001),
GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x82024, 0x00000001),
GATE_CLK(GCC_AGGRE_USB3_PRIM_AXI_CLK, 0x8201c, 0x00000001),
GATE_CLK(GCC_AGGRE_USB3_SEC_AXI_CLK, 0x82020, 0x00000001),
GATE_CLK(GCC_BOOT_ROM_AHB_CLK, 0x52004, 0x00000400),
GATE_CLK(GCC_CAMERA_AHB_CLK, 0x0b008, 0x00000001),
GATE_CLK(GCC_CAMERA_AXI_CLK, 0x0b020, 0x00000001),
GATE_CLK(GCC_CAMERA_XO_CLK, 0x0b02c, 0x00000001),
GATE_CLK(GCC_CE1_AHB_CLK, 0x52004, 0x00000008),
GATE_CLK(GCC_CE1_AXI_CLK, 0x52004, 0x00000010),
GATE_CLK(GCC_CE1_CLK, 0x52004, 0x00000020),
GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x0502c, 0x00000001),
GATE_CLK(GCC_CFG_NOC_USB3_SEC_AXI_CLK, 0x05030, 0x00000001),
GATE_CLK(GCC_CPUSS_AHB_CLK, 0x52004, 0x00200000),
GATE_CLK(GCC_CPUSS_RBCPR_CLK, 0x48008, 0x00000001),
GATE_CLK(GCC_DDRSS_GPU_AXI_CLK, 0x44038, 0x00000001),
GATE_CLK(GCC_DISP_AHB_CLK, 0x0b00c, 0x00000001),
GATE_CLK(GCC_DISP_AXI_CLK, 0x0b024, 0x00000001),
GATE_CLK(GCC_DISP_GPLL0_CLK_SRC, 0x52004, 0x00040000),
GATE_CLK(GCC_DISP_GPLL0_DIV_CLK_SRC, 0x52004, 0x00080000),
GATE_CLK(GCC_DISP_XO_CLK, 0x0b030, 0x00000001),
GATE_CLK(GCC_GP1_CLK, 0x64000, 0x00000001),
GATE_CLK(GCC_GP2_CLK, 0x65000, 0x00000001),
GATE_CLK(GCC_GP3_CLK, 0x66000, 0x00000001),
GATE_CLK(GCC_GPU_CFG_AHB_CLK, 0x71004, 0x00000001),
GATE_CLK(GCC_GPU_GPLL0_CLK_SRC, 0x52004, 0x00008000),
GATE_CLK(GCC_GPU_GPLL0_DIV_CLK_SRC, 0x52004, 0x00010000),
GATE_CLK(GCC_GPU_MEMNOC_GFX_CLK, 0x7100c, 0x00000001),
GATE_CLK(GCC_GPU_SNOC_DVM_GFX_CLK, 0x71018, 0x00000001),
GATE_CLK(GCC_MSS_AXIS2_CLK, 0x8a008, 0x00000001),
GATE_CLK(GCC_MSS_CFG_AHB_CLK, 0x8a000, 0x00000001),
GATE_CLK(GCC_MSS_GPLL0_DIV_CLK_SRC, 0x52004, 0x00020000),
GATE_CLK(GCC_MSS_MFAB_AXIS_CLK, 0x8a004, 0x00000001),
GATE_CLK(GCC_MSS_Q6_MEMNOC_AXI_CLK, 0x8a154, 0x00000001),
GATE_CLK(GCC_MSS_SNOC_AXI_CLK, 0x8a150, 0x00000001),
GATE_CLK(GCC_PCIE_0_AUX_CLK, 0x5200c, 0x00000008),
GATE_CLK(GCC_PCIE_0_CFG_AHB_CLK, 0x5200c, 0x00000004),
GATE_CLK(GCC_PCIE_0_CLKREF_CLK, 0x8c00c, 0x00000001),
GATE_CLK(GCC_PCIE_0_MSTR_AXI_CLK, 0x5200c, 0x00000002),
GATE_CLK(GCC_PCIE_0_PIPE_CLK, 0x5200c, 0x00000010),
GATE_CLK(GCC_PCIE_0_SLV_AXI_CLK, 0x5200c, 0x00000001),
GATE_CLK(GCC_PCIE_0_SLV_Q2A_AXI_CLK, 0x5200c, 0x00000020),
GATE_CLK(GCC_PCIE_1_AUX_CLK, 0x52004, 0x20000000),
GATE_CLK(GCC_PCIE_1_CFG_AHB_CLK, 0x52004, 0x10000000),
GATE_CLK(GCC_PCIE_1_CLKREF_CLK, 0x8c02c, 0x00000001),
GATE_CLK(GCC_PCIE_1_MSTR_AXI_CLK, 0x52004, 0x08000000),
GATE_CLK(GCC_PCIE_1_PIPE_CLK, 0x52004, 0x40000000),
GATE_CLK(GCC_PCIE_1_SLV_AXI_CLK, 0x52004, 0x04000000),
GATE_CLK(GCC_PCIE_1_SLV_Q2A_AXI_CLK, 0x52004, 0x02000000),
GATE_CLK(GCC_PCIE_PHY_AUX_CLK, 0x6f004, 0x00000001),
GATE_CLK(GCC_PCIE_PHY_REFGEN_CLK, 0x6f02c, 0x00000001),
GATE_CLK(GCC_PDM2_CLK, 0x3300c, 0x00000001),
GATE_CLK(GCC_PDM_AHB_CLK, 0x33004, 0x00000001),
GATE_CLK(GCC_PDM_XO4_CLK, 0x33008, 0x00000001),
GATE_CLK(GCC_PRNG_AHB_CLK, 0x52004, 0x00002000),
GATE_CLK(GCC_QMIP_CAMERA_AHB_CLK, 0x0b014, 0x00000001),
GATE_CLK(GCC_QMIP_DISP_AHB_CLK, 0x0b018, 0x00000001),
GATE_CLK(GCC_QMIP_VIDEO_AHB_CLK, 0x0b010, 0x00000001),
GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x5200c, 0x00000400),
GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x5200c, 0x00000800),
GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK, 0x5200c, 0x00001000),
GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x5200c, 0x00002000),
GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK, 0x5200c, 0x00004000),
GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK, 0x5200c, 0x00008000),
GATE_CLK(GCC_QUPV3_WRAP0_S6_CLK, 0x5200c, 0x00010000),
GATE_CLK(GCC_QUPV3_WRAP0_S7_CLK, 0x5200c, 0x00020000),
GATE_CLK(GCC_QUPV3_WRAP1_S0_CLK, 0x5200c, 0x00400000),
GATE_CLK(GCC_QUPV3_WRAP1_S1_CLK, 0x5200c, 0x00800000),
GATE_CLK(GCC_QUPV3_WRAP1_S3_CLK, 0x5200c, 0x02000000),
GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK, 0x5200c, 0x04000000),
GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK, 0x5200c, 0x08000000),
GATE_CLK(GCC_QUPV3_WRAP1_S6_CLK, 0x5200c, 0x10000000),
GATE_CLK(GCC_QUPV3_WRAP1_S7_CLK, 0x5200c, 0x20000000),
GATE_CLK(GCC_QUPV3_WRAP_0_M_AHB_CLK, 0x5200c, 0x00000040),
GATE_CLK(GCC_QUPV3_WRAP_0_S_AHB_CLK, 0x5200c, 0x00000080),
GATE_CLK(GCC_QUPV3_WRAP_1_M_AHB_CLK, 0x5200c, 0x00100000),
GATE_CLK(GCC_QUPV3_WRAP_1_S_AHB_CLK, 0x5200c, 0x00200000),
GATE_CLK(GCC_SDCC2_AHB_CLK, 0x14008, 0x00000001),
GATE_CLK(GCC_SDCC2_APPS_CLK, 0x14004, 0x00000001),
GATE_CLK(GCC_SDCC4_AHB_CLK, 0x16008, 0x00000001),
GATE_CLK(GCC_SDCC4_APPS_CLK, 0x16004, 0x00000001),
GATE_CLK(GCC_SYS_NOC_CPUSS_AHB_CLK, 0x52004, 0x00000001),
GATE_CLK(GCC_TSIF_AHB_CLK, 0x36004, 0x00000001),
GATE_CLK(GCC_TSIF_INACTIVITY_TIMERS_CLK, 0x3600c, 0x00000001),
GATE_CLK(GCC_TSIF_REF_CLK, 0x36008, 0x00000001),
GATE_CLK(GCC_UFS_CARD_AHB_CLK, 0x75010, 0x00000001),
GATE_CLK(GCC_UFS_CARD_AXI_CLK, 0x7500c, 0x00000001),
GATE_CLK(GCC_UFS_CARD_CLKREF_CLK, 0x8c004, 0x00000001),
GATE_CLK(GCC_UFS_CARD_ICE_CORE_CLK, 0x75058, 0x00000001),
GATE_CLK(GCC_UFS_CARD_PHY_AUX_CLK, 0x7508c, 0x00000001),
GATE_CLK(GCC_UFS_CARD_RX_SYMBOL_0_CLK, 0x75018, 0x00000001),
GATE_CLK(GCC_UFS_CARD_RX_SYMBOL_1_CLK, 0x750a8, 0x00000001),
GATE_CLK(GCC_UFS_CARD_TX_SYMBOL_0_CLK, 0x75014, 0x00000001),
GATE_CLK(GCC_UFS_CARD_UNIPRO_CORE_CLK, 0x75054, 0x00000001),
GATE_CLK(GCC_UFS_MEM_CLKREF_CLK, 0x8c000, 0x00000001),
GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77010, 0x00000001),
GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x7700c, 0x00000001),
GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77058, 0x00000001),
GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x7708c, 0x00000001),
GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x77018, 0x00000001),
GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x770a8, 0x00000001),
GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x77014, 0x00000001),
GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x77054, 0x00000001),
GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0x0f00c, 0x00000001),
GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x0f014, 0x00000001),
GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0x0f010, 0x00000001),
GATE_CLK(GCC_USB30_SEC_MASTER_CLK, 0x1000c, 0x00000001),
GATE_CLK(GCC_USB30_SEC_MOCK_UTMI_CLK, 0x10014, 0x00000001),
GATE_CLK(GCC_USB30_SEC_SLEEP_CLK, 0x10010, 0x00000001),
GATE_CLK(GCC_USB3_PRIM_CLKREF_CLK, 0x8c008, 0x00000001),
GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK, 0x0f04c, 0x00000001),
GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0x0f050, 0x00000001),
GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0x0f054, 0x00000001),
GATE_CLK(GCC_USB3_SEC_CLKREF_CLK, 0x8c028, 0x00000001),
GATE_CLK(GCC_USB3_SEC_PHY_AUX_CLK, 0x1004c, 0x00000001),
GATE_CLK(GCC_USB3_SEC_PHY_PIPE_CLK, 0x10054, 0x00000001),
GATE_CLK(GCC_USB3_SEC_PHY_COM_AUX_CLK, 0x10050, 0x00000001),
GATE_CLK(GCC_USB_PHY_CFG_AHB2PHY_CLK, 0x6a004, 0x00000001),
GATE_CLK(GCC_VIDEO_AHB_CLK, 0x0b004, 0x00000001),
GATE_CLK(GCC_VIDEO_AXI_CLK, 0x0b01c, 0x00000001),
GATE_CLK(GCC_VIDEO_XO_CLK, 0x0b028, 0x00000001),
GATE_CLK(GCC_GPU_IREF_CLK, 0x8c010, 0x00000001),
GATE_CLK(GCC_APC_VS_CLK, 0x7a050, 0x00000001),
GATE_CLK(GCC_GPU_VS_CLK, 0x7a04c, 0x00000001),
GATE_CLK(GCC_MSS_VS_CLK, 0x7a048, 0x00000001),
GATE_CLK(GCC_VDDA_VS_CLK, 0x7a00c, 0x00000001),
GATE_CLK(GCC_VDDCX_VS_CLK, 0x7a004, 0x00000001),
GATE_CLK(GCC_VDDMX_VS_CLK, 0x7a008, 0x00000001),
GATE_CLK(GCC_VS_CTRL_AHB_CLK, 0x7a014, 0x00000001),
GATE_CLK(GCC_VS_CTRL_CLK, 0x7a010, 0x00000001),
GATE_CLK(GCC_CPUSS_DVM_BUS_CLK, 0x48190, 0x00000001),
+};
Do we really need all these gate clocks in u-boot? IMO, we should add the ones that would be actually used.
-Sumit
int msm_enable(struct clk *clk) {
struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
debug("%s: clk %s\n", __func__, sdm845_clks[clk->id].name);
qcom_gate_clk_en(priv, clk->id);
return 0;
}
@@ -130,6 +267,8 @@ static const struct qcom_reset_map sdm845_gcc_resets[] = { static const struct qcom_cc_data qcs404_gcc_data = { .resets = sdm845_gcc_resets, .num_resets = ARRAY_SIZE(sdm845_gcc_resets),
.clks = sdm845_clks,
.num_clks = ARRAY_SIZE(sdm845_clks),
};
static const struct udevice_id gcc_sdm845_of_match[] = {
-- 2.42.0

Currently, it isn't possible to build clock drivers for more than one platform due to how the msm_enable() and msm_set_rate() callbacks are implemented.
Extend qcom_cc_data to include function pointers for these and convert all platforms to use them.
Previously, clock drivers relied on common.h to include the board specific sysmap header, include those explicitly to further reduce the dependency between the clock driver and a particular target configuration.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- drivers/clk/qcom/clock-apq8016.c | 12 ++++++------ drivers/clk/qcom/clock-apq8096.c | 12 ++++++------ drivers/clk/qcom/clock-ipq4019.c | 6 ++++-- drivers/clk/qcom/clock-qcom.c | 17 ++++++++++++----- drivers/clk/qcom/clock-qcom.h | 5 +++++ drivers/clk/qcom/clock-qcs404.c | 5 ++++- drivers/clk/qcom/clock-sdm845.c | 12 ++++++++---- 7 files changed, 45 insertions(+), 24 deletions(-)
diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c index e3b9b8c1b91b..f74f7a0f5ad9 100644 --- a/drivers/clk/qcom/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -13,6 +13,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> +#include <mach/sysmap-apq8016.h>
#include "clock-qcom.h"
@@ -94,7 +95,7 @@ static int clk_init_uart(struct qcom_cc_priv *priv) return 0; }
-ulong msm_set_rate(struct clk *clk, ulong rate) +static ulong apq8016_set_rate(struct clk *clk, ulong rate) { struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
@@ -113,15 +114,14 @@ ulong msm_set_rate(struct clk *clk, ulong rate) } }
-int msm_enable(struct clk *clk) -{ - return 0; -} +static struct qcom_cc_data apq8016_data = { + .set_rate = apq8016_set_rate, +};
static const struct udevice_id gcc_apq8016_of_match[] = { { .compatible = "qcom,gcc-apq8016", - /* TODO: add reset map */ + .data = (ulong)&apq8016_data, }, { } }; diff --git a/drivers/clk/qcom/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c index dc64d11ca979..1efb6e2313a5 100644 --- a/drivers/clk/qcom/clock-apq8096.c +++ b/drivers/clk/qcom/clock-apq8096.c @@ -13,6 +13,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> +#include <mach/sysmap-apq8096.h>
#include "clock-qcom.h"
@@ -80,7 +81,7 @@ static int clk_init_uart(struct qcom_cc_priv *priv) return 0; }
-ulong msm_set_rate(struct clk *clk, ulong rate) +static ulong apq8096_set_rate(struct clk *clk, ulong rate) { struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
@@ -95,15 +96,14 @@ ulong msm_set_rate(struct clk *clk, ulong rate) } }
-int msm_enable(struct clk *clk) -{ - return 0; -} +static struct qcom_cc_data apq8096_data = { + .set_rate = apq8096_set_rate, +};
static const struct udevice_id gcc_apq8096_of_match[] = { { .compatible = "qcom,gcc-apq8096", - /* TODO: add reset map */ + .data = (ulong)&apq8096_data, }, { } }; diff --git a/drivers/clk/qcom/clock-ipq4019.c b/drivers/clk/qcom/clock-ipq4019.c index 6636af98132d..d42b32c3afd3 100644 --- a/drivers/clk/qcom/clock-ipq4019.c +++ b/drivers/clk/qcom/clock-ipq4019.c @@ -17,7 +17,7 @@
#include "clock-qcom.h"
-ulong msm_set_rate(struct clk *clk, ulong rate) +static ulong ipq4019_set_rate(struct clk *clk, ulong rate) { switch (clk->id) { case GCC_BLSP1_UART1_APPS_CLK: /*UART1*/ @@ -28,7 +28,7 @@ ulong msm_set_rate(struct clk *clk, ulong rate) } }
-int msm_enable(struct clk *clk) +static int ipq4019_enable(struct clk *clk) { switch (clk->id) { case GCC_BLSP1_QUP1_SPI_APPS_CLK: /*SPI1*/ @@ -125,6 +125,8 @@ static const struct qcom_reset_map gcc_ipq4019_resets[] = { };
static struct qcom_cc_data ipq4019_data = { + .enable = ipq4019_enable, + .set_rate = ipq4019_set_rate, .resets = gcc_ipq4019_resets, .num_resets = ARRAY_SIZE(gcc_ipq4019_resets), }; diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c index b0416a05789d..a9602d0c9ca6 100644 --- a/drivers/clk/qcom/clock-qcom.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -28,9 +28,6 @@ #define CBCR_BRANCH_ENABLE_BIT BIT(0) #define CBCR_BRANCH_OFF_BIT BIT(31)
-extern ulong msm_set_rate(struct clk *clk, ulong rate); -extern int msm_enable(struct clk *clk); - /* Enable clock controlled by CBC soft macro */ void clk_enable_cbc(phys_addr_t cbcr) { @@ -160,12 +157,22 @@ static int msm_clk_probe(struct udevice *dev)
static ulong msm_clk_set_rate(struct clk *clk, ulong rate) { - return msm_set_rate(clk, rate); + struct qcom_cc_data *data = (struct qcom_cc_data *)dev_get_driver_data(clk->dev); + + if (data->set_rate) + return data->set_rate(clk, rate); + + return 0; }
static int msm_clk_enable(struct clk *clk) { - return msm_enable(clk); + struct qcom_cc_data *data = (struct qcom_cc_data *)dev_get_driver_data(clk->dev); + + if (data->enable) + return data->enable(clk); + + return 0; }
static struct clk_ops msm_clk_ops = { diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h index 7b3bcf41f421..4c5959b60038 100644 --- a/drivers/clk/qcom/clock-qcom.h +++ b/drivers/clk/qcom/clock-qcom.h @@ -47,11 +47,16 @@ struct qcom_reset_map { u8 bit; };
+struct clk; + struct qcom_cc_data { const struct qcom_reset_map *resets; unsigned long num_resets; const struct gate_clk *clks; unsigned long num_clks; + + int (*enable)(struct clk *clk); + unsigned long (*set_rate)(struct clk *clk, unsigned long rate); };
struct qcom_cc_priv { diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c index e622309b6747..ce83ec741278 100644 --- a/drivers/clk/qcom/clock-qcs404.c +++ b/drivers/clk/qcom/clock-qcs404.c @@ -12,6 +12,7 @@ #include <asm/io.h> #include <linux/bitops.h> #include <dt-bindings/clock/qcom,gcc-qcs404.h> +#include <mach/sysmap-qcs404.h>
#include "clock-qcom.h"
@@ -157,7 +158,7 @@ ulong msm_set_rate(struct clk *clk, ulong rate) return 0; }
-int msm_enable(struct clk *clk) +static int qcs404_enable(struct clk *clk) { struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
@@ -266,6 +267,8 @@ static const struct qcom_reset_map qcs404_gcc_resets[] = { static const struct qcom_cc_data qcs404_gcc_data = { .resets = qcs404_gcc_resets, .num_resets = ARRAY_SIZE(qcs404_gcc_resets), + .enable = qcs404_enable, + .set_rate = qcs404_set_rate, };
static const struct udevice_id gcc_qcs404_of_match[] = { diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c index ccad73b6ff15..7b614f9661f0 100644 --- a/drivers/clk/qcom/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -16,6 +16,7 @@ #include <asm/io.h> #include <linux/bitops.h> #include <dt-bindings/clock/qcom,gcc-sdm845.h> +#include <mach/sysmap-sdm845.h>
#include "clock-qcom.h"
@@ -72,7 +73,7 @@ const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate) return f - 1; }
-ulong msm_set_rate(struct clk *clk, ulong rate) +static ulong sdm845_set_rate(struct clk *clk, ulong rate) { struct qcom_cc_priv *priv = dev_get_priv(clk->dev); const struct freq_tbl *freq; @@ -224,7 +225,7 @@ static const struct gate_clk sdm845_clks[] = { GATE_CLK(GCC_CPUSS_DVM_BUS_CLK, 0x48190, 0x00000001), };
-int msm_enable(struct clk *clk) +static int sdm845_enable(struct clk *clk) { struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
@@ -264,17 +265,20 @@ static const struct qcom_reset_map sdm845_gcc_resets[] = { [GCC_PCIE_1_PHY_BCR] = { 0x8e01c }, };
-static const struct qcom_cc_data qcs404_gcc_data = { +static struct qcom_cc_data sdm845_gcc_data = { .resets = sdm845_gcc_resets, .num_resets = ARRAY_SIZE(sdm845_gcc_resets), .clks = sdm845_clks, .num_clks = ARRAY_SIZE(sdm845_clks), + + .enable = sdm845_enable, + .set_rate = sdm845_set_rate, };
static const struct udevice_id gcc_sdm845_of_match[] = { { .compatible = "qcom,gcc-sdm845", - .data = (ulong)&qcs404_gcc_data, + .data = (ulong)&sdm845_gcc_data, }, { } };

On Wed, 25 Oct 2023 at 01:55, Caleb Connolly caleb.connolly@linaro.org wrote:
Currently, it isn't possible to build clock drivers for more than one platform due to how the msm_enable() and msm_set_rate() callbacks are implemented.
Extend qcom_cc_data to include function pointers for these and convert all platforms to use them.
Previously, clock drivers relied on common.h to include the board
No it's not included via common.h but rather via target specific include file like: include/configs/sdm845.h.
specific sysmap header, include those explicitly to further reduce the dependency between the clock driver and a particular target configuration.
If you really need to remove that dependency then the clock specific macros need to move out of the system map header as a separate header in drivers/clk/qcom/.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org
drivers/clk/qcom/clock-apq8016.c | 12 ++++++------ drivers/clk/qcom/clock-apq8096.c | 12 ++++++------ drivers/clk/qcom/clock-ipq4019.c | 6 ++++-- drivers/clk/qcom/clock-qcom.c | 17 ++++++++++++----- drivers/clk/qcom/clock-qcom.h | 5 +++++ drivers/clk/qcom/clock-qcs404.c | 5 ++++- drivers/clk/qcom/clock-sdm845.c | 12 ++++++++---- 7 files changed, 45 insertions(+), 24 deletions(-)
diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c index e3b9b8c1b91b..f74f7a0f5ad9 100644 --- a/drivers/clk/qcom/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -13,6 +13,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> +#include <mach/sysmap-apq8016.h>
#include "clock-qcom.h"
@@ -94,7 +95,7 @@ static int clk_init_uart(struct qcom_cc_priv *priv) return 0; }
-ulong msm_set_rate(struct clk *clk, ulong rate) +static ulong apq8016_set_rate(struct clk *clk, ulong rate)
I would rather prefer it to be renamed as: <soc>_clk_set_rate() which is self descriptive.
{ struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
@@ -113,15 +114,14 @@ ulong msm_set_rate(struct clk *clk, ulong rate) } }
-int msm_enable(struct clk *clk) -{
return 0;
-} +static struct qcom_cc_data apq8016_data = {
.set_rate = apq8016_set_rate,
+};
static const struct udevice_id gcc_apq8016_of_match[] = { { .compatible = "qcom,gcc-apq8016",
/* TODO: add reset map */
.data = (ulong)&apq8016_data, }, { }
}; diff --git a/drivers/clk/qcom/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c index dc64d11ca979..1efb6e2313a5 100644 --- a/drivers/clk/qcom/clock-apq8096.c +++ b/drivers/clk/qcom/clock-apq8096.c @@ -13,6 +13,7 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> +#include <mach/sysmap-apq8096.h>
#include "clock-qcom.h"
@@ -80,7 +81,7 @@ static int clk_init_uart(struct qcom_cc_priv *priv) return 0; }
-ulong msm_set_rate(struct clk *clk, ulong rate) +static ulong apq8096_set_rate(struct clk *clk, ulong rate) { struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
@@ -95,15 +96,14 @@ ulong msm_set_rate(struct clk *clk, ulong rate) } }
-int msm_enable(struct clk *clk) -{
return 0;
-} +static struct qcom_cc_data apq8096_data = {
.set_rate = apq8096_set_rate,
+};
static const struct udevice_id gcc_apq8096_of_match[] = { { .compatible = "qcom,gcc-apq8096",
/* TODO: add reset map */
.data = (ulong)&apq8096_data, }, { }
}; diff --git a/drivers/clk/qcom/clock-ipq4019.c b/drivers/clk/qcom/clock-ipq4019.c index 6636af98132d..d42b32c3afd3 100644 --- a/drivers/clk/qcom/clock-ipq4019.c +++ b/drivers/clk/qcom/clock-ipq4019.c @@ -17,7 +17,7 @@
#include "clock-qcom.h"
-ulong msm_set_rate(struct clk *clk, ulong rate) +static ulong ipq4019_set_rate(struct clk *clk, ulong rate) { switch (clk->id) { case GCC_BLSP1_UART1_APPS_CLK: /*UART1*/ @@ -28,7 +28,7 @@ ulong msm_set_rate(struct clk *clk, ulong rate) } }
-int msm_enable(struct clk *clk) +static int ipq4019_enable(struct clk *clk)
Ditto, <soc>_clk_enable().
-Sumit
{ switch (clk->id) { case GCC_BLSP1_QUP1_SPI_APPS_CLK: /*SPI1*/ @@ -125,6 +125,8 @@ static const struct qcom_reset_map gcc_ipq4019_resets[] = { };
static struct qcom_cc_data ipq4019_data = {
.enable = ipq4019_enable,
.set_rate = ipq4019_set_rate, .resets = gcc_ipq4019_resets, .num_resets = ARRAY_SIZE(gcc_ipq4019_resets),
}; diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c index b0416a05789d..a9602d0c9ca6 100644 --- a/drivers/clk/qcom/clock-qcom.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -28,9 +28,6 @@ #define CBCR_BRANCH_ENABLE_BIT BIT(0) #define CBCR_BRANCH_OFF_BIT BIT(31)
-extern ulong msm_set_rate(struct clk *clk, ulong rate); -extern int msm_enable(struct clk *clk);
/* Enable clock controlled by CBC soft macro */ void clk_enable_cbc(phys_addr_t cbcr) { @@ -160,12 +157,22 @@ static int msm_clk_probe(struct udevice *dev)
static ulong msm_clk_set_rate(struct clk *clk, ulong rate) {
return msm_set_rate(clk, rate);
struct qcom_cc_data *data = (struct qcom_cc_data *)dev_get_driver_data(clk->dev);
if (data->set_rate)
return data->set_rate(clk, rate);
return 0;
}
static int msm_clk_enable(struct clk *clk) {
return msm_enable(clk);
struct qcom_cc_data *data = (struct qcom_cc_data *)dev_get_driver_data(clk->dev);
if (data->enable)
return data->enable(clk);
return 0;
}
static struct clk_ops msm_clk_ops = { diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h index 7b3bcf41f421..4c5959b60038 100644 --- a/drivers/clk/qcom/clock-qcom.h +++ b/drivers/clk/qcom/clock-qcom.h @@ -47,11 +47,16 @@ struct qcom_reset_map { u8 bit; };
+struct clk;
struct qcom_cc_data { const struct qcom_reset_map *resets; unsigned long num_resets; const struct gate_clk *clks; unsigned long num_clks;
int (*enable)(struct clk *clk);
unsigned long (*set_rate)(struct clk *clk, unsigned long rate);
};
struct qcom_cc_priv { diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c index e622309b6747..ce83ec741278 100644 --- a/drivers/clk/qcom/clock-qcs404.c +++ b/drivers/clk/qcom/clock-qcs404.c @@ -12,6 +12,7 @@ #include <asm/io.h> #include <linux/bitops.h> #include <dt-bindings/clock/qcom,gcc-qcs404.h> +#include <mach/sysmap-qcs404.h>
#include "clock-qcom.h"
@@ -157,7 +158,7 @@ ulong msm_set_rate(struct clk *clk, ulong rate) return 0; }
-int msm_enable(struct clk *clk) +static int qcs404_enable(struct clk *clk) { struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
@@ -266,6 +267,8 @@ static const struct qcom_reset_map qcs404_gcc_resets[] = { static const struct qcom_cc_data qcs404_gcc_data = { .resets = qcs404_gcc_resets, .num_resets = ARRAY_SIZE(qcs404_gcc_resets),
.enable = qcs404_enable,
.set_rate = qcs404_set_rate,
};
static const struct udevice_id gcc_qcs404_of_match[] = { diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c index ccad73b6ff15..7b614f9661f0 100644 --- a/drivers/clk/qcom/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -16,6 +16,7 @@ #include <asm/io.h> #include <linux/bitops.h> #include <dt-bindings/clock/qcom,gcc-sdm845.h> +#include <mach/sysmap-sdm845.h>
#include "clock-qcom.h"
@@ -72,7 +73,7 @@ const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate) return f - 1; }
-ulong msm_set_rate(struct clk *clk, ulong rate) +static ulong sdm845_set_rate(struct clk *clk, ulong rate) { struct qcom_cc_priv *priv = dev_get_priv(clk->dev); const struct freq_tbl *freq; @@ -224,7 +225,7 @@ static const struct gate_clk sdm845_clks[] = { GATE_CLK(GCC_CPUSS_DVM_BUS_CLK, 0x48190, 0x00000001), };
-int msm_enable(struct clk *clk) +static int sdm845_enable(struct clk *clk) { struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
@@ -264,17 +265,20 @@ static const struct qcom_reset_map sdm845_gcc_resets[] = { [GCC_PCIE_1_PHY_BCR] = { 0x8e01c }, };
-static const struct qcom_cc_data qcs404_gcc_data = { +static struct qcom_cc_data sdm845_gcc_data = { .resets = sdm845_gcc_resets, .num_resets = ARRAY_SIZE(sdm845_gcc_resets), .clks = sdm845_clks, .num_clks = ARRAY_SIZE(sdm845_clks),
.enable = sdm845_enable,
.set_rate = sdm845_set_rate,
};
static const struct udevice_id gcc_sdm845_of_match[] = { { .compatible = "qcom,gcc-sdm845",
.data = (ulong)&qcs404_gcc_data,
.data = (ulong)&sdm845_gcc_data, }, { }
};
-- 2.42.0

This property is needed on some platforms to ensure that only the relevant bits are set in the M/N/D registers.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- drivers/clk/qcom/clock-apq8016.c | 4 ++-- drivers/clk/qcom/clock-apq8096.c | 4 ++-- drivers/clk/qcom/clock-qcom.c | 11 +++++++---- drivers/clk/qcom/clock-qcom.h | 2 +- drivers/clk/qcom/clock-qcs404.c | 20 ++++++++++---------- drivers/clk/qcom/clock-sdm845.c | 3 +-- 6 files changed, 23 insertions(+), 21 deletions(-)
diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c index f74f7a0f5ad9..5eba18739cfb 100644 --- a/drivers/clk/qcom/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -61,7 +61,7 @@ static int clk_init_sdc(struct qcom_cc_priv *priv, int slot, uint rate) clk_enable_cbc(priv->base + SDCC_AHB_CBCR(slot)); /* 800Mhz/div, gpll0 */ clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0, - CFG_CLK_SRC_GPLL0); + CFG_CLK_SRC_GPLL0, 8); clk_enable_gpll0(priv->base, &gpll0_vote_clk); clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
@@ -84,7 +84,7 @@ static int clk_init_uart(struct qcom_cc_priv *priv)
/* 7372800 uart block clock @ GPLL0 */ clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 144, 15625, - CFG_CLK_SRC_GPLL0); + CFG_CLK_SRC_GPLL0, 8);
/* Vote for gpll0 clock */ clk_enable_gpll0(priv->base, &gpll0_vote_clk); diff --git a/drivers/clk/qcom/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c index 1efb6e2313a5..48cac08eed67 100644 --- a/drivers/clk/qcom/clock-apq8096.c +++ b/drivers/clk/qcom/clock-apq8096.c @@ -48,7 +48,7 @@ static int clk_init_sdc(struct qcom_cc_priv *priv, uint rate)
clk_enable_cbc(priv->base + SDCC2_AHB_CBCR); clk_rcg_set_rate_mnd(priv->base, &sdc_regs, div, 0, 0, - CFG_CLK_SRC_GPLL0); + CFG_CLK_SRC_GPLL0, 8); clk_enable_gpll0(priv->base, &gpll0_vote_clk); clk_enable_cbc(priv->base + SDCC2_APPS_CBCR);
@@ -70,7 +70,7 @@ static int clk_init_uart(struct qcom_cc_priv *priv)
/* 7372800 uart block clock @ GPLL0 */ clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 192, 15625, - CFG_CLK_SRC_GPLL0); + CFG_CLK_SRC_GPLL0, 8);
/* Vote for gpll0 clock */ clk_enable_gpll0(priv->base, &gpll0_vote_clk); diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c index a9602d0c9ca6..7a6157bf123f 100644 --- a/drivers/clk/qcom/clock-qcom.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -83,7 +83,7 @@ void clk_bcr_update(phys_addr_t apps_cmd_rcgr)
/* root set rate for clocks with half integer and MND divider */ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, - int div, int m, int n, int source) + int div, int m, int n, int source, u8 mnd_width) { u32 cfg; /* M value for MND divider. */ @@ -92,11 +92,14 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, u32 n_val = ~((n) - (m)) * !!(n); /* NOT 2D value for MND divider. */ u32 d_val = ~(n); + u32 mask = BIT(mnd_width) - 1; + + debug("m %#x n %#x d %#x div %#x mask %#x\n", m_val, n_val, d_val, div, mask);
/* Program MND values */ - writel(m_val, base + regs->M); - writel(n_val, base + regs->N); - writel(d_val, base + regs->D); + setbits_le32(base + regs->M, m_val & mask); + setbits_le32(base + regs->N, n_val & mask); + setbits_le32(base + regs->D, d_val & mask);
/* setup src select and divider */ cfg = readl(base + regs->cfg_rcgr); diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h index 4c5959b60038..6fa88fb40af8 100644 --- a/drivers/clk/qcom/clock-qcom.h +++ b/drivers/clk/qcom/clock-qcom.h @@ -70,7 +70,7 @@ void clk_bcr_update(phys_addr_t apps_cmd_rgcr); void clk_enable_cbc(phys_addr_t cbcr); void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk); void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, - int div, int m, int n, int source); + int div, int m, int n, int source, u8 mnd_width); void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div, int source);
diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c index ce83ec741278..d10992ee58bf 100644 --- a/drivers/clk/qcom/clock-qcs404.c +++ b/drivers/clk/qcom/clock-qcs404.c @@ -113,7 +113,7 @@ static const struct bcr_regs blsp1_qup4_i2c_apps_regs = { /* mnd_width = 0 */ };
-ulong msm_set_rate(struct clk *clk, ulong rate) +static ulong qcs404_set_rate(struct clk *clk, ulong rate) { struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
@@ -121,7 +121,7 @@ ulong msm_set_rate(struct clk *clk, ulong rate) case GCC_BLSP1_UART2_APPS_CLK: /* UART: 115200 */ clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 0, 12, 125, - CFG_CLK_SRC_CXO); + CFG_CLK_SRC_CXO, 8); clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR); break; case GCC_BLSP1_AHB_CLK: @@ -130,7 +130,7 @@ ulong msm_set_rate(struct clk *clk, ulong rate) case GCC_SDCC1_APPS_CLK: /* SDCC1: 200MHz */ clk_rcg_set_rate_mnd(priv->base, &sdc_regs, 4, 0, 0, - CFG_CLK_SRC_GPLL0); + CFG_CLK_SRC_GPLL0, 8); clk_enable_gpll0(priv->base, &gpll0_vote_clk); clk_enable_cbc(priv->base + SDCC_APPS_CBCR(1)); break; @@ -140,16 +140,16 @@ ulong msm_set_rate(struct clk *clk, ulong rate) case GCC_ETH_RGMII_CLK: if (rate == 250000000) clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0, - CFG_CLK_SRC_GPLL1); + CFG_CLK_SRC_GPLL1, 8); else if (rate == 125000000) clk_rcg_set_rate_mnd(priv->base, &emac_regs, 4, 0, 0, - CFG_CLK_SRC_GPLL1); + CFG_CLK_SRC_GPLL1, 8); else if (rate == 50000000) clk_rcg_set_rate_mnd(priv->base, &emac_regs, 10, 0, 0, - CFG_CLK_SRC_GPLL1); + CFG_CLK_SRC_GPLL1, 8); else if (rate == 5000000) clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 1, 50, - CFG_CLK_SRC_GPLL1); + CFG_CLK_SRC_GPLL1, 8); break; default: return 0; @@ -166,7 +166,7 @@ static int qcs404_enable(struct clk *clk) case GCC_USB30_MASTER_CLK: clk_enable_cbc(priv->base + USB30_MASTER_CBCR); clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 4, 0, 0, - CFG_CLK_SRC_GPLL0); + CFG_CLK_SRC_GPLL0, 8); break; case GCC_SYS_NOC_USB3_CLK: clk_enable_cbc(priv->base + SYS_NOC_USB3_CBCR); @@ -188,14 +188,14 @@ static int qcs404_enable(struct clk *clk) clk_enable_cbc(priv->base + ETH_PTP_CBCR); clk_enable_gpll0(priv->base, &gpll1_vote_clk); clk_rcg_set_rate_mnd(priv->base, &emac_ptp_regs, 2, 0, 0, - CFG_CLK_SRC_GPLL1); + CFG_CLK_SRC_GPLL1, 8); break; case GCC_ETH_RGMII_CLK: /* SPEED_1000: freq -> 250MHz */ clk_enable_cbc(priv->base + ETH_RGMII_CBCR); clk_enable_gpll0(priv->base, &gpll1_vote_clk); clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0, - CFG_CLK_SRC_GPLL1); + CFG_CLK_SRC_GPLL1, 8); break; case GCC_ETH_SLAVE_AHB_CLK: clk_enable_cbc(priv->base + ETH_SLAVE_AHB_CBCR); diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c index 7b614f9661f0..9345d5293f1e 100644 --- a/drivers/clk/qcom/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -82,8 +82,7 @@ static ulong sdm845_set_rate(struct clk *clk, ulong rate) case GCC_QUPV3_WRAP1_S1_CLK: /* UART9 */ freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate); clk_rcg_set_rate_mnd(priv->base, &uart2_regs, - freq->pre_div, freq->m, freq->n, freq->src); - + freq->pre_div, freq->m, freq->n, freq->src, 16); return freq->freq; default: return 0;

On Wed, 25 Oct 2023 at 01:55, Caleb Connolly caleb.connolly@linaro.org wrote:
This property is needed on some platforms to ensure that only the relevant bits are set in the M/N/D registers.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org
drivers/clk/qcom/clock-apq8016.c | 4 ++-- drivers/clk/qcom/clock-apq8096.c | 4 ++-- drivers/clk/qcom/clock-qcom.c | 11 +++++++---- drivers/clk/qcom/clock-qcom.h | 2 +- drivers/clk/qcom/clock-qcs404.c | 20 ++++++++++---------- drivers/clk/qcom/clock-sdm845.c | 3 +-- 6 files changed, 23 insertions(+), 21 deletions(-)
Reviewed-by: Sumit Garg sumit.garg@linaro.org
-Sumit
diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c index f74f7a0f5ad9..5eba18739cfb 100644 --- a/drivers/clk/qcom/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -61,7 +61,7 @@ static int clk_init_sdc(struct qcom_cc_priv *priv, int slot, uint rate) clk_enable_cbc(priv->base + SDCC_AHB_CBCR(slot)); /* 800Mhz/div, gpll0 */ clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0,
CFG_CLK_SRC_GPLL0);
CFG_CLK_SRC_GPLL0, 8); clk_enable_gpll0(priv->base, &gpll0_vote_clk); clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
@@ -84,7 +84,7 @@ static int clk_init_uart(struct qcom_cc_priv *priv)
/* 7372800 uart block clock @ GPLL0 */ clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 144, 15625,
CFG_CLK_SRC_GPLL0);
CFG_CLK_SRC_GPLL0, 8); /* Vote for gpll0 clock */ clk_enable_gpll0(priv->base, &gpll0_vote_clk);
diff --git a/drivers/clk/qcom/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c index 1efb6e2313a5..48cac08eed67 100644 --- a/drivers/clk/qcom/clock-apq8096.c +++ b/drivers/clk/qcom/clock-apq8096.c @@ -48,7 +48,7 @@ static int clk_init_sdc(struct qcom_cc_priv *priv, uint rate)
clk_enable_cbc(priv->base + SDCC2_AHB_CBCR); clk_rcg_set_rate_mnd(priv->base, &sdc_regs, div, 0, 0,
CFG_CLK_SRC_GPLL0);
CFG_CLK_SRC_GPLL0, 8); clk_enable_gpll0(priv->base, &gpll0_vote_clk); clk_enable_cbc(priv->base + SDCC2_APPS_CBCR);
@@ -70,7 +70,7 @@ static int clk_init_uart(struct qcom_cc_priv *priv)
/* 7372800 uart block clock @ GPLL0 */ clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 192, 15625,
CFG_CLK_SRC_GPLL0);
CFG_CLK_SRC_GPLL0, 8); /* Vote for gpll0 clock */ clk_enable_gpll0(priv->base, &gpll0_vote_clk);
diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c index a9602d0c9ca6..7a6157bf123f 100644 --- a/drivers/clk/qcom/clock-qcom.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -83,7 +83,7 @@ void clk_bcr_update(phys_addr_t apps_cmd_rcgr)
/* root set rate for clocks with half integer and MND divider */ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
int div, int m, int n, int source)
int div, int m, int n, int source, u8 mnd_width)
{ u32 cfg; /* M value for MND divider. */ @@ -92,11 +92,14 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, u32 n_val = ~((n) - (m)) * !!(n); /* NOT 2D value for MND divider. */ u32 d_val = ~(n);
u32 mask = BIT(mnd_width) - 1;
debug("m %#x n %#x d %#x div %#x mask %#x\n", m_val, n_val, d_val, div, mask); /* Program MND values */
writel(m_val, base + regs->M);
writel(n_val, base + regs->N);
writel(d_val, base + regs->D);
setbits_le32(base + regs->M, m_val & mask);
setbits_le32(base + regs->N, n_val & mask);
setbits_le32(base + regs->D, d_val & mask); /* setup src select and divider */ cfg = readl(base + regs->cfg_rcgr);
diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h index 4c5959b60038..6fa88fb40af8 100644 --- a/drivers/clk/qcom/clock-qcom.h +++ b/drivers/clk/qcom/clock-qcom.h @@ -70,7 +70,7 @@ void clk_bcr_update(phys_addr_t apps_cmd_rgcr); void clk_enable_cbc(phys_addr_t cbcr); void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk); void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
int div, int m, int n, int source);
int div, int m, int n, int source, u8 mnd_width);
void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div, int source);
diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c index ce83ec741278..d10992ee58bf 100644 --- a/drivers/clk/qcom/clock-qcs404.c +++ b/drivers/clk/qcom/clock-qcs404.c @@ -113,7 +113,7 @@ static const struct bcr_regs blsp1_qup4_i2c_apps_regs = { /* mnd_width = 0 */ };
-ulong msm_set_rate(struct clk *clk, ulong rate) +static ulong qcs404_set_rate(struct clk *clk, ulong rate) { struct qcom_cc_priv *priv = dev_get_priv(clk->dev);
@@ -121,7 +121,7 @@ ulong msm_set_rate(struct clk *clk, ulong rate) case GCC_BLSP1_UART2_APPS_CLK: /* UART: 115200 */ clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 0, 12, 125,
CFG_CLK_SRC_CXO);
CFG_CLK_SRC_CXO, 8); clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR); break; case GCC_BLSP1_AHB_CLK:
@@ -130,7 +130,7 @@ ulong msm_set_rate(struct clk *clk, ulong rate) case GCC_SDCC1_APPS_CLK: /* SDCC1: 200MHz */ clk_rcg_set_rate_mnd(priv->base, &sdc_regs, 4, 0, 0,
CFG_CLK_SRC_GPLL0);
CFG_CLK_SRC_GPLL0, 8); clk_enable_gpll0(priv->base, &gpll0_vote_clk); clk_enable_cbc(priv->base + SDCC_APPS_CBCR(1)); break;
@@ -140,16 +140,16 @@ ulong msm_set_rate(struct clk *clk, ulong rate) case GCC_ETH_RGMII_CLK: if (rate == 250000000) clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0,
CFG_CLK_SRC_GPLL1);
CFG_CLK_SRC_GPLL1, 8); else if (rate == 125000000) clk_rcg_set_rate_mnd(priv->base, &emac_regs, 4, 0, 0,
CFG_CLK_SRC_GPLL1);
CFG_CLK_SRC_GPLL1, 8); else if (rate == 50000000) clk_rcg_set_rate_mnd(priv->base, &emac_regs, 10, 0, 0,
CFG_CLK_SRC_GPLL1);
CFG_CLK_SRC_GPLL1, 8); else if (rate == 5000000) clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 1, 50,
CFG_CLK_SRC_GPLL1);
CFG_CLK_SRC_GPLL1, 8); break; default: return 0;
@@ -166,7 +166,7 @@ static int qcs404_enable(struct clk *clk) case GCC_USB30_MASTER_CLK: clk_enable_cbc(priv->base + USB30_MASTER_CBCR); clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 4, 0, 0,
CFG_CLK_SRC_GPLL0);
CFG_CLK_SRC_GPLL0, 8); break; case GCC_SYS_NOC_USB3_CLK: clk_enable_cbc(priv->base + SYS_NOC_USB3_CBCR);
@@ -188,14 +188,14 @@ static int qcs404_enable(struct clk *clk) clk_enable_cbc(priv->base + ETH_PTP_CBCR); clk_enable_gpll0(priv->base, &gpll1_vote_clk); clk_rcg_set_rate_mnd(priv->base, &emac_ptp_regs, 2, 0, 0,
CFG_CLK_SRC_GPLL1);
CFG_CLK_SRC_GPLL1, 8); break; case GCC_ETH_RGMII_CLK: /* SPEED_1000: freq -> 250MHz */ clk_enable_cbc(priv->base + ETH_RGMII_CBCR); clk_enable_gpll0(priv->base, &gpll1_vote_clk); clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0,
CFG_CLK_SRC_GPLL1);
CFG_CLK_SRC_GPLL1, 8); break; case GCC_ETH_SLAVE_AHB_CLK: clk_enable_cbc(priv->base + ETH_SLAVE_AHB_CBCR);
diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c index 7b614f9661f0..9345d5293f1e 100644 --- a/drivers/clk/qcom/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -82,8 +82,7 @@ static ulong sdm845_set_rate(struct clk *clk, ulong rate) case GCC_QUPV3_WRAP1_S1_CLK: /* UART9 */ freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate); clk_rcg_set_rate_mnd(priv->base, &uart2_regs,
freq->pre_div, freq->m, freq->n, freq->src);
freq->pre_div, freq->m, freq->n, freq->src, 16); return freq->freq; default: return 0;
-- 2.42.0

The RCG divider field takes a value of (2*h - 1) where h is the divisor. This allows fractional dividers to be supported by calculating them at compile time using a macro.
However, the clk_rcg_set_rate_mnd() function was also performing the calculation. Clean this all up and consistently use the F() macro to calculate these at compile time and properly support fractional divisors.
Additionally, improve clk_bcr_update() to timeout with a warning rather than hanging the board, and make the freq_tbl struct and helpers common so that they can be reused by future platforms.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- drivers/clk/qcom/clock-apq8016.c | 2 +- drivers/clk/qcom/clock-apq8096.c | 2 +- drivers/clk/qcom/clock-qcom.c | 40 ++++++++++++++++++++++++++++++++-------- drivers/clk/qcom/clock-qcom.h | 11 +++++++++++ drivers/clk/qcom/clock-qcs404.c | 16 ++++++++-------- drivers/clk/qcom/clock-sdm845.c | 26 -------------------------- 6 files changed, 53 insertions(+), 44 deletions(-)
diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c index 5eba18739cfb..a1481cd5177b 100644 --- a/drivers/clk/qcom/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -53,7 +53,7 @@ static struct vote_clk gcc_blsp1_ahb_clk = { /* SDHCI */ static int clk_init_sdc(struct qcom_cc_priv *priv, int slot, uint rate) { - int div = 8; /* 100MHz default */ + int div = 15; /* 100MHz default */
if (rate == 200000000) div = 4; diff --git a/drivers/clk/qcom/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c index 48cac08eed67..ef81cd16223c 100644 --- a/drivers/clk/qcom/clock-apq8096.c +++ b/drivers/clk/qcom/clock-apq8096.c @@ -44,7 +44,7 @@ static struct vote_clk gcc_blsp2_ahb_clk = {
static int clk_init_sdc(struct qcom_cc_priv *priv, uint rate) { - int div = 3; + int div = 5;
clk_enable_cbc(priv->base + SDCC2_AHB_CBCR); clk_rcg_set_rate_mnd(priv->base, &sdc_regs, div, 0, 0, diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c index 7a6157bf123f..a83c74cd20ba 100644 --- a/drivers/clk/qcom/clock-qcom.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -68,20 +68,46 @@ void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk) /* Update clock command via CMD_RCGR */ void clk_bcr_update(phys_addr_t apps_cmd_rcgr) { + u32 count; setbits_le32(apps_cmd_rcgr, APPS_CMD_RCGR_UPDATE);
/* Wait for frequency to be updated. */ - while (readl(apps_cmd_rcgr) & APPS_CMD_RCGR_UPDATE) - ; + for (count = 0; count < 50000; count++) { + if (!(readl(apps_cmd_rcgr) & APPS_CMD_RCGR_UPDATE)) + break; + udelay(1); + } + WARN(count == 50000, "WARNING: RCG @ %#llx [%#010x] stuck at off\n", + apps_cmd_rcgr, readl(apps_cmd_rcgr)); +} + +const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate) +{ + if (!f) + return NULL; + + if (!f->freq) + return f; + + for (; f->freq; f++) + if (rate <= f->freq) + return f; + + /* Default to our fastest rate */ + return f - 1; }
#define CFG_MODE_DUAL_EDGE (0x2 << 12) /* Counter mode */
-#define CFG_MASK 0x3FFF +// Disable the HW_CLK_CONTROL bit +#define CFG_MASK (0x3FFF | (1 << 20))
#define CFG_DIVIDER_MASK 0x1F
-/* root set rate for clocks with half integer and MND divider */ +/* + * root set rate for clocks with half integer and MND divider + * div should be pre-calculated ((div * 2) - 1) + */ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, int div, int m, int n, int source, u8 mnd_width) { @@ -99,17 +125,15 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, /* Program MND values */ setbits_le32(base + regs->M, m_val & mask); setbits_le32(base + regs->N, n_val & mask); - setbits_le32(base + regs->D, d_val & mask); + setbits_le32(base + regs->D, (d_val & mask) == mask ? 0 : (d_val & mask));
/* setup src select and divider */ cfg = readl(base + regs->cfg_rcgr); cfg &= ~CFG_MASK; cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */
- /* Set the divider; HW permits fraction dividers (+0.5), but - for simplicity, we will support integers only */ if (div) - cfg |= (2 * div - 1) & CFG_DIVIDER_MASK; + cfg |= div & CFG_DIVIDER_MASK;
if (n_val) cfg |= CFG_MODE_DUAL_EDGE; diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h index 6fa88fb40af8..f91e9d47dd22 100644 --- a/drivers/clk/qcom/clock-qcom.h +++ b/drivers/clk/qcom/clock-qcom.h @@ -30,6 +30,16 @@ struct bcr_regs { uintptr_t D; };
+struct freq_tbl { + uint freq; + uint src; + u8 pre_div; + u16 m; + u16 n; +}; + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + struct gate_clk { uintptr_t reg; u32 en_val; @@ -69,6 +79,7 @@ void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0); void clk_bcr_update(phys_addr_t apps_cmd_rgcr); void clk_enable_cbc(phys_addr_t cbcr); void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk); +const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate); void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, int div, int m, int n, int source, u8 mnd_width); void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div, diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c index d10992ee58bf..b30d5c388d81 100644 --- a/drivers/clk/qcom/clock-qcs404.c +++ b/drivers/clk/qcom/clock-qcs404.c @@ -129,7 +129,7 @@ static ulong qcs404_set_rate(struct clk *clk, ulong rate) break; case GCC_SDCC1_APPS_CLK: /* SDCC1: 200MHz */ - clk_rcg_set_rate_mnd(priv->base, &sdc_regs, 4, 0, 0, + clk_rcg_set_rate_mnd(priv->base, &sdc_regs, 7, 0, 0, CFG_CLK_SRC_GPLL0, 8); clk_enable_gpll0(priv->base, &gpll0_vote_clk); clk_enable_cbc(priv->base + SDCC_APPS_CBCR(1)); @@ -139,16 +139,16 @@ static ulong qcs404_set_rate(struct clk *clk, ulong rate) break; case GCC_ETH_RGMII_CLK: if (rate == 250000000) - clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0, + clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 0, 0, CFG_CLK_SRC_GPLL1, 8); else if (rate == 125000000) - clk_rcg_set_rate_mnd(priv->base, &emac_regs, 4, 0, 0, + clk_rcg_set_rate_mnd(priv->base, &emac_regs, 7, 0, 0, CFG_CLK_SRC_GPLL1, 8); else if (rate == 50000000) - clk_rcg_set_rate_mnd(priv->base, &emac_regs, 10, 0, 0, + clk_rcg_set_rate_mnd(priv->base, &emac_regs, 19, 0, 0, CFG_CLK_SRC_GPLL1, 8); else if (rate == 5000000) - clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 1, 50, + clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 1, 50, CFG_CLK_SRC_GPLL1, 8); break; default: @@ -165,7 +165,7 @@ static int qcs404_enable(struct clk *clk) switch (clk->id) { case GCC_USB30_MASTER_CLK: clk_enable_cbc(priv->base + USB30_MASTER_CBCR); - clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 4, 0, 0, + clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 7, 0, 0, CFG_CLK_SRC_GPLL0, 8); break; case GCC_SYS_NOC_USB3_CLK: @@ -187,14 +187,14 @@ static int qcs404_enable(struct clk *clk) /* SPEED_1000: freq -> 250MHz */ clk_enable_cbc(priv->base + ETH_PTP_CBCR); clk_enable_gpll0(priv->base, &gpll1_vote_clk); - clk_rcg_set_rate_mnd(priv->base, &emac_ptp_regs, 2, 0, 0, + clk_rcg_set_rate_mnd(priv->base, &emac_ptp_regs, 3, 0, 0, CFG_CLK_SRC_GPLL1, 8); break; case GCC_ETH_RGMII_CLK: /* SPEED_1000: freq -> 250MHz */ clk_enable_cbc(priv->base + ETH_RGMII_CBCR); clk_enable_gpll0(priv->base, &gpll1_vote_clk); - clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0, + clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 0, 0, CFG_CLK_SRC_GPLL1, 8); break; case GCC_ETH_SLAVE_AHB_CLK: diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c index 9345d5293f1e..efe8495b7fb0 100644 --- a/drivers/clk/qcom/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -20,16 +20,6 @@
#include "clock-qcom.h"
-#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } - -struct freq_tbl { - uint freq; - uint src; - u8 pre_div; - u16 m; - u16 n; -}; - static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625), F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625), @@ -57,22 +47,6 @@ static const struct bcr_regs uart2_regs = { .D = SE9_UART_APPS_D, };
-const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate) -{ - if (!f) - return NULL; - - if (!f->freq) - return f; - - for (; f->freq; f++) - if (rate <= f->freq) - return f; - - /* Default to our fastest rate */ - return f - 1; -} - static ulong sdm845_set_rate(struct clk *clk, ulong rate) { struct qcom_cc_priv *priv = dev_get_priv(clk->dev);

On 24/10/2023 21:23, Caleb Connolly wrote:
The RCG divider field takes a value of (2*h - 1) where h is the divisor. This allows fractional dividers to be supported by calculating them at compile time using a macro.
However, the clk_rcg_set_rate_mnd() function was also performing the calculation. Clean this all up and consistently use the F() macro to calculate these at compile time and properly support fractional divisors.
Additionally, improve clk_bcr_update() to timeout with a warning rather than hanging the board, and make the freq_tbl struct and helpers common so that they can be reused by future platforms.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org
[...]
#define CFG_MODE_DUAL_EDGE (0x2 << 12) /* Counter mode */
-#define CFG_MASK 0x3FFF +// Disable the HW_CLK_CONTROL bit +#define CFG_MASK (0x3FFF | (1 << 20))
There seems to be a bug in this patch that causes the actual clock rate to be wrong in some cases, most obvious with db845c UART. I had initially thought it to be a board issue but upon further investigation I think I'm wrong.
The UART clock frequency table in clock-sdm845.c is taken from Linux, the 115200 baud rate corresponds to the lowest frequency (7372800Hz). However, with the implementation changes here, the RCG configuration actually results in a measured clock rate of 9085208Hz.
If the entry is changed as follows - F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625) + F(7372800, CFG_CLK_SRC_GPLL0, 0.5, 192, 15625)
Then the resultant clock rate is 7372604Hz (within the tolerance)...
I will resolve this for v2.
#define CFG_DIVIDER_MASK 0x1F
-/* root set rate for clocks with half integer and MND divider */ +/*
- root set rate for clocks with half integer and MND divider
- div should be pre-calculated ((div * 2) - 1)
- */
void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, int div, int m, int n, int source, u8 mnd_width) { @@ -99,17 +125,15 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, /* Program MND values */ setbits_le32(base + regs->M, m_val & mask); setbits_le32(base + regs->N, n_val & mask);
- setbits_le32(base + regs->D, d_val & mask);
setbits_le32(base + regs->D, (d_val & mask) == mask ? 0 : (d_val & mask));
/* setup src select and divider */ cfg = readl(base + regs->cfg_rcgr); cfg &= ~CFG_MASK; cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */
- /* Set the divider; HW permits fraction dividers (+0.5), but
if (div)for simplicity, we will support integers only */
cfg |= (2 * div - 1) & CFG_DIVIDER_MASK;
cfg |= div & CFG_DIVIDER_MASK;
if (n_val) cfg |= CFG_MODE_DUAL_EDGE;

On Wed, 25 Oct 2023 at 19:14, Caleb Connolly caleb.connolly@linaro.org wrote:
On 24/10/2023 21:23, Caleb Connolly wrote:
The RCG divider field takes a value of (2*h - 1) where h is the divisor. This allows fractional dividers to be supported by calculating them at compile time using a macro.
However, the clk_rcg_set_rate_mnd() function was also performing the calculation. Clean this all up and consistently use the F() macro to calculate these at compile time and properly support fractional divisors.
Additionally, improve clk_bcr_update() to timeout with a warning rather than hanging the board, and make the freq_tbl struct and helpers common so that they can be reused by future platforms.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org
[...]
#define CFG_MODE_DUAL_EDGE (0x2 << 12) /* Counter mode */
-#define CFG_MASK 0x3FFF +// Disable the HW_CLK_CONTROL bit +#define CFG_MASK (0x3FFF | (1 << 20))
There seems to be a bug in this patch that causes the actual clock rate to be wrong in some cases, most obvious with db845c UART. I had initially thought it to be a board issue but upon further investigation I think I'm wrong.
The UART clock frequency table in clock-sdm845.c is taken from Linux, the 115200 baud rate corresponds to the lowest frequency (7372800Hz). However, with the implementation changes here, the RCG configuration actually results in a measured clock rate of 9085208Hz.
If the entry is changed as follows
F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625)
F(7372800, CFG_CLK_SRC_GPLL0, 0.5, 192, 15625)
I would suggest we keep the frequency table aligned to the Linux tree. We should try to fix the mismatch in the computation to support fractional divisors.
-Sumit
Then the resultant clock rate is 7372604Hz (within the tolerance)...
I will resolve this for v2.
#define CFG_DIVIDER_MASK 0x1F
-/* root set rate for clocks with half integer and MND divider */ +/*
- root set rate for clocks with half integer and MND divider
- div should be pre-calculated ((div * 2) - 1)
- */
void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, int div, int m, int n, int source, u8 mnd_width) { @@ -99,17 +125,15 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, /* Program MND values */ setbits_le32(base + regs->M, m_val & mask); setbits_le32(base + regs->N, n_val & mask);
setbits_le32(base + regs->D, d_val & mask);
setbits_le32(base + regs->D, (d_val & mask) == mask ? 0 : (d_val & mask)); /* setup src select and divider */ cfg = readl(base + regs->cfg_rcgr); cfg &= ~CFG_MASK; cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */
/* Set the divider; HW permits fraction dividers (+0.5), but
for simplicity, we will support integers only */ if (div)
cfg |= (2 * div - 1) & CFG_DIVIDER_MASK;
cfg |= div & CFG_DIVIDER_MASK; if (n_val) cfg |= CFG_MODE_DUAL_EDGE;
-- // Caleb (they/them)

On 27/10/2023 13:18, Sumit Garg wrote:
On Wed, 25 Oct 2023 at 19:14, Caleb Connolly caleb.connolly@linaro.org wrote:
On 24/10/2023 21:23, Caleb Connolly wrote:
The RCG divider field takes a value of (2*h - 1) where h is the divisor. This allows fractional dividers to be supported by calculating them at compile time using a macro.
However, the clk_rcg_set_rate_mnd() function was also performing the calculation. Clean this all up and consistently use the F() macro to calculate these at compile time and properly support fractional divisors.
Additionally, improve clk_bcr_update() to timeout with a warning rather than hanging the board, and make the freq_tbl struct and helpers common so that they can be reused by future platforms.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org
[...]
#define CFG_MODE_DUAL_EDGE (0x2 << 12) /* Counter mode */
-#define CFG_MASK 0x3FFF +// Disable the HW_CLK_CONTROL bit +#define CFG_MASK (0x3FFF | (1 << 20))
There seems to be a bug in this patch that causes the actual clock rate to be wrong in some cases, most obvious with db845c UART. I had initially thought it to be a board issue but upon further investigation I think I'm wrong.
The UART clock frequency table in clock-sdm845.c is taken from Linux, the 115200 baud rate corresponds to the lowest frequency (7372800Hz). However, with the implementation changes here, the RCG configuration actually results in a measured clock rate of 9085208Hz.
If the entry is changed as follows
F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625)
F(7372800, CFG_CLK_SRC_GPLL0, 0.5, 192, 15625)
I would suggest we keep the frequency table aligned to the Linux tree. We should try to fix the mismatch in the computation to support fractional divisors.
Please disregard, the original entry F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625) is what Linux has. It turns out that setbits_le32() doesn't use iowmb(), and as a result the writes weren't propagating through to hardware correctly, resulting in the frequency being wrong. This will be fixed in v2, and use the frequency table from Linux.
-Sumit
Then the resultant clock rate is 7372604Hz (within the tolerance)...
I will resolve this for v2.
#define CFG_DIVIDER_MASK 0x1F
-/* root set rate for clocks with half integer and MND divider */ +/*
- root set rate for clocks with half integer and MND divider
- div should be pre-calculated ((div * 2) - 1)
- */
void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, int div, int m, int n, int source, u8 mnd_width) { @@ -99,17 +125,15 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, /* Program MND values */ setbits_le32(base + regs->M, m_val & mask); setbits_le32(base + regs->N, n_val & mask);
setbits_le32(base + regs->D, d_val & mask);
setbits_le32(base + regs->D, (d_val & mask) == mask ? 0 : (d_val & mask)); /* setup src select and divider */ cfg = readl(base + regs->cfg_rcgr); cfg &= ~CFG_MASK; cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */
/* Set the divider; HW permits fraction dividers (+0.5), but
for simplicity, we will support integers only */ if (div)
cfg |= (2 * div - 1) & CFG_DIVIDER_MASK;
cfg |= div & CFG_DIVIDER_MASK; if (n_val) cfg |= CFG_MODE_DUAL_EDGE;
-- // Caleb (they/them)

Hi Caleb,
On Wed, 25 Oct 2023 at 01:54, Caleb Connolly caleb.connolly@linaro.org wrote:
This series begins making some headway towards cleaning up Qualcomm platform support in u-boot. The following is a rough overview of the changes:
- Move the Qualcomm clock drivers out of mach-snapdragon and into clk/qcom
- Introduce per-platform clock driver configs to decouple Qualcomm platform support from mach-snapdragon targets.
- Add the IPQ4019 clock driver, removing it from mach-ipq40xx and introducing the reset map.
- Merge the qcom reset driver is into clk/qcom and rework it to be compatible with upstream devicetrees.
- A callback model is added so that multiple clock drivers can be compiled in at once.
- SDM845 gains support for enabling/disabling all gate clocks (CBC's) by way of a new "gate_clk" abstraction.
- Preperatory cleanup work is done to simplify the bringup process for new platforms.
Thanks for your cleanup work. You should have at least CCed the board maintainers (board/qualcomm/*/MAINTAINERS). Were you able to test this series on all the existing Qcom platforms supported?
Further details are included in each commit.
I will give this series a review.
The primary goal of this series is to prepare for enabling several new Qualcomm platforms in u-boot as well as additional peripherals, while minimising the amount of copy/pasted board-specific code.
I suppose this series would move us closer to directly importing DTs from Linux. Do you plan to close the remaining gap (serial DT nodes are on top of my head) before adding further platform support?
-Sumit
This series conflicts with a previous series introducing support for the Qualcomm RB2 board [1], I plan to resend this initial support pending acceptance of this series and several other cleanups.
Caleb Connolly (7): clk/qcom: move from mach-snapdragon clk/qcom: add per-platform configs clk/qcom: move ipq4019 driver from mach-ipq40xx clk/qcom: sdm845: add register map for simple gate clocks clk/qcom: use function pointers for enable and set_rate clk/qcom: add mnd_width to clk_rcg_set_rate_mnd() clk/qcom: fix rcg divider value
Konrad Dybcio (1): clk/qcom: handle resets and clocks in one device
arch/arm/Kconfig | 2 + arch/arm/dts/qcom-ipq4019.dtsi | 14 +- arch/arm/dts/qcs404-evb.dts | 19 +- arch/arm/mach-ipq40xx/Makefile | 1 - arch/arm/mach-ipq40xx/clock-ipq4019.c | 88 ------ arch/arm/mach-snapdragon/Kconfig | 4 + arch/arm/mach-snapdragon/Makefile | 5 - arch/arm/mach-snapdragon/clock-sdm845.c | 98 ------- arch/arm/mach-snapdragon/clock-snapdragon.c | 181 ------------ arch/arm/mach-snapdragon/clock-snapdragon.h | 48 ---- .../mach-snapdragon/include/mach/sysmap-sdm845.h | 3 + drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/qcom/Kconfig | 52 ++++ drivers/clk/qcom/Makefile | 10 + .../clk/qcom}/clock-apq8016.c | 41 ++- .../clk/qcom}/clock-apq8096.c | 41 ++- .../reset-qcom.c => clk/qcom/clock-ipq4019.c} | 165 ++++------- drivers/clk/qcom/clock-qcom.c | 303 +++++++++++++++++++++ drivers/clk/qcom/clock-qcom.h | 96 +++++++ .../clk/qcom}/clock-qcs404.c | 97 +++++-- drivers/clk/qcom/clock-sdm845.c | 265 ++++++++++++++++++ drivers/reset/Kconfig | 7 - drivers/reset/Makefile | 1 - 24 files changed, 938 insertions(+), 605 deletions(-)
base-commit: 30d01b582f2274eb8c808026c5fb4c33e9f2210d
// Caleb (they/them)

Hi Sumit,
On 25/10/2023 13:10, Sumit Garg wrote:
Hi Caleb,
On Wed, 25 Oct 2023 at 01:54, Caleb Connolly caleb.connolly@linaro.org wrote:
This series begins making some headway towards cleaning up Qualcomm platform support in u-boot. The following is a rough overview of the changes:
- Move the Qualcomm clock drivers out of mach-snapdragon and into clk/qcom
- Introduce per-platform clock driver configs to decouple Qualcomm platform support from mach-snapdragon targets.
- Add the IPQ4019 clock driver, removing it from mach-ipq40xx and introducing the reset map.
- Merge the qcom reset driver is into clk/qcom and rework it to be compatible with upstream devicetrees.
- A callback model is added so that multiple clock drivers can be compiled in at once.
- SDM845 gains support for enabling/disabling all gate clocks (CBC's) by way of a new "gate_clk" abstraction.
- Preperatory cleanup work is done to simplify the bringup process for new platforms.
Thanks for your cleanup work. You should have at least CCed the board maintainers (board/qualcomm/*/MAINTAINERS). Were you able to test this series on all the existing Qcom platforms supported?
Ah! I thought I had done but it seems not :/. Added them in now.
I have only been able to test this series on db845c. I don't have access to qcs404, and no easy access to db820c or db410c (I'm unsure to what extent those two boards work at all with current upstream u-boot).
I should have included this in the cover letter.
Further details are included in each commit.
I will give this series a review.
Thank you!
The primary goal of this series is to prepare for enabling several new Qualcomm platforms in u-boot as well as additional peripherals, while minimising the amount of copy/pasted board-specific code.
I suppose this series would move us closer to directly importing DTs from Linux. Do you plan to close the remaining gap (serial DT nodes are on top of my head) before adding further platform support?
Yes, I currently have patches to move pinctrl out of mach-snapdragon and fix support for upstream DT there, as well as fixes for a number of other drivers. The plan is then to import sdm845 devicetree from Linux and adjust db845c and starqltechn to use it. The three new platforms (QCM2290, SM6115 and SM8250) will all use upstream devicetree.
-Sumit
This series conflicts with a previous series introducing support for the Qualcomm RB2 board [1], I plan to resend this initial support pending acceptance of this series and several other cleanups.
Caleb Connolly (7): clk/qcom: move from mach-snapdragon clk/qcom: add per-platform configs clk/qcom: move ipq4019 driver from mach-ipq40xx clk/qcom: sdm845: add register map for simple gate clocks clk/qcom: use function pointers for enable and set_rate clk/qcom: add mnd_width to clk_rcg_set_rate_mnd() clk/qcom: fix rcg divider value
Konrad Dybcio (1): clk/qcom: handle resets and clocks in one device
arch/arm/Kconfig | 2 + arch/arm/dts/qcom-ipq4019.dtsi | 14 +- arch/arm/dts/qcs404-evb.dts | 19 +- arch/arm/mach-ipq40xx/Makefile | 1 - arch/arm/mach-ipq40xx/clock-ipq4019.c | 88 ------ arch/arm/mach-snapdragon/Kconfig | 4 + arch/arm/mach-snapdragon/Makefile | 5 - arch/arm/mach-snapdragon/clock-sdm845.c | 98 ------- arch/arm/mach-snapdragon/clock-snapdragon.c | 181 ------------ arch/arm/mach-snapdragon/clock-snapdragon.h | 48 ---- .../mach-snapdragon/include/mach/sysmap-sdm845.h | 3 + drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/qcom/Kconfig | 52 ++++ drivers/clk/qcom/Makefile | 10 + .../clk/qcom}/clock-apq8016.c | 41 ++- .../clk/qcom}/clock-apq8096.c | 41 ++- .../reset-qcom.c => clk/qcom/clock-ipq4019.c} | 165 ++++------- drivers/clk/qcom/clock-qcom.c | 303 +++++++++++++++++++++ drivers/clk/qcom/clock-qcom.h | 96 +++++++ .../clk/qcom}/clock-qcs404.c | 97 +++++-- drivers/clk/qcom/clock-sdm845.c | 265 ++++++++++++++++++ drivers/reset/Kconfig | 7 - drivers/reset/Makefile | 1 - 24 files changed, 938 insertions(+), 605 deletions(-)
base-commit: 30d01b582f2274eb8c808026c5fb4c33e9f2210d
// Caleb (they/them)

On Wed, 25 Oct 2023 at 18:17, Caleb Connolly caleb.connolly@linaro.org wrote:
Hi Sumit,
On 25/10/2023 13:10, Sumit Garg wrote:
Hi Caleb,
On Wed, 25 Oct 2023 at 01:54, Caleb Connolly caleb.connolly@linaro.org wrote:
This series begins making some headway towards cleaning up Qualcomm platform support in u-boot. The following is a rough overview of the changes:
- Move the Qualcomm clock drivers out of mach-snapdragon and into clk/qcom
- Introduce per-platform clock driver configs to decouple Qualcomm platform support from mach-snapdragon targets.
- Add the IPQ4019 clock driver, removing it from mach-ipq40xx and introducing the reset map.
- Merge the qcom reset driver is into clk/qcom and rework it to be compatible with upstream devicetrees.
- A callback model is added so that multiple clock drivers can be compiled in at once.
- SDM845 gains support for enabling/disabling all gate clocks (CBC's) by way of a new "gate_clk" abstraction.
- Preperatory cleanup work is done to simplify the bringup process for new platforms.
Thanks for your cleanup work. You should have at least CCed the board maintainers (board/qualcomm/*/MAINTAINERS). Were you able to test this series on all the existing Qcom platforms supported?
Ah! I thought I had done but it seems not :/. Added them in now.
I have only been able to test this series on db845c. I don't have access to qcs404, and no easy access to db820c or db410c (I'm unsure to what extent those two boards work at all with current upstream u-boot).
I can help to test on qcs404 and db410c (I have tested it recently so it should work).
Jorge,
Do you still maintain db820c and can help with testing?
I should have included this in the cover letter.
Further details are included in each commit.
I will give this series a review.
Thank you!
The primary goal of this series is to prepare for enabling several new Qualcomm platforms in u-boot as well as additional peripherals, while minimising the amount of copy/pasted board-specific code.
I suppose this series would move us closer to directly importing DTs from Linux. Do you plan to close the remaining gap (serial DT nodes are on top of my head) before adding further platform support?
Yes, I currently have patches to move pinctrl out of mach-snapdragon and fix support for upstream DT there, as well as fixes for a number of other drivers. The plan is then to import sdm845 devicetree from Linux and adjust db845c and starqltechn to use it. The three new platforms (QCM2290, SM6115 and SM8250) will all use upstream devicetree.
Good to see that coming.
-Sumit
This series conflicts with a previous series introducing support for the Qualcomm RB2 board [1], I plan to resend this initial support pending acceptance of this series and several other cleanups.
Caleb Connolly (7): clk/qcom: move from mach-snapdragon clk/qcom: add per-platform configs clk/qcom: move ipq4019 driver from mach-ipq40xx clk/qcom: sdm845: add register map for simple gate clocks clk/qcom: use function pointers for enable and set_rate clk/qcom: add mnd_width to clk_rcg_set_rate_mnd() clk/qcom: fix rcg divider value
Konrad Dybcio (1): clk/qcom: handle resets and clocks in one device
arch/arm/Kconfig | 2 + arch/arm/dts/qcom-ipq4019.dtsi | 14 +- arch/arm/dts/qcs404-evb.dts | 19 +- arch/arm/mach-ipq40xx/Makefile | 1 - arch/arm/mach-ipq40xx/clock-ipq4019.c | 88 ------ arch/arm/mach-snapdragon/Kconfig | 4 + arch/arm/mach-snapdragon/Makefile | 5 - arch/arm/mach-snapdragon/clock-sdm845.c | 98 ------- arch/arm/mach-snapdragon/clock-snapdragon.c | 181 ------------ arch/arm/mach-snapdragon/clock-snapdragon.h | 48 ---- .../mach-snapdragon/include/mach/sysmap-sdm845.h | 3 + drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/qcom/Kconfig | 52 ++++ drivers/clk/qcom/Makefile | 10 + .../clk/qcom}/clock-apq8016.c | 41 ++- .../clk/qcom}/clock-apq8096.c | 41 ++- .../reset-qcom.c => clk/qcom/clock-ipq4019.c} | 165 ++++------- drivers/clk/qcom/clock-qcom.c | 303 +++++++++++++++++++++ drivers/clk/qcom/clock-qcom.h | 96 +++++++ .../clk/qcom}/clock-qcs404.c | 97 +++++-- drivers/clk/qcom/clock-sdm845.c | 265 ++++++++++++++++++ drivers/reset/Kconfig | 7 - drivers/reset/Makefile | 1 - 24 files changed, 938 insertions(+), 605 deletions(-)
base-commit: 30d01b582f2274eb8c808026c5fb4c33e9f2210d
// Caleb (they/them)
-- // Caleb (they/them)
participants (2)
-
Caleb Connolly
-
Sumit Garg