[PATCH v3 4/4] clk: qcom: Add graphics clock controller driver for SDM845
Add support for the graphics clock controller found on SDM845 based devices. This would allow graphics drivers to probe and control their clocks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/Kconfig| 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-sdm845.c | 438 3 files changed, 448 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 0647686..1595464 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -244,6 +244,15 @@ config SDM_GCC_845 Say Y if you want to use peripheral devices such as UART, SPI, i2C, USB, UFS, SDDC, PCIe, etc. +config SDM_GPUCC_845 + tristate "SDM845 Graphics Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + help + Support for the graphics clock controller on SDM845 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config SDM_VIDEOCC_845 tristate "SDM845 Video Clock Controller" depends on COMMON_CLK_QCOM diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index c4ed36f..93c1089 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -42,5 +42,6 @@ obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o +obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c new file mode 100644 index 000..7a11b70 --- /dev/null +++ b/drivers/clk/qcom/gpucc-sdm845.c @@ -0,0 +1,438 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +#define CX_GMU_CBCR_SLEEP_MASK 0xf +#define CX_GMU_CBCR_SLEEP_SHIFT4 +#define CX_GMU_CBCR_WAKE_MASK 0xf +#define CX_GMU_CBCR_WAKE_SHIFT 8 +#define CLK_DIS_WAIT_SHIFT 12 +#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) + +enum { + P_BI_TCXO, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL0_OUT_EVEN, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL0_OUT_ODD, + P_GPU_CC_PLL1_OUT_EVEN, + P_GPU_CC_PLL1_OUT_MAIN, + P_GPU_CC_PLL1_OUT_ODD, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gpu_cc_parent_names_0[] = { + "bi_tcxo", + "gpu_cc_pll0", + "gpu_cc_pll1", + "gcc_gpu_gpll0_clk_src", + "gcc_gpu_gpll0_div_clk_src", + "core_bi_pll_test_se", +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_EVEN, 1 }, + { P_GPU_CC_PLL0_OUT_ODD, 2 }, + { P_GPU_CC_PLL1_OUT_EVEN, 3 }, + { P_GPU_CC_PLL1_OUT_ODD, 4 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gpu_cc_parent_names_1[] = { + "bi_tcxo", + "gpu_cc_pll0_out_even", + "gpu_cc_pll0_out_odd", + "gpu_cc_pll1_out_even", + "gpu_cc_pll1_out_odd", + "gcc_gpu_gpll0_clk_src", + "core_bi_pll_test_se", +}; + +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x1d, + .alpha = 0x2aaa, +}; + +static const struct alpha_pll_config gpu_cc_pll1_config = { + .l = 0x1a, + .alpha = 0xaab, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, +}; + +static struct clk_alpha_pll_postd
[PATCH v3 4/4] clk: qcom: Add graphics clock controller driver for SDM845
Add support for the graphics clock controller found on SDM845 based devices. This would allow graphics drivers to probe and control their clocks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/Kconfig| 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-sdm845.c | 438 3 files changed, 448 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 0647686..1595464 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -244,6 +244,15 @@ config SDM_GCC_845 Say Y if you want to use peripheral devices such as UART, SPI, i2C, USB, UFS, SDDC, PCIe, etc. +config SDM_GPUCC_845 + tristate "SDM845 Graphics Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + help + Support for the graphics clock controller on SDM845 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config SDM_VIDEOCC_845 tristate "SDM845 Video Clock Controller" depends on COMMON_CLK_QCOM diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index c4ed36f..93c1089 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -42,5 +42,6 @@ obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o +obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c new file mode 100644 index 000..7a11b70 --- /dev/null +++ b/drivers/clk/qcom/gpucc-sdm845.c @@ -0,0 +1,438 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +#define CX_GMU_CBCR_SLEEP_MASK 0xf +#define CX_GMU_CBCR_SLEEP_SHIFT4 +#define CX_GMU_CBCR_WAKE_MASK 0xf +#define CX_GMU_CBCR_WAKE_SHIFT 8 +#define CLK_DIS_WAIT_SHIFT 12 +#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) + +enum { + P_BI_TCXO, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL0_OUT_EVEN, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL0_OUT_ODD, + P_GPU_CC_PLL1_OUT_EVEN, + P_GPU_CC_PLL1_OUT_MAIN, + P_GPU_CC_PLL1_OUT_ODD, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gpu_cc_parent_names_0[] = { + "bi_tcxo", + "gpu_cc_pll0", + "gpu_cc_pll1", + "gcc_gpu_gpll0_clk_src", + "gcc_gpu_gpll0_div_clk_src", + "core_bi_pll_test_se", +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_EVEN, 1 }, + { P_GPU_CC_PLL0_OUT_ODD, 2 }, + { P_GPU_CC_PLL1_OUT_EVEN, 3 }, + { P_GPU_CC_PLL1_OUT_ODD, 4 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gpu_cc_parent_names_1[] = { + "bi_tcxo", + "gpu_cc_pll0_out_even", + "gpu_cc_pll0_out_odd", + "gpu_cc_pll1_out_even", + "gpu_cc_pll1_out_odd", + "gcc_gpu_gpll0_clk_src", + "core_bi_pll_test_se", +}; + +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x1d, + .alpha = 0x2aaa, +}; + +static const struct alpha_pll_config gpu_cc_pll1_config = { + .l = 0x1a, + .alpha = 0xaab, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, +}; + +static struct clk_alpha_pll_postd
[PATCH v3 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings
Add device tree bindings for graphics clock controller for Qualcomm Technology Inc's SDM845 SoCs. Signed-off-by: Amit Nischal --- .../devicetree/bindings/clock/qcom,gpucc.txt | 18 ++ include/dt-bindings/clock/qcom,gpucc-sdm845.h | 38 ++ 2 files changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc.txt create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt new file mode 100644 index 000..93752db --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt @@ -0,0 +1,18 @@ +Qualcomm Graphics Clock & Reset Controller Binding +-- + +Required properties : +- compatible : shall contain "qcom,sdm845-gpucc". +- reg : shall contain base register location and length. +- #clock-cells : from common clock binding, shall contain 1. +- #reset-cells : from common reset binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Example: + gpucc: clock-controller@509 { + compatible = "qcom,sdm845-gpucc"; + reg = <0x509 0x9000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/clock/qcom,gpucc-sdm845.h b/include/dt-bindings/clock/qcom,gpucc-sdm845.h new file mode 100644 index 000..643b42a --- /dev/null +++ b/include/dt-bindings/clock/qcom,gpucc-sdm845.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H +#define _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H + +/* GPU_CC clock registers */ +#define GPU_CC_CRC_AHB_CLK 0 +#define GPU_CC_CX_APB_CLK 1 +#define GPU_CC_CX_GFX3D_CLK2 +#define GPU_CC_CX_GFX3D_SLV_CLK3 +#define GPU_CC_CX_GMU_CLK 4 +#define GPU_CC_CX_SNOC_DVM_CLK 5 +#define GPU_CC_CXO_CLK 6 +#define GPU_CC_GMU_CLK_SRC 7 +#define GPU_CC_GX_GMU_CLK 8 +#define GPU_CC_GX_GFX3D_CLK_SRC9 +#define GPU_CC_GX_GFX3D_CLK10 +#define GPU_CC_PLL011 +#define GPU_CC_PLL0_OUT_EVEN 12 +#define GPU_CC_PLL113 + +/* GPU_CC Resets */ +#define GPUCC_GPU_CC_ACD_BCR 0 +#define GPUCC_GPU_CC_CX_BCR1 +#define GPUCC_GPU_CC_GFX3D_AON_BCR 2 +#define GPUCC_GPU_CC_GMU_BCR 3 +#define GPUCC_GPU_CC_GX_BCR4 +#define GPUCC_GPU_CC_SPDM_BCR 5 +#define GPUCC_GPU_CC_XO_BCR6 + +/* GPU_CC GDSCRs */ +#define GPU_CX_GDSC0 +#define GPU_GX_GDSC1 + +#endif -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings
Add device tree bindings for graphics clock controller for Qualcomm Technology Inc's SDM845 SoCs. Signed-off-by: Amit Nischal --- .../devicetree/bindings/clock/qcom,gpucc.txt | 18 ++ include/dt-bindings/clock/qcom,gpucc-sdm845.h | 38 ++ 2 files changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc.txt create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt new file mode 100644 index 000..93752db --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt @@ -0,0 +1,18 @@ +Qualcomm Graphics Clock & Reset Controller Binding +-- + +Required properties : +- compatible : shall contain "qcom,sdm845-gpucc". +- reg : shall contain base register location and length. +- #clock-cells : from common clock binding, shall contain 1. +- #reset-cells : from common reset binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Example: + gpucc: clock-controller@509 { + compatible = "qcom,sdm845-gpucc"; + reg = <0x509 0x9000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/clock/qcom,gpucc-sdm845.h b/include/dt-bindings/clock/qcom,gpucc-sdm845.h new file mode 100644 index 000..643b42a --- /dev/null +++ b/include/dt-bindings/clock/qcom,gpucc-sdm845.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H +#define _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H + +/* GPU_CC clock registers */ +#define GPU_CC_CRC_AHB_CLK 0 +#define GPU_CC_CX_APB_CLK 1 +#define GPU_CC_CX_GFX3D_CLK2 +#define GPU_CC_CX_GFX3D_SLV_CLK3 +#define GPU_CC_CX_GMU_CLK 4 +#define GPU_CC_CX_SNOC_DVM_CLK 5 +#define GPU_CC_CXO_CLK 6 +#define GPU_CC_GMU_CLK_SRC 7 +#define GPU_CC_GX_GMU_CLK 8 +#define GPU_CC_GX_GFX3D_CLK_SRC9 +#define GPU_CC_GX_GFX3D_CLK10 +#define GPU_CC_PLL011 +#define GPU_CC_PLL0_OUT_EVEN 12 +#define GPU_CC_PLL113 + +/* GPU_CC Resets */ +#define GPUCC_GPU_CC_ACD_BCR 0 +#define GPUCC_GPU_CC_CX_BCR1 +#define GPUCC_GPU_CC_GFX3D_AON_BCR 2 +#define GPUCC_GPU_CC_GMU_BCR 3 +#define GPUCC_GPU_CC_GX_BCR4 +#define GPUCC_GPU_CC_SPDM_BCR 5 +#define GPUCC_GPU_CC_XO_BCR6 + +/* GPU_CC GDSCRs */ +#define GPU_CX_GDSC0 +#define GPU_GX_GDSC1 + +#endif -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 1/4] clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
For some of the GDSCs, there is a requirement to enable/disable the few clocks before turning on/off the gdsc power domain. Add support for the same by specifying a list of clk_hw pointers per gdsc and enable/disable them along with power domain on/off callbacks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/gdsc.c | 44 drivers/clk/qcom/gdsc.h | 5 + 2 files changed, 49 insertions(+) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index a077133..b6adca1 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -12,6 +12,8 @@ */ #include +#include +#include #include #include #include @@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc) regmap_update_bits(sc->regmap, sc->clamp_io_ctrl, GMEM_RESET_MASK, 0); } + +static int gdsc_clk_prepare_enable(struct gdsc *sc) +{ + int i, ret; + + for (i = 0; i < sc->clk_count; i++) { + ret = clk_prepare_enable(sc->clk_hws[i]->clk); + if (ret) { + for (i--; i >= 0; i--) + clk_disable_unprepare(sc->clk_hws[i]->clk); + return ret; + } + } + return 0; +} + +static void gdsc_clk_disable_unprepare(struct gdsc *sc) +{ + int i; + + for (i = 0; i < sc->clk_count; i++) + clk_disable_unprepare(sc->clk_hws[i]->clk); +} + static int gdsc_enable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); int ret; + if (sc->clk_count) { + ret = gdsc_clk_prepare_enable(sc); + if (ret) + return ret; + } + if (sc->pwrsts == PWRSTS_ON) return gdsc_deassert_reset(sc); @@ -260,6 +292,9 @@ static int gdsc_enable(struct generic_pm_domain *domain) udelay(1); } + if (sc->clk_count) + gdsc_clk_disable_unprepare(sc); + return 0; } @@ -268,6 +303,12 @@ static int gdsc_disable(struct generic_pm_domain *domain) struct gdsc *sc = domain_to_gdsc(domain); int ret; + if (sc->clk_count) { + ret = gdsc_clk_prepare_enable(sc); + if (ret) + return ret; + } + if (sc->pwrsts == PWRSTS_ON) return gdsc_assert_reset(sc); @@ -299,6 +340,9 @@ static int gdsc_disable(struct generic_pm_domain *domain) if (sc->flags & CLAMP_IO) gdsc_assert_clamp_io(sc); + if (sc->clk_count) + gdsc_clk_disable_unprepare(sc); + return 0; } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index bd1f2c7..59957d7 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -17,6 +17,7 @@ #include #include +struct clk_hw; struct regmap; struct reset_controller_dev; @@ -32,6 +33,8 @@ * @resets: ids of resets associated with this gdsc * @reset_count: number of @resets * @rcdev: reset controller + * @clk_count: number of associated clocks + * @clk_hws: clk_hw pointers for associated clocks with gdsc */ struct gdsc { struct generic_pm_domainpd; @@ -60,6 +63,8 @@ struct gdsc { struct reset_controller_dev *rcdev; unsigned int*resets; unsigned intreset_count; + unsigned intclk_count; + struct clk_hw *clk_hws[]; }; struct gdsc_desc { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 1/4] clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
For some of the GDSCs, there is a requirement to enable/disable the few clocks before turning on/off the gdsc power domain. Add support for the same by specifying a list of clk_hw pointers per gdsc and enable/disable them along with power domain on/off callbacks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/gdsc.c | 44 drivers/clk/qcom/gdsc.h | 5 + 2 files changed, 49 insertions(+) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index a077133..b6adca1 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -12,6 +12,8 @@ */ #include +#include +#include #include #include #include @@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc) regmap_update_bits(sc->regmap, sc->clamp_io_ctrl, GMEM_RESET_MASK, 0); } + +static int gdsc_clk_prepare_enable(struct gdsc *sc) +{ + int i, ret; + + for (i = 0; i < sc->clk_count; i++) { + ret = clk_prepare_enable(sc->clk_hws[i]->clk); + if (ret) { + for (i--; i >= 0; i--) + clk_disable_unprepare(sc->clk_hws[i]->clk); + return ret; + } + } + return 0; +} + +static void gdsc_clk_disable_unprepare(struct gdsc *sc) +{ + int i; + + for (i = 0; i < sc->clk_count; i++) + clk_disable_unprepare(sc->clk_hws[i]->clk); +} + static int gdsc_enable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); int ret; + if (sc->clk_count) { + ret = gdsc_clk_prepare_enable(sc); + if (ret) + return ret; + } + if (sc->pwrsts == PWRSTS_ON) return gdsc_deassert_reset(sc); @@ -260,6 +292,9 @@ static int gdsc_enable(struct generic_pm_domain *domain) udelay(1); } + if (sc->clk_count) + gdsc_clk_disable_unprepare(sc); + return 0; } @@ -268,6 +303,12 @@ static int gdsc_disable(struct generic_pm_domain *domain) struct gdsc *sc = domain_to_gdsc(domain); int ret; + if (sc->clk_count) { + ret = gdsc_clk_prepare_enable(sc); + if (ret) + return ret; + } + if (sc->pwrsts == PWRSTS_ON) return gdsc_assert_reset(sc); @@ -299,6 +340,9 @@ static int gdsc_disable(struct generic_pm_domain *domain) if (sc->flags & CLAMP_IO) gdsc_assert_clamp_io(sc); + if (sc->clk_count) + gdsc_clk_disable_unprepare(sc); + return 0; } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index bd1f2c7..59957d7 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -17,6 +17,7 @@ #include #include +struct clk_hw; struct regmap; struct reset_controller_dev; @@ -32,6 +33,8 @@ * @resets: ids of resets associated with this gdsc * @reset_count: number of @resets * @rcdev: reset controller + * @clk_count: number of associated clocks + * @clk_hws: clk_hw pointers for associated clocks with gdsc */ struct gdsc { struct generic_pm_domainpd; @@ -60,6 +63,8 @@ struct gdsc { struct reset_controller_dev *rcdev; unsigned int*resets; unsigned intreset_count; + unsigned intclk_count; + struct clk_hw *clk_hws[]; }; struct gdsc_desc { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 0/4] Add QCOM graphics clock controller driver for SDM845
Changes in v3: * Modified the determine_rate() op to use the min/max rate range to round the requested rate within the set_rate range. With this, requested set rate will always stay within the limits. Changes in v2: Addressed review comments given by Stephen: https://lkml.org/lkml/2018/6/6/294 * Introduce clk_rcg2_gfx3d_determine_rate ops to return the best parent as 'gpucc_pll0_even' and best parent rate as twice of the requested rate always. This will eliminate the need of frequency table as source and div-2 are fixed for gfx3d_clk_src. Also modified the clk_rcg2_set_rate ops to configure the fixed source and div. * Add support to check if requested rate falls within allowed set_rate range. This will not let the source gpucc_pll0 to go out of the supported range and also client can request the rate within the range. * Fixed comment text in probe function and added module description for GPUCC driver. The graphics clock driver depends upon the below change. https://lkml.org/lkml/2018/6/23/108 Changes in v1: This patch series adds support for graphics clock controller for SDM845. Below is the brief description for each change: 1. For some of the GDSCs, there is requirement to enable/disable the few clocks before turning on/off the gdsc power domain. This patch will add support to enable/disable the clock associated with the gdsc along with power domain on/off callbacks. 2. To turn on the gpu_gx_gdsc, there is a hardware requirement to turn on the root clock (GFX3D RCG) first which would be the turn on signal for the gdsc along with the SW_COLLAPSE. As per the current implementation of clk_rcg2_shared_ops, it clears the root_enable bit in the enable() clock ops. But due to the above said requirement for GFX3D shared RCG, root_enable bit would be already set by gdsc driver and rcg2_shared_ops should not clear the root unless the disable() is called. This patch add support for the same by reusing the existing clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to take care of the root set/clear requirement. 3. Add device tree bindings for graphics clock controller for SDM845. 4. Add graphics clock controller (GPUCC) driver for SDM845. [v1] : https://lore.kernel.org/patchwork/project/lkml/list/?series=348697 [v2] : https://lore.kernel.org/patchwork/project/lkml/list/?series=359012 Amit Nischal (4): clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845 dt-bindings: clock: Introduce QCOM Graphics clock bindings clk: qcom: Add graphics clock controller driver for SDM845 .../devicetree/bindings/clock/qcom,gpucc.txt | 18 + drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c| 86 +++- drivers/clk/qcom/gdsc.c| 44 +++ drivers/clk/qcom/gdsc.h| 5 + drivers/clk/qcom/gpucc-sdm845.c| 438 + include/dt-bindings/clock/qcom,gpucc-sdm845.h | 38 ++ 9 files changed, 638 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc.txt create mode 100644 drivers/clk/qcom/gpucc-sdm845.c create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm845.h -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
To turn on the gpu_gx_gdsc, there is a hardware requirement to turn on the root clock (GFX3D RCG) first which would be the turn on signal for the gdsc along with the SW_COLLAPSE. As per the current implementation of clk_rcg2_shared_ops, it clears the root_enable bit in the enable() clock op. But due to the above said requirement for GFX3D shared RCG, root_enable bit would be already set by gdsc driver and clk_rcg2_shared_enable()should not clear the root unless the disable is called. Add support for the same by reusing the existing clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to take care of the root set/clear requirement. Signed-off-by: Amit Nischal --- drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c | 86 +++-- 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index dbd5a9e..081eca9 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -162,5 +162,6 @@ struct clk_rcg2 { extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_rcg2_shared_ops; +extern const struct clk_ops clk_rcg2_gfx3d_ops; #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 52208d4..a57ce00 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -866,7 +866,7 @@ static int clk_rcg2_shared_set_rate_and_parent(struct clk_hw *hw, return clk_rcg2_shared_set_rate(hw, rate, parent_rate); } -static int clk_rcg2_shared_enable(struct clk_hw *hw) +static int __clk_rcg2_shared_enable(struct clk_hw *hw) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); int ret; @@ -879,7 +879,14 @@ static int clk_rcg2_shared_enable(struct clk_hw *hw) if (ret) return ret; - ret = update_config(rcg); + return update_config(rcg); +} + +static int clk_rcg2_shared_enable(struct clk_hw *hw) +{ + int ret; + + ret = __clk_rcg2_shared_enable(hw); if (ret) return ret; @@ -929,3 +936,78 @@ static void clk_rcg2_shared_disable(struct clk_hw *hw) .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent, }; EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); + +static int clk_rcg2_gfx3d_enable(struct clk_hw *hw) +{ + return __clk_rcg2_shared_enable(hw); +} + +static int clk_rcg2_gfx3d_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_rate_request parent_req = { }; + struct clk_hw *p; + unsigned long rate = req->rate; + int ret; + + rate = clamp(rate, req->min_rate, req->max_rate); + + /* Get fixed parent - GPU_CC_PLL0_OUT_EVEN */ + p = clk_hw_get_parent_by_index(hw, 1); + + /* Parent should always run at twice of the requested rate */ + parent_req.rate = 2 * rate; + + ret = __clk_determine_rate(req->best_parent_hw, _req); + if (ret) + return ret; + + req->best_parent_hw = p; + req->best_parent_rate = parent_req.rate; + req->rate = parent_req.rate / 2; + + return 0; +} + +static int clk_rcg2_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + int ret; + u32 cfg; + + /* Configure fixed SRC and DIV */ + cfg = rcg->parent_map[1].cfg << CFG_SRC_SEL_SHIFT; + cfg |= 0x3 << CFG_SRC_DIV_SHIFT; + + ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg); + if (ret) + return ret; + + /* +* In case clock is disabled, update the SRC and DIV only +* and return without configuration update. +*/ + if (!__clk_is_enabled(hw->clk)) + return 0; + + return update_config(rcg); +} + +static int clk_rcg2_gfx3d_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate, u8 index) +{ + return clk_rcg2_gfx3d_set_rate(hw, rate, parent_rate); +} + +const struct clk_ops clk_rcg2_gfx3d_ops = { + .enable = clk_rcg2_gfx3d_enable, + .disable = clk_rcg2_shared_disable, + .get_parent = clk_rcg2_get_parent, + .set_parent = clk_rcg2_set_parent, + .recalc_rate = clk_rcg2_recalc_rate, + .determine_rate = clk_rcg2_gfx3d_determine_rate, + .set_rate = clk_rcg2_gfx3d_set_rate, + .set_rate_and_parent = clk_rcg2_gfx3d_set_rate_and_parent, +}; +EXPORT_SYMBOL_GPL(clk_rcg2_gfx3d_ops); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 0/4] Add QCOM graphics clock controller driver for SDM845
Changes in v3: * Modified the determine_rate() op to use the min/max rate range to round the requested rate within the set_rate range. With this, requested set rate will always stay within the limits. Changes in v2: Addressed review comments given by Stephen: https://lkml.org/lkml/2018/6/6/294 * Introduce clk_rcg2_gfx3d_determine_rate ops to return the best parent as 'gpucc_pll0_even' and best parent rate as twice of the requested rate always. This will eliminate the need of frequency table as source and div-2 are fixed for gfx3d_clk_src. Also modified the clk_rcg2_set_rate ops to configure the fixed source and div. * Add support to check if requested rate falls within allowed set_rate range. This will not let the source gpucc_pll0 to go out of the supported range and also client can request the rate within the range. * Fixed comment text in probe function and added module description for GPUCC driver. The graphics clock driver depends upon the below change. https://lkml.org/lkml/2018/6/23/108 Changes in v1: This patch series adds support for graphics clock controller for SDM845. Below is the brief description for each change: 1. For some of the GDSCs, there is requirement to enable/disable the few clocks before turning on/off the gdsc power domain. This patch will add support to enable/disable the clock associated with the gdsc along with power domain on/off callbacks. 2. To turn on the gpu_gx_gdsc, there is a hardware requirement to turn on the root clock (GFX3D RCG) first which would be the turn on signal for the gdsc along with the SW_COLLAPSE. As per the current implementation of clk_rcg2_shared_ops, it clears the root_enable bit in the enable() clock ops. But due to the above said requirement for GFX3D shared RCG, root_enable bit would be already set by gdsc driver and rcg2_shared_ops should not clear the root unless the disable() is called. This patch add support for the same by reusing the existing clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to take care of the root set/clear requirement. 3. Add device tree bindings for graphics clock controller for SDM845. 4. Add graphics clock controller (GPUCC) driver for SDM845. [v1] : https://lore.kernel.org/patchwork/project/lkml/list/?series=348697 [v2] : https://lore.kernel.org/patchwork/project/lkml/list/?series=359012 Amit Nischal (4): clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845 dt-bindings: clock: Introduce QCOM Graphics clock bindings clk: qcom: Add graphics clock controller driver for SDM845 .../devicetree/bindings/clock/qcom,gpucc.txt | 18 + drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c| 86 +++- drivers/clk/qcom/gdsc.c| 44 +++ drivers/clk/qcom/gdsc.h| 5 + drivers/clk/qcom/gpucc-sdm845.c| 438 + include/dt-bindings/clock/qcom,gpucc-sdm845.h | 38 ++ 9 files changed, 638 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc.txt create mode 100644 drivers/clk/qcom/gpucc-sdm845.c create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm845.h -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
To turn on the gpu_gx_gdsc, there is a hardware requirement to turn on the root clock (GFX3D RCG) first which would be the turn on signal for the gdsc along with the SW_COLLAPSE. As per the current implementation of clk_rcg2_shared_ops, it clears the root_enable bit in the enable() clock op. But due to the above said requirement for GFX3D shared RCG, root_enable bit would be already set by gdsc driver and clk_rcg2_shared_enable()should not clear the root unless the disable is called. Add support for the same by reusing the existing clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to take care of the root set/clear requirement. Signed-off-by: Amit Nischal --- drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c | 86 +++-- 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index dbd5a9e..081eca9 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -162,5 +162,6 @@ struct clk_rcg2 { extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_rcg2_shared_ops; +extern const struct clk_ops clk_rcg2_gfx3d_ops; #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 52208d4..a57ce00 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -866,7 +866,7 @@ static int clk_rcg2_shared_set_rate_and_parent(struct clk_hw *hw, return clk_rcg2_shared_set_rate(hw, rate, parent_rate); } -static int clk_rcg2_shared_enable(struct clk_hw *hw) +static int __clk_rcg2_shared_enable(struct clk_hw *hw) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); int ret; @@ -879,7 +879,14 @@ static int clk_rcg2_shared_enable(struct clk_hw *hw) if (ret) return ret; - ret = update_config(rcg); + return update_config(rcg); +} + +static int clk_rcg2_shared_enable(struct clk_hw *hw) +{ + int ret; + + ret = __clk_rcg2_shared_enable(hw); if (ret) return ret; @@ -929,3 +936,78 @@ static void clk_rcg2_shared_disable(struct clk_hw *hw) .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent, }; EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); + +static int clk_rcg2_gfx3d_enable(struct clk_hw *hw) +{ + return __clk_rcg2_shared_enable(hw); +} + +static int clk_rcg2_gfx3d_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_rate_request parent_req = { }; + struct clk_hw *p; + unsigned long rate = req->rate; + int ret; + + rate = clamp(rate, req->min_rate, req->max_rate); + + /* Get fixed parent - GPU_CC_PLL0_OUT_EVEN */ + p = clk_hw_get_parent_by_index(hw, 1); + + /* Parent should always run at twice of the requested rate */ + parent_req.rate = 2 * rate; + + ret = __clk_determine_rate(req->best_parent_hw, _req); + if (ret) + return ret; + + req->best_parent_hw = p; + req->best_parent_rate = parent_req.rate; + req->rate = parent_req.rate / 2; + + return 0; +} + +static int clk_rcg2_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + int ret; + u32 cfg; + + /* Configure fixed SRC and DIV */ + cfg = rcg->parent_map[1].cfg << CFG_SRC_SEL_SHIFT; + cfg |= 0x3 << CFG_SRC_DIV_SHIFT; + + ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg); + if (ret) + return ret; + + /* +* In case clock is disabled, update the SRC and DIV only +* and return without configuration update. +*/ + if (!__clk_is_enabled(hw->clk)) + return 0; + + return update_config(rcg); +} + +static int clk_rcg2_gfx3d_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate, u8 index) +{ + return clk_rcg2_gfx3d_set_rate(hw, rate, parent_rate); +} + +const struct clk_ops clk_rcg2_gfx3d_ops = { + .enable = clk_rcg2_gfx3d_enable, + .disable = clk_rcg2_shared_disable, + .get_parent = clk_rcg2_get_parent, + .set_parent = clk_rcg2_set_parent, + .recalc_rate = clk_rcg2_recalc_rate, + .determine_rate = clk_rcg2_gfx3d_determine_rate, + .set_rate = clk_rcg2_gfx3d_set_rate, + .set_rate_and_parent = clk_rcg2_gfx3d_set_rate_and_parent, +}; +EXPORT_SYMBOL_GPL(clk_rcg2_gfx3d_ops); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
On 2018-08-08 11:28, Stephen Boyd wrote: Quoting Jordan Crouse (2018-08-06 08:04:37) On Mon, Aug 06, 2018 at 02:37:18PM +0530, Amit Nischal wrote: > On 2018-08-03 04:14, Stephen Boyd wrote: > >Quoting Amit Nischal (2018-07-30 04:28:56) > >>On 2018-07-25 12:28, Stephen Boyd wrote: > >>> > >>> Ok. Sounds good! Is the rate range call really needed? It can't be > >>> determined in the PLL code with some table or avoided by making sure > >>> GPU > >>> uses OPP table with only approved frequencies? > >>> > >> > >>Currently fabia PLL code does not have any table to check this and > >>intention > >>was to avoid relying on the client to call set_rate with only approved > >>frequencies so we have added the set_rate_range() call in the GPUCC > >>driver > >>in order to set the rate range. > >> > > > >But GPU will use OPP so it doesn't seem like it really buys us anything > >here. And it really doesn't matter when the clk driver implementation > >doesn't use the min/max to clamp the values of the round_rate() > >call. Is > >that being done here? I need to double check. I would be more convinced > >if the implementation was looking at min/max to constrain the rate > >requested. > > > > So our understanding is that GPU(client) driver will always call the > set_rate with approved frequencies only and we can completely rely > on the > client. Is our understanding is correct? First: on sdm845 the software doesn't set the GPU clocks - we rely on the GMU firmware to do that on our behalf but for the GPU at least this is an academic exercise. So what is this GPU clk driver for then? But that said: traditionally we've expected that the clock driver correctly clamp the requested rate to the correct values. In the past we have taken advantage of this and we may in the future. I don't think it is reasonable to require the leaf driver to only pass "approved" frequencies especially since we depend on our own OPP table that may or may not be similar to the one used by the clock driver. Ok. Sounds like things can't be kept in sync between the clk driver and the OPP tables. Why is that hard to do? Either way, I'd be fine if the code actually used the frequency limits to round the rate to something within range, but I don't recall seeing that being done here. So if the min/max limits stay, the clk driver should round to within that range. Thanks Stephen for your suggestion. I have modified the existing determine_rate() op to use the min/max limits and round the requested rate so that it stays withing the set_rate range. I will submit the same in the next patch series. -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
On 2018-08-08 11:28, Stephen Boyd wrote: Quoting Jordan Crouse (2018-08-06 08:04:37) On Mon, Aug 06, 2018 at 02:37:18PM +0530, Amit Nischal wrote: > On 2018-08-03 04:14, Stephen Boyd wrote: > >Quoting Amit Nischal (2018-07-30 04:28:56) > >>On 2018-07-25 12:28, Stephen Boyd wrote: > >>> > >>> Ok. Sounds good! Is the rate range call really needed? It can't be > >>> determined in the PLL code with some table or avoided by making sure > >>> GPU > >>> uses OPP table with only approved frequencies? > >>> > >> > >>Currently fabia PLL code does not have any table to check this and > >>intention > >>was to avoid relying on the client to call set_rate with only approved > >>frequencies so we have added the set_rate_range() call in the GPUCC > >>driver > >>in order to set the rate range. > >> > > > >But GPU will use OPP so it doesn't seem like it really buys us anything > >here. And it really doesn't matter when the clk driver implementation > >doesn't use the min/max to clamp the values of the round_rate() > >call. Is > >that being done here? I need to double check. I would be more convinced > >if the implementation was looking at min/max to constrain the rate > >requested. > > > > So our understanding is that GPU(client) driver will always call the > set_rate with approved frequencies only and we can completely rely > on the > client. Is our understanding is correct? First: on sdm845 the software doesn't set the GPU clocks - we rely on the GMU firmware to do that on our behalf but for the GPU at least this is an academic exercise. So what is this GPU clk driver for then? But that said: traditionally we've expected that the clock driver correctly clamp the requested rate to the correct values. In the past we have taken advantage of this and we may in the future. I don't think it is reasonable to require the leaf driver to only pass "approved" frequencies especially since we depend on our own OPP table that may or may not be similar to the one used by the clock driver. Ok. Sounds like things can't be kept in sync between the clk driver and the OPP tables. Why is that hard to do? Either way, I'd be fine if the code actually used the frequency limits to round the rate to something within range, but I don't recall seeing that being done here. So if the min/max limits stay, the clk driver should round to within that range. Thanks Stephen for your suggestion. I have modified the existing determine_rate() op to use the min/max limits and round the requested rate so that it stays withing the set_rate range. I will submit the same in the next patch series. -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3] clk: qcom: Add camera clock controller driver for SDM845
Add support for the camera clock controller found on SDM845 based devices. This would allow camera drivers to probe and control their clocks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/Kconfig|8 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sdm845.c | 1745 +++ 3 files changed, 1754 insertions(+) create mode 100644 drivers/clk/qcom/camcc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 1595464..f551432 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,14 @@ config MSM_GCC_8998 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, UFS, SD/eMMC, PCIe, etc. +config SDM_CAMCC_845 + tristate "SDM845 Camera Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + help + Support for the camera clock controller on SDM845 devices. + Say Y if you want to support camera devices and camera functionality. + config SDM_GCC_845 tristate "SDM845 Global Clock Controller" select QCOM_GDSC diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 93c1089..ada8750 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o +obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c new file mode 100644 index 000..1b2cefe --- /dev/null +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -0,0 +1,1745 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CORE_BI_PLL_TEST_SE, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 1 }, + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, + { P_CAM_CC_PLL3_OUT_EVEN, 5 }, + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const cam_cc_parent_names_0[] = { + "bi_tcxo", + "cam_cc_pll2_out_even", + "cam_cc_pll1_out_even", + "cam_cc_pll3_out_even", + "cam_cc_pll0_out_even", + "core_bi_pll_test_se", +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0_out_even", + .parent_names = (const char *[]){ "cam_cc_pll0" }, + .num_parents = 1, + .ops = _alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .
[PATCH v3] clk: qcom: Add camera clock controller driver for SDM845
Add support for the camera clock controller found on SDM845 based devices. This would allow camera drivers to probe and control their clocks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/Kconfig|8 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sdm845.c | 1745 +++ 3 files changed, 1754 insertions(+) create mode 100644 drivers/clk/qcom/camcc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 1595464..f551432 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,14 @@ config MSM_GCC_8998 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, UFS, SD/eMMC, PCIe, etc. +config SDM_CAMCC_845 + tristate "SDM845 Camera Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + help + Support for the camera clock controller on SDM845 devices. + Say Y if you want to support camera devices and camera functionality. + config SDM_GCC_845 tristate "SDM845 Global Clock Controller" select QCOM_GDSC diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 93c1089..ada8750 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o +obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c new file mode 100644 index 000..1b2cefe --- /dev/null +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -0,0 +1,1745 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CORE_BI_PLL_TEST_SE, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 1 }, + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, + { P_CAM_CC_PLL3_OUT_EVEN, 5 }, + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const cam_cc_parent_names_0[] = { + "bi_tcxo", + "cam_cc_pll2_out_even", + "cam_cc_pll1_out_even", + "cam_cc_pll3_out_even", + "cam_cc_pll0_out_even", + "core_bi_pll_test_se", +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0_out_even", + .parent_names = (const char *[]){ "cam_cc_pll0" }, + .num_parents = 1, + .ops = _alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .
[PATCH v3] Add QCOM camera clock controller driver
Changes in v3: 1. Mentioned the name of the non-fixed PLL in the comment text. Changes in v2: Addressed below review comments - https://lkml.org/lkml/2018/7/23/377 1. Add comment to use clk_rcg2_shared_ops and CLK_SET_RATE_PARENT flag. 2. Replace commas with semicolon for PLL configuration in probe function. Changes in v1: This patch series adds a driver and device tree documentation binding for the camera clock controller on some Qualcomm Technologies, Inc, SoCs such as SDM845. This would allow camera drivers to probe and control their clocks. [v1] : https://lore.kernel.org/patchwork/project/lkml/list/?series=360354 [v2] : https://lore.kernel.org/patchwork/project/lkml/list/?series=361196 Amit Nischal (1): clk: qcom: Add camera clock controller driver for SDM845 drivers/clk/qcom/Kconfig|8 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sdm845.c | 1745 +++ 3 files changed, 1754 insertions(+) create mode 100644 drivers/clk/qcom/camcc-sdm845.c -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3] Add QCOM camera clock controller driver
Changes in v3: 1. Mentioned the name of the non-fixed PLL in the comment text. Changes in v2: Addressed below review comments - https://lkml.org/lkml/2018/7/23/377 1. Add comment to use clk_rcg2_shared_ops and CLK_SET_RATE_PARENT flag. 2. Replace commas with semicolon for PLL configuration in probe function. Changes in v1: This patch series adds a driver and device tree documentation binding for the camera clock controller on some Qualcomm Technologies, Inc, SoCs such as SDM845. This would allow camera drivers to probe and control their clocks. [v1] : https://lore.kernel.org/patchwork/project/lkml/list/?series=360354 [v2] : https://lore.kernel.org/patchwork/project/lkml/list/?series=361196 Amit Nischal (1): clk: qcom: Add camera clock controller driver for SDM845 drivers/clk/qcom/Kconfig|8 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sdm845.c | 1745 +++ 3 files changed, 1754 insertions(+) create mode 100644 drivers/clk/qcom/camcc-sdm845.c -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v2] clk: qcom: Add camera clock controller driver for SDM845
On 2018-08-02 22:30, Stephen Boyd wrote: Quoting Amit Nischal (2018-07-30 02:22:20) diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c new file mode 100644 index 000..702ca66 --- /dev/null +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -0,0 +1,1744 @@ + }, +}; + +static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = { + F(1920, P_BI_TCXO, 1, 0, 0), + F(1, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(2, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(40400, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0), + F(48000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(6, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +/* + * As per HW design, some of the CAMCC RCGs needs to + * move to XO clock during their clock disable so using Per hw design sure, but what about hw design is causing this? The RCGs which sources to the CBCRs further connected to the camera memory blocks needs to be moved to XO clock during clock disable. This is required to power down the camera memories gracefully as these memories cannot be powered down instantly. And after memory power down, HW will gate the clock. + * clk_rcg2_shared_ops for such RCGs. + * Also, use CLK_SET_RATE_PARENT flag for the RCGs which + * have non-fixed PLL as parent source and requires Mention the PLL that isn't fixed? Yes sure. I will mention the PLL's name in the next patch. + * reconfiguration of the PLL frequency. + */ +static struct clk_rcg2 cam_cc_bps_clk_src = { + .cmd_rcgr = 0x600c, + .mnd_width = 0, -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] clk: qcom: Add camera clock controller driver for SDM845
On 2018-08-02 22:30, Stephen Boyd wrote: Quoting Amit Nischal (2018-07-30 02:22:20) diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c new file mode 100644 index 000..702ca66 --- /dev/null +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -0,0 +1,1744 @@ + }, +}; + +static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = { + F(1920, P_BI_TCXO, 1, 0, 0), + F(1, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(2, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(40400, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0), + F(48000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(6, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +/* + * As per HW design, some of the CAMCC RCGs needs to + * move to XO clock during their clock disable so using Per hw design sure, but what about hw design is causing this? The RCGs which sources to the CBCRs further connected to the camera memory blocks needs to be moved to XO clock during clock disable. This is required to power down the camera memories gracefully as these memories cannot be powered down instantly. And after memory power down, HW will gate the clock. + * clk_rcg2_shared_ops for such RCGs. + * Also, use CLK_SET_RATE_PARENT flag for the RCGs which + * have non-fixed PLL as parent source and requires Mention the PLL that isn't fixed? Yes sure. I will mention the PLL's name in the next patch. + * reconfiguration of the PLL frequency. + */ +static struct clk_rcg2 cam_cc_bps_clk_src = { + .cmd_rcgr = 0x600c, + .mnd_width = 0, -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
On 2018-08-03 04:14, Stephen Boyd wrote: Quoting Amit Nischal (2018-07-30 04:28:56) On 2018-07-25 12:28, Stephen Boyd wrote: > > Ok. Sounds good! Is the rate range call really needed? It can't be > determined in the PLL code with some table or avoided by making sure > GPU > uses OPP table with only approved frequencies? > Currently fabia PLL code does not have any table to check this and intention was to avoid relying on the client to call set_rate with only approved frequencies so we have added the set_rate_range() call in the GPUCC driver in order to set the rate range. But GPU will use OPP so it doesn't seem like it really buys us anything here. And it really doesn't matter when the clk driver implementation doesn't use the min/max to clamp the values of the round_rate() call. Is that being done here? I need to double check. I would be more convinced if the implementation was looking at min/max to constrain the rate requested. So our understanding is that GPU(client) driver will always call the set_rate with approved frequencies only and we can completely rely on the client. Is our understanding is correct? -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
On 2018-08-03 04:14, Stephen Boyd wrote: Quoting Amit Nischal (2018-07-30 04:28:56) On 2018-07-25 12:28, Stephen Boyd wrote: > > Ok. Sounds good! Is the rate range call really needed? It can't be > determined in the PLL code with some table or avoided by making sure > GPU > uses OPP table with only approved frequencies? > Currently fabia PLL code does not have any table to check this and intention was to avoid relying on the client to call set_rate with only approved frequencies so we have added the set_rate_range() call in the GPUCC driver in order to set the rate range. But GPU will use OPP so it doesn't seem like it really buys us anything here. And it really doesn't matter when the clk driver implementation doesn't use the min/max to clamp the values of the round_rate() call. Is that being done here? I need to double check. I would be more convinced if the implementation was looking at min/max to constrain the rate requested. So our understanding is that GPU(client) driver will always call the set_rate with approved frequencies only and we can completely rely on the client. Is our understanding is correct? -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
On 2018-07-25 12:28, Stephen Boyd wrote: Quoting Amit Nischal (2018-07-12 05:30:21) On 2018-07-09 11:45, Stephen Boyd wrote: > Quoting Amit Nischal (2018-06-06 04:41:46) >> To turn on the gpu_gx_gdsc, there is a hardware requirement to >> turn on the root clock (GFX3D RCG) first which would be the turn >> on signal for the gdsc along with the SW_COLLAPSE. As per the >> current implementation of clk_rcg2_shared_ops, it clears the >> root_enable bit in the enable() and set_rate() clock ops. But due >> to the above said requirement for GFX3D shared RCG, root_enable bit >> would be already set by gdsc driver and rcg2_shared_ops should not >> clear >> the root unless the disable is called. >> > > It sounds like the GDSC enable is ANDed with the RCG's root enable > bit? Here, the root clock (GFX3D RCG) needs to be enabled first before writing to SW_COLLAPSE bit of the GDSC. RCG's CLK_ON signal would power up the GDSC. > Does the RCG need to be clocking for the GDSC to actually turn on? > Or is it purely that the enable bit is logically combined that way so > that if the RCG is parented to a PLL that's off the GDSC will still > turn > on? > Yes, the RCG needs to be clocking for the GPU_GX GDSC to actually turn on. Cool, please add these details to the commit text. Thanks. I will add these details in the commit text in the next patch series. >> Add support for the same by reusing the existing clk_rcg2_shared_ops >> and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to >> take care of the root set/clear requirement. > > Anyway, this patch will probably significantly change given that the > RCG > is a glorified div-2 that muxes between a safe CXO speed and a > configurable PLL frequency. A lot of the logic can probably just be > hardcoded then. > Thanks for the suggestion. We are planning to introduce the "clk_rcg2_gfx3d_determine_rate" op which will always return the best parent as ‘GPU_CC_PLL0_OUT_EVEN’ and best_parent rate equal to twice of the requested rate. With this approach frequency table for rcg2 structure would not be required as all the supported frequencies would be derived from the GPU_CC_PLL0_OUT_EVEN src with a divider of 2. Also, we will add support to check the requested rate if falls within allowed set_rate range. This will make sure that the source PLL would not go out of the supported range. set_rate_range would be set by the GPUCC driver with min/max value by calling below API. clk_hw_set_rate_range(_cc_gx_gfx3d_clk_src.clkr.hw, 18000, 71000) Ok. Sounds good! Is the rate range call really needed? It can't be determined in the PLL code with some table or avoided by making sure GPU uses OPP table with only approved frequencies? Currently fabia PLL code does not have any table to check this and intention was to avoid relying on the client to call set_rate with only approved frequencies so we have added the set_rate_range() call in the GPUCC driver in order to set the rate range. -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
On 2018-07-25 12:28, Stephen Boyd wrote: Quoting Amit Nischal (2018-07-12 05:30:21) On 2018-07-09 11:45, Stephen Boyd wrote: > Quoting Amit Nischal (2018-06-06 04:41:46) >> To turn on the gpu_gx_gdsc, there is a hardware requirement to >> turn on the root clock (GFX3D RCG) first which would be the turn >> on signal for the gdsc along with the SW_COLLAPSE. As per the >> current implementation of clk_rcg2_shared_ops, it clears the >> root_enable bit in the enable() and set_rate() clock ops. But due >> to the above said requirement for GFX3D shared RCG, root_enable bit >> would be already set by gdsc driver and rcg2_shared_ops should not >> clear >> the root unless the disable is called. >> > > It sounds like the GDSC enable is ANDed with the RCG's root enable > bit? Here, the root clock (GFX3D RCG) needs to be enabled first before writing to SW_COLLAPSE bit of the GDSC. RCG's CLK_ON signal would power up the GDSC. > Does the RCG need to be clocking for the GDSC to actually turn on? > Or is it purely that the enable bit is logically combined that way so > that if the RCG is parented to a PLL that's off the GDSC will still > turn > on? > Yes, the RCG needs to be clocking for the GPU_GX GDSC to actually turn on. Cool, please add these details to the commit text. Thanks. I will add these details in the commit text in the next patch series. >> Add support for the same by reusing the existing clk_rcg2_shared_ops >> and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to >> take care of the root set/clear requirement. > > Anyway, this patch will probably significantly change given that the > RCG > is a glorified div-2 that muxes between a safe CXO speed and a > configurable PLL frequency. A lot of the logic can probably just be > hardcoded then. > Thanks for the suggestion. We are planning to introduce the "clk_rcg2_gfx3d_determine_rate" op which will always return the best parent as ‘GPU_CC_PLL0_OUT_EVEN’ and best_parent rate equal to twice of the requested rate. With this approach frequency table for rcg2 structure would not be required as all the supported frequencies would be derived from the GPU_CC_PLL0_OUT_EVEN src with a divider of 2. Also, we will add support to check the requested rate if falls within allowed set_rate range. This will make sure that the source PLL would not go out of the supported range. set_rate_range would be set by the GPUCC driver with min/max value by calling below API. clk_hw_set_rate_range(_cc_gx_gfx3d_clk_src.clkr.hw, 18000, 71000) Ok. Sounds good! Is the rate range call really needed? It can't be determined in the PLL code with some table or avoided by making sure GPU uses OPP table with only approved frequencies? Currently fabia PLL code does not have any table to check this and intention was to avoid relying on the client to call set_rate with only approved frequencies so we have added the set_rate_range() call in the GPUCC driver in order to set the rate range. -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/4] clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
On 2018-07-25 12:22, Stephen Boyd wrote: Quoting Amit Nischal (2018-07-12 05:23:48) On 2018-07-09 11:04, Stephen Boyd wrote: > Quoting Amit Nischal (2018-06-06 04:41:45) >> For some of the GDSCs, there is a requirement to enable/disable the >> few clocks before turning on/off the gdsc power domain. Add support > > Why is there a requirement? Do the clks need to be in hw control mode > or > they can't be turned off when the GDSC is off? It's hard for me to > understand with these vague statements. > This requirement is primarily to turn on the GPU GX GDSC and these clocks do not need to be in HW control mode and clock disable is not related with the GDSC. Ok that's good to know. To turn on the GX GDSC, root clock (GFX3D RCG) needs to be enabled first before writing to SW_COLLAPSE bit of the GDSC. The CLK_ON signal from RCG would power up the GPU GX GDSC. Can you please put this specific information in the commit text instead of making a vague statement about GDSC hardware configurations? Does anything go wrong if the GDSC is enabled from genpd but doesn't actually turn on until the GFX3D RCG root bit is enabled or disabled by the clk enable call? I suppose we won't know if the GDSC is enabled or not until the clk is enabled? Maybe we should make the clk enable of the RCG for GPU go check the GDSC status bit as well to make sure it's toggling on or off? As per the current design, before turning on the GDSC(writing to the GDSCR register) we are setting the ROOT_EN bit of RCG and GDSC's status will be still off without clk_enable call to RCG even though we enable the GDSC. clk_enable for RCG is CLK_ON signal for the GPU_GX_GDSC. Also, does the RCG turn on when the GX GDSC is off? I think we may be able to rely on the GPU driver to "do the right thing" and enable the GPU CX GDSC first, then the RCG and branch for the GFX3D clk, and then the GPU GX GDSC for the core GPU logic. Then we don't need to do anything special in the GDSC code for this. Its a GPU_GX_GDSC requirement to enable the RCG first and then GX_GDSC. We want all of this sequence to be done by the GDSC driver so that client only call for clk_apis for the clock branch. For clients, It will be extra overhead to follow the below sequence. GPU_CX_GDSC enable -> Enable RCG -> Enable GPU_GX_GDSC -> Enable Branch.
Re: [PATCH 1/4] clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
On 2018-07-25 12:22, Stephen Boyd wrote: Quoting Amit Nischal (2018-07-12 05:23:48) On 2018-07-09 11:04, Stephen Boyd wrote: > Quoting Amit Nischal (2018-06-06 04:41:45) >> For some of the GDSCs, there is a requirement to enable/disable the >> few clocks before turning on/off the gdsc power domain. Add support > > Why is there a requirement? Do the clks need to be in hw control mode > or > they can't be turned off when the GDSC is off? It's hard for me to > understand with these vague statements. > This requirement is primarily to turn on the GPU GX GDSC and these clocks do not need to be in HW control mode and clock disable is not related with the GDSC. Ok that's good to know. To turn on the GX GDSC, root clock (GFX3D RCG) needs to be enabled first before writing to SW_COLLAPSE bit of the GDSC. The CLK_ON signal from RCG would power up the GPU GX GDSC. Can you please put this specific information in the commit text instead of making a vague statement about GDSC hardware configurations? Does anything go wrong if the GDSC is enabled from genpd but doesn't actually turn on until the GFX3D RCG root bit is enabled or disabled by the clk enable call? I suppose we won't know if the GDSC is enabled or not until the clk is enabled? Maybe we should make the clk enable of the RCG for GPU go check the GDSC status bit as well to make sure it's toggling on or off? As per the current design, before turning on the GDSC(writing to the GDSCR register) we are setting the ROOT_EN bit of RCG and GDSC's status will be still off without clk_enable call to RCG even though we enable the GDSC. clk_enable for RCG is CLK_ON signal for the GPU_GX_GDSC. Also, does the RCG turn on when the GX GDSC is off? I think we may be able to rely on the GPU driver to "do the right thing" and enable the GPU CX GDSC first, then the RCG and branch for the GFX3D clk, and then the GPU GX GDSC for the core GPU logic. Then we don't need to do anything special in the GDSC code for this. Its a GPU_GX_GDSC requirement to enable the RCG first and then GX_GDSC. We want all of this sequence to be done by the GDSC driver so that client only call for clk_apis for the clock branch. For clients, It will be extra overhead to follow the below sequence. GPU_CX_GDSC enable -> Enable RCG -> Enable GPU_GX_GDSC -> Enable Branch.
[PATCH v2] Add QCOM camera clock controller driver
Changes in v2: Addressed below review comments - https://lkml.org/lkml/2018/7/23/377 1. Add comment to use clk_rcg2_shared_ops and CLK_SET_RATE_PARENT flag. 2. Replace commas with semicolon for PLL configuration in probe function. Changes in v1: This patch series adds a driver and device tree documentation binding for the camera clock controller on some Qualcomm Technologies, Inc, SoCs such as SDM845. This would allow camera drivers to probe and control their clocks. [v1] : https://lkml.org/lkml/2018/7/23/377 Amit Nischal (1): clk: qcom: Add camera clock controller driver for SDM845 drivers/clk/qcom/Kconfig|8 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sdm845.c | 1744 +++ 3 files changed, 1753 insertions(+) create mode 100644 drivers/clk/qcom/camcc-sdm845.c -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v2] clk: qcom: Add camera clock controller driver for SDM845
Add support for the camera clock controller found on SDM845 based devices. This would allow camera drivers to probe and control their clocks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/Kconfig|8 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sdm845.c | 1744 +++ 3 files changed, 1753 insertions(+) create mode 100644 drivers/clk/qcom/camcc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 7b32a33..85babc5 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,14 @@ config MSM_GCC_8998 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, UFS, SD/eMMC, PCIe, etc. +config SDM_CAMCC_845 + tristate "SDM845 Camera Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + help + Support for the camera clock controller on SDM845 devices. + Say Y if you want to support camera devices and camera functionality. + config SDM_GCC_845 tristate "SDM845 Global Clock Controller" select QCOM_GDSC diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 1818d9f..fab1a47 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o +obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c new file mode 100644 index 000..702ca66 --- /dev/null +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -0,0 +1,1744 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CORE_BI_PLL_TEST_SE, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 1 }, + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, + { P_CAM_CC_PLL3_OUT_EVEN, 5 }, + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const cam_cc_parent_names_0[] = { + "bi_tcxo", + "cam_cc_pll2_out_even", + "cam_cc_pll1_out_even", + "cam_cc_pll3_out_even", + "cam_cc_pll0_out_even", + "core_bi_pll_test_se", +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0_out_even", + .parent_names = (const char *[]){ "cam_cc_pll0" }, + .num_parents = 1, + .ops = _alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .w
[PATCH v2] Add QCOM camera clock controller driver
Changes in v2: Addressed below review comments - https://lkml.org/lkml/2018/7/23/377 1. Add comment to use clk_rcg2_shared_ops and CLK_SET_RATE_PARENT flag. 2. Replace commas with semicolon for PLL configuration in probe function. Changes in v1: This patch series adds a driver and device tree documentation binding for the camera clock controller on some Qualcomm Technologies, Inc, SoCs such as SDM845. This would allow camera drivers to probe and control their clocks. [v1] : https://lkml.org/lkml/2018/7/23/377 Amit Nischal (1): clk: qcom: Add camera clock controller driver for SDM845 drivers/clk/qcom/Kconfig|8 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sdm845.c | 1744 +++ 3 files changed, 1753 insertions(+) create mode 100644 drivers/clk/qcom/camcc-sdm845.c -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v2] clk: qcom: Add camera clock controller driver for SDM845
Add support for the camera clock controller found on SDM845 based devices. This would allow camera drivers to probe and control their clocks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/Kconfig|8 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sdm845.c | 1744 +++ 3 files changed, 1753 insertions(+) create mode 100644 drivers/clk/qcom/camcc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 7b32a33..85babc5 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,14 @@ config MSM_GCC_8998 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, UFS, SD/eMMC, PCIe, etc. +config SDM_CAMCC_845 + tristate "SDM845 Camera Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + help + Support for the camera clock controller on SDM845 devices. + Say Y if you want to support camera devices and camera functionality. + config SDM_GCC_845 tristate "SDM845 Global Clock Controller" select QCOM_GDSC diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 1818d9f..fab1a47 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o +obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c new file mode 100644 index 000..702ca66 --- /dev/null +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -0,0 +1,1744 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CORE_BI_PLL_TEST_SE, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 1 }, + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, + { P_CAM_CC_PLL3_OUT_EVEN, 5 }, + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const cam_cc_parent_names_0[] = { + "bi_tcxo", + "cam_cc_pll2_out_even", + "cam_cc_pll1_out_even", + "cam_cc_pll3_out_even", + "cam_cc_pll0_out_even", + "core_bi_pll_test_se", +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0_out_even", + .parent_names = (const char *[]){ "cam_cc_pll0" }, + .num_parents = 1, + .ops = _alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .w
Re: [PATCH 2/2] clk: qcom: Add camera clock controller driver for SDM845
On 2018-07-26 22:52, Stephen Boyd wrote: Quoting Amit Nischal (2018-07-23 04:26:33) diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c new file mode 100644 index 000..61e5ec2 --- /dev/null +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -0,0 +1,1736 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include Is this include used? This is not required. I will remove this in next patch series. +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CORE_BI_PLL_TEST_SE, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 1 }, + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, + { P_CAM_CC_PLL3_OUT_EVEN, 5 }, + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const cam_cc_parent_names_0[] = { + "bi_tcxo", + "cam_cc_pll2_out_even", + "cam_cc_pll1_out_even", + "cam_cc_pll3_out_even", + "cam_cc_pll0_out_even", + "core_bi_pll_test_se", +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0_out_even", + .parent_names = (const char *[]){ "cam_cc_pll0" }, + .num_parents = 1, + .ops = _alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1_out_even", + .parent_names = (const char *[]){ "cam_cc_pll1" }, + .num_parents = 1, + .ops = _alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll2", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = { + .offset = 0x2000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll2_out_even", + .parent_names = (const char *[]){ "cam_cc_pll2" }, + .num_parents = 1, + .ops = _alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .regs = clk_al
Re: [PATCH 2/2] clk: qcom: Add camera clock controller driver for SDM845
On 2018-07-26 22:52, Stephen Boyd wrote: Quoting Amit Nischal (2018-07-23 04:26:33) diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c new file mode 100644 index 000..61e5ec2 --- /dev/null +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -0,0 +1,1736 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include Is this include used? This is not required. I will remove this in next patch series. +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CORE_BI_PLL_TEST_SE, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 1 }, + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, + { P_CAM_CC_PLL3_OUT_EVEN, 5 }, + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const cam_cc_parent_names_0[] = { + "bi_tcxo", + "cam_cc_pll2_out_even", + "cam_cc_pll1_out_even", + "cam_cc_pll3_out_even", + "cam_cc_pll0_out_even", + "core_bi_pll_test_se", +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0_out_even", + .parent_names = (const char *[]){ "cam_cc_pll0" }, + .num_parents = 1, + .ops = _alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1_out_even", + .parent_names = (const char *[]){ "cam_cc_pll1" }, + .num_parents = 1, + .ops = _alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll2", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = { + .offset = 0x2000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll2_out_even", + .parent_names = (const char *[]){ "cam_cc_pll2" }, + .num_parents = 1, + .ops = _alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .regs = clk_al
[PATCH 2/2] clk: qcom: Add camera clock controller driver for SDM845
Add support for the camera clock controller found on SDM845 based devices. This would allow camera drivers to probe and control their clocks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/Kconfig|8 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sdm845.c | 1736 +++ 3 files changed, 1745 insertions(+) create mode 100644 drivers/clk/qcom/camcc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 7b32a33..85babc5 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,14 @@ config MSM_GCC_8998 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, UFS, SD/eMMC, PCIe, etc. +config SDM_CAMCC_845 + tristate "SDM845 Camera Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + help + Support for the camera clock controller on SDM845 devices. + Say Y if you want to support camera devices and camera functionality. + config SDM_GCC_845 tristate "SDM845 Global Clock Controller" select QCOM_GDSC diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 1818d9f..fab1a47 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o +obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c new file mode 100644 index 000..61e5ec2 --- /dev/null +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -0,0 +1,1736 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CORE_BI_PLL_TEST_SE, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 1 }, + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, + { P_CAM_CC_PLL3_OUT_EVEN, 5 }, + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const cam_cc_parent_names_0[] = { + "bi_tcxo", + "cam_cc_pll2_out_even", + "cam_cc_pll1_out_even", + "cam_cc_pll3_out_even", + "cam_cc_pll0_out_even", + "core_bi_pll_test_se", +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0_out_even", + .parent_names = (const char *[]){ "cam_cc_pll0" }, + .num_parents = 1, + .ops = _alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .w
[PATCH 2/2] clk: qcom: Add camera clock controller driver for SDM845
Add support for the camera clock controller found on SDM845 based devices. This would allow camera drivers to probe and control their clocks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/Kconfig|8 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sdm845.c | 1736 +++ 3 files changed, 1745 insertions(+) create mode 100644 drivers/clk/qcom/camcc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 7b32a33..85babc5 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,14 @@ config MSM_GCC_8998 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, UFS, SD/eMMC, PCIe, etc. +config SDM_CAMCC_845 + tristate "SDM845 Camera Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + help + Support for the camera clock controller on SDM845 devices. + Say Y if you want to support camera devices and camera functionality. + config SDM_GCC_845 tristate "SDM845 Global Clock Controller" select QCOM_GDSC diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 1818d9f..fab1a47 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o +obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c new file mode 100644 index 000..61e5ec2 --- /dev/null +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -0,0 +1,1736 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CORE_BI_PLL_TEST_SE, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 1 }, + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, + { P_CAM_CC_PLL3_OUT_EVEN, 5 }, + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const cam_cc_parent_names_0[] = { + "bi_tcxo", + "cam_cc_pll2_out_even", + "cam_cc_pll1_out_even", + "cam_cc_pll3_out_even", + "cam_cc_pll0_out_even", + "core_bi_pll_test_se", +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0_out_even", + .parent_names = (const char *[]){ "cam_cc_pll0" }, + .num_parents = 1, + .ops = _alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .w
[PATCH 0/2] Add QCOM camera clock controller driver
This patch series adds a driver and device tree documentation binding for the camera clock controller on some Qualcomm Technologies, Inc, SoCs such as SDM845. This would allow camera drivers to probe and control their clocks. Amit Nischal (2): dt-bindings: clock: Introduce QCOM Camera clock bindings clk: qcom: Add camera clock controller driver for SDM845 .../devicetree/bindings/clock/qcom,camcc.txt | 18 + drivers/clk/qcom/Kconfig |8 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sdm845.c| 1736 include/dt-bindings/clock/qcom,camcc-sdm845.h | 116 ++ 5 files changed, 1879 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,camcc.txt create mode 100644 drivers/clk/qcom/camcc-sdm845.c create mode 100644 include/dt-bindings/clock/qcom,camcc-sdm845.h -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH 1/2] dt-bindings: clock: Introduce QCOM Camera clock bindings
Add device tree bindings for camera clock controller for Qualcomm Technology Inc's SDM845 SoCs. Signed-off-by: Amit Nischal --- .../devicetree/bindings/clock/qcom,camcc.txt | 18 include/dt-bindings/clock/qcom,camcc-sdm845.h | 116 + 2 files changed, 134 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,camcc.txt create mode 100644 include/dt-bindings/clock/qcom,camcc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,camcc.txt b/Documentation/devicetree/bindings/clock/qcom,camcc.txt new file mode 100644 index 000..c5eb669 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,camcc.txt @@ -0,0 +1,18 @@ +Qualcomm Camera Clock & Reset Controller Binding + + +Required properties : +- compatible : shall contain "qcom,sdm845-camcc". +- reg : shall contain base register location and length. +- #clock-cells : from common clock binding, shall contain 1. +- #reset-cells : from common reset binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Example: + camcc: clock-controller@ad0 { + compatible = "qcom,sdm845-camcc"; + reg = <0xad0 0x1>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/clock/qcom,camcc-sdm845.h b/include/dt-bindings/clock/qcom,camcc-sdm845.h new file mode 100644 index 000..4f7a2d2 --- /dev/null +++ b/include/dt-bindings/clock/qcom,camcc-sdm845.h @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_SDM_CAM_CC_SDM845_H +#define _DT_BINDINGS_CLK_SDM_CAM_CC_SDM845_H + +/* CAM_CC clock registers */ +#define CAM_CC_BPS_AHB_CLK 0 +#define CAM_CC_BPS_AREG_CLK1 +#define CAM_CC_BPS_AXI_CLK 2 +#define CAM_CC_BPS_CLK 3 +#define CAM_CC_BPS_CLK_SRC 4 +#define CAM_CC_CAMNOC_ATB_CLK 5 +#define CAM_CC_CAMNOC_AXI_CLK 6 +#define CAM_CC_CCI_CLK 7 +#define CAM_CC_CCI_CLK_SRC 8 +#define CAM_CC_CPAS_AHB_CLK9 +#define CAM_CC_CPHY_RX_CLK_SRC 10 +#define CAM_CC_CSI0PHYTIMER_CLK11 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC12 +#define CAM_CC_CSI1PHYTIMER_CLK13 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC14 +#define CAM_CC_CSI2PHYTIMER_CLK15 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC16 +#define CAM_CC_CSI3PHYTIMER_CLK17 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC18 +#define CAM_CC_CSIPHY0_CLK 19 +#define CAM_CC_CSIPHY1_CLK 20 +#define CAM_CC_CSIPHY2_CLK 21 +#define CAM_CC_CSIPHY3_CLK 22 +#define CAM_CC_FAST_AHB_CLK_SRC23 +#define CAM_CC_FD_CORE_CLK 24 +#define CAM_CC_FD_CORE_CLK_SRC 25 +#define CAM_CC_FD_CORE_UAR_CLK 26 +#define CAM_CC_ICP_APB_CLK 27 +#define CAM_CC_ICP_ATB_CLK 28 +#define CAM_CC_ICP_CLK 29 +#define CAM_CC_ICP_CLK_SRC 30 +#define CAM_CC_ICP_CTI_CLK 31 +#define CAM_CC_ICP_TS_CLK 32 +#define CAM_CC_IFE_0_AXI_CLK 33 +#define CAM_CC_IFE_0_CLK 34 +#define CAM_CC_IFE_0_CLK_SRC 35 +#define CAM_CC_IFE_0_CPHY_RX_CLK 36 +#define CAM_CC_IFE_0_CSID_CLK 37 +#define CAM_CC_IFE_0_CSID_CLK_SRC 38 +#define CAM_CC_IFE_0_DSP_CLK 39 +#define CAM_CC_IFE_1_AXI_CLK 40 +#define CAM_CC_IFE_1_CLK 41 +#define CAM_CC_IFE_1_CLK_SRC 42 +#define CAM_CC_IFE_1_CPHY_RX_CLK 43 +#define CAM_CC_IFE_1_CSID_CLK 44 +#define CAM_CC_IFE_1_CSID_CLK_SRC 45 +#define CAM_CC_IFE_1_DSP_CLK 46 +#define CAM_CC_IFE_LITE_CLK47 +#define CAM_CC_IFE_LITE_CLK_SRC48 +#define CAM_CC_IFE_LITE_CPHY_RX_CLK49 +#define CAM_CC_IFE_LITE_CSID_CLK
[PATCH 0/2] Add QCOM camera clock controller driver
This patch series adds a driver and device tree documentation binding for the camera clock controller on some Qualcomm Technologies, Inc, SoCs such as SDM845. This would allow camera drivers to probe and control their clocks. Amit Nischal (2): dt-bindings: clock: Introduce QCOM Camera clock bindings clk: qcom: Add camera clock controller driver for SDM845 .../devicetree/bindings/clock/qcom,camcc.txt | 18 + drivers/clk/qcom/Kconfig |8 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sdm845.c| 1736 include/dt-bindings/clock/qcom,camcc-sdm845.h | 116 ++ 5 files changed, 1879 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,camcc.txt create mode 100644 drivers/clk/qcom/camcc-sdm845.c create mode 100644 include/dt-bindings/clock/qcom,camcc-sdm845.h -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH 1/2] dt-bindings: clock: Introduce QCOM Camera clock bindings
Add device tree bindings for camera clock controller for Qualcomm Technology Inc's SDM845 SoCs. Signed-off-by: Amit Nischal --- .../devicetree/bindings/clock/qcom,camcc.txt | 18 include/dt-bindings/clock/qcom,camcc-sdm845.h | 116 + 2 files changed, 134 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,camcc.txt create mode 100644 include/dt-bindings/clock/qcom,camcc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,camcc.txt b/Documentation/devicetree/bindings/clock/qcom,camcc.txt new file mode 100644 index 000..c5eb669 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,camcc.txt @@ -0,0 +1,18 @@ +Qualcomm Camera Clock & Reset Controller Binding + + +Required properties : +- compatible : shall contain "qcom,sdm845-camcc". +- reg : shall contain base register location and length. +- #clock-cells : from common clock binding, shall contain 1. +- #reset-cells : from common reset binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Example: + camcc: clock-controller@ad0 { + compatible = "qcom,sdm845-camcc"; + reg = <0xad0 0x1>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/clock/qcom,camcc-sdm845.h b/include/dt-bindings/clock/qcom,camcc-sdm845.h new file mode 100644 index 000..4f7a2d2 --- /dev/null +++ b/include/dt-bindings/clock/qcom,camcc-sdm845.h @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_SDM_CAM_CC_SDM845_H +#define _DT_BINDINGS_CLK_SDM_CAM_CC_SDM845_H + +/* CAM_CC clock registers */ +#define CAM_CC_BPS_AHB_CLK 0 +#define CAM_CC_BPS_AREG_CLK1 +#define CAM_CC_BPS_AXI_CLK 2 +#define CAM_CC_BPS_CLK 3 +#define CAM_CC_BPS_CLK_SRC 4 +#define CAM_CC_CAMNOC_ATB_CLK 5 +#define CAM_CC_CAMNOC_AXI_CLK 6 +#define CAM_CC_CCI_CLK 7 +#define CAM_CC_CCI_CLK_SRC 8 +#define CAM_CC_CPAS_AHB_CLK9 +#define CAM_CC_CPHY_RX_CLK_SRC 10 +#define CAM_CC_CSI0PHYTIMER_CLK11 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC12 +#define CAM_CC_CSI1PHYTIMER_CLK13 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC14 +#define CAM_CC_CSI2PHYTIMER_CLK15 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC16 +#define CAM_CC_CSI3PHYTIMER_CLK17 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC18 +#define CAM_CC_CSIPHY0_CLK 19 +#define CAM_CC_CSIPHY1_CLK 20 +#define CAM_CC_CSIPHY2_CLK 21 +#define CAM_CC_CSIPHY3_CLK 22 +#define CAM_CC_FAST_AHB_CLK_SRC23 +#define CAM_CC_FD_CORE_CLK 24 +#define CAM_CC_FD_CORE_CLK_SRC 25 +#define CAM_CC_FD_CORE_UAR_CLK 26 +#define CAM_CC_ICP_APB_CLK 27 +#define CAM_CC_ICP_ATB_CLK 28 +#define CAM_CC_ICP_CLK 29 +#define CAM_CC_ICP_CLK_SRC 30 +#define CAM_CC_ICP_CTI_CLK 31 +#define CAM_CC_ICP_TS_CLK 32 +#define CAM_CC_IFE_0_AXI_CLK 33 +#define CAM_CC_IFE_0_CLK 34 +#define CAM_CC_IFE_0_CLK_SRC 35 +#define CAM_CC_IFE_0_CPHY_RX_CLK 36 +#define CAM_CC_IFE_0_CSID_CLK 37 +#define CAM_CC_IFE_0_CSID_CLK_SRC 38 +#define CAM_CC_IFE_0_DSP_CLK 39 +#define CAM_CC_IFE_1_AXI_CLK 40 +#define CAM_CC_IFE_1_CLK 41 +#define CAM_CC_IFE_1_CLK_SRC 42 +#define CAM_CC_IFE_1_CPHY_RX_CLK 43 +#define CAM_CC_IFE_1_CSID_CLK 44 +#define CAM_CC_IFE_1_CSID_CLK_SRC 45 +#define CAM_CC_IFE_1_DSP_CLK 46 +#define CAM_CC_IFE_LITE_CLK47 +#define CAM_CC_IFE_LITE_CLK_SRC48 +#define CAM_CC_IFE_LITE_CPHY_RX_CLK49 +#define CAM_CC_IFE_LITE_CSID_CLK
[PATCH v2 4/4] clk: qcom: Add graphics clock controller driver for SDM845
Add support for the graphics clock controller found on SDM845 based devices. This would allow graphics drivers to probe and control their clocks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/Kconfig| 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-sdm845.c | 438 3 files changed, 448 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 9c3480d..193c2f5 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,15 @@ config SDM_GCC_845 Say Y if you want to use peripheral devices such as UART, SPI, i2C, USB, UFS, SDDC, PCIe, etc. +config SDM_GPUCC_845 + tristate "SDM845 Graphics Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + help + Support for the graphics clock controller on SDM845 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config SDM_VIDEOCC_845 tristate "SDM845 Video Clock Controller" depends on COMMON_CLK_QCOM diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 32d17c2..8aa2bc9 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -40,5 +40,6 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o +obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c new file mode 100644 index 000..7a11b70 --- /dev/null +++ b/drivers/clk/qcom/gpucc-sdm845.c @@ -0,0 +1,438 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +#define CX_GMU_CBCR_SLEEP_MASK 0xf +#define CX_GMU_CBCR_SLEEP_SHIFT4 +#define CX_GMU_CBCR_WAKE_MASK 0xf +#define CX_GMU_CBCR_WAKE_SHIFT 8 +#define CLK_DIS_WAIT_SHIFT 12 +#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) + +enum { + P_BI_TCXO, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL0_OUT_EVEN, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL0_OUT_ODD, + P_GPU_CC_PLL1_OUT_EVEN, + P_GPU_CC_PLL1_OUT_MAIN, + P_GPU_CC_PLL1_OUT_ODD, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gpu_cc_parent_names_0[] = { + "bi_tcxo", + "gpu_cc_pll0", + "gpu_cc_pll1", + "gcc_gpu_gpll0_clk_src", + "gcc_gpu_gpll0_div_clk_src", + "core_bi_pll_test_se", +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_EVEN, 1 }, + { P_GPU_CC_PLL0_OUT_ODD, 2 }, + { P_GPU_CC_PLL1_OUT_EVEN, 3 }, + { P_GPU_CC_PLL1_OUT_ODD, 4 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gpu_cc_parent_names_1[] = { + "bi_tcxo", + "gpu_cc_pll0_out_even", + "gpu_cc_pll0_out_odd", + "gpu_cc_pll1_out_even", + "gpu_cc_pll1_out_odd", + "gcc_gpu_gpll0_clk_src", + "core_bi_pll_test_se", +}; + +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x1d, + .alpha = 0x2aaa, +}; + +static const struct alpha_pll_config gpu_cc_pll1_config = { + .l = 0x1a, + .alpha = 0xaab, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, +}; + +static struct clk_alpha_pll_postd
[PATCH v2 4/4] clk: qcom: Add graphics clock controller driver for SDM845
Add support for the graphics clock controller found on SDM845 based devices. This would allow graphics drivers to probe and control their clocks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/Kconfig| 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-sdm845.c | 438 3 files changed, 448 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 9c3480d..193c2f5 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,15 @@ config SDM_GCC_845 Say Y if you want to use peripheral devices such as UART, SPI, i2C, USB, UFS, SDDC, PCIe, etc. +config SDM_GPUCC_845 + tristate "SDM845 Graphics Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + help + Support for the graphics clock controller on SDM845 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config SDM_VIDEOCC_845 tristate "SDM845 Video Clock Controller" depends on COMMON_CLK_QCOM diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 32d17c2..8aa2bc9 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -40,5 +40,6 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o +obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c new file mode 100644 index 000..7a11b70 --- /dev/null +++ b/drivers/clk/qcom/gpucc-sdm845.c @@ -0,0 +1,438 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +#define CX_GMU_CBCR_SLEEP_MASK 0xf +#define CX_GMU_CBCR_SLEEP_SHIFT4 +#define CX_GMU_CBCR_WAKE_MASK 0xf +#define CX_GMU_CBCR_WAKE_SHIFT 8 +#define CLK_DIS_WAIT_SHIFT 12 +#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) + +enum { + P_BI_TCXO, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL0_OUT_EVEN, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL0_OUT_ODD, + P_GPU_CC_PLL1_OUT_EVEN, + P_GPU_CC_PLL1_OUT_MAIN, + P_GPU_CC_PLL1_OUT_ODD, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gpu_cc_parent_names_0[] = { + "bi_tcxo", + "gpu_cc_pll0", + "gpu_cc_pll1", + "gcc_gpu_gpll0_clk_src", + "gcc_gpu_gpll0_div_clk_src", + "core_bi_pll_test_se", +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_EVEN, 1 }, + { P_GPU_CC_PLL0_OUT_ODD, 2 }, + { P_GPU_CC_PLL1_OUT_EVEN, 3 }, + { P_GPU_CC_PLL1_OUT_ODD, 4 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gpu_cc_parent_names_1[] = { + "bi_tcxo", + "gpu_cc_pll0_out_even", + "gpu_cc_pll0_out_odd", + "gpu_cc_pll1_out_even", + "gpu_cc_pll1_out_odd", + "gcc_gpu_gpll0_clk_src", + "core_bi_pll_test_se", +}; + +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x1d, + .alpha = 0x2aaa, +}; + +static const struct alpha_pll_config gpu_cc_pll1_config = { + .l = 0x1a, + .alpha = 0xaab, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, +}; + +static struct clk_alpha_pll_postd
[PATCH v2 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings
Add device tree bindings for graphics clock controller for Qualcomm Technology Inc's SDM845 SoCs. Signed-off-by: Amit Nischal --- .../devicetree/bindings/clock/qcom,gpucc.txt | 18 ++ include/dt-bindings/clock/qcom,gpucc-sdm845.h | 38 ++ 2 files changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc.txt create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt new file mode 100644 index 000..93752db --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt @@ -0,0 +1,18 @@ +Qualcomm Graphics Clock & Reset Controller Binding +-- + +Required properties : +- compatible : shall contain "qcom,sdm845-gpucc". +- reg : shall contain base register location and length. +- #clock-cells : from common clock binding, shall contain 1. +- #reset-cells : from common reset binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Example: + gpucc: clock-controller@509 { + compatible = "qcom,sdm845-gpucc"; + reg = <0x509 0x9000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/clock/qcom,gpucc-sdm845.h b/include/dt-bindings/clock/qcom,gpucc-sdm845.h new file mode 100644 index 000..b9cbce5 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gpucc-sdm845.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H +#define _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H + +/* GPU_CC clock registers */ +#define GPU_CC_CRC_AHB_CLK 0 +#define GPU_CC_CX_APB_CLK 1 +#define GPU_CC_CX_GFX3D_CLK2 +#define GPU_CC_CX_GFX3D_SLV_CLK3 +#define GPU_CC_CX_GMU_CLK 4 +#define GPU_CC_CX_SNOC_DVM_CLK 5 +#define GPU_CC_CXO_CLK 6 +#define GPU_CC_GMU_CLK_SRC 7 +#define GPU_CC_GX_GMU_CLK 8 +#define GPU_CC_GX_GFX3D_CLK_SRC9 +#define GPU_CC_GX_GFX3D_CLK10 +#define GPU_CC_PLL011 +#define GPU_CC_PLL0_OUT_EVEN 12 +#define GPU_CC_PLL113 + +/* GPU_CC Resets */ +#define GPUCC_GPU_CC_ACD_BCR 0 +#define GPUCC_GPU_CC_CX_BCR1 +#define GPUCC_GPU_CC_GFX3D_AON_BCR 2 +#define GPUCC_GPU_CC_GMU_BCR 3 +#define GPUCC_GPU_CC_GX_BCR4 +#define GPUCC_GPU_CC_SPDM_BCR 5 +#define GPUCC_GPU_CC_XO_BCR6 + +/* GPU_CC GDSCRs */ +#define GPU_CX_GDSC0 +#define GPU_GX_GDSC1 + +#endif -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v2 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings
Add device tree bindings for graphics clock controller for Qualcomm Technology Inc's SDM845 SoCs. Signed-off-by: Amit Nischal --- .../devicetree/bindings/clock/qcom,gpucc.txt | 18 ++ include/dt-bindings/clock/qcom,gpucc-sdm845.h | 38 ++ 2 files changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc.txt create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt new file mode 100644 index 000..93752db --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt @@ -0,0 +1,18 @@ +Qualcomm Graphics Clock & Reset Controller Binding +-- + +Required properties : +- compatible : shall contain "qcom,sdm845-gpucc". +- reg : shall contain base register location and length. +- #clock-cells : from common clock binding, shall contain 1. +- #reset-cells : from common reset binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Example: + gpucc: clock-controller@509 { + compatible = "qcom,sdm845-gpucc"; + reg = <0x509 0x9000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/clock/qcom,gpucc-sdm845.h b/include/dt-bindings/clock/qcom,gpucc-sdm845.h new file mode 100644 index 000..b9cbce5 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gpucc-sdm845.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H +#define _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H + +/* GPU_CC clock registers */ +#define GPU_CC_CRC_AHB_CLK 0 +#define GPU_CC_CX_APB_CLK 1 +#define GPU_CC_CX_GFX3D_CLK2 +#define GPU_CC_CX_GFX3D_SLV_CLK3 +#define GPU_CC_CX_GMU_CLK 4 +#define GPU_CC_CX_SNOC_DVM_CLK 5 +#define GPU_CC_CXO_CLK 6 +#define GPU_CC_GMU_CLK_SRC 7 +#define GPU_CC_GX_GMU_CLK 8 +#define GPU_CC_GX_GFX3D_CLK_SRC9 +#define GPU_CC_GX_GFX3D_CLK10 +#define GPU_CC_PLL011 +#define GPU_CC_PLL0_OUT_EVEN 12 +#define GPU_CC_PLL113 + +/* GPU_CC Resets */ +#define GPUCC_GPU_CC_ACD_BCR 0 +#define GPUCC_GPU_CC_CX_BCR1 +#define GPUCC_GPU_CC_GFX3D_AON_BCR 2 +#define GPUCC_GPU_CC_GMU_BCR 3 +#define GPUCC_GPU_CC_GX_BCR4 +#define GPUCC_GPU_CC_SPDM_BCR 5 +#define GPUCC_GPU_CC_XO_BCR6 + +/* GPU_CC GDSCRs */ +#define GPU_CX_GDSC0 +#define GPU_GX_GDSC1 + +#endif -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v2 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
To turn on the gpu_gx_gdsc, there is a hardware requirement to turn on the root clock (GFX3D RCG) first which would be the turn on signal for the gdsc along with the SW_COLLAPSE. As per the current implementation of clk_rcg2_shared_ops, it clears the root_enable bit in the enable() clock op. But due to the above said requirement for GFX3D shared RCG, root_enable bit would be already set by gdsc driver and clk_rcg2_shared_enable()should not clear the root unless the disable is called. Add support for the same by reusing the existing clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to take care of the root set/clear requirement. Signed-off-by: Amit Nischal --- drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c | 87 +++-- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index b209a2f..c8c9558 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -160,5 +160,6 @@ struct clk_rcg2 { extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_rcg2_shared_ops; +extern const struct clk_ops clk_rcg2_gfx3d_ops; #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 52208d4..667edd9 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -866,7 +866,7 @@ static int clk_rcg2_shared_set_rate_and_parent(struct clk_hw *hw, return clk_rcg2_shared_set_rate(hw, rate, parent_rate); } -static int clk_rcg2_shared_enable(struct clk_hw *hw) +static int __clk_rcg2_shared_enable(struct clk_hw *hw) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); int ret; @@ -879,7 +879,14 @@ static int clk_rcg2_shared_enable(struct clk_hw *hw) if (ret) return ret; - ret = update_config(rcg); + return update_config(rcg); +} + +static int clk_rcg2_shared_enable(struct clk_hw *hw) +{ + int ret; + + ret = __clk_rcg2_shared_enable(hw); if (ret) return ret; @@ -929,3 +936,79 @@ static void clk_rcg2_shared_disable(struct clk_hw *hw) .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent, }; EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); + +static int clk_rcg2_gfx3d_enable(struct clk_hw *hw) +{ + return __clk_rcg2_shared_enable(hw); +} + +static int clk_rcg2_gfx3d_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_rate_request parent_req = { }; + struct clk_hw *p; + unsigned long rate = req->rate; + int ret; + + if (rate < req->min_rate || rate > req->max_rate) + return -EINVAL; + + /* Get fixed parent - GPU_CC_PLL0_OUT_EVEN */ + p = clk_hw_get_parent_by_index(hw, 1); + + /* Parent should always run at twice of the requested rate */ + parent_req.rate = 2 * req->rate; + + ret = __clk_determine_rate(req->best_parent_hw, _req); + if (ret) + return ret; + + req->best_parent_hw = p; + req->best_parent_rate = parent_req.rate; + req->rate = parent_req.rate / 2; + + return 0; +} + +static int clk_rcg2_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + int ret; + u32 cfg; + + /* Configure fixed SRC and DIV */ + cfg = rcg->parent_map[1].cfg << CFG_SRC_SEL_SHIFT; + cfg |= 0x3 << CFG_SRC_DIV_SHIFT; + + ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg); + if (ret) + return ret; + + /* +* In case clock is disabled, update the SRC and DIV only +* and return without configuration update. +*/ + if (!__clk_is_enabled(hw->clk)) + return 0; + + return update_config(rcg); +} + +static int clk_rcg2_gfx3d_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate, u8 index) +{ + return clk_rcg2_gfx3d_set_rate(hw, rate, parent_rate); +} + +const struct clk_ops clk_rcg2_gfx3d_ops = { + .enable = clk_rcg2_gfx3d_enable, + .disable = clk_rcg2_shared_disable, + .get_parent = clk_rcg2_get_parent, + .set_parent = clk_rcg2_set_parent, + .recalc_rate = clk_rcg2_recalc_rate, + .determine_rate = clk_rcg2_gfx3d_determine_rate, + .set_rate = clk_rcg2_gfx3d_set_rate, + .set_rate_and_parent = clk_rcg2_gfx3d_set_rate_and_parent, +}; +EXPORT_SYMBOL_GPL(clk_rcg2_gfx3d_ops); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v2 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
To turn on the gpu_gx_gdsc, there is a hardware requirement to turn on the root clock (GFX3D RCG) first which would be the turn on signal for the gdsc along with the SW_COLLAPSE. As per the current implementation of clk_rcg2_shared_ops, it clears the root_enable bit in the enable() clock op. But due to the above said requirement for GFX3D shared RCG, root_enable bit would be already set by gdsc driver and clk_rcg2_shared_enable()should not clear the root unless the disable is called. Add support for the same by reusing the existing clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to take care of the root set/clear requirement. Signed-off-by: Amit Nischal --- drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c | 87 +++-- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index b209a2f..c8c9558 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -160,5 +160,6 @@ struct clk_rcg2 { extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_rcg2_shared_ops; +extern const struct clk_ops clk_rcg2_gfx3d_ops; #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 52208d4..667edd9 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -866,7 +866,7 @@ static int clk_rcg2_shared_set_rate_and_parent(struct clk_hw *hw, return clk_rcg2_shared_set_rate(hw, rate, parent_rate); } -static int clk_rcg2_shared_enable(struct clk_hw *hw) +static int __clk_rcg2_shared_enable(struct clk_hw *hw) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); int ret; @@ -879,7 +879,14 @@ static int clk_rcg2_shared_enable(struct clk_hw *hw) if (ret) return ret; - ret = update_config(rcg); + return update_config(rcg); +} + +static int clk_rcg2_shared_enable(struct clk_hw *hw) +{ + int ret; + + ret = __clk_rcg2_shared_enable(hw); if (ret) return ret; @@ -929,3 +936,79 @@ static void clk_rcg2_shared_disable(struct clk_hw *hw) .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent, }; EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); + +static int clk_rcg2_gfx3d_enable(struct clk_hw *hw) +{ + return __clk_rcg2_shared_enable(hw); +} + +static int clk_rcg2_gfx3d_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_rate_request parent_req = { }; + struct clk_hw *p; + unsigned long rate = req->rate; + int ret; + + if (rate < req->min_rate || rate > req->max_rate) + return -EINVAL; + + /* Get fixed parent - GPU_CC_PLL0_OUT_EVEN */ + p = clk_hw_get_parent_by_index(hw, 1); + + /* Parent should always run at twice of the requested rate */ + parent_req.rate = 2 * req->rate; + + ret = __clk_determine_rate(req->best_parent_hw, _req); + if (ret) + return ret; + + req->best_parent_hw = p; + req->best_parent_rate = parent_req.rate; + req->rate = parent_req.rate / 2; + + return 0; +} + +static int clk_rcg2_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + int ret; + u32 cfg; + + /* Configure fixed SRC and DIV */ + cfg = rcg->parent_map[1].cfg << CFG_SRC_SEL_SHIFT; + cfg |= 0x3 << CFG_SRC_DIV_SHIFT; + + ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg); + if (ret) + return ret; + + /* +* In case clock is disabled, update the SRC and DIV only +* and return without configuration update. +*/ + if (!__clk_is_enabled(hw->clk)) + return 0; + + return update_config(rcg); +} + +static int clk_rcg2_gfx3d_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate, u8 index) +{ + return clk_rcg2_gfx3d_set_rate(hw, rate, parent_rate); +} + +const struct clk_ops clk_rcg2_gfx3d_ops = { + .enable = clk_rcg2_gfx3d_enable, + .disable = clk_rcg2_shared_disable, + .get_parent = clk_rcg2_get_parent, + .set_parent = clk_rcg2_set_parent, + .recalc_rate = clk_rcg2_recalc_rate, + .determine_rate = clk_rcg2_gfx3d_determine_rate, + .set_rate = clk_rcg2_gfx3d_set_rate, + .set_rate_and_parent = clk_rcg2_gfx3d_set_rate_and_parent, +}; +EXPORT_SYMBOL_GPL(clk_rcg2_gfx3d_ops); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v2 0/4] Add QCOM graphics clock controller driver for SDM845
Changes in v2: Addressed review comments given by Stephen: https://lkml.org/lkml/2018/6/6/294 * Introduce clk_rcg2_gfx3d_determine_rate ops to return the best parent as 'gpucc_pll0_even' and best parent rate as twice of the requested rate always. This will eliminate the need of frequency table as source and div-2 are fixed for gfx3d_clk_src. Also modified the clk_rcg2_set_rate ops to configure the fixed source and div. * Add support to check if requested rate falls within allowed set_rate range. This will not let the source gpucc_pll0 to go out of the supported range and also client can request the rate within the range. * Fixed comment text in probe function and added module description for GPUCC driver. The graphics clock driver depends upon the below change. https://lkml.org/lkml/2018/6/23/108 Changes in v1: This patch series adds support for graphics clock controller for SDM845. Below is the brief description for each change: 1. For some of the GDSCs, there is requirement to enable/disable the few clocks before turning on/off the gdsc power domain. This patch will add support to enable/disable the clock associated with the gdsc along with power domain on/off callbacks. 2. To turn on the gpu_gx_gdsc, there is a hardware requirement to turn on the root clock (GFX3D RCG) first which would be the turn on signal for the gdsc along with the SW_COLLAPSE. As per the current implementation of clk_rcg2_shared_ops, it clears the root_enable bit in the enable() clock ops. But due to the above said requirement for GFX3D shared RCG, root_enable bit would be already set by gdsc driver and rcg2_shared_ops should not clear the root unless the disable() is called. This patch add support for the same by reusing the existing clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to take care of the root set/clear requirement. 3. Add device tree bindings for graphics clock controller for SDM845. 4. Add graphics clock controller (GPUCC) driver for SDM845. [v1] : https://lkml.org/lkml/2018/6/6/294 Amit Nischal (4): clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845 dt-bindings: clock: Introduce QCOM Graphics clock bindings clk: qcom: Add graphics clock controller driver for SDM845 .../devicetree/bindings/clock/qcom,gpucc.txt | 18 + drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c| 87 +++- drivers/clk/qcom/gdsc.c| 44 +++ drivers/clk/qcom/gdsc.h| 5 + drivers/clk/qcom/gpucc-sdm845.c| 438 + include/dt-bindings/clock/qcom,gpucc-sdm845.h | 38 ++ 9 files changed, 639 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc.txt create mode 100644 drivers/clk/qcom/gpucc-sdm845.c create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm845.h -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v2 1/4] clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
For some of the GDSCs, there is a requirement to enable/disable the few clocks before turning on/off the gdsc power domain. Add support for the same by specifying a list of clk_hw pointers per gdsc and enable/disable them along with power domain on/off callbacks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/gdsc.c | 44 drivers/clk/qcom/gdsc.h | 5 + 2 files changed, 49 insertions(+) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index a077133..b6adca1 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -12,6 +12,8 @@ */ #include +#include +#include #include #include #include @@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc) regmap_update_bits(sc->regmap, sc->clamp_io_ctrl, GMEM_RESET_MASK, 0); } + +static int gdsc_clk_prepare_enable(struct gdsc *sc) +{ + int i, ret; + + for (i = 0; i < sc->clk_count; i++) { + ret = clk_prepare_enable(sc->clk_hws[i]->clk); + if (ret) { + for (i--; i >= 0; i--) + clk_disable_unprepare(sc->clk_hws[i]->clk); + return ret; + } + } + return 0; +} + +static void gdsc_clk_disable_unprepare(struct gdsc *sc) +{ + int i; + + for (i = 0; i < sc->clk_count; i++) + clk_disable_unprepare(sc->clk_hws[i]->clk); +} + static int gdsc_enable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); int ret; + if (sc->clk_count) { + ret = gdsc_clk_prepare_enable(sc); + if (ret) + return ret; + } + if (sc->pwrsts == PWRSTS_ON) return gdsc_deassert_reset(sc); @@ -260,6 +292,9 @@ static int gdsc_enable(struct generic_pm_domain *domain) udelay(1); } + if (sc->clk_count) + gdsc_clk_disable_unprepare(sc); + return 0; } @@ -268,6 +303,12 @@ static int gdsc_disable(struct generic_pm_domain *domain) struct gdsc *sc = domain_to_gdsc(domain); int ret; + if (sc->clk_count) { + ret = gdsc_clk_prepare_enable(sc); + if (ret) + return ret; + } + if (sc->pwrsts == PWRSTS_ON) return gdsc_assert_reset(sc); @@ -299,6 +340,9 @@ static int gdsc_disable(struct generic_pm_domain *domain) if (sc->flags & CLAMP_IO) gdsc_assert_clamp_io(sc); + if (sc->clk_count) + gdsc_clk_disable_unprepare(sc); + return 0; } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index bd1f2c7..59957d7 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -17,6 +17,7 @@ #include #include +struct clk_hw; struct regmap; struct reset_controller_dev; @@ -32,6 +33,8 @@ * @resets: ids of resets associated with this gdsc * @reset_count: number of @resets * @rcdev: reset controller + * @clk_count: number of associated clocks + * @clk_hws: clk_hw pointers for associated clocks with gdsc */ struct gdsc { struct generic_pm_domainpd; @@ -60,6 +63,8 @@ struct gdsc { struct reset_controller_dev *rcdev; unsigned int*resets; unsigned intreset_count; + unsigned intclk_count; + struct clk_hw *clk_hws[]; }; struct gdsc_desc { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v2 0/4] Add QCOM graphics clock controller driver for SDM845
Changes in v2: Addressed review comments given by Stephen: https://lkml.org/lkml/2018/6/6/294 * Introduce clk_rcg2_gfx3d_determine_rate ops to return the best parent as 'gpucc_pll0_even' and best parent rate as twice of the requested rate always. This will eliminate the need of frequency table as source and div-2 are fixed for gfx3d_clk_src. Also modified the clk_rcg2_set_rate ops to configure the fixed source and div. * Add support to check if requested rate falls within allowed set_rate range. This will not let the source gpucc_pll0 to go out of the supported range and also client can request the rate within the range. * Fixed comment text in probe function and added module description for GPUCC driver. The graphics clock driver depends upon the below change. https://lkml.org/lkml/2018/6/23/108 Changes in v1: This patch series adds support for graphics clock controller for SDM845. Below is the brief description for each change: 1. For some of the GDSCs, there is requirement to enable/disable the few clocks before turning on/off the gdsc power domain. This patch will add support to enable/disable the clock associated with the gdsc along with power domain on/off callbacks. 2. To turn on the gpu_gx_gdsc, there is a hardware requirement to turn on the root clock (GFX3D RCG) first which would be the turn on signal for the gdsc along with the SW_COLLAPSE. As per the current implementation of clk_rcg2_shared_ops, it clears the root_enable bit in the enable() clock ops. But due to the above said requirement for GFX3D shared RCG, root_enable bit would be already set by gdsc driver and rcg2_shared_ops should not clear the root unless the disable() is called. This patch add support for the same by reusing the existing clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to take care of the root set/clear requirement. 3. Add device tree bindings for graphics clock controller for SDM845. 4. Add graphics clock controller (GPUCC) driver for SDM845. [v1] : https://lkml.org/lkml/2018/6/6/294 Amit Nischal (4): clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845 dt-bindings: clock: Introduce QCOM Graphics clock bindings clk: qcom: Add graphics clock controller driver for SDM845 .../devicetree/bindings/clock/qcom,gpucc.txt | 18 + drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c| 87 +++- drivers/clk/qcom/gdsc.c| 44 +++ drivers/clk/qcom/gdsc.h| 5 + drivers/clk/qcom/gpucc-sdm845.c| 438 + include/dt-bindings/clock/qcom,gpucc-sdm845.h | 38 ++ 9 files changed, 639 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc.txt create mode 100644 drivers/clk/qcom/gpucc-sdm845.c create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm845.h -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v2 1/4] clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
For some of the GDSCs, there is a requirement to enable/disable the few clocks before turning on/off the gdsc power domain. Add support for the same by specifying a list of clk_hw pointers per gdsc and enable/disable them along with power domain on/off callbacks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/gdsc.c | 44 drivers/clk/qcom/gdsc.h | 5 + 2 files changed, 49 insertions(+) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index a077133..b6adca1 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -12,6 +12,8 @@ */ #include +#include +#include #include #include #include @@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc) regmap_update_bits(sc->regmap, sc->clamp_io_ctrl, GMEM_RESET_MASK, 0); } + +static int gdsc_clk_prepare_enable(struct gdsc *sc) +{ + int i, ret; + + for (i = 0; i < sc->clk_count; i++) { + ret = clk_prepare_enable(sc->clk_hws[i]->clk); + if (ret) { + for (i--; i >= 0; i--) + clk_disable_unprepare(sc->clk_hws[i]->clk); + return ret; + } + } + return 0; +} + +static void gdsc_clk_disable_unprepare(struct gdsc *sc) +{ + int i; + + for (i = 0; i < sc->clk_count; i++) + clk_disable_unprepare(sc->clk_hws[i]->clk); +} + static int gdsc_enable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); int ret; + if (sc->clk_count) { + ret = gdsc_clk_prepare_enable(sc); + if (ret) + return ret; + } + if (sc->pwrsts == PWRSTS_ON) return gdsc_deassert_reset(sc); @@ -260,6 +292,9 @@ static int gdsc_enable(struct generic_pm_domain *domain) udelay(1); } + if (sc->clk_count) + gdsc_clk_disable_unprepare(sc); + return 0; } @@ -268,6 +303,12 @@ static int gdsc_disable(struct generic_pm_domain *domain) struct gdsc *sc = domain_to_gdsc(domain); int ret; + if (sc->clk_count) { + ret = gdsc_clk_prepare_enable(sc); + if (ret) + return ret; + } + if (sc->pwrsts == PWRSTS_ON) return gdsc_assert_reset(sc); @@ -299,6 +340,9 @@ static int gdsc_disable(struct generic_pm_domain *domain) if (sc->flags & CLAMP_IO) gdsc_assert_clamp_io(sc); + if (sc->clk_count) + gdsc_clk_disable_unprepare(sc); + return 0; } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index bd1f2c7..59957d7 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -17,6 +17,7 @@ #include #include +struct clk_hw; struct regmap; struct reset_controller_dev; @@ -32,6 +33,8 @@ * @resets: ids of resets associated with this gdsc * @reset_count: number of @resets * @rcdev: reset controller + * @clk_count: number of associated clocks + * @clk_hws: clk_hw pointers for associated clocks with gdsc */ struct gdsc { struct generic_pm_domainpd; @@ -60,6 +63,8 @@ struct gdsc { struct reset_controller_dev *rcdev; unsigned int*resets; unsigned intreset_count; + unsigned intclk_count; + struct clk_hw *clk_hws[]; }; struct gdsc_desc { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH 4/4] clk: qcom: Add graphics clock controller driver for SDM845
On 2018-07-09 11:37, Stephen Boyd wrote: Quoting Amit Nischal (2018-06-06 04:41:48) diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c new file mode 100644 index 000..81f8926 --- /dev/null +++ b/drivers/clk/qcom/gpucc-sdm845.c @@ -0,0 +1,441 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +#define CX_GMU_CBCR_SLEEP_MASK 0xf +#define CX_GMU_CBCR_SLEEP_SHIFT4 +#define CX_GMU_CBCR_WAKE_MASK 0xf +#define CX_GMU_CBCR_WAKE_SHIFT 8 +#define CLK_DIS_WAIT_SHIFT 12 +#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } This should be removed and series can depend on Taniya's patch. Yes sure. I will do the required change and will submit the next patch series. + +enum { + P_BI_TCXO, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, [...] + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + {}, Drop the trailing comma, it's a sentinel presumably. Will fix this in the next patch series. +}; + +static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll0_out_even", + .parent_names = (const char *[]){ "gpu_cc_pll0" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = _alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll gpu_cc_pll1 = { + .offset = 0x100, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll1", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { + F(1920, P_BI_TCXO, 1, 0, 0), + F(2, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0), + F(5, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .cmd_rcgr = 0x1120, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_0, + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpu_cc_gmu_clk_src", + .parent_names = gpu_cc_parent_names_0, + .num_parents = 6, + .ops = _rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = { + F(18000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(25700, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(34200, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(41400, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(52000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(59600, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(67500, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(71000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), Do we really need to encode anything here in this table? Why can't we have clk_ops that hardcode this clk to be a div-2 that passes the frequency up to the parent source? Then this frequency table doesn't need to be here at all, and can live in DT as an OPP table used by the GPU driver. Thanks for the suggestion. I will address the same in the next patch series where "clk_rcg2_gfx3d_determine_rate" op will always return the best parent as ‘GPU_CC_PLL0_OUT_EVEN’ and best_parent rate equal to twice of the requested rate. This will eliminate the need of frequency table. + { } +}; + +static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = { + .cmd_rcgr = 0x101c, + .mnd_width = 0, + .hid_wi
Re: [PATCH 4/4] clk: qcom: Add graphics clock controller driver for SDM845
On 2018-07-09 11:37, Stephen Boyd wrote: Quoting Amit Nischal (2018-06-06 04:41:48) diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c new file mode 100644 index 000..81f8926 --- /dev/null +++ b/drivers/clk/qcom/gpucc-sdm845.c @@ -0,0 +1,441 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +#define CX_GMU_CBCR_SLEEP_MASK 0xf +#define CX_GMU_CBCR_SLEEP_SHIFT4 +#define CX_GMU_CBCR_WAKE_MASK 0xf +#define CX_GMU_CBCR_WAKE_SHIFT 8 +#define CLK_DIS_WAIT_SHIFT 12 +#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } This should be removed and series can depend on Taniya's patch. Yes sure. I will do the required change and will submit the next patch series. + +enum { + P_BI_TCXO, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, [...] + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + {}, Drop the trailing comma, it's a sentinel presumably. Will fix this in the next patch series. +}; + +static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll0_out_even", + .parent_names = (const char *[]){ "gpu_cc_pll0" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = _alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll gpu_cc_pll1 = { + .offset = 0x100, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll1", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { + F(1920, P_BI_TCXO, 1, 0, 0), + F(2, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0), + F(5, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .cmd_rcgr = 0x1120, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_0, + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpu_cc_gmu_clk_src", + .parent_names = gpu_cc_parent_names_0, + .num_parents = 6, + .ops = _rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = { + F(18000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(25700, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(34200, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(41400, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(52000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(59600, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(67500, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(71000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0), Do we really need to encode anything here in this table? Why can't we have clk_ops that hardcode this clk to be a div-2 that passes the frequency up to the parent source? Then this frequency table doesn't need to be here at all, and can live in DT as an OPP table used by the GPU driver. Thanks for the suggestion. I will address the same in the next patch series where "clk_rcg2_gfx3d_determine_rate" op will always return the best parent as ‘GPU_CC_PLL0_OUT_EVEN’ and best_parent rate equal to twice of the requested rate. This will eliminate the need of frequency table. + { } +}; + +static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = { + .cmd_rcgr = 0x101c, + .mnd_width = 0, + .hid_wi
Re: [PATCH 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings
On 2018-07-09 11:08, Stephen Boyd wrote: Quoting Amit Nischal (2018-06-06 04:41:47) diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt new file mode 100644 index 000..e311219 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt @@ -0,0 +1,18 @@ +Qualcomm Graphics Clock & Reset Controller Binding +-- + +Required properties : +- compatible : shall contain "qcom,sdm845-gpucc". +- reg : shall contain base register location and length. +- #clock-cells : from common clock binding, shall contain 1. +- #reset-cells : from common reset binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Example: + gpucc: clock-controller@@509 { Drop the double '@' Oh. I will fix this in next patch series. + compatible = "qcom,sdm845-gpucc"; + reg = <0x509 0x9000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings
On 2018-07-09 11:08, Stephen Boyd wrote: Quoting Amit Nischal (2018-06-06 04:41:47) diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt new file mode 100644 index 000..e311219 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt @@ -0,0 +1,18 @@ +Qualcomm Graphics Clock & Reset Controller Binding +-- + +Required properties : +- compatible : shall contain "qcom,sdm845-gpucc". +- reg : shall contain base register location and length. +- #clock-cells : from common clock binding, shall contain 1. +- #reset-cells : from common reset binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Example: + gpucc: clock-controller@@509 { Drop the double '@' Oh. I will fix this in next patch series. + compatible = "qcom,sdm845-gpucc"; + reg = <0x509 0x9000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
On 2018-07-09 11:45, Stephen Boyd wrote: Quoting Amit Nischal (2018-06-06 04:41:46) To turn on the gpu_gx_gdsc, there is a hardware requirement to turn on the root clock (GFX3D RCG) first which would be the turn on signal for the gdsc along with the SW_COLLAPSE. As per the current implementation of clk_rcg2_shared_ops, it clears the root_enable bit in the enable() and set_rate() clock ops. But due to the above said requirement for GFX3D shared RCG, root_enable bit would be already set by gdsc driver and rcg2_shared_ops should not clear the root unless the disable is called. It sounds like the GDSC enable is ANDed with the RCG's root enable bit? Here, the root clock (GFX3D RCG) needs to be enabled first before writing to SW_COLLAPSE bit of the GDSC. RCG's CLK_ON signal would power up the GDSC. Does the RCG need to be clocking for the GDSC to actually turn on? Or is it purely that the enable bit is logically combined that way so that if the RCG is parented to a PLL that's off the GDSC will still turn on? Yes, the RCG needs to be clocking for the GPU_GX GDSC to actually turn on. Add support for the same by reusing the existing clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to take care of the root set/clear requirement. Anyway, this patch will probably significantly change given that the RCG is a glorified div-2 that muxes between a safe CXO speed and a configurable PLL frequency. A lot of the logic can probably just be hardcoded then. Thanks for the suggestion. We are planning to introduce the "clk_rcg2_gfx3d_determine_rate" op which will always return the best parent as ‘GPU_CC_PLL0_OUT_EVEN’ and best_parent rate equal to twice of the requested rate. With this approach frequency table for rcg2 structure would not be required as all the supported frequencies would be derived from the GPU_CC_PLL0_OUT_EVEN src with a divider of 2. Also, we will add support to check the requested rate if falls within allowed set_rate range. This will make sure that the source PLL would not go out of the supported range. set_rate_range would be set by the GPUCC driver with min/max value by calling below API. clk_hw_set_rate_range(_cc_gx_gfx3d_clk_src.clkr.hw, 18000, 71000) Signed-off-by: Amit Nischal Patch looks sane. -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
On 2018-07-09 11:45, Stephen Boyd wrote: Quoting Amit Nischal (2018-06-06 04:41:46) To turn on the gpu_gx_gdsc, there is a hardware requirement to turn on the root clock (GFX3D RCG) first which would be the turn on signal for the gdsc along with the SW_COLLAPSE. As per the current implementation of clk_rcg2_shared_ops, it clears the root_enable bit in the enable() and set_rate() clock ops. But due to the above said requirement for GFX3D shared RCG, root_enable bit would be already set by gdsc driver and rcg2_shared_ops should not clear the root unless the disable is called. It sounds like the GDSC enable is ANDed with the RCG's root enable bit? Here, the root clock (GFX3D RCG) needs to be enabled first before writing to SW_COLLAPSE bit of the GDSC. RCG's CLK_ON signal would power up the GDSC. Does the RCG need to be clocking for the GDSC to actually turn on? Or is it purely that the enable bit is logically combined that way so that if the RCG is parented to a PLL that's off the GDSC will still turn on? Yes, the RCG needs to be clocking for the GPU_GX GDSC to actually turn on. Add support for the same by reusing the existing clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to take care of the root set/clear requirement. Anyway, this patch will probably significantly change given that the RCG is a glorified div-2 that muxes between a safe CXO speed and a configurable PLL frequency. A lot of the logic can probably just be hardcoded then. Thanks for the suggestion. We are planning to introduce the "clk_rcg2_gfx3d_determine_rate" op which will always return the best parent as ‘GPU_CC_PLL0_OUT_EVEN’ and best_parent rate equal to twice of the requested rate. With this approach frequency table for rcg2 structure would not be required as all the supported frequencies would be derived from the GPU_CC_PLL0_OUT_EVEN src with a divider of 2. Also, we will add support to check the requested rate if falls within allowed set_rate range. This will make sure that the source PLL would not go out of the supported range. set_rate_range would be set by the GPUCC driver with min/max value by calling below API. clk_hw_set_rate_range(_cc_gx_gfx3d_clk_src.clkr.hw, 18000, 71000) Signed-off-by: Amit Nischal Patch looks sane. -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/4] clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
Hi Stephen, Thanks for the review comments. Regards, Amit On 2018-07-09 11:04, Stephen Boyd wrote: Quoting Amit Nischal (2018-06-06 04:41:45) For some of the GDSCs, there is a requirement to enable/disable the few clocks before turning on/off the gdsc power domain. Add support Why is there a requirement? Do the clks need to be in hw control mode or they can't be turned off when the GDSC is off? It's hard for me to understand with these vague statements. This requirement is primarily to turn on the GPU GX GDSC and these clocks do not need to be in HW control mode and clock disable is not related with the GDSC. To turn on the GX GDSC, root clock (GFX3D RCG) needs to be enabled first before writing to SW_COLLAPSE bit of the GDSC. The CLK_ON signal from RCG would power up the GPU GX GDSC. for the same by specifying a list of clk_hw pointers per gdsc and enable/disable them along with power domain on/off callbacks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/gdsc.c | 44 drivers/clk/qcom/gdsc.h | 5 + 2 files changed, 49 insertions(+) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index a077133..b6adca1 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -12,6 +12,8 @@ */ #include +#include Ugh. +#include Both, really? Above includes are required else we get a compilation error as below: error: dereferencing pointer to incomplete type ret = clk_prepare_enable(sc->clk_hws[i]->clk); ^ #include #include #include @@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc) regmap_update_bits(sc->regmap, sc->clamp_io_ctrl, GMEM_RESET_MASK, 0); } + +static int gdsc_clk_prepare_enable(struct gdsc *sc) +{ + int i, ret; + + for (i = 0; i < sc->clk_count; i++) { + ret = clk_prepare_enable(sc->clk_hws[i]->clk); + if (ret) { + for (i--; i >= 0; i--) + clk_disable_unprepare(sc->clk_hws[i]->clk); + return ret; + } + } + return 0; +} + Looks an awful lot like bulk_enable clk API. As mentioned above, ROOT_EN bit of GFX3D RCG needs to be enabled first to turn on the GDSC. We want this enable to happen only through clock framework API in order to avoid stability issues. -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/4] clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
Hi Stephen, Thanks for the review comments. Regards, Amit On 2018-07-09 11:04, Stephen Boyd wrote: Quoting Amit Nischal (2018-06-06 04:41:45) For some of the GDSCs, there is a requirement to enable/disable the few clocks before turning on/off the gdsc power domain. Add support Why is there a requirement? Do the clks need to be in hw control mode or they can't be turned off when the GDSC is off? It's hard for me to understand with these vague statements. This requirement is primarily to turn on the GPU GX GDSC and these clocks do not need to be in HW control mode and clock disable is not related with the GDSC. To turn on the GX GDSC, root clock (GFX3D RCG) needs to be enabled first before writing to SW_COLLAPSE bit of the GDSC. The CLK_ON signal from RCG would power up the GPU GX GDSC. for the same by specifying a list of clk_hw pointers per gdsc and enable/disable them along with power domain on/off callbacks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/gdsc.c | 44 drivers/clk/qcom/gdsc.h | 5 + 2 files changed, 49 insertions(+) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index a077133..b6adca1 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -12,6 +12,8 @@ */ #include +#include Ugh. +#include Both, really? Above includes are required else we get a compilation error as below: error: dereferencing pointer to incomplete type ret = clk_prepare_enable(sc->clk_hws[i]->clk); ^ #include #include #include @@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc) regmap_update_bits(sc->regmap, sc->clamp_io_ctrl, GMEM_RESET_MASK, 0); } + +static int gdsc_clk_prepare_enable(struct gdsc *sc) +{ + int i, ret; + + for (i = 0; i < sc->clk_count; i++) { + ret = clk_prepare_enable(sc->clk_hws[i]->clk); + if (ret) { + for (i--; i >= 0; i--) + clk_disable_unprepare(sc->clk_hws[i]->clk); + return ret; + } + } + return 0; +} + Looks an awful lot like bulk_enable clk API. As mentioned above, ROOT_EN bit of GFX3D RCG needs to be enabled first to turn on the GDSC. We want this enable to happen only through clock framework API in order to avoid stability issues. -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3] clk: qcom: Enable clocks which needs to be always on for SDM845
There are certain clocks which needs to be always enabled for system operation. Add support for the same by adding 'CLK_IS_CRITICAL' flag for such clocks. Signed-off-by: Amit Nischal --- Changes in v3: * Addressed review comments by Stephen to associate 'CLK_IS_CRITICAL' flag for the clocks which are required to be always ON. * Added two gcc_cpuss* critical clocks and remove direct clock enable for them from gcc probe function. Changes in v2: * Fix target name in kernel configuration help text for SDM845 GCC clock driver. [v1]: https://lkml.org/lkml/2018/5/28/171 [v2]: https://lkml.org/lkml/2018/5/29/43 drivers/clk/qcom/gcc-sdm845.c | 43 ++--- include/dt-bindings/clock/qcom,gcc-sdm845.h | 2 ++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index e78e6f5..0f694ed 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -1103,6 +1103,7 @@ enum { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_camera_ahb_clk", + .flags = CLK_IS_CRITICAL, .ops = _branch2_ops, }, }, @@ -1129,6 +1130,7 @@ enum { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_camera_xo_clk", + .flags = CLK_IS_CRITICAL, .ops = _branch2_ops, }, }, @@ -1270,6 +1272,7 @@ enum { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_disp_ahb_clk", + .flags = CLK_IS_CRITICAL, .ops = _branch2_ops, }, }, @@ -1328,6 +1331,7 @@ enum { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_disp_xo_clk", + .flags = CLK_IS_CRITICAL, .ops = _branch2_ops, }, }, @@ -1397,6 +1401,7 @@ enum { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_gpu_cfg_ahb_clk", + .flags = CLK_IS_CRITICAL, .ops = _branch2_ops, }, }, @@ -2985,6 +2990,7 @@ enum { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_video_ahb_clk", + .flags = CLK_IS_CRITICAL, .ops = _branch2_ops, }, }, @@ -3011,6 +3017,7 @@ enum { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_video_xo_clk", + .flags = CLK_IS_CRITICAL, .ops = _branch2_ops, }, }, @@ -3049,6 +3056,36 @@ enum { }, }; +static struct clk_branch gcc_cpuss_dvm_bus_clk = { + .halt_reg = 0x48190, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x48190, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_dvm_bus_clk", + .flags = CLK_IS_CRITICAL, + .ops = _branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cpuss_gnoc_clk = { + .halt_reg = 0x48004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x48004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_gnoc_clk", + .flags = CLK_IS_CRITICAL, + .ops = _branch2_ops, + }, + }, +}; + static struct gdsc pcie_0_gdsc = { .gdscr = 0x6b004, .pd = { @@ -3344,6 +3381,8 @@ enum { [GPLL0] = , [GPLL0_OUT_EVEN] = _out_even.clkr, [GPLL4] = , + [GCC_CPUSS_DVM_BUS_CLK] = _cpuss_dvm_bus_clk.clkr, + [GCC_CPUSS_GNOC_CLK] = _cpuss_gnoc_clk.clkr, }; static const struct qcom_reset_map gcc_sdm845_resets[] = { @@ -3433,10 +3472,6 @@ static int gcc_sdm845_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); regmap_update_bits(regmap, 0x71028, 0x3, 0x3); - /* Enable CPUSS clocks */ - regmap_update_bits(regmap, 0x48190, BIT(0), 0x1); - regmap_update_bits(regmap, 0x52004, BIT(22), 0x1); - return qcom_cc_really_probe(pdev, _sdm845_desc, regmap); } diff --
[PATCH v3] clk: qcom: Enable clocks which needs to be always on for SDM845
There are certain clocks which needs to be always enabled for system operation. Add support for the same by adding 'CLK_IS_CRITICAL' flag for such clocks. Signed-off-by: Amit Nischal --- Changes in v3: * Addressed review comments by Stephen to associate 'CLK_IS_CRITICAL' flag for the clocks which are required to be always ON. * Added two gcc_cpuss* critical clocks and remove direct clock enable for them from gcc probe function. Changes in v2: * Fix target name in kernel configuration help text for SDM845 GCC clock driver. [v1]: https://lkml.org/lkml/2018/5/28/171 [v2]: https://lkml.org/lkml/2018/5/29/43 drivers/clk/qcom/gcc-sdm845.c | 43 ++--- include/dt-bindings/clock/qcom,gcc-sdm845.h | 2 ++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index e78e6f5..0f694ed 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -1103,6 +1103,7 @@ enum { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_camera_ahb_clk", + .flags = CLK_IS_CRITICAL, .ops = _branch2_ops, }, }, @@ -1129,6 +1130,7 @@ enum { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_camera_xo_clk", + .flags = CLK_IS_CRITICAL, .ops = _branch2_ops, }, }, @@ -1270,6 +1272,7 @@ enum { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_disp_ahb_clk", + .flags = CLK_IS_CRITICAL, .ops = _branch2_ops, }, }, @@ -1328,6 +1331,7 @@ enum { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_disp_xo_clk", + .flags = CLK_IS_CRITICAL, .ops = _branch2_ops, }, }, @@ -1397,6 +1401,7 @@ enum { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_gpu_cfg_ahb_clk", + .flags = CLK_IS_CRITICAL, .ops = _branch2_ops, }, }, @@ -2985,6 +2990,7 @@ enum { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_video_ahb_clk", + .flags = CLK_IS_CRITICAL, .ops = _branch2_ops, }, }, @@ -3011,6 +3017,7 @@ enum { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_video_xo_clk", + .flags = CLK_IS_CRITICAL, .ops = _branch2_ops, }, }, @@ -3049,6 +3056,36 @@ enum { }, }; +static struct clk_branch gcc_cpuss_dvm_bus_clk = { + .halt_reg = 0x48190, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x48190, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_dvm_bus_clk", + .flags = CLK_IS_CRITICAL, + .ops = _branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cpuss_gnoc_clk = { + .halt_reg = 0x48004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x48004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_gnoc_clk", + .flags = CLK_IS_CRITICAL, + .ops = _branch2_ops, + }, + }, +}; + static struct gdsc pcie_0_gdsc = { .gdscr = 0x6b004, .pd = { @@ -3344,6 +3381,8 @@ enum { [GPLL0] = , [GPLL0_OUT_EVEN] = _out_even.clkr, [GPLL4] = , + [GCC_CPUSS_DVM_BUS_CLK] = _cpuss_dvm_bus_clk.clkr, + [GCC_CPUSS_GNOC_CLK] = _cpuss_gnoc_clk.clkr, }; static const struct qcom_reset_map gcc_sdm845_resets[] = { @@ -3433,10 +3472,6 @@ static int gcc_sdm845_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); regmap_update_bits(regmap, 0x71028, 0x3, 0x3); - /* Enable CPUSS clocks */ - regmap_update_bits(regmap, 0x48190, BIT(0), 0x1); - regmap_update_bits(regmap, 0x52004, BIT(22), 0x1); - return qcom_cc_really_probe(pdev, _sdm845_desc, regmap); } diff --
Re: [PATCH v2] clk: qcom: Enable clocks which needs to be always on for SDM845
On 2018-06-01 22:06, Stephen Boyd wrote: Quoting Amit Nischal (2018-05-28 23:07:46) There are certain clocks which needs to be always enabled for system operation. Remove support for such clocks from the clock driver and enable them explicitly gcc driver probe. Also fix the target name in kernel configuration description for SDM845 gcc driver. This is why we have CLK_IS_CRITICAL. Signed-off-by: Amit Nischal --- diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index fc3edd1..79e9144 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -231,7 +231,7 @@ config SDM_GCC_845 select QCOM_GDSC depends on COMMON_CLK_QCOM help - Support for the global clock controller on msm8998 devices. + Support for the global clock controller on SDM845 devices. Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDDC, PCIe, etc. This can be its own patch. Thanks for fixing above as this is already in the clk-next branch under commit "77122d". diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index e78e6f5..b40aafc 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -3433,9 +3327,16 @@ static int gcc_sdm845_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); regmap_update_bits(regmap, 0x71028, 0x3, 0x3); - /* Enable CPUSS clocks */ - regmap_update_bits(regmap, 0x48190, BIT(0), 0x1); - regmap_update_bits(regmap, 0x52004, BIT(22), 0x1); + /* Enable clocks which are required to be always ON */ + regmap_update_bits(regmap, 0xb004, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb008, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb00c, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb028, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb02c, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb030, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x48190, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x52004, BIT(22), BIT(22)); + regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0)); Let's do CLK_IS_CRITICAL flag instead. That has the added benefit of checking to make sure the halt bit toggles correctly so the clks are verified to be enabled. I will submit the next patch for all above-listed clocks with CLK_IS_CRITICAL flag. return qcom_cc_really_probe(pdev, _sdm845_desc, regmap); } diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h b/include/dt-bindings/clock/qcom,gcc-sdm845.h index aca6126..6330c3f 100644 --- a/include/dt-bindings/clock/qcom,gcc-sdm845.h +++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h @@ -13,185 +13,178 @@ #define GCC_AGGRE_USB3_PRIM_AXI_CLK3 #define GCC_AGGRE_USB3_SEC_AXI_CLK 4 #define GCC_BOOT_ROM_AHB_CLK 5 -#define GCC_CAMERA_AHB_CLK 6 Don't do this. Things should only be added to here, not removed or reshuffled. -#define GCC_CAMERA_AXI_CLK 7 -#define GCC_CAMERA_XO_CLK 8 -#define GCC_CE1_AHB_CLK 9 -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] clk: qcom: Enable clocks which needs to be always on for SDM845
On 2018-06-01 22:06, Stephen Boyd wrote: Quoting Amit Nischal (2018-05-28 23:07:46) There are certain clocks which needs to be always enabled for system operation. Remove support for such clocks from the clock driver and enable them explicitly gcc driver probe. Also fix the target name in kernel configuration description for SDM845 gcc driver. This is why we have CLK_IS_CRITICAL. Signed-off-by: Amit Nischal --- diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index fc3edd1..79e9144 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -231,7 +231,7 @@ config SDM_GCC_845 select QCOM_GDSC depends on COMMON_CLK_QCOM help - Support for the global clock controller on msm8998 devices. + Support for the global clock controller on SDM845 devices. Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDDC, PCIe, etc. This can be its own patch. Thanks for fixing above as this is already in the clk-next branch under commit "77122d". diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index e78e6f5..b40aafc 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -3433,9 +3327,16 @@ static int gcc_sdm845_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); regmap_update_bits(regmap, 0x71028, 0x3, 0x3); - /* Enable CPUSS clocks */ - regmap_update_bits(regmap, 0x48190, BIT(0), 0x1); - regmap_update_bits(regmap, 0x52004, BIT(22), 0x1); + /* Enable clocks which are required to be always ON */ + regmap_update_bits(regmap, 0xb004, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb008, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb00c, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb028, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb02c, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb030, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x48190, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x52004, BIT(22), BIT(22)); + regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0)); Let's do CLK_IS_CRITICAL flag instead. That has the added benefit of checking to make sure the halt bit toggles correctly so the clks are verified to be enabled. I will submit the next patch for all above-listed clocks with CLK_IS_CRITICAL flag. return qcom_cc_really_probe(pdev, _sdm845_desc, regmap); } diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h b/include/dt-bindings/clock/qcom,gcc-sdm845.h index aca6126..6330c3f 100644 --- a/include/dt-bindings/clock/qcom,gcc-sdm845.h +++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h @@ -13,185 +13,178 @@ #define GCC_AGGRE_USB3_PRIM_AXI_CLK3 #define GCC_AGGRE_USB3_SEC_AXI_CLK 4 #define GCC_BOOT_ROM_AHB_CLK 5 -#define GCC_CAMERA_AHB_CLK 6 Don't do this. Things should only be added to here, not removed or reshuffled. -#define GCC_CAMERA_AXI_CLK 7 -#define GCC_CAMERA_XO_CLK 8 -#define GCC_CE1_AHB_CLK 9 -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
To turn on the gpu_gx_gdsc, there is a hardware requirement to turn on the root clock (GFX3D RCG) first which would be the turn on signal for the gdsc along with the SW_COLLAPSE. As per the current implementation of clk_rcg2_shared_ops, it clears the root_enable bit in the enable() and set_rate() clock ops. But due to the above said requirement for GFX3D shared RCG, root_enable bit would be already set by gdsc driver and rcg2_shared_ops should not clear the root unless the disable is called. Add support for the same by reusing the existing clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to take care of the root set/clear requirement. Signed-off-by: Amit Nischal --- drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c | 78 + 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index b209a2f..c8c9558 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -160,5 +160,6 @@ struct clk_rcg2 { extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_rcg2_shared_ops; +extern const struct clk_ops clk_rcg2_gfx3d_ops; #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 52208d4..491e710 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -823,28 +823,12 @@ static int clk_rcg2_clear_force_enable(struct clk_hw *hw) CMD_ROOT_EN, 0); } -static int -clk_rcg2_shared_force_enable_clear(struct clk_hw *hw, const struct freq_tbl *f) -{ - struct clk_rcg2 *rcg = to_clk_rcg2(hw); - int ret; - - ret = clk_rcg2_set_force_enable(hw); - if (ret) - return ret; - - ret = clk_rcg2_configure(rcg, f); - if (ret) - return ret; - - return clk_rcg2_clear_force_enable(hw); -} - -static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate, +static int __clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); const struct freq_tbl *f; + int ret; f = qcom_find_freq(rcg->freq_tbl, rate); if (!f) @@ -857,7 +841,23 @@ static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate, if (!__clk_is_enabled(hw->clk)) return __clk_rcg2_configure(rcg, f); - return clk_rcg2_shared_force_enable_clear(hw, f); + ret = clk_rcg2_set_force_enable(hw); + if (ret) + return ret; + + return clk_rcg2_configure(rcg, f); +} + +static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + int ret; + + ret = __clk_rcg2_shared_set_rate(hw, rate, parent_rate); + if (ret) + return ret; + + return clk_rcg2_clear_force_enable(hw); } static int clk_rcg2_shared_set_rate_and_parent(struct clk_hw *hw, @@ -866,7 +866,7 @@ static int clk_rcg2_shared_set_rate_and_parent(struct clk_hw *hw, return clk_rcg2_shared_set_rate(hw, rate, parent_rate); } -static int clk_rcg2_shared_enable(struct clk_hw *hw) +static int __clk_rcg2_shared_enable(struct clk_hw *hw) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); int ret; @@ -879,7 +879,14 @@ static int clk_rcg2_shared_enable(struct clk_hw *hw) if (ret) return ret; - ret = update_config(rcg); + return update_config(rcg); +} + +static int clk_rcg2_shared_enable(struct clk_hw *hw) +{ + int ret; + + ret = __clk_rcg2_shared_enable(hw); if (ret) return ret; @@ -929,3 +936,32 @@ static void clk_rcg2_shared_disable(struct clk_hw *hw) .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent, }; EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); + +static int clk_rcg2_gfx3d_enable(struct clk_hw *hw) +{ + return __clk_rcg2_shared_enable(hw); +} + +static int clk_rcg2_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return __clk_rcg2_shared_set_rate(hw, rate, parent_rate); +} + +static int clk_rcg2_gfx3d_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate, u8 index) +{ + return clk_rcg2_gfx3d_set_rate(hw, rate, parent_rate); +} + +const struct clk_ops clk_rcg2_gfx3d_ops = { + .enable = clk_rcg2_gfx3d_enable, + .disable = clk_rcg2_shared_disable, + .get_parent = clk_rcg2_get_parent, + .set_parent = clk_rcg2_set_parent, + .recalc_rate = clk_rcg2_recalc_rate, + .determine_rate = clk_rcg2_determine_rate, + .set_rate = clk_rcg2_gfx3d_set_rate, + .set_rate_and_parent = clk_rcg2_gfx3d_set
[PATCH 2/4] clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845
To turn on the gpu_gx_gdsc, there is a hardware requirement to turn on the root clock (GFX3D RCG) first which would be the turn on signal for the gdsc along with the SW_COLLAPSE. As per the current implementation of clk_rcg2_shared_ops, it clears the root_enable bit in the enable() and set_rate() clock ops. But due to the above said requirement for GFX3D shared RCG, root_enable bit would be already set by gdsc driver and rcg2_shared_ops should not clear the root unless the disable is called. Add support for the same by reusing the existing clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to take care of the root set/clear requirement. Signed-off-by: Amit Nischal --- drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c | 78 + 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index b209a2f..c8c9558 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -160,5 +160,6 @@ struct clk_rcg2 { extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_rcg2_shared_ops; +extern const struct clk_ops clk_rcg2_gfx3d_ops; #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 52208d4..491e710 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -823,28 +823,12 @@ static int clk_rcg2_clear_force_enable(struct clk_hw *hw) CMD_ROOT_EN, 0); } -static int -clk_rcg2_shared_force_enable_clear(struct clk_hw *hw, const struct freq_tbl *f) -{ - struct clk_rcg2 *rcg = to_clk_rcg2(hw); - int ret; - - ret = clk_rcg2_set_force_enable(hw); - if (ret) - return ret; - - ret = clk_rcg2_configure(rcg, f); - if (ret) - return ret; - - return clk_rcg2_clear_force_enable(hw); -} - -static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate, +static int __clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); const struct freq_tbl *f; + int ret; f = qcom_find_freq(rcg->freq_tbl, rate); if (!f) @@ -857,7 +841,23 @@ static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate, if (!__clk_is_enabled(hw->clk)) return __clk_rcg2_configure(rcg, f); - return clk_rcg2_shared_force_enable_clear(hw, f); + ret = clk_rcg2_set_force_enable(hw); + if (ret) + return ret; + + return clk_rcg2_configure(rcg, f); +} + +static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + int ret; + + ret = __clk_rcg2_shared_set_rate(hw, rate, parent_rate); + if (ret) + return ret; + + return clk_rcg2_clear_force_enable(hw); } static int clk_rcg2_shared_set_rate_and_parent(struct clk_hw *hw, @@ -866,7 +866,7 @@ static int clk_rcg2_shared_set_rate_and_parent(struct clk_hw *hw, return clk_rcg2_shared_set_rate(hw, rate, parent_rate); } -static int clk_rcg2_shared_enable(struct clk_hw *hw) +static int __clk_rcg2_shared_enable(struct clk_hw *hw) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); int ret; @@ -879,7 +879,14 @@ static int clk_rcg2_shared_enable(struct clk_hw *hw) if (ret) return ret; - ret = update_config(rcg); + return update_config(rcg); +} + +static int clk_rcg2_shared_enable(struct clk_hw *hw) +{ + int ret; + + ret = __clk_rcg2_shared_enable(hw); if (ret) return ret; @@ -929,3 +936,32 @@ static void clk_rcg2_shared_disable(struct clk_hw *hw) .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent, }; EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); + +static int clk_rcg2_gfx3d_enable(struct clk_hw *hw) +{ + return __clk_rcg2_shared_enable(hw); +} + +static int clk_rcg2_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return __clk_rcg2_shared_set_rate(hw, rate, parent_rate); +} + +static int clk_rcg2_gfx3d_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate, u8 index) +{ + return clk_rcg2_gfx3d_set_rate(hw, rate, parent_rate); +} + +const struct clk_ops clk_rcg2_gfx3d_ops = { + .enable = clk_rcg2_gfx3d_enable, + .disable = clk_rcg2_shared_disable, + .get_parent = clk_rcg2_get_parent, + .set_parent = clk_rcg2_set_parent, + .recalc_rate = clk_rcg2_recalc_rate, + .determine_rate = clk_rcg2_determine_rate, + .set_rate = clk_rcg2_gfx3d_set_rate, + .set_rate_and_parent = clk_rcg2_gfx3d_set
[PATCH 1/4] clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
For some of the GDSCs, there is a requirement to enable/disable the few clocks before turning on/off the gdsc power domain. Add support for the same by specifying a list of clk_hw pointers per gdsc and enable/disable them along with power domain on/off callbacks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/gdsc.c | 44 drivers/clk/qcom/gdsc.h | 5 + 2 files changed, 49 insertions(+) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index a077133..b6adca1 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -12,6 +12,8 @@ */ #include +#include +#include #include #include #include @@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc) regmap_update_bits(sc->regmap, sc->clamp_io_ctrl, GMEM_RESET_MASK, 0); } + +static int gdsc_clk_prepare_enable(struct gdsc *sc) +{ + int i, ret; + + for (i = 0; i < sc->clk_count; i++) { + ret = clk_prepare_enable(sc->clk_hws[i]->clk); + if (ret) { + for (i--; i >= 0; i--) + clk_disable_unprepare(sc->clk_hws[i]->clk); + return ret; + } + } + return 0; +} + +static void gdsc_clk_disable_unprepare(struct gdsc *sc) +{ + int i; + + for (i = 0; i < sc->clk_count; i++) + clk_disable_unprepare(sc->clk_hws[i]->clk); +} + static int gdsc_enable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); int ret; + if (sc->clk_count) { + ret = gdsc_clk_prepare_enable(sc); + if (ret) + return ret; + } + if (sc->pwrsts == PWRSTS_ON) return gdsc_deassert_reset(sc); @@ -260,6 +292,9 @@ static int gdsc_enable(struct generic_pm_domain *domain) udelay(1); } + if (sc->clk_count) + gdsc_clk_disable_unprepare(sc); + return 0; } @@ -268,6 +303,12 @@ static int gdsc_disable(struct generic_pm_domain *domain) struct gdsc *sc = domain_to_gdsc(domain); int ret; + if (sc->clk_count) { + ret = gdsc_clk_prepare_enable(sc); + if (ret) + return ret; + } + if (sc->pwrsts == PWRSTS_ON) return gdsc_assert_reset(sc); @@ -299,6 +340,9 @@ static int gdsc_disable(struct generic_pm_domain *domain) if (sc->flags & CLAMP_IO) gdsc_assert_clamp_io(sc); + if (sc->clk_count) + gdsc_clk_disable_unprepare(sc); + return 0; } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index bd1f2c7..59957d7 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -17,6 +17,7 @@ #include #include +struct clk_hw; struct regmap; struct reset_controller_dev; @@ -32,6 +33,8 @@ * @resets: ids of resets associated with this gdsc * @reset_count: number of @resets * @rcdev: reset controller + * @clk_count: number of associated clocks + * @clk_hws: clk_hw pointers for associated clocks with gdsc */ struct gdsc { struct generic_pm_domainpd; @@ -60,6 +63,8 @@ struct gdsc { struct reset_controller_dev *rcdev; unsigned int*resets; unsigned intreset_count; + unsigned intclk_count; + struct clk_hw *clk_hws[]; }; struct gdsc_desc { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH 1/4] clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC
For some of the GDSCs, there is a requirement to enable/disable the few clocks before turning on/off the gdsc power domain. Add support for the same by specifying a list of clk_hw pointers per gdsc and enable/disable them along with power domain on/off callbacks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/gdsc.c | 44 drivers/clk/qcom/gdsc.h | 5 + 2 files changed, 49 insertions(+) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index a077133..b6adca1 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -12,6 +12,8 @@ */ #include +#include +#include #include #include #include @@ -208,11 +210,41 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc) regmap_update_bits(sc->regmap, sc->clamp_io_ctrl, GMEM_RESET_MASK, 0); } + +static int gdsc_clk_prepare_enable(struct gdsc *sc) +{ + int i, ret; + + for (i = 0; i < sc->clk_count; i++) { + ret = clk_prepare_enable(sc->clk_hws[i]->clk); + if (ret) { + for (i--; i >= 0; i--) + clk_disable_unprepare(sc->clk_hws[i]->clk); + return ret; + } + } + return 0; +} + +static void gdsc_clk_disable_unprepare(struct gdsc *sc) +{ + int i; + + for (i = 0; i < sc->clk_count; i++) + clk_disable_unprepare(sc->clk_hws[i]->clk); +} + static int gdsc_enable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); int ret; + if (sc->clk_count) { + ret = gdsc_clk_prepare_enable(sc); + if (ret) + return ret; + } + if (sc->pwrsts == PWRSTS_ON) return gdsc_deassert_reset(sc); @@ -260,6 +292,9 @@ static int gdsc_enable(struct generic_pm_domain *domain) udelay(1); } + if (sc->clk_count) + gdsc_clk_disable_unprepare(sc); + return 0; } @@ -268,6 +303,12 @@ static int gdsc_disable(struct generic_pm_domain *domain) struct gdsc *sc = domain_to_gdsc(domain); int ret; + if (sc->clk_count) { + ret = gdsc_clk_prepare_enable(sc); + if (ret) + return ret; + } + if (sc->pwrsts == PWRSTS_ON) return gdsc_assert_reset(sc); @@ -299,6 +340,9 @@ static int gdsc_disable(struct generic_pm_domain *domain) if (sc->flags & CLAMP_IO) gdsc_assert_clamp_io(sc); + if (sc->clk_count) + gdsc_clk_disable_unprepare(sc); + return 0; } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index bd1f2c7..59957d7 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -17,6 +17,7 @@ #include #include +struct clk_hw; struct regmap; struct reset_controller_dev; @@ -32,6 +33,8 @@ * @resets: ids of resets associated with this gdsc * @reset_count: number of @resets * @rcdev: reset controller + * @clk_count: number of associated clocks + * @clk_hws: clk_hw pointers for associated clocks with gdsc */ struct gdsc { struct generic_pm_domainpd; @@ -60,6 +63,8 @@ struct gdsc { struct reset_controller_dev *rcdev; unsigned int*resets; unsigned intreset_count; + unsigned intclk_count; + struct clk_hw *clk_hws[]; }; struct gdsc_desc { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH 0/4] Add QCOM graphics clock controller driver for SDM845
This patch series adds support for graphics clock controller for SDM845. Below is the brief description for each change: 1. For some of the GDSCs, there is requirement to enable/disable the few clocks before turning on/off the gdsc power domain. This patch will add support to enable/disable the clock associated with the gdsc along with power domain on/off callbacks. 2. To turn on the gpu_gx_gdsc, there is a hardware requirement to turn on the root clock (GFX3D RCG) first which would be the turn on signal for the gdsc along with the SW_COLLAPSE. As per the current implementation of clk_rcg2_shared_ops, it clears the root_enable bit in the enable() and set_rate() clock ops. But due to the above said requirement for GFX3D shared RCG, root_enable bit would be already set by gdsc driver and rcg2_shared_ops should not clear the root unless the disable() is called. This patch add support for the same by reusing the existing clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to take care of the root set/clear requirement. 3. Add device tree bindings for graphics clock controller for SDM845. 4. Add graphics clock controller (GPUCC) driver for SDM845. Amit Nischal (4): clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845 dt-bindings: clock: Introduce QCOM Graphics clock bindings clk: qcom: Add graphics clock controller driver for SDM845 .../devicetree/bindings/clock/qcom,gpucc.txt | 18 + drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c| 78 +++- drivers/clk/qcom/gdsc.c| 44 ++ drivers/clk/qcom/gdsc.h| 5 + drivers/clk/qcom/gpucc-sdm845.c| 441 + include/dt-bindings/clock/qcom,gpucc-sdm845.h | 38 ++ 9 files changed, 614 insertions(+), 21 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc.txt create mode 100644 drivers/clk/qcom/gpucc-sdm845.c create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm845.h -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH 4/4] clk: qcom: Add graphics clock controller driver for SDM845
Add support for the graphics clock controller found on SDM845 based devices. This would allow graphics drivers to probe and control their clocks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/Kconfig| 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-sdm845.c | 441 3 files changed, 451 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 9c3480d..193c2f5 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,15 @@ config SDM_GCC_845 Say Y if you want to use peripheral devices such as UART, SPI, i2C, USB, UFS, SDDC, PCIe, etc. +config SDM_GPUCC_845 + tristate "SDM845 Graphics Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + help + Support for the graphics clock controller on SDM845 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config SDM_VIDEOCC_845 tristate "SDM845 Video Clock Controller" depends on COMMON_CLK_QCOM diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 32d17c2..8aa2bc9 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -40,5 +40,6 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o +obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c new file mode 100644 index 000..81f8926 --- /dev/null +++ b/drivers/clk/qcom/gpucc-sdm845.c @@ -0,0 +1,441 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +#define CX_GMU_CBCR_SLEEP_MASK 0xf +#define CX_GMU_CBCR_SLEEP_SHIFT4 +#define CX_GMU_CBCR_WAKE_MASK 0xf +#define CX_GMU_CBCR_WAKE_SHIFT 8 +#define CLK_DIS_WAIT_SHIFT 12 +#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +enum { + P_BI_TCXO, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL0_OUT_EVEN, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL0_OUT_ODD, + P_GPU_CC_PLL1_OUT_EVEN, + P_GPU_CC_PLL1_OUT_MAIN, + P_GPU_CC_PLL1_OUT_ODD, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gpu_cc_parent_names_0[] = { + "bi_tcxo", + "gpu_cc_pll0", + "gpu_cc_pll1", + "gcc_gpu_gpll0_clk_src", + "gcc_gpu_gpll0_div_clk_src", + "core_bi_pll_test_se", +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_EVEN, 1 }, + { P_GPU_CC_PLL0_OUT_ODD, 2 }, + { P_GPU_CC_PLL1_OUT_EVEN, 3 }, + { P_GPU_CC_PLL1_OUT_ODD, 4 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gpu_cc_parent_names_1[] = { + "bi_tcxo", + "gpu_cc_pll0_out_even", + "gpu_cc_pll0_out_odd", + "gpu_cc_pll1_out_even", + "gpu_cc_pll1_out_odd", + "gcc_gpu_gpll0_clk_src", + "core_bi_pll_test_se", +}; + +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x1d, + .alpha = 0x2aaa, +}; + +static const struct alpha_pll_config gpu_cc_pll1_config = { + .l = 0x1a, + .alpha = 0xaab, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_
[PATCH 0/4] Add QCOM graphics clock controller driver for SDM845
This patch series adds support for graphics clock controller for SDM845. Below is the brief description for each change: 1. For some of the GDSCs, there is requirement to enable/disable the few clocks before turning on/off the gdsc power domain. This patch will add support to enable/disable the clock associated with the gdsc along with power domain on/off callbacks. 2. To turn on the gpu_gx_gdsc, there is a hardware requirement to turn on the root clock (GFX3D RCG) first which would be the turn on signal for the gdsc along with the SW_COLLAPSE. As per the current implementation of clk_rcg2_shared_ops, it clears the root_enable bit in the enable() and set_rate() clock ops. But due to the above said requirement for GFX3D shared RCG, root_enable bit would be already set by gdsc driver and rcg2_shared_ops should not clear the root unless the disable() is called. This patch add support for the same by reusing the existing clk_rcg2_shared_ops and deriving "clk_rcg2_gfx3d_ops" clk_ops for GFX3D clock to take care of the root set/clear requirement. 3. Add device tree bindings for graphics clock controller for SDM845. 4. Add graphics clock controller (GPUCC) driver for SDM845. Amit Nischal (4): clk: qcom: gdsc: Add support to enable/disable the clocks with GDSC clk: qcom: Add clk_rcg2_gfx3d_ops for SDM845 dt-bindings: clock: Introduce QCOM Graphics clock bindings clk: qcom: Add graphics clock controller driver for SDM845 .../devicetree/bindings/clock/qcom,gpucc.txt | 18 + drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c| 78 +++- drivers/clk/qcom/gdsc.c| 44 ++ drivers/clk/qcom/gdsc.h| 5 + drivers/clk/qcom/gpucc-sdm845.c| 441 + include/dt-bindings/clock/qcom,gpucc-sdm845.h | 38 ++ 9 files changed, 614 insertions(+), 21 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc.txt create mode 100644 drivers/clk/qcom/gpucc-sdm845.c create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm845.h -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH 4/4] clk: qcom: Add graphics clock controller driver for SDM845
Add support for the graphics clock controller found on SDM845 based devices. This would allow graphics drivers to probe and control their clocks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/Kconfig| 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-sdm845.c | 441 3 files changed, 451 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 9c3480d..193c2f5 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,15 @@ config SDM_GCC_845 Say Y if you want to use peripheral devices such as UART, SPI, i2C, USB, UFS, SDDC, PCIe, etc. +config SDM_GPUCC_845 + tristate "SDM845 Graphics Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + help + Support for the graphics clock controller on SDM845 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config SDM_VIDEOCC_845 tristate "SDM845 Video Clock Controller" depends on COMMON_CLK_QCOM diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 32d17c2..8aa2bc9 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -40,5 +40,6 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o +obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c new file mode 100644 index 000..81f8926 --- /dev/null +++ b/drivers/clk/qcom/gpucc-sdm845.c @@ -0,0 +1,441 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +#define CX_GMU_CBCR_SLEEP_MASK 0xf +#define CX_GMU_CBCR_SLEEP_SHIFT4 +#define CX_GMU_CBCR_WAKE_MASK 0xf +#define CX_GMU_CBCR_WAKE_SHIFT 8 +#define CLK_DIS_WAIT_SHIFT 12 +#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +enum { + P_BI_TCXO, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL0_OUT_EVEN, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL0_OUT_ODD, + P_GPU_CC_PLL1_OUT_EVEN, + P_GPU_CC_PLL1_OUT_MAIN, + P_GPU_CC_PLL1_OUT_ODD, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gpu_cc_parent_names_0[] = { + "bi_tcxo", + "gpu_cc_pll0", + "gpu_cc_pll1", + "gcc_gpu_gpll0_clk_src", + "gcc_gpu_gpll0_div_clk_src", + "core_bi_pll_test_se", +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_EVEN, 1 }, + { P_GPU_CC_PLL0_OUT_ODD, 2 }, + { P_GPU_CC_PLL1_OUT_EVEN, 3 }, + { P_GPU_CC_PLL1_OUT_ODD, 4 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gpu_cc_parent_names_1[] = { + "bi_tcxo", + "gpu_cc_pll0_out_even", + "gpu_cc_pll0_out_odd", + "gpu_cc_pll1_out_even", + "gpu_cc_pll1_out_odd", + "gcc_gpu_gpll0_clk_src", + "core_bi_pll_test_se", +}; + +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x1d, + .alpha = 0x2aaa, +}; + +static const struct alpha_pll_config gpu_cc_pll1_config = { + .l = 0x1a, + .alpha = 0xaab, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_
[PATCH 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings
Add device tree bindings for graphics clock controller for Qualcomm Technology Inc's SoCs. Signed-off-by: Amit Nischal --- .../devicetree/bindings/clock/qcom,gpucc.txt | 18 ++ include/dt-bindings/clock/qcom,gpucc-sdm845.h | 38 ++ 2 files changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc.txt create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt new file mode 100644 index 000..e311219 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt @@ -0,0 +1,18 @@ +Qualcomm Graphics Clock & Reset Controller Binding +-- + +Required properties : +- compatible : shall contain "qcom,sdm845-gpucc". +- reg : shall contain base register location and length. +- #clock-cells : from common clock binding, shall contain 1. +- #reset-cells : from common reset binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Example: + gpucc: clock-controller@@509 { + compatible = "qcom,sdm845-gpucc"; + reg = <0x509 0x9000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/clock/qcom,gpucc-sdm845.h b/include/dt-bindings/clock/qcom,gpucc-sdm845.h new file mode 100644 index 000..b9cbce5 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gpucc-sdm845.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H +#define _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H + +/* GPU_CC clock registers */ +#define GPU_CC_CRC_AHB_CLK 0 +#define GPU_CC_CX_APB_CLK 1 +#define GPU_CC_CX_GFX3D_CLK2 +#define GPU_CC_CX_GFX3D_SLV_CLK3 +#define GPU_CC_CX_GMU_CLK 4 +#define GPU_CC_CX_SNOC_DVM_CLK 5 +#define GPU_CC_CXO_CLK 6 +#define GPU_CC_GMU_CLK_SRC 7 +#define GPU_CC_GX_GMU_CLK 8 +#define GPU_CC_GX_GFX3D_CLK_SRC9 +#define GPU_CC_GX_GFX3D_CLK10 +#define GPU_CC_PLL011 +#define GPU_CC_PLL0_OUT_EVEN 12 +#define GPU_CC_PLL112 + +/* GPU_CC Resets */ +#define GPUCC_GPU_CC_ACD_BCR 0 +#define GPUCC_GPU_CC_CX_BCR1 +#define GPUCC_GPU_CC_GFX3D_AON_BCR 2 +#define GPUCC_GPU_CC_GMU_BCR 3 +#define GPUCC_GPU_CC_GX_BCR4 +#define GPUCC_GPU_CC_SPDM_BCR 5 +#define GPUCC_GPU_CC_XO_BCR6 + +/* GPU_CC GDSCRs */ +#define GPU_CX_GDSC0 +#define GPU_GX_GDSC1 + +#endif -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH 3/4] dt-bindings: clock: Introduce QCOM Graphics clock bindings
Add device tree bindings for graphics clock controller for Qualcomm Technology Inc's SoCs. Signed-off-by: Amit Nischal --- .../devicetree/bindings/clock/qcom,gpucc.txt | 18 ++ include/dt-bindings/clock/qcom,gpucc-sdm845.h | 38 ++ 2 files changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gpucc.txt create mode 100644 include/dt-bindings/clock/qcom,gpucc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt new file mode 100644 index 000..e311219 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt @@ -0,0 +1,18 @@ +Qualcomm Graphics Clock & Reset Controller Binding +-- + +Required properties : +- compatible : shall contain "qcom,sdm845-gpucc". +- reg : shall contain base register location and length. +- #clock-cells : from common clock binding, shall contain 1. +- #reset-cells : from common reset binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Example: + gpucc: clock-controller@@509 { + compatible = "qcom,sdm845-gpucc"; + reg = <0x509 0x9000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/clock/qcom,gpucc-sdm845.h b/include/dt-bindings/clock/qcom,gpucc-sdm845.h new file mode 100644 index 000..b9cbce5 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gpucc-sdm845.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H +#define _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H + +/* GPU_CC clock registers */ +#define GPU_CC_CRC_AHB_CLK 0 +#define GPU_CC_CX_APB_CLK 1 +#define GPU_CC_CX_GFX3D_CLK2 +#define GPU_CC_CX_GFX3D_SLV_CLK3 +#define GPU_CC_CX_GMU_CLK 4 +#define GPU_CC_CX_SNOC_DVM_CLK 5 +#define GPU_CC_CXO_CLK 6 +#define GPU_CC_GMU_CLK_SRC 7 +#define GPU_CC_GX_GMU_CLK 8 +#define GPU_CC_GX_GFX3D_CLK_SRC9 +#define GPU_CC_GX_GFX3D_CLK10 +#define GPU_CC_PLL011 +#define GPU_CC_PLL0_OUT_EVEN 12 +#define GPU_CC_PLL112 + +/* GPU_CC Resets */ +#define GPUCC_GPU_CC_ACD_BCR 0 +#define GPUCC_GPU_CC_CX_BCR1 +#define GPUCC_GPU_CC_GFX3D_AON_BCR 2 +#define GPUCC_GPU_CC_GMU_BCR 3 +#define GPUCC_GPU_CC_GX_BCR4 +#define GPUCC_GPU_CC_SPDM_BCR 5 +#define GPUCC_GPU_CC_XO_BCR6 + +/* GPU_CC GDSCRs */ +#define GPU_CX_GDSC0 +#define GPU_GX_GDSC1 + +#endif -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v2] clk: qcom: Enable clocks which needs to be always on for SDM845
There are certain clocks which needs to be always enabled for system operation. Remove support for such clocks from the clock driver and enable them explicitly gcc driver probe. Also fix the target name in kernel configuration description for SDM845 gcc driver. Signed-off-by: Amit Nischal --- Changes in v2: * Fix target name in kernel configuration help text for SDM845 GCC clock driver. [v1]: https://lkml.org/lkml/2018/5/28/171 drivers/clk/qcom/Kconfig| 2 +- drivers/clk/qcom/gcc-sdm845.c | 119 +- include/dt-bindings/clock/qcom,gcc-sdm845.h | 351 ++-- 3 files changed, 183 insertions(+), 289 deletions(-) diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index fc3edd1..79e9144 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -231,7 +231,7 @@ config SDM_GCC_845 select QCOM_GDSC depends on COMMON_CLK_QCOM help - Support for the global clock controller on msm8998 devices. + Support for the global clock controller on SDM845 devices. Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDDC, PCIe, etc. diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index e78e6f5..b40aafc 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -1093,21 +1093,6 @@ enum { }, }; -static struct clk_branch gcc_camera_ahb_clk = { - .halt_reg = 0xb008, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb008, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb008, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_camera_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_camera_axi_clk = { .halt_reg = 0xb020, .halt_check = BRANCH_VOTED, @@ -1121,19 +1106,6 @@ enum { }, }; -static struct clk_branch gcc_camera_xo_clk = { - .halt_reg = 0xb02c, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0xb02c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_camera_xo_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_ce1_ahb_clk = { .halt_reg = 0x4100c, .halt_check = BRANCH_HALT_VOTED, @@ -1260,21 +1232,6 @@ enum { }, }; -static struct clk_branch gcc_disp_ahb_clk = { - .halt_reg = 0xb00c, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb00c, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb00c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_disp_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_disp_axi_clk = { .halt_reg = 0xb024, .halt_check = BRANCH_VOTED, @@ -1320,19 +1277,6 @@ enum { }, }; -static struct clk_branch gcc_disp_xo_clk = { - .halt_reg = 0xb030, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0xb030, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_disp_xo_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gp1_clk = { .halt_reg = 0x64000, .halt_check = BRANCH_HALT, @@ -1387,21 +1331,6 @@ enum { }, }; -static struct clk_branch gcc_gpu_cfg_ahb_clk = { - .halt_reg = 0x71004, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0x71004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x71004, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_gpu_cfg_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gpu_gpll0_clk_src = { .halt_check = BRANCH_HALT_DELAY, .clkr = { @@ -2975,21 +2904,6 @@ enum { }, }; -static struct clk_branch gcc_video_ahb_clk = { - .halt_reg = 0xb004, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb004, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_video_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_video_axi_clk = { .halt_reg = 0xb01c, .halt_check = BRANCH_VOTED, @@ -
[PATCH v2] clk: qcom: Enable clocks which needs to be always on for SDM845
There are certain clocks which needs to be always enabled for system operation. Remove support for such clocks from the clock driver and enable them explicitly gcc driver probe. Also fix the target name in kernel configuration description for SDM845 gcc driver. Signed-off-by: Amit Nischal --- Changes in v2: * Fix target name in kernel configuration help text for SDM845 GCC clock driver. [v1]: https://lkml.org/lkml/2018/5/28/171 drivers/clk/qcom/Kconfig| 2 +- drivers/clk/qcom/gcc-sdm845.c | 119 +- include/dt-bindings/clock/qcom,gcc-sdm845.h | 351 ++-- 3 files changed, 183 insertions(+), 289 deletions(-) diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index fc3edd1..79e9144 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -231,7 +231,7 @@ config SDM_GCC_845 select QCOM_GDSC depends on COMMON_CLK_QCOM help - Support for the global clock controller on msm8998 devices. + Support for the global clock controller on SDM845 devices. Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDDC, PCIe, etc. diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index e78e6f5..b40aafc 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -1093,21 +1093,6 @@ enum { }, }; -static struct clk_branch gcc_camera_ahb_clk = { - .halt_reg = 0xb008, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb008, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb008, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_camera_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_camera_axi_clk = { .halt_reg = 0xb020, .halt_check = BRANCH_VOTED, @@ -1121,19 +1106,6 @@ enum { }, }; -static struct clk_branch gcc_camera_xo_clk = { - .halt_reg = 0xb02c, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0xb02c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_camera_xo_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_ce1_ahb_clk = { .halt_reg = 0x4100c, .halt_check = BRANCH_HALT_VOTED, @@ -1260,21 +1232,6 @@ enum { }, }; -static struct clk_branch gcc_disp_ahb_clk = { - .halt_reg = 0xb00c, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb00c, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb00c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_disp_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_disp_axi_clk = { .halt_reg = 0xb024, .halt_check = BRANCH_VOTED, @@ -1320,19 +1277,6 @@ enum { }, }; -static struct clk_branch gcc_disp_xo_clk = { - .halt_reg = 0xb030, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0xb030, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_disp_xo_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gp1_clk = { .halt_reg = 0x64000, .halt_check = BRANCH_HALT, @@ -1387,21 +1331,6 @@ enum { }, }; -static struct clk_branch gcc_gpu_cfg_ahb_clk = { - .halt_reg = 0x71004, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0x71004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x71004, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_gpu_cfg_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gpu_gpll0_clk_src = { .halt_check = BRANCH_HALT_DELAY, .clkr = { @@ -2975,21 +2904,6 @@ enum { }, }; -static struct clk_branch gcc_video_ahb_clk = { - .halt_reg = 0xb004, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb004, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_video_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_video_axi_clk = { .halt_reg = 0xb01c, .halt_check = BRANCH_VOTED, @@ -
[PATCH] clk: qcom: Enable clocks which needs to be always on for SDM845
There are certain clocks which needs to be always enabled for system operation. Remove support for such clocks from the clock driver and enable them explicitly gcc driver probe. Signed-off-by: Amit Nischal <anisc...@codeaurora.org> --- drivers/clk/qcom/gcc-sdm845.c | 119 +- include/dt-bindings/clock/qcom,gcc-sdm845.h | 351 ++-- 2 files changed, 182 insertions(+), 288 deletions(-) diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index e78e6f5..b40aafc 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -1093,21 +1093,6 @@ enum { }, }; -static struct clk_branch gcc_camera_ahb_clk = { - .halt_reg = 0xb008, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb008, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb008, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_camera_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_camera_axi_clk = { .halt_reg = 0xb020, .halt_check = BRANCH_VOTED, @@ -1121,19 +1106,6 @@ enum { }, }; -static struct clk_branch gcc_camera_xo_clk = { - .halt_reg = 0xb02c, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0xb02c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_camera_xo_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_ce1_ahb_clk = { .halt_reg = 0x4100c, .halt_check = BRANCH_HALT_VOTED, @@ -1260,21 +1232,6 @@ enum { }, }; -static struct clk_branch gcc_disp_ahb_clk = { - .halt_reg = 0xb00c, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb00c, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb00c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_disp_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_disp_axi_clk = { .halt_reg = 0xb024, .halt_check = BRANCH_VOTED, @@ -1320,19 +1277,6 @@ enum { }, }; -static struct clk_branch gcc_disp_xo_clk = { - .halt_reg = 0xb030, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0xb030, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_disp_xo_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gp1_clk = { .halt_reg = 0x64000, .halt_check = BRANCH_HALT, @@ -1387,21 +1331,6 @@ enum { }, }; -static struct clk_branch gcc_gpu_cfg_ahb_clk = { - .halt_reg = 0x71004, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0x71004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x71004, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_gpu_cfg_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gpu_gpll0_clk_src = { .halt_check = BRANCH_HALT_DELAY, .clkr = { @@ -2975,21 +2904,6 @@ enum { }, }; -static struct clk_branch gcc_video_ahb_clk = { - .halt_reg = 0xb004, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb004, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_video_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_video_axi_clk = { .halt_reg = 0xb01c, .halt_check = BRANCH_VOTED, @@ -3003,19 +2917,6 @@ enum { }, }; -static struct clk_branch gcc_video_xo_clk = { - .halt_reg = 0xb028, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0xb028, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_video_xo_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_vs_ctrl_ahb_clk = { .halt_reg = 0x7a014, .halt_check = BRANCH_HALT, @@ -3167,9 +3068,7 @@ enum { [GCC_AGGRE_USB3_SEC_AXI_CLK] = _aggre_usb3_sec_axi_clk.clkr, [GCC_APC_VS_CLK] = _apc_vs_clk.clkr, [GCC_BOOT_ROM_AHB_CLK] = _boot_rom_ahb_clk.clkr, - [GCC_CAMERA_AHB_CLK]
[PATCH] clk: qcom: Enable clocks which needs to be always on for SDM845
There are certain clocks which needs to be always enabled for system operation. Remove support for such clocks from the clock driver and enable them explicitly gcc driver probe. Signed-off-by: Amit Nischal --- drivers/clk/qcom/gcc-sdm845.c | 119 +- include/dt-bindings/clock/qcom,gcc-sdm845.h | 351 ++-- 2 files changed, 182 insertions(+), 288 deletions(-) diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index e78e6f5..b40aafc 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -1093,21 +1093,6 @@ enum { }, }; -static struct clk_branch gcc_camera_ahb_clk = { - .halt_reg = 0xb008, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb008, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb008, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_camera_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_camera_axi_clk = { .halt_reg = 0xb020, .halt_check = BRANCH_VOTED, @@ -1121,19 +1106,6 @@ enum { }, }; -static struct clk_branch gcc_camera_xo_clk = { - .halt_reg = 0xb02c, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0xb02c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_camera_xo_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_ce1_ahb_clk = { .halt_reg = 0x4100c, .halt_check = BRANCH_HALT_VOTED, @@ -1260,21 +1232,6 @@ enum { }, }; -static struct clk_branch gcc_disp_ahb_clk = { - .halt_reg = 0xb00c, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb00c, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb00c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_disp_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_disp_axi_clk = { .halt_reg = 0xb024, .halt_check = BRANCH_VOTED, @@ -1320,19 +1277,6 @@ enum { }, }; -static struct clk_branch gcc_disp_xo_clk = { - .halt_reg = 0xb030, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0xb030, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_disp_xo_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gp1_clk = { .halt_reg = 0x64000, .halt_check = BRANCH_HALT, @@ -1387,21 +1331,6 @@ enum { }, }; -static struct clk_branch gcc_gpu_cfg_ahb_clk = { - .halt_reg = 0x71004, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0x71004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x71004, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_gpu_cfg_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gpu_gpll0_clk_src = { .halt_check = BRANCH_HALT_DELAY, .clkr = { @@ -2975,21 +2904,6 @@ enum { }, }; -static struct clk_branch gcc_video_ahb_clk = { - .halt_reg = 0xb004, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb004, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_video_ahb_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_video_axi_clk = { .halt_reg = 0xb01c, .halt_check = BRANCH_VOTED, @@ -3003,19 +2917,6 @@ enum { }, }; -static struct clk_branch gcc_video_xo_clk = { - .halt_reg = 0xb028, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0xb028, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_video_xo_clk", - .ops = _branch2_ops, - }, - }, -}; - static struct clk_branch gcc_vs_ctrl_ahb_clk = { .halt_reg = 0x7a014, .halt_check = BRANCH_HALT, @@ -3167,9 +3068,7 @@ enum { [GCC_AGGRE_USB3_SEC_AXI_CLK] = _aggre_usb3_sec_axi_clk.clkr, [GCC_APC_VS_CLK] = _apc_vs_clk.clkr, [GCC_BOOT_ROM_AHB_CLK] = _boot_rom_ahb_clk.clkr, - [GCC_CAMERA_AHB_CLK] = _camera_ahb_clk.clkr,
Re: [PATCH v1 0/2] Add QCOM video clock controller driver
On 2018-05-09 01:45, Stephen Boyd wrote: Quoting Rob Herring (2018-05-08 05:48:07) On Mon, May 7, 2018 at 11:53 PM, Amit Nischal <anisc...@codeaurora.org> wrote: > On 2018-05-07 22:41, Rob Herring wrote: >> >> On Mon, May 07, 2018 at 04:16:53PM +0530, Amit Nischal wrote: >>> >>> On 2018-05-04 22:01, Stephen Boyd wrote: >>> > Quoting Amit Nischal (2018-05-03 05:35:23) >>> > > Changes in v1: >>> > >https://lkml.org/lkml/2018/4/24/545 >>> > > Addressed below review comments given by Rob >>> > > - Change the compatible property as per ',-' >>> > > format. >>> > > - Add header definitions for resets and power-domain cells. >>> > >>> > You didn't add any reset definitions though? >>> >>> We haven't added the reset definitions for videocc as there is no >>> video reset client. >> >> >> So? You don't know what resets there are? >> > > We know the resets, but video driver doesn't do any block resets > prior to accessing the video subsystem so that's the reason we do > not want to expose the resets in videocc driver. Bindings don't have to match what drivers currently use but should be complete as possible. Right. Please add the #defines in the header file for the resets. You can leave them out of the driver if you really want to, but typically we still add them and then rely on not touching them if they shouldn't be used. Thanks for the suggestion. I will add the videocc resets in the header file.
Re: [PATCH v1 0/2] Add QCOM video clock controller driver
On 2018-05-09 01:45, Stephen Boyd wrote: Quoting Rob Herring (2018-05-08 05:48:07) On Mon, May 7, 2018 at 11:53 PM, Amit Nischal wrote: > On 2018-05-07 22:41, Rob Herring wrote: >> >> On Mon, May 07, 2018 at 04:16:53PM +0530, Amit Nischal wrote: >>> >>> On 2018-05-04 22:01, Stephen Boyd wrote: >>> > Quoting Amit Nischal (2018-05-03 05:35:23) >>> > > Changes in v1: >>> > >https://lkml.org/lkml/2018/4/24/545 >>> > > Addressed below review comments given by Rob >>> > > - Change the compatible property as per ',-' >>> > > format. >>> > > - Add header definitions for resets and power-domain cells. >>> > >>> > You didn't add any reset definitions though? >>> >>> We haven't added the reset definitions for videocc as there is no >>> video reset client. >> >> >> So? You don't know what resets there are? >> > > We know the resets, but video driver doesn't do any block resets > prior to accessing the video subsystem so that's the reason we do > not want to expose the resets in videocc driver. Bindings don't have to match what drivers currently use but should be complete as possible. Right. Please add the #defines in the header file for the resets. You can leave them out of the driver if you really want to, but typically we still add them and then rely on not touching them if they shouldn't be used. Thanks for the suggestion. I will add the videocc resets in the header file.
[PATCH v2 2/2] clk: qcom: Add video clock controller driver for SDM845
Add support for the video clock controller found on SDM845 based devices. This would allow video drivers to probe and control their clocks. Signed-off-by: Amit Nischal <anisc...@codeaurora.org> --- drivers/clk/qcom/Kconfig | 11 ++ drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/videocc-sdm845.c | 358 ++ 3 files changed, 370 insertions(+) create mode 100644 drivers/clk/qcom/videocc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index aec69d2..81388ee 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,17 @@ config SDM_GCC_845 Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDDC, PCIe, etc. +config SDM_VIDEOCC_845 + tristate "SDM845 Video Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + select QCOM_GDSC + help + Support for the video clock controller on Qualcomm Technologies, Inc + SDM845 devices. + Say Y if you want to support video devices and functionality such as + video encode and decode. + config SPMI_PMIC_CLKDIV tristate "SPMI PMIC clkdiv Support" depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index bf8fb25..762c011 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -39,4 +39,5 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o +obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o diff --git a/drivers/clk/qcom/videocc-sdm845.c b/drivers/clk/qcom/videocc-sdm845.c new file mode 100644 index 000..9073b7a --- /dev/null +++ b/drivers/clk/qcom/videocc-sdm845.c @@ -0,0 +1,358 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-pll.h" +#include "gdsc.h" + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +enum { + P_BI_TCXO, + P_CORE_BI_PLL_TEST_SE, + P_VIDEO_PLL0_OUT_EVEN, + P_VIDEO_PLL0_OUT_MAIN, + P_VIDEO_PLL0_OUT_ODD, +}; + +static const struct parent_map video_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_PLL0_OUT_MAIN, 1 }, + { P_VIDEO_PLL0_OUT_EVEN, 2 }, + { P_VIDEO_PLL0_OUT_ODD, 3 }, + { P_CORE_BI_PLL_TEST_SE, 4 }, +}; + +static const char * const video_cc_parent_names_0[] = { + "bi_tcxo", + "video_pll0", + "video_pll0_out_even", + "video_pll0_out_odd", + "core_bi_pll_test_se", +}; + +static const struct alpha_pll_config video_pll0_config = { + .l = 0x10, + .alpha = 0xaaab, +}; + +static struct clk_alpha_pll video_pll0 = { + .offset = 0x42c, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "video_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_video_cc_venus_clk_src[] = { + F(1, P_VIDEO_PLL0_OUT_MAIN, 4, 0, 0), + F(2, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0), + F(33000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), + F(40400, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), + F(44400, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), + F(53300, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_venus_clk_src = { + .cmd_rcgr = 0x7f0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_venus_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "video_cc_venus_clk_src", + .parent_names = video_cc_parent_names_0, + .num_parents = 5, + .flags = CLK_SET_RATE_PARENT, + .ops = _rcg2_shared_ops, + }, +}; + +static struct clk_branch video_cc_apb_clk = { + .halt_reg = 0x990, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x990, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_cc_apb_clk", + .ops = _bran
[PATCH v2 2/2] clk: qcom: Add video clock controller driver for SDM845
Add support for the video clock controller found on SDM845 based devices. This would allow video drivers to probe and control their clocks. Signed-off-by: Amit Nischal --- drivers/clk/qcom/Kconfig | 11 ++ drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/videocc-sdm845.c | 358 ++ 3 files changed, 370 insertions(+) create mode 100644 drivers/clk/qcom/videocc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index aec69d2..81388ee 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,17 @@ config SDM_GCC_845 Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDDC, PCIe, etc. +config SDM_VIDEOCC_845 + tristate "SDM845 Video Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + select QCOM_GDSC + help + Support for the video clock controller on Qualcomm Technologies, Inc + SDM845 devices. + Say Y if you want to support video devices and functionality such as + video encode and decode. + config SPMI_PMIC_CLKDIV tristate "SPMI PMIC clkdiv Support" depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index bf8fb25..762c011 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -39,4 +39,5 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o +obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o diff --git a/drivers/clk/qcom/videocc-sdm845.c b/drivers/clk/qcom/videocc-sdm845.c new file mode 100644 index 000..9073b7a --- /dev/null +++ b/drivers/clk/qcom/videocc-sdm845.c @@ -0,0 +1,358 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-pll.h" +#include "gdsc.h" + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +enum { + P_BI_TCXO, + P_CORE_BI_PLL_TEST_SE, + P_VIDEO_PLL0_OUT_EVEN, + P_VIDEO_PLL0_OUT_MAIN, + P_VIDEO_PLL0_OUT_ODD, +}; + +static const struct parent_map video_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_PLL0_OUT_MAIN, 1 }, + { P_VIDEO_PLL0_OUT_EVEN, 2 }, + { P_VIDEO_PLL0_OUT_ODD, 3 }, + { P_CORE_BI_PLL_TEST_SE, 4 }, +}; + +static const char * const video_cc_parent_names_0[] = { + "bi_tcxo", + "video_pll0", + "video_pll0_out_even", + "video_pll0_out_odd", + "core_bi_pll_test_se", +}; + +static const struct alpha_pll_config video_pll0_config = { + .l = 0x10, + .alpha = 0xaaab, +}; + +static struct clk_alpha_pll video_pll0 = { + .offset = 0x42c, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "video_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = _alpha_pll_fabia_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_video_cc_venus_clk_src[] = { + F(1, P_VIDEO_PLL0_OUT_MAIN, 4, 0, 0), + F(2, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0), + F(33000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), + F(40400, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), + F(44400, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), + F(53300, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_venus_clk_src = { + .cmd_rcgr = 0x7f0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_venus_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "video_cc_venus_clk_src", + .parent_names = video_cc_parent_names_0, + .num_parents = 5, + .flags = CLK_SET_RATE_PARENT, + .ops = _rcg2_shared_ops, + }, +}; + +static struct clk_branch video_cc_apb_clk = { + .halt_reg = 0x990, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x990, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_cc_apb_clk", + .ops = _branch2_ops, + }, +
[PATCH v2 1/2] dt-bindings: clock: Introduce QCOM Video clock bindings
Add device tree bindings for video clock controller for Qualcomm Technology Inc's SoCs. Signed-off-by: Amit Nischal <anisc...@codeaurora.org> --- .../devicetree/bindings/clock/qcom,videocc.txt | 19 include/dt-bindings/clock/qcom,videocc-sdm845.h| 35 ++ 2 files changed, 54 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,videocc.txt create mode 100644 include/dt-bindings/clock/qcom,videocc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,videocc.txt b/Documentation/devicetree/bindings/clock/qcom,videocc.txt new file mode 100644 index 000..e7c035a --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,videocc.txt @@ -0,0 +1,19 @@ +Qualcomm Video Clock & Reset Controller Binding +--- + +Required properties : +- compatible : shall contain "qcom,sdm845-videocc" +- reg : shall contain base register location and length +- #clock-cells : from common clock binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Optional properties : +- #reset-cells : from common reset binding, shall contain 1. + +Example: + videocc: clock-controller@ab0 { + compatible = "qcom,sdm845-videocc"; + reg = <0xab0 0x1>; + #clock-cells = <1>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/clock/qcom,videocc-sdm845.h b/include/dt-bindings/clock/qcom,videocc-sdm845.h new file mode 100644 index 000..1b86816 --- /dev/null +++ b/include/dt-bindings/clock/qcom,videocc-sdm845.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_SDM_VIDEO_CC_SDM845_H +#define _DT_BINDINGS_CLK_SDM_VIDEO_CC_SDM845_H + +/* VIDEO_CC clock registers */ +#define VIDEO_CC_APB_CLK 0 +#define VIDEO_CC_AT_CLK1 +#define VIDEO_CC_QDSS_TRIG_CLK 2 +#define VIDEO_CC_QDSS_TSCTR_DIV8_CLK 3 +#define VIDEO_CC_VCODEC0_AXI_CLK 4 +#define VIDEO_CC_VCODEC0_CORE_CLK 5 +#define VIDEO_CC_VCODEC1_AXI_CLK 6 +#define VIDEO_CC_VCODEC1_CORE_CLK 7 +#define VIDEO_CC_VENUS_AHB_CLK 8 +#define VIDEO_CC_VENUS_CLK_SRC 9 +#define VIDEO_CC_VENUS_CTL_AXI_CLK 10 +#define VIDEO_CC_VENUS_CTL_CORE_CLK11 +#define VIDEO_PLL0 12 + +/* VIDEO_CC Resets */ +#define VIDEO_CC_VENUS_BCR 0 +#define VIDEO_CC_VCODEC0_BCR 1 +#define VIDEO_CC_VCODEC1_BCR 2 +#define VIDEO_CC_INTERFACE_BCR 3 + +/* VIDEO_CC GDSCRs */ +#define VENUS_GDSC 0 +#define VCODEC0_GDSC 1 +#define VCODEC1_GDSC 2 + +#endif -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v2 1/2] dt-bindings: clock: Introduce QCOM Video clock bindings
Add device tree bindings for video clock controller for Qualcomm Technology Inc's SoCs. Signed-off-by: Amit Nischal --- .../devicetree/bindings/clock/qcom,videocc.txt | 19 include/dt-bindings/clock/qcom,videocc-sdm845.h| 35 ++ 2 files changed, 54 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,videocc.txt create mode 100644 include/dt-bindings/clock/qcom,videocc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,videocc.txt b/Documentation/devicetree/bindings/clock/qcom,videocc.txt new file mode 100644 index 000..e7c035a --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,videocc.txt @@ -0,0 +1,19 @@ +Qualcomm Video Clock & Reset Controller Binding +--- + +Required properties : +- compatible : shall contain "qcom,sdm845-videocc" +- reg : shall contain base register location and length +- #clock-cells : from common clock binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Optional properties : +- #reset-cells : from common reset binding, shall contain 1. + +Example: + videocc: clock-controller@ab0 { + compatible = "qcom,sdm845-videocc"; + reg = <0xab0 0x1>; + #clock-cells = <1>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/clock/qcom,videocc-sdm845.h b/include/dt-bindings/clock/qcom,videocc-sdm845.h new file mode 100644 index 000..1b86816 --- /dev/null +++ b/include/dt-bindings/clock/qcom,videocc-sdm845.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_SDM_VIDEO_CC_SDM845_H +#define _DT_BINDINGS_CLK_SDM_VIDEO_CC_SDM845_H + +/* VIDEO_CC clock registers */ +#define VIDEO_CC_APB_CLK 0 +#define VIDEO_CC_AT_CLK1 +#define VIDEO_CC_QDSS_TRIG_CLK 2 +#define VIDEO_CC_QDSS_TSCTR_DIV8_CLK 3 +#define VIDEO_CC_VCODEC0_AXI_CLK 4 +#define VIDEO_CC_VCODEC0_CORE_CLK 5 +#define VIDEO_CC_VCODEC1_AXI_CLK 6 +#define VIDEO_CC_VCODEC1_CORE_CLK 7 +#define VIDEO_CC_VENUS_AHB_CLK 8 +#define VIDEO_CC_VENUS_CLK_SRC 9 +#define VIDEO_CC_VENUS_CTL_AXI_CLK 10 +#define VIDEO_CC_VENUS_CTL_CORE_CLK11 +#define VIDEO_PLL0 12 + +/* VIDEO_CC Resets */ +#define VIDEO_CC_VENUS_BCR 0 +#define VIDEO_CC_VCODEC0_BCR 1 +#define VIDEO_CC_VCODEC1_BCR 2 +#define VIDEO_CC_INTERFACE_BCR 3 + +/* VIDEO_CC GDSCRs */ +#define VENUS_GDSC 0 +#define VCODEC0_GDSC 1 +#define VCODEC1_GDSC 2 + +#endif -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v2 0/2] Add QCOM video clock controller driver
Changes in v2: https://lkml.org/lkml/2018/5/8/918 - Added #defines for resets in the header file. Changes in v1: https://lkml.org/lkml/2018/4/24/545 Addressed below review comments given by Rob - Change the compatible property as per ',-' format. - Add header definitions for resets and power-domain cells. This patch series adds a driver and device tree documentation binding for the video clock controller on some Qualcomm Technologies, Inc, SoCs such as SDM845. This would allow video drivers to probe and control their clocks. The video clock driver depends upon the RPMh driver[1], command DB driver[2], RPMh clock driver[3], rcg2 shared ops[4] and GCC clock driver[5] changes which are undergoing review. [1]: https://lkml.org/lkml/2018/4/19/914 [2]: https://lkml.org/lkml/2018/4/5/451 [3]: https://lkml.org/lkml/2018/4/24/390 [4]: https://lkml.org/lkml/2018/4/18/367 [5]: https://lkml.org/lkml/2018/4/30/533 [v1]: https://lkml.org/lkml/2018/5/3/386 Amit Nischal (2): dt-bindings: clock: Introduce QCOM Video clock bindings clk: qcom: Add video clock controller driver for SDM845 .../devicetree/bindings/clock/qcom,videocc.txt | 19 ++ drivers/clk/qcom/Kconfig | 11 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/videocc-sdm845.c | 358 + include/dt-bindings/clock/qcom,videocc-sdm845.h| 35 ++ 5 files changed, 424 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,videocc.txt create mode 100644 drivers/clk/qcom/videocc-sdm845.c create mode 100644 include/dt-bindings/clock/qcom,videocc-sdm845.h -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v2 0/2] Add QCOM video clock controller driver
Changes in v2: https://lkml.org/lkml/2018/5/8/918 - Added #defines for resets in the header file. Changes in v1: https://lkml.org/lkml/2018/4/24/545 Addressed below review comments given by Rob - Change the compatible property as per ',-' format. - Add header definitions for resets and power-domain cells. This patch series adds a driver and device tree documentation binding for the video clock controller on some Qualcomm Technologies, Inc, SoCs such as SDM845. This would allow video drivers to probe and control their clocks. The video clock driver depends upon the RPMh driver[1], command DB driver[2], RPMh clock driver[3], rcg2 shared ops[4] and GCC clock driver[5] changes which are undergoing review. [1]: https://lkml.org/lkml/2018/4/19/914 [2]: https://lkml.org/lkml/2018/4/5/451 [3]: https://lkml.org/lkml/2018/4/24/390 [4]: https://lkml.org/lkml/2018/4/18/367 [5]: https://lkml.org/lkml/2018/4/30/533 [v1]: https://lkml.org/lkml/2018/5/3/386 Amit Nischal (2): dt-bindings: clock: Introduce QCOM Video clock bindings clk: qcom: Add video clock controller driver for SDM845 .../devicetree/bindings/clock/qcom,videocc.txt | 19 ++ drivers/clk/qcom/Kconfig | 11 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/videocc-sdm845.c | 358 + include/dt-bindings/clock/qcom,videocc-sdm845.h| 35 ++ 5 files changed, 424 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,videocc.txt create mode 100644 drivers/clk/qcom/videocc-sdm845.c create mode 100644 include/dt-bindings/clock/qcom,videocc-sdm845.h -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v1 0/2] Add QCOM video clock controller driver
On 2018-05-07 22:41, Rob Herring wrote: On Mon, May 07, 2018 at 04:16:53PM +0530, Amit Nischal wrote: On 2018-05-04 22:01, Stephen Boyd wrote: > Quoting Amit Nischal (2018-05-03 05:35:23) > > Changes in v1: > >https://lkml.org/lkml/2018/4/24/545 > > Addressed below review comments given by Rob > > - Change the compatible property as per ',-' > > format. > > - Add header definitions for resets and power-domain cells. > > You didn't add any reset definitions though? We haven't added the reset definitions for videocc as there is no video reset client. So? You don't know what resets there are? We know the resets, but video driver doesn't do any block resets prior to accessing the video subsystem so that's the reason we do not want to expose the resets in videocc driver. Rob -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v1 0/2] Add QCOM video clock controller driver
On 2018-05-07 22:41, Rob Herring wrote: On Mon, May 07, 2018 at 04:16:53PM +0530, Amit Nischal wrote: On 2018-05-04 22:01, Stephen Boyd wrote: > Quoting Amit Nischal (2018-05-03 05:35:23) > > Changes in v1: > >https://lkml.org/lkml/2018/4/24/545 > > Addressed below review comments given by Rob > > - Change the compatible property as per ',-' > > format. > > - Add header definitions for resets and power-domain cells. > > You didn't add any reset definitions though? We haven't added the reset definitions for videocc as there is no video reset client. So? You don't know what resets there are? We know the resets, but video driver doesn't do any block resets prior to accessing the video subsystem so that's the reason we do not want to expose the resets in videocc driver. Rob -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 2/3] clk: qcom: Add DT bindings for SDM845 gcc clock controller
Add compatible string and the include file for gcc clock controller for SDM845. Signed-off-by: Amit Nischal <anisc...@codeaurora.org> Reviewed-by: Rob Herring <r...@kernel.org> --- .../devicetree/bindings/clock/qcom,gcc.txt | 1 + include/dt-bindings/clock/qcom,gcc-sdm845.h| 239 + 2 files changed, 240 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,gcc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt b/Documentation/devicetree/bindings/clock/qcom,gcc.txt index d1fb8b2..664ea1f 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt @@ -19,6 +19,7 @@ Required properties : "qcom,gcc-msm8996" "qcom,gcc-msm8998" "qcom,gcc-mdm9615" + "qcom,gcc-sdm845" - reg : shall contain base register location and length - #clock-cells : shall contain 1 diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h b/include/dt-bindings/clock/qcom,gcc-sdm845.h new file mode 100644 index 000..aca6126 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_SDM_GCC_SDM845_H +#define _DT_BINDINGS_CLK_SDM_GCC_SDM845_H + +/* GCC clock registers */ +#define GCC_AGGRE_NOC_PCIE_TBU_CLK 0 +#define GCC_AGGRE_UFS_CARD_AXI_CLK 1 +#define GCC_AGGRE_UFS_PHY_AXI_CLK 2 +#define GCC_AGGRE_USB3_PRIM_AXI_CLK3 +#define GCC_AGGRE_USB3_SEC_AXI_CLK 4 +#define GCC_BOOT_ROM_AHB_CLK 5 +#define GCC_CAMERA_AHB_CLK 6 +#define GCC_CAMERA_AXI_CLK 7 +#define GCC_CAMERA_XO_CLK 8 +#define GCC_CE1_AHB_CLK9 +#define GCC_CE1_AXI_CLK10 +#define GCC_CE1_CLK11 +#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK 12 +#define GCC_CFG_NOC_USB3_SEC_AXI_CLK 13 +#define GCC_CPUSS_AHB_CLK 14 +#define GCC_CPUSS_AHB_CLK_SRC 15 +#define GCC_CPUSS_RBCPR_CLK16 +#define GCC_CPUSS_RBCPR_CLK_SRC17 +#define GCC_DDRSS_GPU_AXI_CLK 18 +#define GCC_DISP_AHB_CLK 19 +#define GCC_DISP_AXI_CLK 20 +#define GCC_DISP_GPLL0_CLK_SRC 21 +#define GCC_DISP_GPLL0_DIV_CLK_SRC 22 +#define GCC_DISP_XO_CLK23 +#define GCC_GP1_CLK24 +#define GCC_GP1_CLK_SRC25 +#define GCC_GP2_CLK26 +#define GCC_GP2_CLK_SRC27 +#define GCC_GP3_CLK28 +#define GCC_GP3_CLK_SRC29 +#define GCC_GPU_CFG_AHB_CLK30 +#define GCC_GPU_GPLL0_CLK_SRC 31 +#define GCC_GPU_GPLL0_DIV_CLK_SRC 32 +#define GCC_GPU_MEMNOC_GFX_CLK 33 +#define GCC_GPU_SNOC_DVM_GFX_CLK 34 +#define GCC_MSS_AXIS2_CLK 35 +#define GCC_MSS_CFG_AHB_CLK36 +#define GCC_MSS_GPLL0_DIV_CLK_SRC 37 +#define GCC_MSS_MFAB_AXIS_CLK 38 +#define GCC_MSS_Q6_MEMNOC_AXI_CLK 39 +#define GCC_MSS_SNOC_AXI_CLK 40 +#define GCC_PCIE_0_AUX_CLK 41 +#define GCC_PCIE_0_AUX_CLK_SRC 42 +#define GCC_PCIE_0_CFG_AHB_CLK 43 +#define GCC_PCIE_0_CLKREF_CLK 44 +#define GCC_PCIE_0_MSTR_AXI_CLK45 +#define GCC_PCIE_0_PIPE_CLK46 +#define GCC_PCIE_0_SLV_AXI_CLK 47 +#define GCC_PCIE_0_SLV_Q2A_AXI_CLK 48 +#define GCC_PCIE_1_AUX_CLK 49 +#define GCC_PCIE_1_AUX_CLK_SRC 50 +#define GCC_P
[PATCH v7 2/3] clk: qcom: Add DT bindings for SDM845 gcc clock controller
Add compatible string and the include file for gcc clock controller for SDM845. Signed-off-by: Amit Nischal Reviewed-by: Rob Herring --- .../devicetree/bindings/clock/qcom,gcc.txt | 1 + include/dt-bindings/clock/qcom,gcc-sdm845.h| 239 + 2 files changed, 240 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,gcc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt b/Documentation/devicetree/bindings/clock/qcom,gcc.txt index d1fb8b2..664ea1f 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt @@ -19,6 +19,7 @@ Required properties : "qcom,gcc-msm8996" "qcom,gcc-msm8998" "qcom,gcc-mdm9615" + "qcom,gcc-sdm845" - reg : shall contain base register location and length - #clock-cells : shall contain 1 diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h b/include/dt-bindings/clock/qcom,gcc-sdm845.h new file mode 100644 index 000..aca6126 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_SDM_GCC_SDM845_H +#define _DT_BINDINGS_CLK_SDM_GCC_SDM845_H + +/* GCC clock registers */ +#define GCC_AGGRE_NOC_PCIE_TBU_CLK 0 +#define GCC_AGGRE_UFS_CARD_AXI_CLK 1 +#define GCC_AGGRE_UFS_PHY_AXI_CLK 2 +#define GCC_AGGRE_USB3_PRIM_AXI_CLK3 +#define GCC_AGGRE_USB3_SEC_AXI_CLK 4 +#define GCC_BOOT_ROM_AHB_CLK 5 +#define GCC_CAMERA_AHB_CLK 6 +#define GCC_CAMERA_AXI_CLK 7 +#define GCC_CAMERA_XO_CLK 8 +#define GCC_CE1_AHB_CLK9 +#define GCC_CE1_AXI_CLK10 +#define GCC_CE1_CLK11 +#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK 12 +#define GCC_CFG_NOC_USB3_SEC_AXI_CLK 13 +#define GCC_CPUSS_AHB_CLK 14 +#define GCC_CPUSS_AHB_CLK_SRC 15 +#define GCC_CPUSS_RBCPR_CLK16 +#define GCC_CPUSS_RBCPR_CLK_SRC17 +#define GCC_DDRSS_GPU_AXI_CLK 18 +#define GCC_DISP_AHB_CLK 19 +#define GCC_DISP_AXI_CLK 20 +#define GCC_DISP_GPLL0_CLK_SRC 21 +#define GCC_DISP_GPLL0_DIV_CLK_SRC 22 +#define GCC_DISP_XO_CLK23 +#define GCC_GP1_CLK24 +#define GCC_GP1_CLK_SRC25 +#define GCC_GP2_CLK26 +#define GCC_GP2_CLK_SRC27 +#define GCC_GP3_CLK28 +#define GCC_GP3_CLK_SRC29 +#define GCC_GPU_CFG_AHB_CLK30 +#define GCC_GPU_GPLL0_CLK_SRC 31 +#define GCC_GPU_GPLL0_DIV_CLK_SRC 32 +#define GCC_GPU_MEMNOC_GFX_CLK 33 +#define GCC_GPU_SNOC_DVM_GFX_CLK 34 +#define GCC_MSS_AXIS2_CLK 35 +#define GCC_MSS_CFG_AHB_CLK36 +#define GCC_MSS_GPLL0_DIV_CLK_SRC 37 +#define GCC_MSS_MFAB_AXIS_CLK 38 +#define GCC_MSS_Q6_MEMNOC_AXI_CLK 39 +#define GCC_MSS_SNOC_AXI_CLK 40 +#define GCC_PCIE_0_AUX_CLK 41 +#define GCC_PCIE_0_AUX_CLK_SRC 42 +#define GCC_PCIE_0_CFG_AHB_CLK 43 +#define GCC_PCIE_0_CLKREF_CLK 44 +#define GCC_PCIE_0_MSTR_AXI_CLK45 +#define GCC_PCIE_0_PIPE_CLK46 +#define GCC_PCIE_0_SLV_AXI_CLK 47 +#define GCC_PCIE_0_SLV_Q2A_AXI_CLK 48 +#define GCC_PCIE_1_AUX_CLK 49 +#define GCC_PCIE_1_AUX_CLK_SRC 50 +#define GCC_PCIE_1_CFG_AHB_CLK
[PATCH v7 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845
From: Taniya Das <t...@codeaurora.org> Add support for the global clock controller found on SDM845 based devices. This should allow most non-multimedia device drivers to probe and control their clocks. Signed-off-by: Taniya Das <t...@codeaurora.org> Signed-off-by: Amit Nischal <anisc...@codeaurora.org> --- drivers/clk/qcom/Kconfig |9 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/gcc-sdm845.c | 3465 + 3 files changed, 3475 insertions(+) create mode 100644 drivers/clk/qcom/gcc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index e42e1af..aec69d2 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -226,6 +226,15 @@ config MSM_GCC_8998 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, UFS, SD/eMMC, PCIe, etc. +config SDM_GCC_845 + tristate "SDM845 Global Clock Controller" + select QCOM_GDSC + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on msm8998 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + I2C, USB, UFS, SDDC, PCIe, etc. + config SPMI_PMIC_CLKDIV tristate "SPMI PMIC clkdiv Support" depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 7c09ab1..bf8fb25 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -38,4 +38,5 @@ obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o +obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c new file mode 100644 index 000..e78e6f5 --- /dev/null +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -0,0 +1,3465 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "clk-alpha-pll.h" +#include "gdsc.h" +#include "reset.h" + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +enum { + P_BI_TCXO, + P_AUD_REF_CLK, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_EVEN, + P_GPLL0_OUT_MAIN, + P_GPLL4_OUT_MAIN, + P_SLEEP_CLK, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_0[] = { + "bi_tcxo", + "gpll0", + "gpll0_out_even", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_SLEEP_CLK, 5 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_1[] = { + "bi_tcxo", + "gpll0", + "core_pi_sleep_clk", + "gpll0_out_even", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_SLEEP_CLK, 5 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_2[] = { + "bi_tcxo", + "core_pi_sleep_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_3[] = { + "bi_tcxo", + "gpll0", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_4[] = { + "bi_tcxo", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL4_OUT_MAIN, 5 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_5[] = { + "bi_tcxo", + "gpll0", + "gpll4", + "gpll0_out_even", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_pare
[PATCH v7 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845
From: Taniya Das Add support for the global clock controller found on SDM845 based devices. This should allow most non-multimedia device drivers to probe and control their clocks. Signed-off-by: Taniya Das Signed-off-by: Amit Nischal --- drivers/clk/qcom/Kconfig |9 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/gcc-sdm845.c | 3465 + 3 files changed, 3475 insertions(+) create mode 100644 drivers/clk/qcom/gcc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index e42e1af..aec69d2 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -226,6 +226,15 @@ config MSM_GCC_8998 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, UFS, SD/eMMC, PCIe, etc. +config SDM_GCC_845 + tristate "SDM845 Global Clock Controller" + select QCOM_GDSC + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on msm8998 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + I2C, USB, UFS, SDDC, PCIe, etc. + config SPMI_PMIC_CLKDIV tristate "SPMI PMIC clkdiv Support" depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 7c09ab1..bf8fb25 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -38,4 +38,5 @@ obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o +obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c new file mode 100644 index 000..e78e6f5 --- /dev/null +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -0,0 +1,3465 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "clk-alpha-pll.h" +#include "gdsc.h" +#include "reset.h" + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +enum { + P_BI_TCXO, + P_AUD_REF_CLK, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_EVEN, + P_GPLL0_OUT_MAIN, + P_GPLL4_OUT_MAIN, + P_SLEEP_CLK, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_0[] = { + "bi_tcxo", + "gpll0", + "gpll0_out_even", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_SLEEP_CLK, 5 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_1[] = { + "bi_tcxo", + "gpll0", + "core_pi_sleep_clk", + "gpll0_out_even", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_SLEEP_CLK, 5 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_2[] = { + "bi_tcxo", + "core_pi_sleep_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_3[] = { + "bi_tcxo", + "gpll0", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_4[] = { + "bi_tcxo", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL4_OUT_MAIN, 5 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_5[] = { + "bi_tcxo", + "gpll0", + "gpll4", + "gpll0_out_even", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_AUD_REF_C
[PATCH v7 1/3] clk: qcom: Configure the RCGs to a safe source as needed
For some root clock generators, there could be child branches which are controlled by an entity other than application processor subsystem. For such RCGs, as per application processor subsystem clock driver, all of its downstream clocks are disabled and RCG is in disabled state but in reality downstream clocks can be left enabled before. So in this scenario, when RCG is disabled as per clock driver's point of view and when rate scaling request comes before downstream clock enable request, then RCG fails to update its configuration because in reality RCG is on and it expects its new source to already be in enable state but in reality new source is off. In order to avoid having the RCG to go into an invalid state, add support to update the CFG, M, N and D registers during set_rate() without configuration update and defer the actual RCG configuration update to be done during clk_enable() as at this point of time, both its new parent and safe source will be already enabled and RCG can safely switch to new parent. During clk_disable() request, configure it to safe source as both its parents, safe source and current parent will be enabled and RCG can safely execute a switch. Signed-off-by: Taniya Das <t...@codeaurora.org> Signed-off-by: Amit Nischal <anisc...@codeaurora.org> --- drivers/clk/qcom/clk-rcg.h | 17 ++--- drivers/clk/qcom/clk-rcg2.c | 170 2 files changed, 163 insertions(+), 24 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index 2a7489a..b209a2f 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -1,15 +1,5 @@ -/* - * Copyright (c) 2013, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2013, 2018, The Linux Foundation. All rights reserved. */ #ifndef __QCOM_CLK_RCG_H__ #define __QCOM_CLK_RCG_H__ @@ -144,6 +134,7 @@ struct clk_dyn_rcg { * @cmd_rcgr: corresponds to *_CMD_RCGR * @mnd_width: number of bits in m/n/d values * @hid_width: number of bits in half integer divider + * @safe_src_index: safe src index value * @parent_map: map from software's parent index to hardware's src_sel field * @freq_tbl: frequency table * @clkr: regmap clock handle @@ -153,6 +144,7 @@ struct clk_rcg2 { u32 cmd_rcgr; u8 mnd_width; u8 hid_width; + u8 safe_src_index; const struct parent_map *parent_map; const struct freq_tbl *freq_tbl; struct clk_regmap clkr; @@ -167,5 +159,6 @@ struct clk_rcg2 { extern const struct clk_ops clk_byte2_ops; extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; +extern const struct clk_ops clk_rcg2_shared_ops; #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index e63db10..6827ab3 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2013, 2018, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include @@ -249,7 +241,7 @@ static int clk_rcg2_determine_floor_rate(struct clk_hw *hw, return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req, FLOOR); } -static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) +static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) { u32 cfg, mask; struct clk_hw *hw = >clkr.hw; @@ -282,8 +274,16 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT; if (rcg->mnd_width && f->n && (f->m != f->n)) cfg |= CFG_MODE_DUAL_EDGE; - ret = regmap_update_bits(rcg->clkr.regmap, - rcg->cmd_rcgr + CFG_REG, mask, cfg); + + return regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, +
[PATCH v7 1/3] clk: qcom: Configure the RCGs to a safe source as needed
For some root clock generators, there could be child branches which are controlled by an entity other than application processor subsystem. For such RCGs, as per application processor subsystem clock driver, all of its downstream clocks are disabled and RCG is in disabled state but in reality downstream clocks can be left enabled before. So in this scenario, when RCG is disabled as per clock driver's point of view and when rate scaling request comes before downstream clock enable request, then RCG fails to update its configuration because in reality RCG is on and it expects its new source to already be in enable state but in reality new source is off. In order to avoid having the RCG to go into an invalid state, add support to update the CFG, M, N and D registers during set_rate() without configuration update and defer the actual RCG configuration update to be done during clk_enable() as at this point of time, both its new parent and safe source will be already enabled and RCG can safely switch to new parent. During clk_disable() request, configure it to safe source as both its parents, safe source and current parent will be enabled and RCG can safely execute a switch. Signed-off-by: Taniya Das Signed-off-by: Amit Nischal --- drivers/clk/qcom/clk-rcg.h | 17 ++--- drivers/clk/qcom/clk-rcg2.c | 170 2 files changed, 163 insertions(+), 24 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index 2a7489a..b209a2f 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -1,15 +1,5 @@ -/* - * Copyright (c) 2013, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2013, 2018, The Linux Foundation. All rights reserved. */ #ifndef __QCOM_CLK_RCG_H__ #define __QCOM_CLK_RCG_H__ @@ -144,6 +134,7 @@ struct clk_dyn_rcg { * @cmd_rcgr: corresponds to *_CMD_RCGR * @mnd_width: number of bits in m/n/d values * @hid_width: number of bits in half integer divider + * @safe_src_index: safe src index value * @parent_map: map from software's parent index to hardware's src_sel field * @freq_tbl: frequency table * @clkr: regmap clock handle @@ -153,6 +144,7 @@ struct clk_rcg2 { u32 cmd_rcgr; u8 mnd_width; u8 hid_width; + u8 safe_src_index; const struct parent_map *parent_map; const struct freq_tbl *freq_tbl; struct clk_regmap clkr; @@ -167,5 +159,6 @@ struct clk_rcg2 { extern const struct clk_ops clk_byte2_ops; extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; +extern const struct clk_ops clk_rcg2_shared_ops; #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index e63db10..6827ab3 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2013, 2018, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include @@ -249,7 +241,7 @@ static int clk_rcg2_determine_floor_rate(struct clk_hw *hw, return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req, FLOOR); } -static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) +static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) { u32 cfg, mask; struct clk_hw *hw = >clkr.hw; @@ -282,8 +274,16 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT; if (rcg->mnd_width && f->n && (f->m != f->n)) cfg |= CFG_MODE_DUAL_EDGE; - ret = regmap_update_bits(rcg->clkr.regmap, - rcg->cmd_rcgr + CFG_REG, mask, cfg); + + return regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, + mask, cfg); +} + +static in
[PATCH v7 0/3] Misc patches to support clocks for SDM845
Changes in v7: 1. Addressed review comments from Stephen and Rob for GCC driver. - Split dt-bindings to a separate patch from the driver patch. - Change the 'halt_check' type to BRANCH_HALT_SKIP for pipe and ufs_card tx/rx symbol clocks. - Remove 'halt_reg' for the clocks where 'halt_check' type is BRANCH_HALT_DELAY. For such clocks, there is no status bit to poll. For e.g. gcc_disp_gpll0_clk_src clock. 2. Implemented rcg2_shared_ops as suggested by Stephen in https://lkml.org/lkml/2018/5/2/91. 3. The GCC clock driver(patch 3) depends upon the below patches related to GDSC operation and RPMh clock driver, which are under review. https://lkml.org/lkml/2018/4/27/110 https://lkml.org/lkml/2018/4/24/390 Changes in v6: 1. Addressed review comments for v3 and v4 version of GCC driver for SDM845. https://lkml.org/lkml/2018/4/16/1129. 2. Add support for new flag 'BRANCH_NO_DELAY' for branch clocks. 3. Addressed review comments for v5 version of rcg2_shared_ops patch. https://lkml.org/lkml/2018/4/19/86 4. The GCC clock driver(patch 3) depends upon the below patches related to GDSC operation and RPMh clock driver, which are under review. https://lkml.org/lkml/2018/4/27/110 https://lkml.org/lkml/2018/4/24/390 Changes in v5: 1. Addressed review comments for v3 and v4 version of GCC driver for SDM845 https://lkml.org/lkml/2018/4/16/1129 2. Removed bi_tcxo clock being modelled from the GCC driver, as RPMH clock driver would provide the same. https://lkml.org/lkml/2018/4/13/685 3. The GCC clock driver(patch 2) depends upon the below patches related to GDSC operation and RPMh clock driver, which are under review. https://lkml.org/lkml/2018/4/2/143 https://lkml.org/lkml/2018/4/13/685 Changes in v4: 1. Addressed review comments for v2 version of GCC driver for SDM845 https://lkml.org/lkml/2018/4/9/55. 2. The GCC clock driver(patch 3) depends upon the below patches related to GDSC operation and are under review. https://lkml.org/lkml/2018/4/2/142 Changes in v3: 1. Addressed review comments given for v2 series. 2. The GCC clock driver(patch 3) depends upon the below patches related to GDSC operation and are under review. https://lkml.org/lkml/2018/4/2/142 Changes in v2: Fixup for recalc_rate ops for clk_rcg2_shared_ops: There could be few scenarios where shared clocks are configured at rate other than CXO by boot. In those cases there would be a mismatch between the rate calculated by the recalc shared ops and the actual HW register configuration. Fix the same by adding an additional check to read current src from CFG register and make a decision based on that. Changes in v1: https://lkml.org/lkml/2018/1/31/209 This patch series does the miscellaneous changes to support clock nodes for SDM845. Below are the major changes for which the existing code does not have support. 1. Clear hardware clock control bit of RCGs where HW clock control bit is set by default so that software can control those root clocks. 2. Introduces clk_rcg2_shared_ops to support clock controller drivers for SDM845. With new shared ops, RCGs with shared branches will be configured to a safe source in disable path and actual RCG update configuration will be done in enable path instead of doing config update in set_rate. In set_rate(), just cache the rate instead of doing actual configuration update. Also each RCG in clock controller driver will have their own safe configuration frequency table to switch to safe frequency. 3. Add support for controlling Fabia PLL for which the support is not available in existing alpha PLL code. 4. Add Global Clock controller (GCC) driver for SDM845. This should allow most non-multimedia device drivers to probe and control their clocks. [v1] : https://lkml.org/lkml/2018/1/31/209 [v2] : https://lkml.org/lkml/2018/3/8/495 [v3] : https://lkml.org/lkml/2018/4/3/356 [v4] : https://lkml.org/lkml/2018/4/9/79 [v5] : https://lkml.org/lkml/2018/4/18/367 [v6] : https://lkml.org/lkml/2018/4/30/533 Amit Nischal (2): clk: qcom: Configure the RCGs to a safe source as needed clk: qcom: Add DT bindings for SDM845 gcc clock controller Taniya Das (1): clk: qcom: Add Global Clock controller (GCC) driver for SDM845 .../devicetree/bindings/clock/qcom,gcc.txt |1 + drivers/clk/qcom/Kconfig |9 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/clk-rcg.h | 17 +- drivers/clk/qcom/clk-rcg2.c| 170 +- drivers/clk/qcom/gcc-sdm845.c | 3465 include/dt-bindings/clock/qcom,gcc-sdm845.h| 239 ++ 7 files changed, 3878 insertions(+), 24 deletions(-) create mode 100644 drivers/clk/qcom/gcc-sdm845.c create mode 100644 include/dt-bindings/clock/qcom,gcc-sdm845.h -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code
[PATCH v7 0/3] Misc patches to support clocks for SDM845
Changes in v7: 1. Addressed review comments from Stephen and Rob for GCC driver. - Split dt-bindings to a separate patch from the driver patch. - Change the 'halt_check' type to BRANCH_HALT_SKIP for pipe and ufs_card tx/rx symbol clocks. - Remove 'halt_reg' for the clocks where 'halt_check' type is BRANCH_HALT_DELAY. For such clocks, there is no status bit to poll. For e.g. gcc_disp_gpll0_clk_src clock. 2. Implemented rcg2_shared_ops as suggested by Stephen in https://lkml.org/lkml/2018/5/2/91. 3. The GCC clock driver(patch 3) depends upon the below patches related to GDSC operation and RPMh clock driver, which are under review. https://lkml.org/lkml/2018/4/27/110 https://lkml.org/lkml/2018/4/24/390 Changes in v6: 1. Addressed review comments for v3 and v4 version of GCC driver for SDM845. https://lkml.org/lkml/2018/4/16/1129. 2. Add support for new flag 'BRANCH_NO_DELAY' for branch clocks. 3. Addressed review comments for v5 version of rcg2_shared_ops patch. https://lkml.org/lkml/2018/4/19/86 4. The GCC clock driver(patch 3) depends upon the below patches related to GDSC operation and RPMh clock driver, which are under review. https://lkml.org/lkml/2018/4/27/110 https://lkml.org/lkml/2018/4/24/390 Changes in v5: 1. Addressed review comments for v3 and v4 version of GCC driver for SDM845 https://lkml.org/lkml/2018/4/16/1129 2. Removed bi_tcxo clock being modelled from the GCC driver, as RPMH clock driver would provide the same. https://lkml.org/lkml/2018/4/13/685 3. The GCC clock driver(patch 2) depends upon the below patches related to GDSC operation and RPMh clock driver, which are under review. https://lkml.org/lkml/2018/4/2/143 https://lkml.org/lkml/2018/4/13/685 Changes in v4: 1. Addressed review comments for v2 version of GCC driver for SDM845 https://lkml.org/lkml/2018/4/9/55. 2. The GCC clock driver(patch 3) depends upon the below patches related to GDSC operation and are under review. https://lkml.org/lkml/2018/4/2/142 Changes in v3: 1. Addressed review comments given for v2 series. 2. The GCC clock driver(patch 3) depends upon the below patches related to GDSC operation and are under review. https://lkml.org/lkml/2018/4/2/142 Changes in v2: Fixup for recalc_rate ops for clk_rcg2_shared_ops: There could be few scenarios where shared clocks are configured at rate other than CXO by boot. In those cases there would be a mismatch between the rate calculated by the recalc shared ops and the actual HW register configuration. Fix the same by adding an additional check to read current src from CFG register and make a decision based on that. Changes in v1: https://lkml.org/lkml/2018/1/31/209 This patch series does the miscellaneous changes to support clock nodes for SDM845. Below are the major changes for which the existing code does not have support. 1. Clear hardware clock control bit of RCGs where HW clock control bit is set by default so that software can control those root clocks. 2. Introduces clk_rcg2_shared_ops to support clock controller drivers for SDM845. With new shared ops, RCGs with shared branches will be configured to a safe source in disable path and actual RCG update configuration will be done in enable path instead of doing config update in set_rate. In set_rate(), just cache the rate instead of doing actual configuration update. Also each RCG in clock controller driver will have their own safe configuration frequency table to switch to safe frequency. 3. Add support for controlling Fabia PLL for which the support is not available in existing alpha PLL code. 4. Add Global Clock controller (GCC) driver for SDM845. This should allow most non-multimedia device drivers to probe and control their clocks. [v1] : https://lkml.org/lkml/2018/1/31/209 [v2] : https://lkml.org/lkml/2018/3/8/495 [v3] : https://lkml.org/lkml/2018/4/3/356 [v4] : https://lkml.org/lkml/2018/4/9/79 [v5] : https://lkml.org/lkml/2018/4/18/367 [v6] : https://lkml.org/lkml/2018/4/30/533 Amit Nischal (2): clk: qcom: Configure the RCGs to a safe source as needed clk: qcom: Add DT bindings for SDM845 gcc clock controller Taniya Das (1): clk: qcom: Add Global Clock controller (GCC) driver for SDM845 .../devicetree/bindings/clock/qcom,gcc.txt |1 + drivers/clk/qcom/Kconfig |9 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/clk-rcg.h | 17 +- drivers/clk/qcom/clk-rcg2.c| 170 +- drivers/clk/qcom/gcc-sdm845.c | 3465 include/dt-bindings/clock/qcom,gcc-sdm845.h| 239 ++ 7 files changed, 3878 insertions(+), 24 deletions(-) create mode 100644 drivers/clk/qcom/gcc-sdm845.c create mode 100644 include/dt-bindings/clock/qcom,gcc-sdm845.h -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code
Re: [PATCH v1 0/2] Add QCOM video clock controller driver
On 2018-05-04 22:01, Stephen Boyd wrote: Quoting Amit Nischal (2018-05-03 05:35:23) Changes in v1: https://lkml.org/lkml/2018/4/24/545 Addressed below review comments given by Rob - Change the compatible property as per ',-' format. - Add header definitions for resets and power-domain cells. You didn't add any reset definitions though? We haven't added the reset definitions for videocc as there is no video reset client. -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v1 0/2] Add QCOM video clock controller driver
On 2018-05-04 22:01, Stephen Boyd wrote: Quoting Amit Nischal (2018-05-03 05:35:23) Changes in v1: https://lkml.org/lkml/2018/4/24/545 Addressed below review comments given by Rob - Change the compatible property as per ',-' format. - Add header definitions for resets and power-domain cells. You didn't add any reset definitions though? We haven't added the reset definitions for videocc as there is no video reset client. -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845
On 2018-05-05 08:44, Stephen Boyd wrote: Quoting Amit Nischal (2018-05-04 03:45:12) On 2018-05-02 12:53, Stephen Boyd wrote: > Quoting Amit Nischal (2018-04-30 09:20:10) >> + >> +static struct clk_branch gcc_disp_gpll0_clk_src = { >> + .halt_reg = 0x52004, >> + .halt_check = BRANCH_HALT_DELAY, > > What about this one? It's not a phy so I'm confused again why we're > unable to check the halt bit. To be clear(er), I don't see why we ever > want to have HALT_DELAY used. Hopefully we can remove that flag. > > From what I recall, the flag is there for clks that don't toggle their > status bit at all, but that we know take a few cycles to ungate the > upstream clk. So we threw a delay into the code to make sure that when > clk_enable() returned, a driver wouldn't try to use hardware before the > clk was actually on. But these cases should pretty much never happen, > hence all the pushback against this flag. > For these "*gpll0_clk_src" and "*gpll0_div_clk" clocks, there is no halt bit to check the status and it is required to have delay for few cycles so that clock gets turned on before a client driver to use the hardware. Ok.. but then why is there a 'halt_reg' configured for the clk? Thanks for the review. I will remove the halt_reg for the clocks where we are using the 'HALT_DELAY' flag and there is no need to poll the status bit as we are returning early from the 'clk_branch_wait()' function. >> + >> +static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = { >> + .halt_reg = 0x75018, >> + .halt_check = BRANCH_HALT_DELAY, > > There are still HALT_DELAY flags for UFS though? Why? For ufs_card tx/rx symbol clocks, we don't poll the status bit as per the recommendation from the HW team. We can change the halt_check type to newly implemented flag "BRANCH_HALT_SKIP". Please update us with your thoughts to change the flag to "BRANCH_HALT_SKIP". Yes use HALT_SKIP please. Thanks for confirming. I will do the changes in the next patch series. > > Also, are you going to send DFS support for the QUP clks? I would like > to see that code merged soon. Taniya has sent the patches for DFS support for QUP clocks. https://patchwork.kernel.org/patch/10376951/ I'll take a look. -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845
On 2018-05-05 08:44, Stephen Boyd wrote: Quoting Amit Nischal (2018-05-04 03:45:12) On 2018-05-02 12:53, Stephen Boyd wrote: > Quoting Amit Nischal (2018-04-30 09:20:10) >> + >> +static struct clk_branch gcc_disp_gpll0_clk_src = { >> + .halt_reg = 0x52004, >> + .halt_check = BRANCH_HALT_DELAY, > > What about this one? It's not a phy so I'm confused again why we're > unable to check the halt bit. To be clear(er), I don't see why we ever > want to have HALT_DELAY used. Hopefully we can remove that flag. > > From what I recall, the flag is there for clks that don't toggle their > status bit at all, but that we know take a few cycles to ungate the > upstream clk. So we threw a delay into the code to make sure that when > clk_enable() returned, a driver wouldn't try to use hardware before the > clk was actually on. But these cases should pretty much never happen, > hence all the pushback against this flag. > For these "*gpll0_clk_src" and "*gpll0_div_clk" clocks, there is no halt bit to check the status and it is required to have delay for few cycles so that clock gets turned on before a client driver to use the hardware. Ok.. but then why is there a 'halt_reg' configured for the clk? Thanks for the review. I will remove the halt_reg for the clocks where we are using the 'HALT_DELAY' flag and there is no need to poll the status bit as we are returning early from the 'clk_branch_wait()' function. >> + >> +static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = { >> + .halt_reg = 0x75018, >> + .halt_check = BRANCH_HALT_DELAY, > > There are still HALT_DELAY flags for UFS though? Why? For ufs_card tx/rx symbol clocks, we don't poll the status bit as per the recommendation from the HW team. We can change the halt_check type to newly implemented flag "BRANCH_HALT_SKIP". Please update us with your thoughts to change the flag to "BRANCH_HALT_SKIP". Yes use HALT_SKIP please. Thanks for confirming. I will do the changes in the next patch series. > > Also, are you going to send DFS support for the QUP clks? I would like > to see that code merged soon. Taniya has sent the patches for DFS support for QUP clocks. https://patchwork.kernel.org/patch/10376951/ I'll take a look. -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 1/3] clk: qcom: Configure the RCGs to a safe source as needed
On 2018-05-05 08:54, Stephen Boyd wrote: Quoting Amit Nischal (2018-05-03 04:57:37) On 2018-05-02 13:15, Stephen Boyd wrote: > Quoting Amit Nischal (2018-04-30 09:20:08) > >> +} >> + >> +static void clk_rcg2_shared_disable(struct clk_hw *hw) >> +{ >> + struct clk_rcg2 *rcg = to_clk_rcg2(hw); >> + struct freq_tbl safe_src_tbl = { 0 }; >> + >> + /* >> +* Park the RCG at a safe configuration - sourced off from >> safe source. >> +* Force enable and disable the RCG while configuring it to >> safeguard >> +* against any update signal coming from the downstream clock. >> +* The current parent is still prepared and enabled at this >> point, and >> +* the safe source is always on while application processor >> subsystem >> +* is online. Therefore, the RCG can safely switch its parent. >> +*/ >> + safe_src_tbl.src = rcg->safe_src_index; >> + clk_rcg2_shared_force_enable_clear(hw, _src_tbl); > > This should then re-dirty the config register to have the software > frequency settings that existed in the hardware when disable was > called. > Given that MND shouldn't be changed here, this should be as simple as > saving away the CFG register, forcing it to XO speed by changing the > src > and disabling dual edge in the CFG register (please don't call > force_enable_clear with some frequency pointer, just do this inline > here), and then rewriting the cfg register with the "real" settings for > whatever frequency it's supposed to run at and then returning from this > function. > > I guess we have to do a read cfg from hardware, write cfg, hit update > config, and then write cfg again each time we disable. For enable, we > just do an update config (if it's dirty?) inside of a force > enable/disable pair. And set_rate doesn't really change except it > either > does or doesn't hit the update config bit if the clk is enabled or > disabled respectively. > We have done the below changes suggested by you and that logic seems to be working fine. But we have one concern about leaving the RCG registers in dirty state and would like to have a little bit modification as explained below: Suggested Logic: 1. set_rate()--> Update CFG, M, N and D registers and don't hit the update bit if clock is disabled - call new __clk_rcg2_configure(). Above will make the CFG register as dirty. 2. _disable()--> 2.1 - Store the CFG register configuration in a variable. 2.2 - Move to the safe source (XO) and hit the update bit. It will only touch the CFG register and M, N, D register values will remain as it was. 2.3 - Write back the stored CFG value done in step #2.1 This will again redirty the CFG register. 3. _enable()--> Just hit the update bit as the configuration write will be taken care in the steps #1 and #2. It would be great if we don't redirty the CFG register and leave the RCG CFG register to at safe source(XO) in disable() path. This would help us to debug the issues where device crashes and we want to dump the RCG registers to know whether from software, we have actually moved to safe source or not. Otherwise, we would get the dirty register values in crash dumps. So instead of writing back the stored CFG(corresponding to real rate settings) in disable path, we want to restore the stored CFG in enable path and then hit the update bit. CFG configuration store can happen at two places - set_rate() and disable() path and above logic will be modified as below: 1. set_rate()--> 1.1 - Update CFG, M, N and D registers and don't hit the update bit if clock is disabled. 1.2 - Store CFG register value in 'current_cfg' member of 'rcg2' structure. 2. _disable()--> 2.1 - Store the CFG register value in 'current_cfg' before switching to the safe source (XO). 2.2 - Move to the safe source (XO) and hit the update bit. Now RCG configuration wil not be dirty. 3. _enable()--> 3.1 - Check for 'current_cfg' value and if 0 then return. This would catch the below one time condition: - when clk_enable() gets call without set_rate(). We want clk_enable() to work without set_rate() though. So returning 0 if the value is 0 is wrong. 3.2 - Write the CFG value from 'current_cfg' to CFG register. 3.2 - Hit the update bit as we have already written the latest configuration in step #3.2. 3.3 - Clear the 'cu
Re: [PATCH v6 1/3] clk: qcom: Configure the RCGs to a safe source as needed
On 2018-05-05 08:54, Stephen Boyd wrote: Quoting Amit Nischal (2018-05-03 04:57:37) On 2018-05-02 13:15, Stephen Boyd wrote: > Quoting Amit Nischal (2018-04-30 09:20:08) > >> +} >> + >> +static void clk_rcg2_shared_disable(struct clk_hw *hw) >> +{ >> + struct clk_rcg2 *rcg = to_clk_rcg2(hw); >> + struct freq_tbl safe_src_tbl = { 0 }; >> + >> + /* >> +* Park the RCG at a safe configuration - sourced off from >> safe source. >> +* Force enable and disable the RCG while configuring it to >> safeguard >> +* against any update signal coming from the downstream clock. >> +* The current parent is still prepared and enabled at this >> point, and >> +* the safe source is always on while application processor >> subsystem >> +* is online. Therefore, the RCG can safely switch its parent. >> +*/ >> + safe_src_tbl.src = rcg->safe_src_index; >> + clk_rcg2_shared_force_enable_clear(hw, _src_tbl); > > This should then re-dirty the config register to have the software > frequency settings that existed in the hardware when disable was > called. > Given that MND shouldn't be changed here, this should be as simple as > saving away the CFG register, forcing it to XO speed by changing the > src > and disabling dual edge in the CFG register (please don't call > force_enable_clear with some frequency pointer, just do this inline > here), and then rewriting the cfg register with the "real" settings for > whatever frequency it's supposed to run at and then returning from this > function. > > I guess we have to do a read cfg from hardware, write cfg, hit update > config, and then write cfg again each time we disable. For enable, we > just do an update config (if it's dirty?) inside of a force > enable/disable pair. And set_rate doesn't really change except it > either > does or doesn't hit the update config bit if the clk is enabled or > disabled respectively. > We have done the below changes suggested by you and that logic seems to be working fine. But we have one concern about leaving the RCG registers in dirty state and would like to have a little bit modification as explained below: Suggested Logic: 1. set_rate()--> Update CFG, M, N and D registers and don't hit the update bit if clock is disabled - call new __clk_rcg2_configure(). Above will make the CFG register as dirty. 2. _disable()--> 2.1 - Store the CFG register configuration in a variable. 2.2 - Move to the safe source (XO) and hit the update bit. It will only touch the CFG register and M, N, D register values will remain as it was. 2.3 - Write back the stored CFG value done in step #2.1 This will again redirty the CFG register. 3. _enable()--> Just hit the update bit as the configuration write will be taken care in the steps #1 and #2. It would be great if we don't redirty the CFG register and leave the RCG CFG register to at safe source(XO) in disable() path. This would help us to debug the issues where device crashes and we want to dump the RCG registers to know whether from software, we have actually moved to safe source or not. Otherwise, we would get the dirty register values in crash dumps. So instead of writing back the stored CFG(corresponding to real rate settings) in disable path, we want to restore the stored CFG in enable path and then hit the update bit. CFG configuration store can happen at two places - set_rate() and disable() path and above logic will be modified as below: 1. set_rate()--> 1.1 - Update CFG, M, N and D registers and don't hit the update bit if clock is disabled. 1.2 - Store CFG register value in 'current_cfg' member of 'rcg2' structure. 2. _disable()--> 2.1 - Store the CFG register value in 'current_cfg' before switching to the safe source (XO). 2.2 - Move to the safe source (XO) and hit the update bit. Now RCG configuration wil not be dirty. 3. _enable()--> 3.1 - Check for 'current_cfg' value and if 0 then return. This would catch the below one time condition: - when clk_enable() gets call without set_rate(). We want clk_enable() to work without set_rate() though. So returning 0 if the value is 0 is wrong. 3.2 - Write the CFG value from 'current_cfg' to CFG register. 3.2 - Hit the update bit as we have already written the latest configuration in step #3.2. 3.3 - Clear the 'cu
Re: [PATCH v6 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845
On 2018-05-02 12:53, Stephen Boyd wrote: Quoting Amit Nischal (2018-04-30 09:20:10) --- .../devicetree/bindings/clock/qcom,gcc.txt |1 + drivers/clk/qcom/Kconfig | 10 +- drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/gcc-sdm845.c | 3480 include/dt-bindings/clock/qcom,gcc-sdm845.h| 239 ++ Do the split that Rob suggests please, given that you're resending. And also include his reviewed-by tag. Thanks for the review. Sure I will split the dt-binding into separate patch in next series. 5 files changed, 3727 insertions(+), 4 deletions(-) create mode 100644 drivers/clk/qcom/gcc-sdm845.c create mode 100644 include/dt-bindings/clock/qcom,gcc-sdm845.h diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index e42e1af..3298beb 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -218,13 +218,15 @@ config MSM_MMCC_8996 Say Y if you want to support multimedia devices such as display, graphics, video encode/decode, camera, etc. -config MSM_GCC_8998 - tristate "MSM8998 Global Clock Controller" +config SDM_GCC_845 + tristate "SDM845 Global Clock Controller" + select QCOM_GDSC depends on COMMON_CLK_QCOM help - Support for the global clock controller on msm8998 devices. + Support for the global clock controller on Qualcomm Technologies, Inc + sdm845 devices. Say Y if you want to use peripheral devices such as UART, SPI, - i2c, USB, UFS, SD/eMMC, PCIe, etc. + I2C, USB, UFS, SDDC, PCIe, etc. This is all wrong. My bad. I did by mistake. Will fix this in next series. config SPMI_PMIC_CLKDIV tristate "SPMI PMIC clkdiv Support" diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c new file mode 100644 index 000..6484cba --- /dev/null +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -0,0 +1,3480 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + [...] + .name = "gcc_disp_axi_clk", + .ops = _branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_gpll0_clk_src = { + .halt_reg = 0x52004, + .halt_check = BRANCH_HALT_DELAY, What about this one? It's not a phy so I'm confused again why we're unable to check the halt bit. To be clear(er), I don't see why we ever want to have HALT_DELAY used. Hopefully we can remove that flag. From what I recall, the flag is there for clks that don't toggle their status bit at all, but that we know take a few cycles to ungate the upstream clk. So we threw a delay into the code to make sure that when clk_enable() returned, a driver wouldn't try to use hardware before the clk was actually on. But these cases should pretty much never happen, hence all the pushback against this flag. For these "*gpll0_clk_src" and "*gpll0_div_clk" clocks, there is no halt bit to check the status and it is required to have delay for few cycles so that clock gets turned on before a client driver to use the hardware. + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(18), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_gpll0_clk_src", + .parent_names = (const char *[]){ + "gpll0", + }, + .num_parents = 1, [...] + .enable_reg = 0x7508c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_phy_aux_clk", + .parent_names = (const char *[]){ + "gcc_ufs_card_phy_aux_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = _branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = { + .halt_reg = 0x75018, + .halt_check = BRANCH_HALT_DELAY, There are still HALT_DELAY flags for UFS though? Why? For ufs_card tx/rx symbol clocks, we don't poll the status bit as per the recommendation from the HW team. We can change the halt_check type to newly implemented flag "BRANCH_HALT_SKIP". Please update us with your thoughts to change the flag to "BRANCH_HALT_SKIP". Also, are you going to send DFS support for the QUP clks? I would like to see that code merged soon. Taniya has sent the patches for DFS support for QUP clocks. https://patchwork.kernel.org/patch/10376951/
Re: [PATCH v6 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845
On 2018-05-02 12:53, Stephen Boyd wrote: Quoting Amit Nischal (2018-04-30 09:20:10) --- .../devicetree/bindings/clock/qcom,gcc.txt |1 + drivers/clk/qcom/Kconfig | 10 +- drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/gcc-sdm845.c | 3480 include/dt-bindings/clock/qcom,gcc-sdm845.h| 239 ++ Do the split that Rob suggests please, given that you're resending. And also include his reviewed-by tag. Thanks for the review. Sure I will split the dt-binding into separate patch in next series. 5 files changed, 3727 insertions(+), 4 deletions(-) create mode 100644 drivers/clk/qcom/gcc-sdm845.c create mode 100644 include/dt-bindings/clock/qcom,gcc-sdm845.h diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index e42e1af..3298beb 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -218,13 +218,15 @@ config MSM_MMCC_8996 Say Y if you want to support multimedia devices such as display, graphics, video encode/decode, camera, etc. -config MSM_GCC_8998 - tristate "MSM8998 Global Clock Controller" +config SDM_GCC_845 + tristate "SDM845 Global Clock Controller" + select QCOM_GDSC depends on COMMON_CLK_QCOM help - Support for the global clock controller on msm8998 devices. + Support for the global clock controller on Qualcomm Technologies, Inc + sdm845 devices. Say Y if you want to use peripheral devices such as UART, SPI, - i2c, USB, UFS, SD/eMMC, PCIe, etc. + I2C, USB, UFS, SDDC, PCIe, etc. This is all wrong. My bad. I did by mistake. Will fix this in next series. config SPMI_PMIC_CLKDIV tristate "SPMI PMIC clkdiv Support" diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c new file mode 100644 index 000..6484cba --- /dev/null +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -0,0 +1,3480 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + [...] + .name = "gcc_disp_axi_clk", + .ops = _branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_gpll0_clk_src = { + .halt_reg = 0x52004, + .halt_check = BRANCH_HALT_DELAY, What about this one? It's not a phy so I'm confused again why we're unable to check the halt bit. To be clear(er), I don't see why we ever want to have HALT_DELAY used. Hopefully we can remove that flag. From what I recall, the flag is there for clks that don't toggle their status bit at all, but that we know take a few cycles to ungate the upstream clk. So we threw a delay into the code to make sure that when clk_enable() returned, a driver wouldn't try to use hardware before the clk was actually on. But these cases should pretty much never happen, hence all the pushback against this flag. For these "*gpll0_clk_src" and "*gpll0_div_clk" clocks, there is no halt bit to check the status and it is required to have delay for few cycles so that clock gets turned on before a client driver to use the hardware. + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(18), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_gpll0_clk_src", + .parent_names = (const char *[]){ + "gpll0", + }, + .num_parents = 1, [...] + .enable_reg = 0x7508c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_phy_aux_clk", + .parent_names = (const char *[]){ + "gcc_ufs_card_phy_aux_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = _branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = { + .halt_reg = 0x75018, + .halt_check = BRANCH_HALT_DELAY, There are still HALT_DELAY flags for UFS though? Why? For ufs_card tx/rx symbol clocks, we don't poll the status bit as per the recommendation from the HW team. We can change the halt_check type to newly implemented flag "BRANCH_HALT_SKIP". Please update us with your thoughts to change the flag to "BRANCH_HALT_SKIP". Also, are you going to send DFS support for the QUP clks? I would like to see that code merged soon. Taniya has sent the patches for DFS support for QUP clocks. https://patchwork.kernel.org/patch/10376951/
[PATCH v1 1/2] dt-bindings: clock: Introduce QCOM Video clock controller bindings
Add device tree bindings for video clock controller for Qualcomm Technology Inc's SoCs. Signed-off-by: Amit Nischal <anisc...@codeaurora.org> --- .../devicetree/bindings/clock/qcom,videocc.txt | 18 include/dt-bindings/clock/qcom,videocc-sdm845.h| 25 ++ 2 files changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,videocc.txt create mode 100644 include/dt-bindings/clock/qcom,videocc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,videocc.txt b/Documentation/devicetree/bindings/clock/qcom,videocc.txt new file mode 100644 index 000..600eda2 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,videocc.txt @@ -0,0 +1,18 @@ +Qualcomm Video Clock & Reset Controller Binding +--- + +Required properties : +- compatible : shall contain "qcom,sdm845-videocc" +- reg : shall contain base register location and length +- #clock-cells : from common clock binding, shall contain 1. +- #reset-cells : from common reset binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Example: + videocc: clock-controller@ab0 { + compatible = "qcom,sdm845-videocc"; + reg = <0xab0 0x1>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/clock/qcom,videocc-sdm845.h b/include/dt-bindings/clock/qcom,videocc-sdm845.h new file mode 100644 index 000..48f6a9e --- /dev/null +++ b/include/dt-bindings/clock/qcom,videocc-sdm845.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ + +#ifndef _DT_BINDINGS_CLK_MSM_VIDEO_CC_SDM845_H +#define _DT_BINDINGS_CLK_MSM_VIDEO_CC_SDM845_H + +#define VIDEO_CC_APB_CLK 0 +#define VIDEO_CC_AT_CLK1 +#define VIDEO_CC_QDSS_TRIG_CLK 2 +#define VIDEO_CC_QDSS_TSCTR_DIV8_CLK 3 +#define VIDEO_CC_VCODEC0_AXI_CLK 4 +#define VIDEO_CC_VCODEC0_CORE_CLK 5 +#define VIDEO_CC_VCODEC1_AXI_CLK 6 +#define VIDEO_CC_VCODEC1_CORE_CLK 7 +#define VIDEO_CC_VENUS_AHB_CLK 8 +#define VIDEO_CC_VENUS_CLK_SRC 9 +#define VIDEO_CC_VENUS_CTL_AXI_CLK 10 +#define VIDEO_CC_VENUS_CTL_CORE_CLK11 +#define VIDEO_PLL0 12 + +#define VENUS_GDSC 0 +#define VCODEC0_GDSC 1 +#define VCODEC1_GDSC 2 + +#endif -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v1 1/2] dt-bindings: clock: Introduce QCOM Video clock controller bindings
Add device tree bindings for video clock controller for Qualcomm Technology Inc's SoCs. Signed-off-by: Amit Nischal --- .../devicetree/bindings/clock/qcom,videocc.txt | 18 include/dt-bindings/clock/qcom,videocc-sdm845.h| 25 ++ 2 files changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,videocc.txt create mode 100644 include/dt-bindings/clock/qcom,videocc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,videocc.txt b/Documentation/devicetree/bindings/clock/qcom,videocc.txt new file mode 100644 index 000..600eda2 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,videocc.txt @@ -0,0 +1,18 @@ +Qualcomm Video Clock & Reset Controller Binding +--- + +Required properties : +- compatible : shall contain "qcom,sdm845-videocc" +- reg : shall contain base register location and length +- #clock-cells : from common clock binding, shall contain 1. +- #reset-cells : from common reset binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Example: + videocc: clock-controller@ab0 { + compatible = "qcom,sdm845-videocc"; + reg = <0xab0 0x1>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/clock/qcom,videocc-sdm845.h b/include/dt-bindings/clock/qcom,videocc-sdm845.h new file mode 100644 index 000..48f6a9e --- /dev/null +++ b/include/dt-bindings/clock/qcom,videocc-sdm845.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ + +#ifndef _DT_BINDINGS_CLK_MSM_VIDEO_CC_SDM845_H +#define _DT_BINDINGS_CLK_MSM_VIDEO_CC_SDM845_H + +#define VIDEO_CC_APB_CLK 0 +#define VIDEO_CC_AT_CLK1 +#define VIDEO_CC_QDSS_TRIG_CLK 2 +#define VIDEO_CC_QDSS_TSCTR_DIV8_CLK 3 +#define VIDEO_CC_VCODEC0_AXI_CLK 4 +#define VIDEO_CC_VCODEC0_CORE_CLK 5 +#define VIDEO_CC_VCODEC1_AXI_CLK 6 +#define VIDEO_CC_VCODEC1_CORE_CLK 7 +#define VIDEO_CC_VENUS_AHB_CLK 8 +#define VIDEO_CC_VENUS_CLK_SRC 9 +#define VIDEO_CC_VENUS_CTL_AXI_CLK 10 +#define VIDEO_CC_VENUS_CTL_CORE_CLK11 +#define VIDEO_PLL0 12 + +#define VENUS_GDSC 0 +#define VCODEC0_GDSC 1 +#define VCODEC1_GDSC 2 + +#endif -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation