[PATCH v4 03/14] clk: qcom: Add CPU clock driver for msm8996
From: Rajendra NayakEach of the CPU clusters (Power and Perf) on msm8996 are clocked via 2 PLLs, a primary and alternate. There are also 2 Mux'es, a primary and secondary all connected together as shown below +---+ XO | | +-->0 | | | PLL/2 | SMUX ++ +--->1 || | | || | +---+|+---+ |+>0 | | | | +---+| +--->1 | CPU clk |Primary PLL++ PLL_EARLY | | +--> | +--+---++-->2 PMUX | +---+ || | | | +--+ | +-->3 | +--^+ ACD +-+ | +---+ +---+ +--+ | |Alt PLL| | | +---+ +---+ PLL_EARLY The primary PLL is what drives the CPU clk, except for times when we are reprogramming the PLL itself (for rate changes) when we temporarily switch to an alternate PLL. A subsequent patch adds support to switch between primary and alternate PLL during rate changes. The primary PLL operates on a single VCO range, between 600MHz and 3GHz. However the CPUs do support OPPs with frequencies between 300MHz and 600MHz. In order to support running the CPUs at those frequencies we end up having to lock the PLL at twice the rate and drive the CPU clk via the PLL/2 output and SMUX. So for frequencies above 600MHz we follow the following path Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk and for frequencies between 300MHz and 600MHz we follow Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk Support for this is added in a subsequent patch as well. ACD stands for Adaptive Clock Distribution and is used to detect voltage droops. We do not add support for ACD as yet. Signed-off-by: Rajendra Nayak Signed-off-by: Ilia Lin --- drivers/clk/clk-fixed-factor.c | 2 +- drivers/clk/qcom/Kconfig | 8 + drivers/clk/qcom/Makefile| 1 + drivers/clk/qcom/clk-alpha-pll.h | 6 + drivers/clk/qcom/clk-cpu-8996.c | 413 +++ 5 files changed, 429 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/qcom/clk-cpu-8996.c diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index a5d402d..8e39bda 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -94,7 +94,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, init.num_parents = 1; hw = >hw; - ret = clk_hw_register(dev, hw); + ret = devm_clk_hw_register(dev, hw); if (ret) { kfree(fix); hw = ERR_PTR(ret); diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index fbf4532..e204471 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -33,6 +33,14 @@ config QCOM_CLK_APCS_MSM8916 Say Y if you want to support CPU frequency scaling on devices such as msm8916. +config QCOM_CLK_APCC_MSM8996 + tristate "MSM8996 CPU Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the CPU clock controller on msm8996 devices. + Say Y if you want to support CPU clock scaling using CPUfreq + drivers for dyanmic power management. + config QCOM_CLK_RPM tristate "RPM based Clock Controller" depends on COMMON_CLK_QCOM && MFD_QCOM_RPM diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 230332c..f037e16 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o +obj-$(CONFIG_QCOM_CLK_APCC_MSM8996) += clk-cpu-8996.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 7593e8a..0a0d59d 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -47,6 +47,12 @@ struct pll_vco { u32 val; }; +#define VCO(a, b, c) { \ + .val = a,\ + .min_freq = b,\ + .max_freq = c,\ +} + /** * struct clk_alpha_pll - phase locked loop (PLL) * @offset: base address of registers diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c new file mode 100644
[PATCH v4 03/14] clk: qcom: Add CPU clock driver for msm8996
From: Rajendra Nayak Each of the CPU clusters (Power and Perf) on msm8996 are clocked via 2 PLLs, a primary and alternate. There are also 2 Mux'es, a primary and secondary all connected together as shown below +---+ XO | | +-->0 | | | PLL/2 | SMUX ++ +--->1 || | | || | +---+|+---+ |+>0 | | | | +---+| +--->1 | CPU clk |Primary PLL++ PLL_EARLY | | +--> | +--+---++-->2 PMUX | +---+ || | | | +--+ | +-->3 | +--^+ ACD +-+ | +---+ +---+ +--+ | |Alt PLL| | | +---+ +---+ PLL_EARLY The primary PLL is what drives the CPU clk, except for times when we are reprogramming the PLL itself (for rate changes) when we temporarily switch to an alternate PLL. A subsequent patch adds support to switch between primary and alternate PLL during rate changes. The primary PLL operates on a single VCO range, between 600MHz and 3GHz. However the CPUs do support OPPs with frequencies between 300MHz and 600MHz. In order to support running the CPUs at those frequencies we end up having to lock the PLL at twice the rate and drive the CPU clk via the PLL/2 output and SMUX. So for frequencies above 600MHz we follow the following path Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk and for frequencies between 300MHz and 600MHz we follow Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk Support for this is added in a subsequent patch as well. ACD stands for Adaptive Clock Distribution and is used to detect voltage droops. We do not add support for ACD as yet. Signed-off-by: Rajendra Nayak Signed-off-by: Ilia Lin --- drivers/clk/clk-fixed-factor.c | 2 +- drivers/clk/qcom/Kconfig | 8 + drivers/clk/qcom/Makefile| 1 + drivers/clk/qcom/clk-alpha-pll.h | 6 + drivers/clk/qcom/clk-cpu-8996.c | 413 +++ 5 files changed, 429 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/qcom/clk-cpu-8996.c diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index a5d402d..8e39bda 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -94,7 +94,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, init.num_parents = 1; hw = >hw; - ret = clk_hw_register(dev, hw); + ret = devm_clk_hw_register(dev, hw); if (ret) { kfree(fix); hw = ERR_PTR(ret); diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index fbf4532..e204471 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -33,6 +33,14 @@ config QCOM_CLK_APCS_MSM8916 Say Y if you want to support CPU frequency scaling on devices such as msm8916. +config QCOM_CLK_APCC_MSM8996 + tristate "MSM8996 CPU Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the CPU clock controller on msm8996 devices. + Say Y if you want to support CPU clock scaling using CPUfreq + drivers for dyanmic power management. + config QCOM_CLK_RPM tristate "RPM based Clock Controller" depends on COMMON_CLK_QCOM && MFD_QCOM_RPM diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 230332c..f037e16 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o +obj-$(CONFIG_QCOM_CLK_APCC_MSM8996) += clk-cpu-8996.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 7593e8a..0a0d59d 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -47,6 +47,12 @@ struct pll_vco { u32 val; }; +#define VCO(a, b, c) { \ + .val = a,\ + .min_freq = b,\ + .max_freq = c,\ +} + /** * struct clk_alpha_pll - phase locked loop (PLL) * @offset: base address of registers diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c new file mode 100644 index 000..f096410 --- /dev/null +++