Re: [PATCH v4 5/7] cpufreq: qcom-hw: Implement CPRh aware OSM programming
On 4/13/2021 9:19 AM, Viresh Kumar wrote: On 12-04-21, 15:01, Taniya Das wrote: Technically the HW we are trying to program here differs in terms of clocking, the LUT definitions and many more. It will definitely make debugging much more troublesome if we try to accommodate multiple versions of CPUFREQ-HW in the same code. Thus to keep it simple, easy to read, debug, the suggestion is to keep it with "v1" tag as the OSM version we are trying to put here is from OSM1.0. That is a valid point and is always a case with so many drivers. What I am concerned about is how much code is common across versions, if it is 5-70%, or more, then we should definitely share, arrange to have callbacks or ops per version and call them in a generic fashion instead of writing a new driver. This is what's done across drivers/frameworks, etc. The code sharing here between versions should be very minimal as most portion of the code here in V1 would focus on programming to prepare the LUT to be further read by the driver, the programming in itself is huge for v1. I am okay if you move the v1 in a different file and invoke based on version. -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
Re: [PATCH v4 5/7] cpufreq: qcom-hw: Implement CPRh aware OSM programming
Hi Bjorn, On 1/21/2021 12:35 AM, Bjorn Andersson wrote: On Wed 20 Jan 12:25 CST 2021, Taniya Das wrote: The CPUFREQ-HW driver is intended to be used only for CPUFREQ HW designs where the firmware programs the look up tables. It's obvious that this is the intended target for the current version of the driver, but what are your technical arguments for keeping it that way? Technically the HW we are trying to program here differs in terms of clocking, the LUT definitions and many more. It will definitely make debugging much more troublesome if we try to accomodate multiple versions of CPUFREQ-HW in the same code. Thus to keep it simple, easy to read, debug, the suggestion is to keep it with "v1" tag as the OSM version we are trying to put here is from OSM1.0. Suggestion is to separate out the driver where the programming is managed by high level OS. Can you please elaborate on the benefits of this approach? PS. Please don't top-post on LKML. Regards, Bjorn On 1/19/2021 11:15 PM, AngeloGioacchino Del Regno wrote: On new SoCs (SDM845 onwards) the Operating State Manager (OSM) is being programmed in the bootloader and write-protected by the hypervisor, leaving to the OS read-only access to some of its registers (in order to read the Lookup Tables and also some status registers) and write access to the p-state register, for for the OS to request a specific performance state to trigger a DVFS switch on the CPU through the OSM hardware. On old SoCs though (MSM8998, SDM630/660 and variants), the bootloader will *not* initialize the OSM (and the CPRh, as it is a requirement for it) before booting the OS, making any request to trigger a performance state change ineffective, as the hardware doesn't have any Lookup Table, nor is storing any parameter to trigger a DVFS switch. In this case, basically all of the OSM registers are *not* write protected for the OS, even though some are - but write access is granted through SCM calls. This commit introduces support for OSM programming, which has to be done on these old SoCs that were distributed (almost?) always with a bootloader that does not do any CPRh nor OSM init before booting the kernel. In order to program the OSM on these SoCs, it is necessary to fullfill a "special" requirement: the Core Power Reduction Hardened (CPRh) hardware block must be initialized, as the OSM is "talking" to it in order to perform the Voltage part of DVFS; here, we are calling initialization of this through Linux generic power domains, specifically by requesting a genpd attach from the qcom-cpufreq-hw driver, which will give back voltages associated to each CPU frequency that has been declared in the OPPs, scaled and interpolated with the previous one, and will also give us parameters for the Array Power Mux (APM) and mem-acc, in order for this driver to be then able to generate the Lookup Tables that will be finally programmed to the OSM hardware. After writing the parameters to the OSM and enabling it, all the programming work will never happen anymore until a OS reboot, so all of the allocations and "the rest" will be disposed-of: this is done mainly to leave the code that was referred only to the new SoCs intact, as to also emphasize on the fact that the OSM HW is, in the end, the exact same; apart some register offsets that are slightly different, the entire logic is the same. This also adds the parameters to support CPU scaling on SDM630 and MSM8998. Signed-off-by: AngeloGioacchino Del Regno --- drivers/cpufreq/qcom-cpufreq-hw.c | 1240 - 1 file changed, 1208 insertions(+), 32 deletions(-) diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index acc645b85e79..a92959bb7b50 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -1,33 +1,256 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * OSM hardware initial programming + * Copyright (C) 2020, AngeloGioacchino Del Regno + * */ #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #define LUT_MAX_ENTRIES 40U -#define LUT_SRCGENMASK(31, 30) +#define LUT_SRC_845GENMASK(31, 30) +#define LUT_SRC_8998 GENMASK(27, 26) +#define LUT_PLL_DIVGENMASK(25, 24) #define LUT_L_VALGENMASK(7, 0) #define LUT_CORE_COUNT GENMASK(18, 16) +#define LUT_VOLT_VCGENMASK(21, 16) #define LUT_VOLT GENMASK(11, 0) -#define CLK_HW_DIV 2 #define LUT_TURBO_IND1 +#define OSM_BOOT_TIME_US 5 + +#define CYCLE_
[PATCH v1 2/2] arm64: dts: qcom: sc7280: Add clock controller nodes
Add support for the video, gpu, display, lpass clock controller device nodes for SC7280 SoC. Signed-off-by: Taniya Das --- arch/arm64/boot/dts/qcom/sc7280.dtsi | 58 1 file changed, 58 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index cda3f2a..b59 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -5,8 +5,12 @@ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ +#include #include +#include +#include #include +#include #include #include #include @@ -324,6 +328,31 @@ }; }; + lpasscc: lpasscc@300 { + compatible = "qcom,sc7280-lpasscc"; + reg = <0 0x0300 0 0x40>, + <0 0x03c04000 0 0x4>, + <0 0x03389000 0 0x24>; + reg-names = "qdsp6ss", "top_cc", "cc"; + clocks = <&gcc GCC_CFG_NOC_LPASS_CLK>; + clock-names = "iface"; + #clock-cells = <1>; + }; + + gpucc: clock-controller@3d9 { + compatible = "qcom,sc7280-gpucc"; + reg = <0 0x03d9 0 0x9000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, +<&gcc GCC_GPU_GPLL0_CLK_SRC>, +<&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>; + clock-names = "bi_tcxo", + "gcc_gpu_gpll0_clk_src", + "gcc_gpu_gpll0_div_clk_src"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + stm@6002000 { compatible = "arm,coresight-stm", "arm,primecell"; reg = <0 0x06002000 0 0x1000>, @@ -820,6 +849,35 @@ interrupts = ; }; + videocc: clock-controller@aaf { + compatible = "qcom,sc7280-videocc"; + reg = <0 0xaaf 0 0x1>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&rpmhcc RPMH_CXO_CLK_A>; + clock-names = "bi_tcxo", "bi_tcxo_ao"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + dispcc: clock-controller@af0 { + compatible = "qcom,sc7280-dispcc"; + reg = <0 0xaf0 0 0x2>; + clocks = <&rpmhcc RPMH_CXO_CLK>, +<&gcc GCC_DISP_GPLL0_CLK_SRC>, +<0>, <0>, <0>, <0>, <0>, <0>; + clock-names = "bi_tcxo", "gcc_disp_gpll0_clk", + "dsi0_phy_pll_out_byteclk", + "dsi0_phy_pll_out_dsiclk", + "dp_phy_pll_link_clk", + "dp_phy_pll_vco_div_clk", + "edp_phy_pll_link_clk", + "edp_phy_pll_vco_div_clk"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + pdc: interrupt-controller@b22 { compatible = "qcom,sc7280-pdc", "qcom,pdc"; reg = <0 0x0b22 0 0x3>; -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v1 0/2] Add device nodes for SC7280 SoCs
Add device node for cpufreq HW and clock controllers of GPU, DISP, VIDEO, LPASS. The clock controller nodes are dependent on the following VIDEO/DISP/GPU: https://lkml.org/lkml/2021/3/16/1624 LPASS: https://lkml.org/lkml/2021/4/9/812 Taniya Das (2): arm64: dts: qcom: sc7280: Add cpufreq hw node arm64: dts: qcom: sc7280: Add clock controller nodes arch/arm64/boot/dts/qcom/sc7280.dtsi | 78 1 file changed, 78 insertions(+) -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v1 1/2] arm64: dts: qcom: sc7280: Add cpufreq hw node
Add cpufreq HW device node to scale 4-Silver/3-Gold/1-Gold+ cores on SC7280 SoCs. Signed-off-by: Taniya Das --- arch/arm64/boot/dts/qcom/sc7280.dtsi | 19 +++ 1 file changed, 19 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index 2cc4785..cda3f2a 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -70,6 +70,7 @@ &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; next-level-cache = <&L2_0>; + qcom,freq-domain = <&cpufreq_hw 0>; L2_0: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -88,6 +89,7 @@ &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; next-level-cache = <&L2_100>; + qcom,freq-domain = <&cpufreq_hw 0>; L2_100: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -103,6 +105,7 @@ &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; next-level-cache = <&L2_200>; + qcom,freq-domain = <&cpufreq_hw 0>; L2_200: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -118,6 +121,7 @@ &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; next-level-cache = <&L2_300>; + qcom,freq-domain = <&cpufreq_hw 0>; L2_300: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -133,6 +137,7 @@ &BIG_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; next-level-cache = <&L2_400>; + qcom,freq-domain = <&cpufreq_hw 1>; L2_400: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -148,6 +153,7 @@ &BIG_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; next-level-cache = <&L2_500>; + qcom,freq-domain = <&cpufreq_hw 1>; L2_500: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -163,6 +169,7 @@ &BIG_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; next-level-cache = <&L2_600>; + qcom,freq-domain = <&cpufreq_hw 1>; L2_600: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -178,6 +185,7 @@ &BIG_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; next-level-cache = <&L2_700>; + qcom,freq-domain = <&cpufreq_hw 2>; L2_700: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -1116,6 +1124,17 @@ #clock-cells = <1>; }; }; + + cpufreq_hw: cpufreq@18591000 { + compatible = "qcom,cpufreq-epss"; + reg = <0 0x18591000 0 0x1000>, + <0 0x18592000 0 0x1000>, + <0 0x18593000 0 0x1000>; + reg-names = "freq-domain0", "freq-domain1", "freq-domain2"; + clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>; + clock-names = "xo", "alternate"; + #freq-domain-cells = <1>; + }; }; timer { -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v1 2/2] clk: qcom: Add lpass clock controller driver for SC7280
Add support for the lpass clock controller found on SC7280 based devices. This would allow lpass peripheral loader drivers to control the clocks to bring the subsystem out of reset. Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 8 ++ drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/lpasscc-sc7280.c | 216 ++ 3 files changed, 225 insertions(+) create mode 100644 drivers/clk/qcom/lpasscc-sc7280.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 45646b8..caf986e 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -361,6 +361,14 @@ config SC_LPASS_CORECC_7180 Say Y if you want to use LPASS clocks and power domains of the LPASS core clock controller. +config SC_LPASSCC_7280 + tristate "SC7280 Low Power Audio Subsystem (LPAAS) Clock Controller" + select SC_GCC_7280 + help + Support for the LPASS clock controller on SC7280 devices. + Say Y if you want to use the LPASS branch clocks of the LPASS clock + controller to reset the LPASS subsystem. + config SC_GPUCC_7180 tristate "SC7180 Graphics Clock Controller" select SC_GCC_7180 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index c829131..6f0ab5f 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_SC_GCC_7280) += gcc-sc7280.o obj-$(CONFIG_SC_GCC_8180X) += gcc-sc8180x.o obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o +obj-$(CONFIG_SC_LPASSCC_7280) += lpasscc-sc7280.o obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o diff --git a/drivers/clk/qcom/lpasscc-sc7280.c b/drivers/clk/qcom/lpasscc-sc7280.c new file mode 100644 index 000..89f1ad6 --- /dev/null +++ b/drivers/clk/qcom/lpasscc-sc7280.c @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-regmap.h" +#include "clk-branch.h" +#include "common.h" + +static struct clk_branch lpass_q6ss_ahbm_clk = { + .halt_reg = 0x1c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lpass_q6ss_ahbm_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lpass_q6ss_ahbs_clk = { + .halt_reg = 0x20, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x20, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lpass_q6ss_ahbs_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lpass_top_cc_lpi_q6_axim_hs_clk = { + .halt_reg = 0x0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lpass_top_cc_lpi_q6_axim_hs_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lpass_qdsp6ss_core_clk = { + .halt_reg = 0x20, + /* CLK_OFF would not toggle until LPASS is out of reset */ + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x20, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lpass_qdsp6ss_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lpass_qdsp6ss_xo_clk = { + .halt_reg = 0x38, + /* CLK_OFF would not toggle until LPASS is out of reset */ + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x38, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lpass_qdsp6ss_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lpass_qdsp6ss_sleep_clk = { + .halt_reg = 0x3c, + /* CLK_OFF would not toggle until LPASS is out of reset */ + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x3c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lpass_qdsp6ss_sleep_clk", +
[PATCH v1 1/2] dt-bindings: clock: Add YAML schemas for LPASS clocks on SC7280
The LPASS(Low Power Audio Subsystem) clock provider have a bunch of generic properties that are needed in a device tree. Add the LPASS clock IDs for LPASS PIL client to request for the clocks. Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sc7280-lpasscc.yaml| 69 ++ include/dt-bindings/clock/qcom,lpass-sc7280.h | 16 + 2 files changed, 85 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscc.yaml create mode 100644 include/dt-bindings/clock/qcom,lpass-sc7280.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscc.yaml new file mode 100644 index 000..7b62763 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscc.yaml @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sc7280-lpasscc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm LPASS Core Clock Controller Binding for SC7280 + +maintainers: + - Taniya Das + +description: | + Qualcomm LPASS core clock control module which supports the clocks and + power domains on SC7280. + + See also: + - dt-bindings/clock/qcom,lpass-sc7280.h + +properties: + compatible: +enum: + - qcom,sc7280-lpasscc + + clocks: +items: + - description: gcc_cfg_noc_lpass_clk from GCC + + clock-names: +items: + - const: iface + + '#clock-cells': +const: 1 + + reg: +minItems: 3 +items: + - description: LPASS qdsp6ss register + - description: LPASS top-cc register + - description: LPASS cc register + + reg-names: +items: + - const: qdsp6ss + - const: top_cc + - const: cc + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + +additionalProperties: false + +examples: + - | +#include +#include +clock-controller@300 { + compatible = "qcom,sc7280-lpasscc"; + reg = <0x0300 0x40>, <0x03c04000 0x4>, <0x03389000 0x24>; + reg-names = "qdsp6ss", "top_cc", "cc"; + clocks = <&gcc GCC_CFG_NOC_LPASS_CLK>; + clock-names = "iface"; + #clock-cells = <1>; +}; +... diff --git a/include/dt-bindings/clock/qcom,lpass-sc7280.h b/include/dt-bindings/clock/qcom,lpass-sc7280.h new file mode 100644 index 000..a259463 --- /dev/null +++ b/include/dt-bindings/clock/qcom,lpass-sc7280.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_LPASS_SC7280_H +#define _DT_BINDINGS_CLK_QCOM_LPASS_SC7280_H + +#define LPASS_Q6SS_AHBM_CLK0 +#define LPASS_Q6SS_AHBS_CLK1 +#define LPASS_TOP_CC_LPI_Q6_AXIM_HS_CLK2 +#define LPASS_QDSP6SS_XO_CLK 3 +#define LPASS_QDSP6SS_SLEEP_CLK4 +#define LPASS_QDSP6SS_CORE_CLK 5 + +#endif -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
Re: [PATCH] clk: qcom: camcc: Update the clock ops for the SC7180
Thanks Stephen for the review. On 3/23/2021 12:59 PM, Stephen Boyd wrote: Quoting Taniya Das (2021-03-19 00:47:34) Update the RCGs to use shared ops to park the RCGs at XO. s/Update/fix/? Can you also elaborate more on why we need to park the RCGs here for all these different clks? Is the camera driver supposed to not touch these and let the firmware take over? Is there zero coordination between the kernel and the firmware? Updated the patch with details. Fixes: 15d09e830bbc ("clk: qcom: camcc: Add camera clock controller driver for SC7180") Signed-off-by: Taniya Das -- 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: camcc: Update the clock ops for the SC7180
Some of the RCGs could be always ON from the XO source and could be used as the clock on signal for the GDSC to be operational. In the cases where the GDSCs are parked at different source with the source clock disabled, it could lead to the GDSC to be stuck at ON/OFF during gdsc disable/enable. Thus park the RCGs at XO during clock disable and update the rcg_ops to use the shared_ops. Fixes: 15d09e830bbc ("clk: qcom: camcc: Add camera clock controller driver for SC7180") Signed-off-by: Taniya Das --- drivers/clk/qcom/camcc-sc7180.c | 50 - 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/clk/qcom/camcc-sc7180.c b/drivers/clk/qcom/camcc-sc7180.c index dbac565..9bcf2f8 100644 --- a/drivers/clk/qcom/camcc-sc7180.c +++ b/drivers/clk/qcom/camcc-sc7180.c @@ -304,7 +304,7 @@ static struct clk_rcg2 cam_cc_bps_clk_src = { .name = "cam_cc_bps_clk_src", .parent_data = cam_cc_parent_data_2, .num_parents = 5, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -325,7 +325,7 @@ static struct clk_rcg2 cam_cc_cci_0_clk_src = { .name = "cam_cc_cci_0_clk_src", .parent_data = cam_cc_parent_data_5, .num_parents = 3, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -339,7 +339,7 @@ static struct clk_rcg2 cam_cc_cci_1_clk_src = { .name = "cam_cc_cci_1_clk_src", .parent_data = cam_cc_parent_data_5, .num_parents = 3, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -360,7 +360,7 @@ static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { .name = "cam_cc_cphy_rx_clk_src", .parent_data = cam_cc_parent_data_3, .num_parents = 6, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -379,7 +379,7 @@ static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { .name = "cam_cc_csi0phytimer_clk_src", .parent_data = cam_cc_parent_data_0, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -393,7 +393,7 @@ static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { .name = "cam_cc_csi1phytimer_clk_src", .parent_data = cam_cc_parent_data_0, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -407,7 +407,7 @@ static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = { .name = "cam_cc_csi2phytimer_clk_src", .parent_data = cam_cc_parent_data_0, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -421,7 +421,7 @@ static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { .name = "cam_cc_csi3phytimer_clk_src", .parent_data = cam_cc_parent_data_0, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -443,7 +443,7 @@ static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { .name = "cam_cc_fast_ahb_clk_src", .parent_data = cam_cc_parent_data_0, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -466,7 +466,7 @@ static struct clk_rcg2 cam_cc_icp_clk_src = { .name = "cam_cc_icp_clk_src", .parent_data = cam_cc_parent_data_2, .num_parents = 5, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -488,7 +488,7 @@ static struct clk_rcg2 cam_cc_ife_0_clk_src = { .name = "cam_cc_ife_0_clk_src", .parent_data = cam_cc_parent_data_4, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -510,7 +510,7 @@ static struct clk_rcg2 cam_cc_ife_0_csid_clk_src = { .name = "cam_cc_ife_0_csid_clk_src", .parent_data = cam_cc_parent_data_3, .num_parents = 6, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -524,7 +524,7 @@ static struct clk_rcg2 cam_cc_ife_1_clk_src = { .name = "cam_cc_ife_1_clk_src", .parent_data = cam_cc_parent_data_4, .num_parents = 4, - .ops = &clk_rcg2_ops
Re: [PATCH v2] clk: qcom: clk-rcg2: Add support for duty-cycle for RCG
Hello Stephen, Thanks for your review. On 3/14/2021 4:29 AM, Stephen Boyd wrote: Quoting Taniya Das (2021-03-11 04:51:32) The root clock generators with MND divider has the capability to support change in duty-cycle by updating the 'D'. Add the clock ops which would check all the boundary conditions and enable setting the desired duty-cycle as per the consumer. Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-rcg2.c | 42 ++ 1 file changed, 42 insertions(+) diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 42f13a2..aac6893 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -357,6 +357,46 @@ static int clk_rcg2_set_floor_rate_and_parent(struct clk_hw *hw, return __clk_rcg2_set_rate(hw, rate, FLOOR); } +static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + u32 notn_m_val, n_val, m_val, d_val, not2d_val, mask, duty_per; + int ret; + + if (!rcg->mnd_width) + return 0; Shouldn't we fail this call if the duty cycle can't be changed? Or have another set of clk ops that doesn't support this clk op if the mnd isn't present. Sure, will fail the call for non-MND(HID)RCGs, will be part of my next patch. + + mask = BIT(rcg->mnd_width) - 1; + + regmap_read(rcg->clkr.regmap, RCG_N_OFFSET(rcg), ¬n_m_val); + regmap_read(rcg->clkr.regmap, RCG_M_OFFSET(rcg), &m_val); + + n_val = (~(notn_m_val) + m_val) & mask; + + duty_per = (duty->num * 100) / duty->den; + + /* Calculate 2d value */ + d_val = DIV_ROUND_CLOSEST(n_val * duty_per * 2, 100); + +/* Check BIT WIDTHS OF 2d. If D is too big reduce Duty cycle. */ Why is BIT WIDTHS capitalized? And Duty? Will take care of it in the next patch. + if (d_val > mask) + d_val = mask; + + if ((d_val / 2) > (n_val - m_val)) + d_val = (n_val - m_val) * 2; + else if ((d_val / 2) < (m_val / 2)) + d_val = m_val; + + not2d_val = ~d_val & mask; + + ret = regmap_update_bits(rcg->clkr.regmap, RCG_D_OFFSET(rcg), mask, +not2d_val); + if (ret) + return ret; + + return update_config(rcg); +} + const struct clk_ops clk_rcg2_ops = { .is_enabled = clk_rcg2_is_enabled, .get_parent = clk_rcg2_get_parent, @@ -365,6 +405,7 @@ const struct clk_ops clk_rcg2_ops = { .determine_rate = clk_rcg2_determine_rate, .set_rate = clk_rcg2_set_rate, .set_rate_and_parent = clk_rcg2_set_rate_and_parent, + .set_duty_cycle = clk_rcg2_set_duty_cycle, Can you also implement get_duty_cycle? Sure, will implement the same. }; EXPORT_SYMBOL_GPL(clk_rcg2_ops); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
[PATCH] clk: qcom: camcc: Update the clock ops for the SC7180
Update the RCGs to use shared ops to park the RCGs at XO. Fixes: 15d09e830bbc ("clk: qcom: camcc: Add camera clock controller driver for SC7180") Signed-off-by: Taniya Das --- drivers/clk/qcom/camcc-sc7180.c | 50 - 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/clk/qcom/camcc-sc7180.c b/drivers/clk/qcom/camcc-sc7180.c index dbac565..9bcf2f8 100644 --- a/drivers/clk/qcom/camcc-sc7180.c +++ b/drivers/clk/qcom/camcc-sc7180.c @@ -304,7 +304,7 @@ static struct clk_rcg2 cam_cc_bps_clk_src = { .name = "cam_cc_bps_clk_src", .parent_data = cam_cc_parent_data_2, .num_parents = 5, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -325,7 +325,7 @@ static struct clk_rcg2 cam_cc_cci_0_clk_src = { .name = "cam_cc_cci_0_clk_src", .parent_data = cam_cc_parent_data_5, .num_parents = 3, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -339,7 +339,7 @@ static struct clk_rcg2 cam_cc_cci_1_clk_src = { .name = "cam_cc_cci_1_clk_src", .parent_data = cam_cc_parent_data_5, .num_parents = 3, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -360,7 +360,7 @@ static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { .name = "cam_cc_cphy_rx_clk_src", .parent_data = cam_cc_parent_data_3, .num_parents = 6, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -379,7 +379,7 @@ static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { .name = "cam_cc_csi0phytimer_clk_src", .parent_data = cam_cc_parent_data_0, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -393,7 +393,7 @@ static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { .name = "cam_cc_csi1phytimer_clk_src", .parent_data = cam_cc_parent_data_0, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -407,7 +407,7 @@ static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = { .name = "cam_cc_csi2phytimer_clk_src", .parent_data = cam_cc_parent_data_0, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -421,7 +421,7 @@ static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { .name = "cam_cc_csi3phytimer_clk_src", .parent_data = cam_cc_parent_data_0, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -443,7 +443,7 @@ static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { .name = "cam_cc_fast_ahb_clk_src", .parent_data = cam_cc_parent_data_0, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -466,7 +466,7 @@ static struct clk_rcg2 cam_cc_icp_clk_src = { .name = "cam_cc_icp_clk_src", .parent_data = cam_cc_parent_data_2, .num_parents = 5, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -488,7 +488,7 @@ static struct clk_rcg2 cam_cc_ife_0_clk_src = { .name = "cam_cc_ife_0_clk_src", .parent_data = cam_cc_parent_data_4, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -510,7 +510,7 @@ static struct clk_rcg2 cam_cc_ife_0_csid_clk_src = { .name = "cam_cc_ife_0_csid_clk_src", .parent_data = cam_cc_parent_data_3, .num_parents = 6, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -524,7 +524,7 @@ static struct clk_rcg2 cam_cc_ife_1_clk_src = { .name = "cam_cc_ife_1_clk_src", .parent_data = cam_cc_parent_data_4, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -538,7 +538,7 @@ static struct clk_rcg2 cam_cc_ife_1_csid_clk_src = { .name = "cam_cc_ife_1_csid_clk_src", .parent_data = cam_cc_parent_data_3, .num_parents = 6, - .ops = &a
[PATCH v1 4/6] clk: qcom: Add graphics clock controller driver for SC7280
Add support for the graphics clock controller found on SC7280 based devices. This would allow graphics drivers to probe and control their clocks. Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig| 8 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-sc7280.c | 491 3 files changed, 500 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-sc7280.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 336f15c..13fb381 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -378,6 +378,14 @@ config SC_GPUCC_7180 Say Y if you want to support graphics controller devices and functionality such as 3D graphics. +config SC_GPUCC_7280 + tristate "SC7280 Graphics Clock Controller" + select SC_GCC_7280 + help + Support for the graphics clock controller on SC7280 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config SC_MSS_7180 tristate "SC7180 Modem Clock Controller" select SC_GCC_7180 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index db07a19..c84a31d 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o obj-$(CONFIG_SC_GCC_7280) += gcc-sc7280.o obj-$(CONFIG_SC_GCC_8180X) += gcc-sc8180x.o obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o +obj-$(CONFIG_SC_GPUCC_7280) += gpucc-sc7280.o obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o diff --git a/drivers/clk/qcom/gpucc-sc7280.c b/drivers/clk/qcom/gpucc-sc7280.c new file mode 100644 index 000..734a812 --- /dev/null +++ b/drivers/clk/qcom/gpucc-sc7280.c @@ -0,0 +1,491 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "reset.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_GCC_GPU_GPLL0_CLK_SRC, + P_GCC_GPU_GPLL0_DIV_CLK_SRC, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL1_OUT_MAIN, +}; + +static struct pll_vco lucid_vco[] = { + { 24960, 20, 0 }, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .vco_table = lucid_vco, + .num_vco = ARRAY_SIZE(lucid_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_ops, + }, + }, +}; + +/* 500MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll1_config = { + .l = 0x1A, + .alpha = 0xAAA, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x2261, + .config_ctl_hi1_val = 0x329A299C, + .user_ctl_val = 0x0001, + .user_ctl_hi_val = 0x0805, + .user_ctl_hi1_val = 0x, +}; + +static struct clk_alpha_pll gpu_cc_pll1 = { + .offset = 0x100, + .vco_table = lucid_vco, + .num_vco = ARRAY_SIZE(lucid_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll1", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_ops, + }, + }, +}; + +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_GCC_GPU_GPLL0_CLK_SRC, 5 }, + { P_GCC_GPU_GPLL0_DIV_CLK_SRC, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_0[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .hw = &gpu_cc_pll1.clkr.hw }, + { .fw_name = "gcc_gpu_gpll0_clk_src" }, + { .fw_name = "gcc_gpu_gpll0_div_clk_src" }, +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GCC_GPU_GPLL0_CLK_SRC, 5 }, + { P_GCC
[PATCH v1 6/6] clk: qcom: Add video clock controller driver for SC7280
Add support for the video clock controller found on SC7280 based devices. This would allow video drivers to probe and control their clocks. Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 8 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/videocc-sc7280.c | 372 ++ 3 files changed, 381 insertions(+) create mode 100644 drivers/clk/qcom/videocc-sc7280.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 13fb381..ad85e6d 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -403,6 +403,14 @@ config SC_VIDEOCC_7180 Say Y if you want to support video devices and functionality such as video encode and decode. +config SC_VIDEOCC_7280 + tristate "SC7280 Video Clock Controller" + select SC_GCC_7280 + help + Support for the video clock controller on SC7280 devices. + Say Y if you want to support video devices and functionality such as + video encode and decode. + config SDM_CAMCC_845 tristate "SDM845 Camera Clock Controller" select SDM_GCC_845 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index c84a31d..d87c2ed 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -65,6 +65,7 @@ obj-$(CONFIG_SC_GPUCC_7280) += gpucc-sc7280.o obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o +obj-$(CONFIG_SC_VIDEOCC_7280) += videocc-sc7280.o obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o diff --git a/drivers/clk/qcom/videocc-sc7280.c b/drivers/clk/qcom/videocc-sc7280.c new file mode 100644 index 000..6b99ef9 --- /dev/null +++ b/drivers/clk/qcom/videocc-sc7280.c @@ -0,0 +1,372 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "common.h" +#include "reset.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_SLEEP_CLK, + P_VIDEO_PLL0_OUT_EVEN, +}; + +static struct pll_vco lucid_vco[] = { + { 24960, 20, 0 }, +}; + +/* 400MHz Configuration */ +static const struct alpha_pll_config video_pll0_config = { + .l = 0x14, + .alpha = 0xD555, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x2261, + .config_ctl_hi1_val = 0x329A299C, + .user_ctl_val = 0x0001, + .user_ctl_hi_val = 0x0805, + .user_ctl_hi1_val = 0x, +}; + +static struct clk_alpha_pll video_pll0 = { + .offset = 0x0, + .vco_table = lucid_vco, + .num_vco = ARRAY_SIZE(lucid_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "video_pll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_ops, + }, + }, +}; + +static const struct parent_map video_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_PLL0_OUT_EVEN, 3 }, +}; + +static const struct clk_parent_data video_cc_parent_data_0[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &video_pll0.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_1[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_1[] = { + { .fw_name = "sleep_clk" }, +}; + +static const struct parent_map video_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_2_ao[] = { + { .fw_name = "bi_tcxo_ao" }, +}; + +static const struct freq_tbl ftbl_video_cc_iris_clk_src[] = { + F(1, P_VIDEO_PLL0_OUT_EVEN, 3, 0, 0), + F(24000, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0), + F(33500, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0), + F(42400, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0), + F(46000, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_iris_clk_src = { + .cmd_rcgr = 0x1000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_iris_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "video_cc_iris_clk_src", + .parent_data = video_cc_parent_data_0, + .num_parents = ARRAY_SIZE(vi
[PATCH v1 5/6] dt-bindings: clock: Add SC7280 VideoCC clock binding
Add device tree bindings for video clock subsystem clock controller for Qualcomm Technology Inc's SC7280 SoCs. Signed-off-by: Taniya Das --- .../devicetree/bindings/clock/qcom,videocc.yaml| 4 +++- include/dt-bindings/clock/qcom,videocc-sc7280.h| 27 ++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 include/dt-bindings/clock/qcom,videocc-sc7280.h diff --git a/Documentation/devicetree/bindings/clock/qcom,videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,videocc.yaml index 5672029..dc90d82 100644 --- a/Documentation/devicetree/bindings/clock/qcom,videocc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,videocc.yaml @@ -11,10 +11,11 @@ maintainers: description: | Qualcomm video clock control module which supports the clocks, resets and - power domains on SDM845/SC7180/SM8150/SM8250. + power domains on SDM845/SC7180/SC7280/SM8150/SM8250. See also: dt-bindings/clock/qcom,videocc-sc7180.h +dt-bindings/clock/qcom,videocc-sc7280.h dt-bindings/clock/qcom,videocc-sdm845.h dt-bindings/clock/qcom,videocc-sm8150.h dt-bindings/clock/qcom,videocc-sm8250.h @@ -23,6 +24,7 @@ properties: compatible: enum: - qcom,sc7180-videocc + - qcom,sc7280-videocc - qcom,sdm845-videocc - qcom,sm8150-videocc - qcom,sm8250-videocc diff --git a/include/dt-bindings/clock/qcom,videocc-sc7280.h b/include/dt-bindings/clock/qcom,videocc-sc7280.h new file mode 100644 index 000..c976d85 --- /dev/null +++ b/include/dt-bindings/clock/qcom,videocc-sc7280.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SC7280_H +#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SC7280_H + +/* VIDEO_CC clocks */ +#define VIDEO_PLL0 0 +#define VIDEO_CC_IRIS_AHB_CLK 1 +#define VIDEO_CC_IRIS_CLK_SRC 2 +#define VIDEO_CC_MVS0_AXI_CLK 3 +#define VIDEO_CC_MVS0_CORE_CLK 4 +#define VIDEO_CC_MVSC_CORE_CLK 5 +#define VIDEO_CC_MVSC_CTL_AXI_CLK 6 +#define VIDEO_CC_SLEEP_CLK 7 +#define VIDEO_CC_SLEEP_CLK_SRC 8 +#define VIDEO_CC_VENUS_AHB_CLK 9 +#define VIDEO_CC_XO_CLK10 +#define VIDEO_CC_XO_CLK_SRC11 + +/* VIDEO_CC power domains */ +#define MVS0_GDSC 0 +#define MVSC_GDSC 1 + +#endif -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v1 2/6] clk: qcom: Add display clock controller driver for SC7280
Add support for the display clock controller found on SC7280 based devices. This would allow display drivers to probe and control their clocks. Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile| 1 + drivers/clk/qcom/dispcc-sc7280.c | 908 +++ 3 files changed, 918 insertions(+) create mode 100644 drivers/clk/qcom/dispcc-sc7280.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 45646b8..336f15c 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -325,6 +325,15 @@ config SC_DISPCC_7180 Say Y if you want to support display devices and functionality such as splash screen. +config SC_DISPCC_7280 + tristate "SC7280 Display Clock Controller" + select SC_GCC_7280 + help + Support for the display clock controller on Qualcomm Technologies, Inc. + SC7280 devices. + Say Y if you want to support display devices and functionality such as + splash screen. + config SC_GCC_7180 tristate "SC7180 Global Clock Controller" select QCOM_GDSC diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index c829131..db07a19 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -56,6 +56,7 @@ obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o +obj-$(CONFIG_SC_DISPCC_7280) += dispcc-sc7280.o obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o obj-$(CONFIG_SC_GCC_7280) += gcc-sc7280.o obj-$(CONFIG_SC_GCC_8180X) += gcc-sc8180x.o diff --git a/drivers/clk/qcom/dispcc-sc7280.c b/drivers/clk/qcom/dispcc-sc7280.c new file mode 100644 index 000..add9434 --- /dev/null +++ b/drivers/clk/qcom/dispcc-sc7280.c @@ -0,0 +1,908 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_DISP_CC_PLL0_OUT_EVEN, + P_DISP_CC_PLL0_OUT_MAIN, + P_DP_PHY_PLL_LINK_CLK, + P_DP_PHY_PLL_VCO_DIV_CLK, + P_DSI0_PHY_PLL_OUT_BYTECLK, + P_DSI0_PHY_PLL_OUT_DSICLK, + P_EDP_PHY_PLL_LINK_CLK, + P_EDP_PHY_PLL_VCO_DIV_CLK, + P_GCC_DISP_GPLL0_CLK, +}; + +static struct pll_vco lucid_vco[] = { + { 24960, 20, 0 }, +}; + +/* 1520MHz Configuration*/ +static const struct alpha_pll_config disp_cc_pll0_config = { + .l = 0x4F, + .alpha = 0x2AAA, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x2261, + .config_ctl_hi1_val = 0x329A299C, + .user_ctl_val = 0x0001, + .user_ctl_hi_val = 0x0805, + .user_ctl_hi1_val = 0x, +}; + +static struct clk_alpha_pll disp_cc_pll0 = { + .offset = 0x0, + .vco_table = lucid_vco, + .num_vco = ARRAY_SIZE(lucid_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_pll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_ops, + }, + }, +}; + +static const struct parent_map disp_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_0[] = { + { .fw_name = "bi_tcxo" }, +}; + +static const struct parent_map disp_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_DP_PHY_PLL_LINK_CLK, 1 }, + { P_DP_PHY_PLL_VCO_DIV_CLK, 2 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_1[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "dp_phy_pll_link_clk" }, + { .fw_name = "dp_phy_pll_vco_div_clk" }, +}; + +static const struct parent_map disp_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_2[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "dsi0_phy_pll_out_byteclk" }, +}; + +static const struct parent_map disp_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_EDP_PHY_PLL_LINK_CLK, 1 }, + { P_EDP_PHY_PLL_VCO_DIV_CLK, 2 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_3[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "edp_phy_pll_lin
[PATCH v1 1/6] dt-bindings: clock: Add SC7280 DISPCC clock binding
Add device tree bindings for display clock controller subsystem for Qualcomm Technology Inc's SC7280 SoCs. Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sc7280-dispcc.yaml | 94 ++ include/dt-bindings/clock/qcom,dispcc-sc7280.h | 55 + 2 files changed, 149 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7280-dispcc.yaml create mode 100644 include/dt-bindings/clock/qcom,dispcc-sc7280.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7280-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7280-dispcc.yaml new file mode 100644 index 000..2178666 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sc7280-dispcc.yaml @@ -0,0 +1,94 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sc7280-dispcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Display Clock & Reset Controller Binding for SC7280 + +maintainers: + - Taniya Das + +description: | + Qualcomm display clock control module which supports the clocks, resets and + power domains on SC7280. + + See also dt-bindings/clock/qcom,dispcc-sc7280.h. + +properties: + compatible: +const: qcom,sc7280-dispcc + + clocks: +items: + - description: Board XO source + - description: GPLL0 source from GCC + - description: Byte clock from DSI PHY + - description: Pixel clock from DSI PHY + - description: Link clock from DP PHY + - description: VCO DIV clock from DP PHY + - description: Link clock from EDP PHY + - description: VCO DIV clock from EDP PHY + + clock-names: +items: + - const: bi_tcxo + - const: gcc_disp_gpll0_clk + - const: dsi0_phy_pll_out_byteclk + - const: dsi0_phy_pll_out_dsiclk + - const: dp_phy_pll_link_clk + - const: dp_phy_pll_vco_div_clk + - const: edp_phy_pll_link_clk + - const: edp_phy_pll_vco_div_clk + + '#clock-cells': +const: 1 + + '#reset-cells': +const: 1 + + '#power-domain-cells': +const: 1 + + reg: +maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | +#include +#include +clock-controller@af0 { + compatible = "qcom,sc7280-dispcc"; + reg = <0x0af0 0x20>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_DISP_GPLL0_CLK_SRC>, + <&dsi_phy 0>, + <&dsi_phy 1>, + <&dp_phy 0>, + <&dp_phy 1>, + <&edp_phy 0>, + <&edp_phy 1>; + clock-names = "bi_tcxo", +"gcc_disp_gpll0_clk", +"dsi0_phy_pll_out_byteclk", +"dsi0_phy_pll_out_dsiclk", +"dp_phy_pll_link_clk", +"dp_phy_pll_vco_div_clk", +"edp_phy_pll_link_clk", +"edp_phy_pll_vco_div_clk"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; +}; +... diff --git a/include/dt-bindings/clock/qcom,dispcc-sc7280.h b/include/dt-bindings/clock/qcom,dispcc-sc7280.h new file mode 100644 index 000..2074b30 --- /dev/null +++ b/include/dt-bindings/clock/qcom,dispcc-sc7280.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_DISP_CC_SC7280_H +#define _DT_BINDINGS_CLK_QCOM_DISP_CC_SC7280_H + +/* DISP_CC clocks */ +#define DISP_CC_PLL0 0 +#define DISP_CC_MDSS_AHB_CLK 1 +#define DISP_CC_MDSS_AHB_CLK_SRC 2 +#define DISP_CC_MDSS_BYTE0_CLK 3 +#define DISP_CC_MDSS_BYTE0_CLK_SRC 4 +#define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC 5 +#define DISP_CC_MDSS_BYTE0_INTF_CLK6 +#define DISP_CC_MDSS_DP_AUX_CLK7 +#define DISP_CC_MDSS_DP_AUX_CLK_SRC8 +#define DISP_CC_MDSS_DP_CRYPTO_CLK 9 +#define DISP_CC_MDSS_DP_CRYPTO_CLK_SRC 10 +#define DISP_CC_MDSS_DP_LINK_CLK 11 +#define DISP_CC_MDSS_DP_LINK_CLK_SRC 12 +#define DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC 13 +#define DISP_CC_MDSS_DP_LINK_INTF_CLK 14 +#define DISP_CC_MDSS_DP_PIXEL_CLK 15 +#define DISP_CC_MDSS_DP_PIXEL_CLK_SRC 16 +#define DISP_CC_MDSS_EDP_AUX_CLK
[PATCH v1 3/6] dt-bindings: clock: Add SC7280 GPUCC clock binding
Add device tree bindings for graphics clock subsystem clock controller for Qualcomm Technology Inc's SC7280 SoCs. Signed-off-by: Taniya Das --- .../devicetree/bindings/clock/qcom,gpucc.yaml | 4 ++- include/dt-bindings/clock/qcom,gpucc-sc7280.h | 35 ++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 include/dt-bindings/clock/qcom,gpucc-sc7280.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml index df943c4..7e3f9e7 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml @@ -11,11 +11,12 @@ maintainers: description: | Qualcomm graphics clock control module which supports the clocks, resets and - power domains on SDM845/SC7180/SM8150/SM8250. + power domains on SDM845/SC7180/SC7280/SM8150/SM8250. See also: dt-bindings/clock/qcom,gpucc-sdm845.h dt-bindings/clock/qcom,gpucc-sc7180.h +dt-bindings/clock/qcom,gpucc-sc7280.h dt-bindings/clock/qcom,gpucc-sm8150.h dt-bindings/clock/qcom,gpucc-sm8250.h @@ -24,6 +25,7 @@ properties: enum: - qcom,sdm845-gpucc - qcom,sc7180-gpucc + - qcom,sc7280-gpucc - qcom,sm8150-gpucc - qcom,sm8250-gpucc diff --git a/include/dt-bindings/clock/qcom,gpucc-sc7280.h b/include/dt-bindings/clock/qcom,gpucc-sc7280.h new file mode 100644 index 000..37999e6 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gpucc-sc7280.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SC7280_H +#define _DT_BINDINGS_CLK_QCOM_GPU_CC_SC7280_H + +/* GPU_CC clocks */ +#define GPU_CC_PLL00 +#define GPU_CC_PLL11 +#define GPU_CC_AHB_CLK 2 +#define GPU_CC_CB_CLK 3 +#define GPU_CC_CRC_AHB_CLK 4 +#define GPU_CC_CX_GMU_CLK 5 +#define GPU_CC_CX_SNOC_DVM_CLK 6 +#define GPU_CC_CXO_AON_CLK 7 +#define GPU_CC_CXO_CLK 8 +#define GPU_CC_GMU_CLK_SRC 9 +#define GPU_CC_GX_GMU_CLK 10 +#define GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK 11 +#define GPU_CC_HUB_AHB_DIV_CLK_SRC 12 +#define GPU_CC_HUB_AON_CLK 13 +#define GPU_CC_HUB_CLK_SRC 14 +#define GPU_CC_HUB_CX_INT_CLK 15 +#define GPU_CC_HUB_CX_INT_DIV_CLK_SRC 16 +#define GPU_CC_MND1X_0_GFX3D_CLK 17 +#define GPU_CC_MND1X_1_GFX3D_CLK 18 +#define GPU_CC_SLEEP_CLK 19 + +/* GPU_CC power domains */ +#define GPU_CC_CX_GDSC 0 +#define GPU_CC_GX_GDSC 1 + +#endif -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v1 0/6] Add support for DISP/VIDEO/GPU CCs for SC7280
Add support for display, video & graphics clock controllers on SC7280 along with the bindings for each of the clock controllers. Taniya Das (6): dt-bindings: clock: Add SC7280 DISPCC clock binding clk: qcom: Add display clock controller driver for SC7280 dt-bindings: clock: Add SC7280 GPUCC clock binding clk: qcom: Add graphics clock controller driver for SC7280 dt-bindings: clock: Add SC7280 VideoCC clock binding clk: qcom: Add video clock controller driver for SC7280 .../devicetree/bindings/clock/qcom,gpucc.yaml | 4 +- .../bindings/clock/qcom,sc7280-dispcc.yaml | 94 +++ .../devicetree/bindings/clock/qcom,videocc.yaml| 4 +- drivers/clk/qcom/Kconfig | 25 + drivers/clk/qcom/Makefile | 3 + drivers/clk/qcom/dispcc-sc7280.c | 908 + drivers/clk/qcom/gpucc-sc7280.c| 491 +++ drivers/clk/qcom/videocc-sc7280.c | 372 + include/dt-bindings/clock/qcom,dispcc-sc7280.h | 55 ++ include/dt-bindings/clock/qcom,gpucc-sc7280.h | 35 + include/dt-bindings/clock/qcom,videocc-sc7280.h| 27 + 11 files changed, 2016 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7280-dispcc.yaml create mode 100644 drivers/clk/qcom/dispcc-sc7280.c create mode 100644 drivers/clk/qcom/gpucc-sc7280.c create mode 100644 drivers/clk/qcom/videocc-sc7280.c create mode 100644 include/dt-bindings/clock/qcom,dispcc-sc7280.h create mode 100644 include/dt-bindings/clock/qcom,gpucc-sc7280.h create mode 100644 include/dt-bindings/clock/qcom,videocc-sc7280.h -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v2] clk: qcom: clk-rcg2: Add support for duty-cycle for RCG
The root clock generators with MND divider has the capability to support change in duty-cycle by updating the 'D'. Add the clock ops which would check all the boundary conditions and enable setting the desired duty-cycle as per the consumer. Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-rcg2.c | 42 ++ 1 file changed, 42 insertions(+) diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 42f13a2..aac6893 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -357,6 +357,46 @@ static int clk_rcg2_set_floor_rate_and_parent(struct clk_hw *hw, return __clk_rcg2_set_rate(hw, rate, FLOOR); } +static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + u32 notn_m_val, n_val, m_val, d_val, not2d_val, mask, duty_per; + int ret; + + if (!rcg->mnd_width) + return 0; + + mask = BIT(rcg->mnd_width) - 1; + + regmap_read(rcg->clkr.regmap, RCG_N_OFFSET(rcg), ¬n_m_val); + regmap_read(rcg->clkr.regmap, RCG_M_OFFSET(rcg), &m_val); + + n_val = (~(notn_m_val) + m_val) & mask; + + duty_per = (duty->num * 100) / duty->den; + + /* Calculate 2d value */ + d_val = DIV_ROUND_CLOSEST(n_val * duty_per * 2, 100); + +/* Check BIT WIDTHS OF 2d. If D is too big reduce Duty cycle. */ + if (d_val > mask) + d_val = mask; + + if ((d_val / 2) > (n_val - m_val)) + d_val = (n_val - m_val) * 2; + else if ((d_val / 2) < (m_val / 2)) + d_val = m_val; + + not2d_val = ~d_val & mask; + + ret = regmap_update_bits(rcg->clkr.regmap, RCG_D_OFFSET(rcg), mask, +not2d_val); + if (ret) + return ret; + + return update_config(rcg); +} + const struct clk_ops clk_rcg2_ops = { .is_enabled = clk_rcg2_is_enabled, .get_parent = clk_rcg2_get_parent, @@ -365,6 +405,7 @@ const struct clk_ops clk_rcg2_ops = { .determine_rate = clk_rcg2_determine_rate, .set_rate = clk_rcg2_set_rate, .set_rate_and_parent = clk_rcg2_set_rate_and_parent, + .set_duty_cycle = clk_rcg2_set_duty_cycle, }; EXPORT_SYMBOL_GPL(clk_rcg2_ops); @@ -376,6 +417,7 @@ const struct clk_ops clk_rcg2_floor_ops = { .determine_rate = clk_rcg2_determine_floor_rate, .set_rate = clk_rcg2_set_floor_rate, .set_rate_and_parent = clk_rcg2_set_floor_rate_and_parent, + .set_duty_cycle = clk_rcg2_set_duty_cycle, }; EXPORT_SYMBOL_GPL(clk_rcg2_floor_ops); -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v1] clk: qcom: clk-rcg2: Add support for duty-cycle for RCG
The root clock generators with MND divider has the capability to support change in duty-cycle by updating the 'D'. Add the clock ops which would check all the boundary conditions and enable setting the desired duty-cycle as per the consumer. Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-rcg2.c | 40 1 file changed, 40 insertions(+) diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 42f13a2..e070f1a 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -357,6 +357,44 @@ static int clk_rcg2_set_floor_rate_and_parent(struct clk_hw *hw, return __clk_rcg2_set_rate(hw, rate, FLOOR); } +static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + u32 notn_m_val, n_val, m_val, d_val, not2d_val, mask, duty_per; + int ret; + + if (!rcg->mnd_width) + return 0; + + mask = BIT(rcg->mnd_width) - 1; + + regmap_read(rcg->clkr.regmap, RCG_N_OFFSET(rcg), ¬n_m_val); + regmap_read(rcg->clkr.regmap, RCG_M_OFFSET(rcg), &m_val); + + n_val = (~(notn_m_val) + m_val) & mask; + + /* Calculate 2d value */ + d_val = DIV_ROUND_CLOSEST(n_val * duty_per * 2, 100); + +/* Check BIT WIDTHS OF 2d. If D is too big reduce Duty cycle. */ + if (d_val > mask) + d_val = mask; + + if ((d_val / 2) > (n_val - m_val)) + d_val = (n_val - m_val) * 2; + else if ((d_val / 2) < (m_val / 2)) + d_val = m_val; + + not2d_val = ~d_val & mask; + + ret = regmap_update_bits(rcg->clkr.regmap, RCG_D_OFFSET(rcg), mask, +not2d_val); + if (ret) + return ret; + + return update_config(rcg); +} + const struct clk_ops clk_rcg2_ops = { .is_enabled = clk_rcg2_is_enabled, .get_parent = clk_rcg2_get_parent, @@ -365,6 +403,7 @@ const struct clk_ops clk_rcg2_ops = { .determine_rate = clk_rcg2_determine_rate, .set_rate = clk_rcg2_set_rate, .set_rate_and_parent = clk_rcg2_set_rate_and_parent, + .set_duty_cycle = clk_rcg2_set_duty_cycle, }; EXPORT_SYMBOL_GPL(clk_rcg2_ops); @@ -376,6 +415,7 @@ const struct clk_ops clk_rcg2_floor_ops = { .determine_rate = clk_rcg2_determine_floor_rate, .set_rate = clk_rcg2_set_floor_rate, .set_rate_and_parent = clk_rcg2_set_floor_rate_and_parent, + .set_duty_cycle = clk_rcg2_set_duty_cycle, }; EXPORT_SYMBOL_GPL(clk_rcg2_floor_ops); -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v1] clk: qcom: rpmh: Update the XO clock source for SC7280
The bi_tcxo clock source for SC7280 requires a div 4 to derive 19.2MHz from the xo_board. Thus update the same. Fixes: fff2b9a65162 ("clk: qcom: rpmh: Add support for RPMH clocks on SC7280") Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-rpmh.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 91dc390..c623ce9 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -510,9 +510,12 @@ static const struct clk_rpmh_desc clk_rpmh_sm8350 = { .num_clks = ARRAY_SIZE(sm8350_rpmh_clocks), }; +/* Resource name must match resource id present in cmd-db */ +DEFINE_CLK_RPMH_ARC(sc7280, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 4); + static struct clk_hw *sc7280_rpmh_clocks[] = { - [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, - [RPMH_CXO_CLK_A]= &sdm845_bi_tcxo_ao.hw, + [RPMH_CXO_CLK] = &sc7280_bi_tcxo.hw, + [RPMH_CXO_CLK_A]= &sc7280_bi_tcxo_ao.hw, [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw, [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw, [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw, -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
Re: [PATCH 06/13] arm64: dts: qcom: SC7280: Add rpmhcc clock controller node
Hello Stephen, Thanks for the review. On 2/23/2021 1:13 PM, Stephen Boyd wrote: Quoting Rajendra Nayak (2021-02-11 23:28:43) diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index 7848e88..10851e7 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -29,6 +30,42 @@ clock-frequency = <32000>; #clock-cells = <0>; }; + + pcie_0_pipe_clk: pcie-0-pipe-clk { + compatible = "fixed-clock"; + clock-frequency = <1000>; + #clock-cells = <0>; + }; + + pcie_1_pipe_clk: pcie-1-pipe-clk { + compatible = "fixed-clock"; + clock-frequency = <1000>; + #clock-cells = <0>; + }; + + ufs_phy_rx_symbol_0_clk: ufs-phy-rx-symbol-0-clk { + compatible = "fixed-clock"; + clock-frequency = <1000>; + #clock-cells = <0>; + }; + + ufs_phy_rx_symbol_1_clk: ufs-phy-rx-symbol-1-clk { + compatible = "fixed-clock"; + clock-frequency = <1000>; + #clock-cells = <0>; + }; + + ufs_phy_tx_symbol_0_clk: ufs-phy-tx-symbol-0-clk { + compatible = "fixed-clock"; + clock-frequency = <1000>; + #clock-cells = <0>; + }; + + usb3_phy_wrapper_gcc_usb30_pipe_clk: usb3-phy-wrapper-gcc-usb30-pipe-clk { + compatible = "fixed-clock"; + clock-frequency = <1000>; + #clock-cells = <0>; + }; Shouldn't these come from the phys? Why are they being added here? Once the phys are added, these could be replaced, that was the reason to add them. }; reserved_memory: reserved-memory { @@ -174,6 +211,17 @@ gcc: clock-controller@10 { compatible = "qcom,gcc-sc7280"; reg = <0 0x0010 0 0x1f>; + clocks = <&rpmhcc RPMH_CXO_CLK>, +<&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>, +<&pcie_0_pipe_clk>, <&pcie_1_pipe_clk>, +<&ufs_phy_rx_symbol_0_clk>, <&ufs_phy_rx_symbol_1_clk>, +<&ufs_phy_tx_symbol_0_clk>, +<&usb3_phy_wrapper_gcc_usb30_pipe_clk>; If the phys aren't ready then <0> should work. Unless something goes wrong? Nothing would go wrong if we add <0>, but wanted them to be replaced once the support is added. + clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk", + "pcie_0_pipe_clk", "pcie_1_pipe-clk", + "ufs_phy_rx_symbol_0_clk", "ufs_phy_rx_symbol_1_clk", + "ufs_phy_tx_symbol_0_clk", + "usb3_phy_wrapper_gcc_usb30_pipe_clk"; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; @@ -325,6 +373,13 @@ , , ; + + rpmhcc: qcom,rpmhcc { rpmhcc: clock-controller { Will update in the next patch. + compatible = "qcom,sc7280-rpmh-clk"; + clocks = <&xo_board>; + clock-names = "xo"; + #clock-cells = <1>; + }; }; }; -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
Re: [PATCH] clk: qcom: gcc-sc7180: Use floor ops for the correct sdcc1 clk
Reviewed-by: Taniya Das On 2/24/2021 11:20 PM, Douglas Anderson wrote: While picking commit a8cd989e1a57 ("mmc: sdhci-msm: Warn about overclocking SD/MMC") back to my tree I was surprised that it was reporting warnings. I thought I fixed those! Looking closer at the fix, I see that I totally bungled it (or at least I halfway bungled it). The SD card clock got fixed (and that was the one I was really focused on fixing), but I totally adjusted the wrong clock for eMMC. Sigh. Let's fix my dumb mistake. Now both SD and eMMC have floor for the "apps" clock. This doesn't matter a lot for the final clock rate for HS400 eMMC but could matter if someone happens to put some slower eMMC on a sc7180. We also transition through some of these lower rates sometimes and having them wrong could cause problems during these transitions. These were the messages I was seeing at boot: mmc1: Card appears overclocked; req 5200 Hz, actual 1 Hz mmc1: Card appears overclocked; req 5200 Hz, actual 1 Hz mmc1: Card appears overclocked; req 10400 Hz, actual 19200 Hz Fixes: 6d37a8d19283 ("clk: qcom: gcc-sc7180: Use floor ops for sdcc clks") Signed-off-by: Douglas Anderson --- drivers/clk/qcom/gcc-sc7180.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index c5c2e93bda8e..5cacd20a31b3 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -620,7 +620,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { .name = "gcc_sdcc1_apps_clk_src", .parent_data = gcc_parent_data_1, .num_parents = 5, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; @@ -642,7 +642,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { .name = "gcc_sdcc1_ice_core_clk_src", .parent_data = gcc_parent_data_0, .num_parents = 4, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_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/2] clk: qcom: Add Global Clock controller (GCC) driver for SC7280
Add support for the global clock controller found on SC7280 based devices. This should allow most non-multimedia device drivers to probe and control their clocks. Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig |9 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/gcc-sc7280.c | 3603 + 3 files changed, 3613 insertions(+) create mode 100644 drivers/clk/qcom/gcc-sc7280.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index d32bb12..7992ed9 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -317,6 +317,15 @@ config SC_GCC_7180 Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDCC, etc. +config SC_GCC_7280 + tristate "SC7280 Global Clock Controller" + select QCOM_GDSC + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on SC7280 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + I2C, USB, UFS, SDCC, PCIe etc. + config SC_LPASS_CORECC_7180 tristate "SC7180 LPASS Core Clock Controller" select SC_GCC_7180 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 9e5e0e3..db62d40 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o +obj-$(CONFIG_SC_GCC_7280) += gcc-sc7280.o obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o diff --git a/drivers/clk/qcom/gcc-sc7280.c b/drivers/clk/qcom/gcc-sc7280.c new file mode 100644 index 000..22736c1 --- /dev/null +++ b/drivers/clk/qcom/gcc-sc7280.c @@ -0,0 +1,3603 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + P_BI_TCXO, + P_GCC_GPLL0_OUT_EVEN, + P_GCC_GPLL0_OUT_MAIN, + P_GCC_GPLL0_OUT_ODD, + P_GCC_GPLL10_OUT_MAIN, + P_GCC_GPLL4_OUT_MAIN, + P_GCC_GPLL9_OUT_MAIN, + P_PCIE_0_PIPE_CLK, + P_PCIE_1_PIPE_CLK, + P_SLEEP_CLK, + P_UFS_PHY_RX_SYMBOL_0_CLK, + P_UFS_PHY_RX_SYMBOL_1_CLK, + P_UFS_PHY_TX_SYMBOL_0_CLK, + P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, + P_GCC_MSS_GPLL0_MAIN_DIV_CLK, +}; + +static struct clk_alpha_pll gcc_gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_lucid_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gcc_gpll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gcc_gpll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_gcc_gpll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gcc_gpll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gpll0_out_even", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_lucid_ops, + }, +}; + +static const struct clk_div_table post_div_table_gcc_gpll0_out_odd[] = { + { 0x3, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv gcc_gpll0_out_odd = { + .offset = 0x0, + .post_div_shift = 12, + .post_div_table = post_div_table_gcc_gpll0_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_gcc_gpll0_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gpll0_out_odd", + .parent_data = &(const struct clk_parent_data){ +
[PATCH v2 1/2] dt-bindings: clock: Add SC7280 GCC clock binding
Add device tree bindings for global clock subsystem clock controller for Qualcomm Technology Inc's SC7280 SoCs. Signed-off-by: Taniya Das --- .../devicetree/bindings/clock/qcom,gcc-sc7280.yaml | 92 + include/dt-bindings/clock/qcom,gcc-sc7280.h| 226 + 2 files changed, 318 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gcc-sc7280.yaml create mode 100644 include/dt-bindings/clock/qcom,gcc-sc7280.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sc7280.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sc7280.yaml new file mode 100644 index 000..5693b899 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-sc7280.yaml @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,gcc-sc7280.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Global Clock & Reset Controller Binding for SC7280 + +maintainers: + - Taniya Das + +description: | + Qualcomm global clock control module which supports the clocks, resets and + power domains on SC7280. + + See also: + - dt-bindings/clock/qcom,gcc-sc7280.h + +properties: + compatible: +const: qcom,gcc-sc7280 + + clocks: +items: + - description: Board XO source + - description: Board active XO source + - description: Sleep clock source + - description: PCIE-0 pipe clock source + - description: PCIE-1 pipe clock source + - description: USF phy rx symbol 0 clock source + - description: USF phy rx symbol 1 clock source + - description: USF phy tx symbol 0 clock source + - description: USB30 phy wrapper pipe clock source + + clock-names: +items: + - const: bi_tcxo + - const: bi_tcxo_ao + - const: sleep_clk + - const: pcie_0_pipe_clk + - const: pcie_1_pipe_clk + - const: ufs_phy_rx_symbol_0_clk + - const: ufs_phy_rx_symbol_1_clk + - const: ufs_phy_tx_symbol_0_clk + - const: usb3_phy_wrapper_gcc_usb30_pipe_clk + + '#clock-cells': +const: 1 + + '#reset-cells': +const: 1 + + '#power-domain-cells': +const: 1 + + reg: +maxItems: 1 + +required: + - compatible + - clocks + - clock-names + - reg + - '#clock-cells' + - '#reset-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | +#include +clock-controller@10 { + compatible = "qcom,gcc-sc7280"; + reg = <0x0010 0x1f>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&rpmhcc RPMH_CXO_CLK_A>, + <&sleep_clk>, + <&pcie_0_pipe_clk>, <&pcie_1_pipe_clk>, + <&ufs_phy_rx_symbol_0_clk>, <&ufs_phy_rx_symbol_1_clk>, + <&ufs_phy_tx_symbol_0_clk>, + <&usb3_phy_wrapper_gcc_usb30_pipe_clk>; + + clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk", "pcie_0_pipe_clk", + "pcie_1_pipe_clk", "ufs_phy_rx_symbol_0_clk", + "ufs_phy_rx_symbol_1_clk", "ufs_phy_tx_symbol_0_clk", + "usb3_phy_wrapper_gcc_usb30_pipe_clk"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; +}; +... diff --git a/include/dt-bindings/clock/qcom,gcc-sc7280.h b/include/dt-bindings/clock/qcom,gcc-sc7280.h new file mode 100644 index 000..4394f15 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-sc7280.h @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SC7280_H +#define _DT_BINDINGS_CLK_QCOM_GCC_SC7280_H + +/* GCC clocks */ +#define GCC_GPLL0 0 +#define GCC_GPLL0_OUT_EVEN 1 +#define GCC_GPLL0_OUT_ODD 2 +#define GCC_GPLL1 3 +#define GCC_GPLL10 4 +#define GCC_GPLL4 5 +#define GCC_GPLL9 6 +#define GCC_AGGRE_NOC_PCIE_0_AXI_CLK 7 +#define GCC_AGGRE_NOC_PCIE_1_AXI_CLK 8 +#define GCC_AGGRE_UFS_PHY_AXI_CLK 9 +#define GCC_AGGRE_USB3_PRIM_AXI_CLK10 +#define GCC_CAMERA_AHB_CLK 11 +#define GCC_CAMERA_HF_AXI_CLK 12 +#define GCC_CAMERA_SF_AXI_CLK 13 +#define GCC_CAMERA_XO_CLK 14 +#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK 15 +#define GCC_CFG_NOC_USB3_SEC_AXI_CLK
[PATCH v2 0/2] Add Global Clock controller (GCC) driver for SC7280
Add driver support for Global Clock controller for SC7280 and also update device tree bindings for the various clocks supported in the clock controller. [v2] * Add UFS phy rx/tx symbol clocks in bindings. * Remove protected-clocks node & description. * Add support for extra clocks for QSPI/WPSS/MSS/LPASS/PCIE clocks. * Update the floor rcg ops for SDCC/QSPI clock. * Add comment for cpuss critical clocks. [v1] * Documentation binding for GCC clock for SC7280. * GCC clock driver for SC7280. Taniya Das (2): dt-bindings: clock: Add SC7280 GCC clock binding clk: qcom: Add Global Clock controller (GCC) driver for SC7280 .../devicetree/bindings/clock/qcom,gcc-sc7280.yaml | 92 + drivers/clk/qcom/Kconfig |9 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/gcc-sc7280.c | 3603 include/dt-bindings/clock/qcom,gcc-sc7280.h| 226 ++ 5 files changed, 3931 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gcc-sc7280.yaml create mode 100644 drivers/clk/qcom/gcc-sc7280.c create mode 100644 include/dt-bindings/clock/qcom,gcc-sc7280.h -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
Re: [PATCH v1 2/2] clk: qcom: Add Global Clock controller (GCC) driver for SC7280
Thanks Stephen for your review comments. On 1/13/2021 1:34 AM, Stephen Boyd wrote: + +static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { + .cmd_rcgr = 0x7500c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, This needs to use floor clk ops? My bad I missed them in my patch, latest patch has this fixed. + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = { + F(1, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(15000, P_GCC_GPLL0_OUT_EVEN, 2, 0, 0), + F(3, P_GCC_GPLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x7502c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, Same. + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(40, P_BI_TCXO, 12, 1, 4), + F(1920, P_BI_TCXO, 1, 0, 0), + F(2500, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(5000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), + F(1, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(20200, P_GCC_GPLL9_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .cmd_rcgr = 0x1400c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_9, + .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parent_data_9, + .num_parents = ARRAY_SIZE(gcc_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, Same. + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc4_apps_clk_src[] = { + F(40, P_BI_TCXO, 12, 1, 4), + F(1920, P_BI_TCXO, 1, 0, 0), + F(2500, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(5000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), + F(1, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { + .cmd_rcgr = 0x1600c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_sdcc4_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc4_apps_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, Same. + }, +}; + [...] +static struct clk_branch gcc_cpuss_ahb_clk = { + .halt_reg = 0x48000, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x48000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_ahb_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_cpuss_ahb_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, Why is it critical? Please add a comment like sc7180. Updated the comment in the latest patch. + .ops = &clk_branch2_ops, + }, + }, +}; + -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
Re: [PATCH v1 1/2] dt-bindings: clock: Add SC7280 GCC clock binding
Thanks Stephen for your review comments. On 1/13/2021 1:36 AM, Stephen Boyd wrote: + clock-names: +items: + - const: bi_tcxo + - const: bi_tcxo_ao + - const: sleep_clk + - const: pcie_0_pipe_clk + - const: pcie_1_pipe_clk + - const: usb3_phy_wrapper_gcc_usb30_pipe_clk Don't ufs phy clks also go into gcc? The latest patch has this updated. + + '#clock-cells': +const: 1 + + '#reset-cells': +const: 1 + + '#power-domain-cells': +const: 1 + + reg: +maxItems: 1 + + protected-clocks: +description: + Protected clock specifier list as per common clock binding. I suppose this is fine. Removed the above in the latest patch. -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
Re: [PATCH v1 1/2] dt-bindings: clock: Add SC7280 GCC clock binding
Thanks Rob for your review comments. diff --git a/include/dt-bindings/clock/qcom,gcc-sc7280.h b/include/dt-bindings/clock/qcom,gcc-sc7280.h new file mode 100644 index 000..3295bd4 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-sc7280.h @@ -0,0 +1,215 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ Don't care about non-GPL OS? Better ask your legal dept. Currently this is the recommendation from the legal dept. +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SC7280_H +#define _DT_BINDINGS_CLK_QCOM_GCC_SC7280_H + +/* GCC clocks */ -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
[PATCH v1 2/2] clk: qcom: rpmh: Add support for RPMH clocks on SC7280
Add support for RPMH clocks on SC7280 SoCs. Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-rpmh.c | 24 +++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 6a2a13c..c180959 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ #include @@ -486,6 +486,27 @@ static const struct clk_rpmh_desc clk_rpmh_sm8350 = { .num_clks = ARRAY_SIZE(sm8350_rpmh_clocks), }; +static struct clk_hw *sc7280_rpmh_clocks[] = { + [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, + [RPMH_CXO_CLK_A]= &sdm845_bi_tcxo_ao.hw, + [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw, + [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw, + [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw, + [RPMH_RF_CLK1_A]= &sdm845_rf_clk1_ao.hw, + [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw, + [RPMH_RF_CLK3_A]= &sdm845_rf_clk3_ao.hw, + [RPMH_RF_CLK4] = &sm8350_rf_clk4.hw, + [RPMH_RF_CLK4_A]= &sm8350_rf_clk4_ao.hw, + [RPMH_IPA_CLK] = &sdm845_ipa.hw, + [RPMH_PKA_CLK] = &sm8350_pka.hw, + [RPMH_HWKM_CLK] = &sm8350_hwkm.hw, +}; + +static const struct clk_rpmh_desc clk_rpmh_sc7280 = { + .clks = sc7280_rpmh_clocks, + .num_clks = ARRAY_SIZE(sc7280_rpmh_clocks), +}; + static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -575,6 +596,7 @@ static const struct of_device_id clk_rpmh_match_table[] = { { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150}, { .compatible = "qcom,sm8250-rpmh-clk", .data = &clk_rpmh_sm8250}, { .compatible = "qcom,sm8350-rpmh-clk", .data = &clk_rpmh_sm8350}, + { .compatible = "qcom,sc7280-rpmh-clk", .data = &clk_rpmh_sc7280}, { } }; MODULE_DEVICE_TABLE(of, clk_rpmh_match_table); -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v1 0/2] Add support for RPMH clock for SC7280
Add the bindings for sc7280 and support the rpmh clock which are required to be supported on SC7280. Taniya Das (2): dt-bindings: clock: Add RPMHCC bindings for SC7280 clk: qcom: rpmh: Add support for RPMH clocks on SC7280 .../devicetree/bindings/clock/qcom,rpmhcc.yaml | 1 + drivers/clk/qcom/clk-rpmh.c| 24 +- 2 files changed, 24 insertions(+), 1 deletion(-) -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v1 1/2] dt-bindings: clock: Add RPMHCC bindings for SC7280
Add bindings and update documentation for clock rpmh driver on SC7280. Signed-off-by: Taniya Das --- Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml index 12c9cbc..3d16c8e 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml @@ -18,6 +18,7 @@ properties: compatible: enum: - qcom,sc7180-rpmh-clk + - qcom,sc7280-rpmh-clk - qcom,sdm845-rpmh-clk - qcom,sdx55-rpmh-clk - qcom,sm8150-rpmh-clk -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
Re: [PATCH V1] clk: qcom: gcc-sc7180: Mark the MM XO clocks to be always ON
Hi Bjorn, On 1/21/2021 4:10 AM, Bjorn Andersson wrote: On Wed 20 Jan 01:47 CST 2021, Taniya Das wrote: There are intermittent GDSC power-up failures observed for titan top gdsc, which requires the XO clock. Thus mark all the MM XO clocks always enabled from probe. But if this is the reason for keeping all these {ahb,xo}_clks critical (or upstream just a bunch of hard coded regmap_update_bits()) why don't we properly describe them as dependencies for the clock controller/gdsc? I.e. by the use of pm_clk_add()? Regards, Bjorn They are already defined in the camcc driver, but they are not working as expected, thus I am forced to mark them always ON. Fixes: 8d4025943e13 ("clk: qcom: camcc-sc7180: Use runtime PM ops instead of clk ones") Signed-off-by: Taniya Das --- drivers/clk/qcom/gcc-sc7180.c | 47 --- 1 file changed, 4 insertions(+), 43 deletions(-) diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index b05901b..88e896a 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. */ #include @@ -919,19 +919,6 @@ static struct clk_branch gcc_camera_throttle_hf_axi_clk = { }, }; -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 = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_ce1_ahb_clk = { .halt_reg = 0x4100c, .halt_check = BRANCH_HALT_VOTED, @@ -1096,19 +1083,6 @@ static struct clk_branch gcc_disp_throttle_hf_axi_clk = { }, }; -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 = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gp1_clk = { .halt_reg = 0x64000, .halt_check = BRANCH_HALT, @@ -2159,19 +2133,6 @@ static struct clk_branch gcc_video_throttle_axi_clk = { }, }; -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 = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_mss_cfg_ahb_clk = { .halt_reg = 0x8a000, .halt_check = BRANCH_HALT, @@ -2304,7 +2265,6 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr, [GCC_CAMERA_THROTTLE_HF_AXI_CLK] = &gcc_camera_throttle_hf_axi_clk.clkr, - [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr, [GCC_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr, [GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr, [GCC_CE1_CLK] = &gcc_ce1_clk.clkr, @@ -2317,7 +2277,6 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { [GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr, [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, [GCC_DISP_THROTTLE_HF_AXI_CLK] = &gcc_disp_throttle_hf_axi_clk.clkr, - [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr, [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, @@ -2413,7 +2372,6 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { [GCC_VIDEO_AXI_CLK] = &gcc_video_axi_clk.clkr, [GCC_VIDEO_GPLL0_DIV_CLK_SRC] = &gcc_video_gpll0_div_clk_src.clkr, [GCC_VIDEO_THROTTLE_AXI_CLK] = &gcc_video_throttle_axi_clk.clkr, - [GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr, [GPLL0] = &gpll0.clkr, [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr, [GPLL6] = &gpll6.clkr, @@ -2510,6 +2468,9 @@ static int gcc_sc7180_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x0b004, BIT(0), BIT(0)); regmap_update_bits(regmap, 0x0b008, BIT(0), BIT(0)); regmap_update_bits(regmap, 0x0b00c, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x0b02c, BIT(0), BIT(
Re: [PATCH v4 5/7] cpufreq: qcom-hw: Implement CPRh aware OSM programming
The CPUFREQ-HW driver is intended to be used only for CPUFREQ HW designs where the firmware programs the look up tables. Suggestion is to separate out the driver where the programming is managed by high level OS. On 1/19/2021 11:15 PM, AngeloGioacchino Del Regno wrote: On new SoCs (SDM845 onwards) the Operating State Manager (OSM) is being programmed in the bootloader and write-protected by the hypervisor, leaving to the OS read-only access to some of its registers (in order to read the Lookup Tables and also some status registers) and write access to the p-state register, for for the OS to request a specific performance state to trigger a DVFS switch on the CPU through the OSM hardware. On old SoCs though (MSM8998, SDM630/660 and variants), the bootloader will *not* initialize the OSM (and the CPRh, as it is a requirement for it) before booting the OS, making any request to trigger a performance state change ineffective, as the hardware doesn't have any Lookup Table, nor is storing any parameter to trigger a DVFS switch. In this case, basically all of the OSM registers are *not* write protected for the OS, even though some are - but write access is granted through SCM calls. This commit introduces support for OSM programming, which has to be done on these old SoCs that were distributed (almost?) always with a bootloader that does not do any CPRh nor OSM init before booting the kernel. In order to program the OSM on these SoCs, it is necessary to fullfill a "special" requirement: the Core Power Reduction Hardened (CPRh) hardware block must be initialized, as the OSM is "talking" to it in order to perform the Voltage part of DVFS; here, we are calling initialization of this through Linux generic power domains, specifically by requesting a genpd attach from the qcom-cpufreq-hw driver, which will give back voltages associated to each CPU frequency that has been declared in the OPPs, scaled and interpolated with the previous one, and will also give us parameters for the Array Power Mux (APM) and mem-acc, in order for this driver to be then able to generate the Lookup Tables that will be finally programmed to the OSM hardware. After writing the parameters to the OSM and enabling it, all the programming work will never happen anymore until a OS reboot, so all of the allocations and "the rest" will be disposed-of: this is done mainly to leave the code that was referred only to the new SoCs intact, as to also emphasize on the fact that the OSM HW is, in the end, the exact same; apart some register offsets that are slightly different, the entire logic is the same. This also adds the parameters to support CPU scaling on SDM630 and MSM8998. Signed-off-by: AngeloGioacchino Del Regno --- drivers/cpufreq/qcom-cpufreq-hw.c | 1240 - 1 file changed, 1208 insertions(+), 32 deletions(-) diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index acc645b85e79..a92959bb7b50 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -1,33 +1,256 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * OSM hardware initial programming + * Copyright (C) 2020, AngeloGioacchino Del Regno + * */ #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #define LUT_MAX_ENTRIES 40U -#define LUT_SRCGENMASK(31, 30) +#define LUT_SRC_845GENMASK(31, 30) +#define LUT_SRC_8998 GENMASK(27, 26) +#define LUT_PLL_DIVGENMASK(25, 24) #define LUT_L_VAL GENMASK(7, 0) #define LUT_CORE_COUNTGENMASK(18, 16) +#define LUT_VOLT_VCGENMASK(21, 16) #define LUT_VOLT GENMASK(11, 0) -#define CLK_HW_DIV 2 #define LUT_TURBO_IND 1 +#define OSM_BOOT_TIME_US 5 + +#define CYCLE_COUNTER_CLK_RATIOGENMASK(5, 1) +#define OSM_XO_RATIO_VAL (10 - 1) +#define CYCLE_COUNTER_USE_XO_EDGE BIT(8) + +/* FSM Boost Control */ +#define CC_BOOST_ENBIT(0) +#define PS_BOOST_ENBIT(1) +#define DCVS_BOOST_EN BIT(2) +#define BOOST_TIMER_REG_HI GENMASK(31, 16) +#define BOOST_TIMER_REG_LO GENMASK(15, 0) + +#define PLL_WAIT_LOCK_TIME_NS 2000 +#define SAFE_FREQ_WAIT_NS 1000 +#define DEXT_DECREMENT_WAIT_NS 200 + +#define BOOST_SYNC_DELAY 5 + +#define HYSTERESIS_UP_MASK GENMASK(31, 16) +#define HYSTERESIS_DN_MASK GENMASK(15, 0) +#define HYSTERESIS_CC_NS 200 +#define HYSTERESIS_LLM_NS 65535 + +/* FSM Droop Control */ +#define PC_RET_EXIT_DROOP_EN BIT(3)
[PATCH V1] clk: qcom: gcc-sc7180: Mark the MM XO clocks to be always ON
There are intermittent GDSC power-up failures observed for titan top gdsc, which requires the XO clock. Thus mark all the MM XO clocks always enabled from probe. Fixes: 8d4025943e13 ("clk: qcom: camcc-sc7180: Use runtime PM ops instead of clk ones") Signed-off-by: Taniya Das --- drivers/clk/qcom/gcc-sc7180.c | 47 --- 1 file changed, 4 insertions(+), 43 deletions(-) diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index b05901b..88e896a 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. */ #include @@ -919,19 +919,6 @@ static struct clk_branch gcc_camera_throttle_hf_axi_clk = { }, }; -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 = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_ce1_ahb_clk = { .halt_reg = 0x4100c, .halt_check = BRANCH_HALT_VOTED, @@ -1096,19 +1083,6 @@ static struct clk_branch gcc_disp_throttle_hf_axi_clk = { }, }; -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 = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gp1_clk = { .halt_reg = 0x64000, .halt_check = BRANCH_HALT, @@ -2159,19 +2133,6 @@ static struct clk_branch gcc_video_throttle_axi_clk = { }, }; -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 = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_mss_cfg_ahb_clk = { .halt_reg = 0x8a000, .halt_check = BRANCH_HALT, @@ -2304,7 +2265,6 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr, [GCC_CAMERA_THROTTLE_HF_AXI_CLK] = &gcc_camera_throttle_hf_axi_clk.clkr, - [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr, [GCC_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr, [GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr, [GCC_CE1_CLK] = &gcc_ce1_clk.clkr, @@ -2317,7 +2277,6 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { [GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr, [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, [GCC_DISP_THROTTLE_HF_AXI_CLK] = &gcc_disp_throttle_hf_axi_clk.clkr, - [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr, [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, @@ -2413,7 +2372,6 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { [GCC_VIDEO_AXI_CLK] = &gcc_video_axi_clk.clkr, [GCC_VIDEO_GPLL0_DIV_CLK_SRC] = &gcc_video_gpll0_div_clk_src.clkr, [GCC_VIDEO_THROTTLE_AXI_CLK] = &gcc_video_throttle_axi_clk.clkr, - [GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr, [GPLL0] = &gpll0.clkr, [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr, [GPLL6] = &gpll6.clkr, @@ -2510,6 +2468,9 @@ static int gcc_sc7180_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x0b004, BIT(0), BIT(0)); regmap_update_bits(regmap, 0x0b008, BIT(0), BIT(0)); regmap_update_bits(regmap, 0x0b00c, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x0b02c, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x0b028, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x0b030, BIT(0), BIT(0)); regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0)); ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v1] clk: qcom: gcc-sc7180: Mark the camera abh clock always ON
The camera clock controller requires the AHB clock, the driver when moved to use the pm_runtime_get() API, the camera ahb clock failed turn on before access, thus mark it as always ON. Reported-by: Stephen Boyd Fixes: 8d4025943e13 ("clk: qcom: camcc-sc7180: Use runtime PM ops instead of clk ones") Signed-off-by: Taniya Das --- drivers/clk/qcom/gcc-sc7180.c | 21 +++-- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index d82d725..b05901b 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -891,21 +891,6 @@ static struct clk_branch gcc_boot_rom_ahb_clk = { }, }; -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 = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_camera_hf_axi_clk = { .halt_reg = 0xb020, .halt_check = BRANCH_HALT, @@ -2317,7 +2302,6 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr, [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr, [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, - [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr, [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr, [GCC_CAMERA_THROTTLE_HF_AXI_CLK] = &gcc_camera_throttle_hf_axi_clk.clkr, [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr, @@ -2519,11 +2503,12 @@ static int gcc_sc7180_probe(struct platform_device *pdev) /* * Keep the clocks always-ON -* GCC_CPUSS_GNOC_CLK, GCC_VIDEO_AHB_CLK, GCC_DISP_AHB_CLK -* GCC_GPU_CFG_AHB_CLK +* GCC_CPUSS_GNOC_CLK, GCC_VIDEO_AHB_CLK, GCC_CAMERA_AHB_CLK, +* GCC_DISP_AHB_CLK, GCC_GPU_CFG_AHB_CLK */ regmap_update_bits(regmap, 0x48004, BIT(0), BIT(0)); regmap_update_bits(regmap, 0x0b004, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x0b008, BIT(0), BIT(0)); regmap_update_bits(regmap, 0x0b00c, BIT(0), BIT(0)); regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0)); -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v1 0/2] Add Global Clock controller (GCC) driver for SC7280
Add driver support for Global Clock controller for SC7280 and also update device tree bindings for the various clocks supported in the clock controller. Taniya Das (2): dt-bindings: clock: Add SC7280 GCC clock binding clk: qcom: Add Global Clock controller (GCC) driver for SC7280 .../devicetree/bindings/clock/qcom,gcc-sc7280.yaml | 85 + drivers/clk/qcom/Kconfig |9 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/gcc-sc7280.c | 3361 include/dt-bindings/clock/qcom,gcc-sc7280.h| 215 ++ 5 files changed, 3671 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gcc-sc7280.yaml create mode 100644 drivers/clk/qcom/gcc-sc7280.c create mode 100644 include/dt-bindings/clock/qcom,gcc-sc7280.h -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v1 2/2] clk: qcom: Add Global Clock controller (GCC) driver for SC7280
Add support for the global clock controller found on SC7280 based devices. This should allow most non-multimedia device drivers to probe and control their clocks. Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig |9 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/gcc-sc7280.c | 3361 + 3 files changed, 3371 insertions(+) create mode 100644 drivers/clk/qcom/gcc-sc7280.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index d32bb12..7992ed9 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -317,6 +317,15 @@ config SC_GCC_7180 Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDCC, etc. +config SC_GCC_7280 + tristate "SC7280 Global Clock Controller" + select QCOM_GDSC + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on SC7280 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + I2C, USB, UFS, SDCC, PCIe etc. + config SC_LPASS_CORECC_7180 tristate "SC7180 LPASS Core Clock Controller" select SC_GCC_7180 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 9e5e0e3..db62d40 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o +obj-$(CONFIG_SC_GCC_7280) += gcc-sc7280.o obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o diff --git a/drivers/clk/qcom/gcc-sc7280.c b/drivers/clk/qcom/gcc-sc7280.c new file mode 100644 index 000..74a3151 --- /dev/null +++ b/drivers/clk/qcom/gcc-sc7280.c @@ -0,0 +1,3361 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + P_BI_TCXO, + P_GCC_GPLL0_OUT_EVEN, + P_GCC_GPLL0_OUT_MAIN, + P_GCC_GPLL0_OUT_ODD, + P_GCC_GPLL10_OUT_MAIN, + P_GCC_GPLL4_OUT_MAIN, + P_GCC_GPLL9_OUT_MAIN, + P_PCIE_0_PIPE_CLK, + P_PCIE_1_PIPE_CLK, + P_SLEEP_CLK, + P_UFS_PHY_RX_SYMBOL_0_CLK, + P_UFS_PHY_RX_SYMBOL_1_CLK, + P_UFS_PHY_TX_SYMBOL_0_CLK, + P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, +}; + +static struct clk_alpha_pll gcc_gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_lucid_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gcc_gpll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gcc_gpll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_gcc_gpll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gcc_gpll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gpll0_out_even", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_lucid_ops, + }, +}; + +static const struct clk_div_table post_div_table_gcc_gpll0_out_odd[] = { + { 0x3, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv gcc_gpll0_out_odd = { + .offset = 0x0, + .post_div_shift = 12, + .post_div_table = post_div_table_gcc_gpll0_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_gcc_gpll0_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gpll0_out_odd", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_gpll0.clkr.hw, +
[PATCH v1 1/2] dt-bindings: clock: Add SC7280 GCC clock binding
Add device tree bindings for global clock subsystem clock controller for Qualcomm Technology Inc's SC7280 SoCs. Signed-off-by: Taniya Das --- .../devicetree/bindings/clock/qcom,gcc-sc7280.yaml | 85 include/dt-bindings/clock/qcom,gcc-sc7280.h| 215 + 2 files changed, 300 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gcc-sc7280.yaml create mode 100644 include/dt-bindings/clock/qcom,gcc-sc7280.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sc7280.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sc7280.yaml new file mode 100644 index 000..79c64d8 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-sc7280.yaml @@ -0,0 +1,85 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,gcc-sc7280.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Global Clock & Reset Controller Binding for SC7280 + +maintainers: + - Taniya Das + +description: | + Qualcomm global clock control module which supports the clocks, resets and + power domains on SC7280. + + See also: + - dt-bindings/clock/qcom,gcc-sc7280.h + +properties: + compatible: +const: qcom,gcc-sc7280 + + clocks: +items: + - description: Board XO source + - description: Board active XO source + - description: Sleep clock source + - description: PCIE-0 pipe clock source + - description: PCIE-1 pipe clock source + - description: USB30 phy wrapper pipe clock source + + clock-names: +items: + - const: bi_tcxo + - const: bi_tcxo_ao + - const: sleep_clk + - const: pcie_0_pipe_clk + - const: pcie_1_pipe_clk + - const: usb3_phy_wrapper_gcc_usb30_pipe_clk + + '#clock-cells': +const: 1 + + '#reset-cells': +const: 1 + + '#power-domain-cells': +const: 1 + + reg: +maxItems: 1 + + protected-clocks: +description: + Protected clock specifier list as per common clock binding. + +required: + - compatible + - clocks + - clock-names + - reg + - '#clock-cells' + - '#reset-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | +#include +clock-controller@10 { + compatible = "qcom,gcc-sc7280"; + reg = <0x0010 0x1f>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&rpmhcc RPMH_CXO_CLK_A>, + <&sleep_clk>, + <&pcie_0_pipe_clk>, <&pcie_1_pipe_clk>, + <&usb3_phy_wrapper_gcc_usb30_pipe_clk>; + clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk", "pcie_0_pipe_clk", + "pcie_1_pipe_clk", "usb3_phy_wrapper_gcc_usb30_pipe_clk"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; +}; +... diff --git a/include/dt-bindings/clock/qcom,gcc-sc7280.h b/include/dt-bindings/clock/qcom,gcc-sc7280.h new file mode 100644 index 000..3295bd4 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-sc7280.h @@ -0,0 +1,215 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SC7280_H +#define _DT_BINDINGS_CLK_QCOM_GCC_SC7280_H + +/* GCC clocks */ +#define GCC_GPLL0 0 +#define GCC_GPLL0_OUT_EVEN 1 +#define GCC_GPLL0_OUT_ODD 2 +#define GCC_GPLL1 3 +#define GCC_GPLL10 4 +#define GCC_GPLL4 5 +#define GCC_GPLL9 6 +#define GCC_AGGRE_NOC_PCIE_0_AXI_CLK 7 +#define GCC_AGGRE_NOC_PCIE_1_AXI_CLK 8 +#define GCC_AGGRE_UFS_PHY_AXI_CLK 9 +#define GCC_AGGRE_USB3_PRIM_AXI_CLK10 +#define GCC_CAMERA_AHB_CLK 11 +#define GCC_CAMERA_HF_AXI_CLK 12 +#define GCC_CAMERA_SF_AXI_CLK 13 +#define GCC_CAMERA_XO_CLK 14 +#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK 15 +#define GCC_CFG_NOC_USB3_SEC_AXI_CLK 16 +#define GCC_CPUSS_AHB_CLK 17 +#define GCC_CPUSS_AHB_CLK_SRC 18 +#define GCC_CPUSS_AHB_POSTDIV_CLK_SRC 19 +#define GCC_DDRSS_GPU_AXI_CLK 20 +#define GCC_DDRSS_PCIE_SF_CLK 21 +#define GCC_DISP_AHB_CLK 22 +#define GCC_DISP_GPLL0_CLK_SRC 23 +#define GCC_DISP_HF_AXI_CLK
Re: [PATCH v2 5/5] clk: qcom: gcc: Add clock driver for SM8350
On 12/11/2020 12:40 PM, Stephen Boyd wrote: Quoting Vinod Koul (2020-12-10 21:43:49) On 10-12-20, 12:43, Stephen Boyd wrote: +static struct clk_branch gcc_camera_ahb_clk = { + .halt_reg = 0x26004, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x26004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_ahb_clk", + .flags = CLK_IS_CRITICAL, Why is it critical? Can we just enable it in driver probe and stop modeling it as a clk? it does not have a parent we control, yeah it would make sense to do that. Tanya do you folks agree ..? Maybe it is needed for camera clk controller? Have to check other SoCs and see if they're using it. Yes, they would have to be left enabled. Vinod, could you please move them to probe, similar to kona/sc7180 where all the CRITICALs clocks are left enabled? -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
Re: [PATCH 5/5] clk: qcom: gcc: Add clock driver for SM8350
Hi Vinod, On 12/4/2020 10:05 AM, Vinod Koul wrote: Hi Bjorn, On 03-12-20, 18:06, Bjorn Andersson wrote: On Thu 03 Dec 01:02 CST 2020, Vinod Koul wrote: diff --git a/drivers/clk/qcom/gcc-sm8350.c b/drivers/clk/qcom/gcc-sm8350.c [..] +static int gcc_sm8350_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret; + + regmap = qcom_cc_map(pdev, &gcc_sm8350_desc); + if (IS_ERR(regmap)) { + dev_err(&pdev->dev, "Failed to map gcc registers\n"); + return PTR_ERR(regmap); + } + + ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, ARRAY_SIZE(gcc_dfs_clocks)); + if (ret) + return ret; + + /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ + regmap_update_bits(regmap, gcc_ufs_phy_ice_core_clk.halt_reg, BIT(14), BIT(14)); + + /* +* Enable clocks required by the i2c-connected pm8008 regulators. Don't +* register them with the clock framework so that client requests are +* short-circuited before grabbing the enable/prepare locks. This +* prevents deadlocks between the clk/regulator frameworks. +* +* gcc_qupv3_wrap_1_m_ahb_clk +* gcc_qupv3_wrap_1_s_ahb_clk +* gcc_qupv3_wrap1_s5_clk +*/ Isn't this a workaround inherited from the downstream control of regulators from within the clock core? Does this still apply upstream? Let me check on this bit... Thanks No it should not apply. -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
[PATCH v1] clk: qcom: lpasscc: Introduce pm autosuspend for SC7180
The LPASSCC driver's suspend/resume is invoked multiple number of times and thus allow the device to autosuspend for 500ms. Signed-off-by: Taniya Das --- drivers/clk/qcom/lpasscorecc-sc7180.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c index 9081649..2e0ecc3 100644 --- a/drivers/clk/qcom/lpasscorecc-sc7180.c +++ b/drivers/clk/qcom/lpasscorecc-sc7180.c @@ -370,7 +370,10 @@ static int lpass_create_pm_clks(struct platform_device *pdev) { int ret; + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, 500); pm_runtime_enable(&pdev->dev); + ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_runtime_disable, &pdev->dev); if (ret) return ret; @@ -423,7 +426,12 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap, &lpass_lpaaudio_dig_pll_config); - return qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap); + ret = qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap); + + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); + + return ret; } static int lpass_hm_core_probe(struct platform_device *pdev) -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v1] arm64: dts: sc7180: Add camera clock controller node
Add the camera clock controller node supported on SC7180. Signed-off-by: Taniya Das --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 13 + 1 file changed, 13 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index f5ef2cb..e795dba 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -5,6 +5,7 @@ * Copyright (c) 2019, The Linux Foundation. All rights reserved. */ +#include #include #include #include @@ -2896,6 +2897,18 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; + camcc: clock-controller@ad0 { + compatible = "qcom,sc7180-camcc"; + reg = <0 0x0ad0 0 0x1>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_XO_CLK>; + clock-names = "bi_tcxo", "iface", "xo"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + mdss: mdss@ae0 { compatible = "qcom,sc7180-mdss"; reg = <0 0x0ae0 0 0x1000>; -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
Re: [PATCH v5 1/2] clk: qcom: lpasscc-sc7810: Use devm in probe
Reviewed-by: Taniya Das On 10/20/2020 4:19 AM, Douglas Anderson wrote: Let's convert the lpass clock control driver to use devm. This is a few more lines of code, but it will be useful in a later patch which disentangles the two devices handled by this driver. Signed-off-by: Douglas Anderson --- (no changes since v4) Changes in v4: - Fixed typo lapss => lpass - Moved lpass_pm_runtime_disable() lpass_pm_clk_destroy() in file. Changes in v3: - ("clk: qcom: lpasscc-sc7810: Use devm in probe") new for v3. drivers/clk/qcom/lpasscorecc-sc7180.c | 38 +++ 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c index 228d08f5d26f..2d15e33ec837 100644 --- a/drivers/clk/qcom/lpasscorecc-sc7180.c +++ b/drivers/clk/qcom/lpasscorecc-sc7180.c @@ -356,6 +356,16 @@ static const struct qcom_cc_desc lpass_audio_hm_sc7180_desc = { .num_gdscs = ARRAY_SIZE(lpass_audio_hm_sc7180_gdscs), }; +static void lpass_pm_runtime_disable(void *data) +{ + pm_runtime_disable(data); +} + +static void lpass_pm_clk_destroy(void *data) +{ + pm_clk_destroy(data); +} + static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) { const struct qcom_cc_desc *desc; @@ -418,34 +428,28 @@ static int lpass_core_sc7180_probe(struct platform_device *pdev) int ret; pm_runtime_enable(&pdev->dev); + ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_runtime_disable, &pdev->dev); + if (ret) + return ret; + ret = pm_clk_create(&pdev->dev); if (ret) - goto disable_pm_runtime; + return ret; + ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_clk_destroy, &pdev->dev); + if (ret) + return ret; ret = pm_clk_add(&pdev->dev, "iface"); if (ret < 0) { dev_err(&pdev->dev, "failed to acquire iface clock\n"); - goto destroy_pm_clk; + return ret; } - ret = -EINVAL; clk_probe = of_device_get_match_data(&pdev->dev); if (!clk_probe) - goto destroy_pm_clk; - - ret = clk_probe(pdev); - if (ret) - goto destroy_pm_clk; - - return 0; - -destroy_pm_clk: - pm_clk_destroy(&pdev->dev); - -disable_pm_runtime: - pm_runtime_disable(&pdev->dev); + return -EINVAL; - return ret; + return clk_probe(pdev); } static const struct dev_pm_ops lpass_core_cc_pm_ops = { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
Re: [PATCH v5 2/2] clk: qcom: lpass-sc7180: Disentangle the two clock devices
Reviewed-by: Taniya Das On 10/20/2020 4:19 AM, Douglas Anderson wrote: The sc7180 lpass clock driver manages two different devices. These two devices were tangled together, using one probe and a lookup to figure out the real probe. I think it's cleaner to really separate the probe for these two devices since they're really different things, just both managed by the same driver. Signed-off-by: Douglas Anderson --- Note: this is now a 2-patch cleanup series with no actual bugfixes since the problem solved by patch #3 was better solved with: https://lore.kernel.org/r/20201017020137.1251319-1-sb...@kernel.org Changes in v5: - Two blank lines inserted before "return" statements. Changes in v3: - ("clk: qcom: lpass-sc7180: Disentangle the two clock devices") new for v3. drivers/clk/qcom/lpasscorecc-sc7180.c | 103 -- 1 file changed, 64 insertions(+), 39 deletions(-) diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c index 2d15e33ec837..1a3925badd7c 100644 --- a/drivers/clk/qcom/lpasscorecc-sc7180.c +++ b/drivers/clk/qcom/lpasscorecc-sc7180.c @@ -366,12 +366,39 @@ static void lpass_pm_clk_destroy(void *data) pm_clk_destroy(data); } +static int lpass_create_pm_clks(struct platform_device *pdev) +{ + int ret; + + pm_runtime_enable(&pdev->dev); + ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_runtime_disable, &pdev->dev); + if (ret) + return ret; + + ret = pm_clk_create(&pdev->dev); + if (ret) + return ret; + ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_clk_destroy, &pdev->dev); + if (ret) + return ret; + + ret = pm_clk_add(&pdev->dev, "iface"); + if (ret < 0) + dev_err(&pdev->dev, "failed to acquire iface clock\n"); + + return ret; +} + static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) { const struct qcom_cc_desc *desc; struct regmap *regmap; int ret; + ret = lpass_create_pm_clks(pdev); + if (ret) + return ret; + lpass_core_cc_sc7180_regmap_config.name = "lpass_audio_cc"; desc = &lpass_audio_hm_sc7180_desc; ret = qcom_cc_probe_by_index(pdev, 1, desc); @@ -402,6 +429,11 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) static int lpass_hm_core_probe(struct platform_device *pdev) { const struct qcom_cc_desc *desc; + int ret; + + ret = lpass_create_pm_clks(pdev); + if (ret) + return ret; lpass_core_cc_sc7180_regmap_config.name = "lpass_hm_core"; desc = &lpass_core_hm_sc7180_desc; @@ -409,55 +441,28 @@ static int lpass_hm_core_probe(struct platform_device *pdev) return qcom_cc_probe_by_index(pdev, 0, desc); } -static const struct of_device_id lpass_core_cc_sc7180_match_table[] = { +static const struct of_device_id lpass_hm_sc7180_match_table[] = { { .compatible = "qcom,sc7180-lpasshm", - .data = lpass_hm_core_probe, }, + { } +}; +MODULE_DEVICE_TABLE(of, lpass_hm_sc7180_match_table); + +static const struct of_device_id lpass_core_cc_sc7180_match_table[] = { { .compatible = "qcom,sc7180-lpasscorecc", - .data = lpass_core_cc_sc7180_probe, }, { } }; MODULE_DEVICE_TABLE(of, lpass_core_cc_sc7180_match_table); -static int lpass_core_sc7180_probe(struct platform_device *pdev) -{ - int (*clk_probe)(struct platform_device *p); - int ret; - - pm_runtime_enable(&pdev->dev); - ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_runtime_disable, &pdev->dev); - if (ret) - return ret; - - ret = pm_clk_create(&pdev->dev); - if (ret) - return ret; - ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_clk_destroy, &pdev->dev); - if (ret) - return ret; - - ret = pm_clk_add(&pdev->dev, "iface"); - if (ret < 0) { - dev_err(&pdev->dev, "failed to acquire iface clock\n"); - return ret; - } - - clk_probe = of_device_get_match_data(&pdev->dev); - if (!clk_probe) - return -EINVAL; - - return clk_probe(pdev); -} - static const struct dev_pm_ops lpass_core_cc_pm_ops = { SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) }; static struct platform_driver lpass_core_cc_sc7180_driver = { - .probe = lpass_core_sc7180_probe, + .probe = lpass_core_cc_sc7180_probe, .driver = { .name = "lpass_core_cc-sc7180", .o
Re: [PATCH] clk: qcom: gdsc: Keep RETAIN_FF bit set if gdsc is already on
Reviewed-by: Taniya Das On 10/17/2020 7:31 AM, Stephen Boyd wrote: If the GDSC is enabled out of boot but doesn't have the retain ff bit set we will get confusing results where the registers that are powered by the GDSC lose their contents on the first power off of the GDSC but thereafter they retain their contents. This is because gdsc_init() fails to make sure the RETAIN_FF bit is set when it probes the GDSC the first time and thus powering off the GDSC causes the register contents to be reset. We do set the RETAIN_FF bit the next time we power on the GDSC, see gdsc_enable(), so that subsequent GDSC power off's don't lose register contents state. Forcibly set the bit at device probe time so that the kernel's assumed view of the GDSC is consistent with the state of the hardware. This fixes a problem where the audio PLL doesn't work on sc7180 when the bootloader leaves the lpass_core_hm GDSC enabled at boot (e.g. to make a noise) but critically doesn't set the RETAIN_FF bit. Cc: Douglas Anderson Cc: Taniya Das Cc: Rajendra Nayak Fixes: 173722995cdb ("clk: qcom: gdsc: Add support to enable retention of GSDCR") Signed-off-by: Stephen Boyd --- drivers/clk/qcom/gdsc.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index bfc4ac02f9ea..af26e0695b86 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -358,6 +358,14 @@ static int gdsc_init(struct gdsc *sc) if ((sc->flags & VOTABLE) && on) gdsc_enable(&sc->pd); + /* +* Make sure the retain bit is set if the GDSC is already on, otherwise +* we end up turning off the GDSC and destroying all the register +* contents that we thought we were saving. +*/ + if ((sc->flags & RETAIN_FF_ENABLE) && on) + gdsc_retain_ff_on(sc); + /* If ALWAYS_ON GDSCs are not ON, turn them ON */ if (sc->flags & ALWAYS_ON) { if (!on) base-commit: 9ff9b0d392ea08090cd1780fb196f36dbb586529 -- 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: Add YAML schemas for the QCOM Camera clock bindings.
The Camera Subsystem clock provider have a bunch of generic properties that are needed in a device tree. Add a YAML schemas for those. Add clock ids for camera clocks which are required to bring the camera subsystem out of reset. Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sc7180-camcc.yaml | 73 + include/dt-bindings/clock/qcom,camcc-sc7180.h | 121 + 2 files changed, 194 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml create mode 100644 include/dt-bindings/clock/qcom,camcc-sc7180.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml new file mode 100644 index 000..f49027e --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sc7180-camcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Camera Clock & Reset Controller Binding for SC7180 + +maintainers: + - Taniya Das + +description: | + Qualcomm camera clock control module which supports the clocks, resets and + power domains on SC7180. + + See also: + - dt-bindings/clock/qcom,camcc-sc7180.h + +properties: + compatible: +const: qcom,sc7180-camcc + + clocks: +items: + - description: Board XO source + - description: Camera_ahb clock from GCC + - description: Camera XO clock from GCC + + clock-names: +items: + - const: bi_tcxo + - const: iface + - const: xo + + '#clock-cells': +const: 1 + + '#reset-cells': +const: 1 + + '#power-domain-cells': +const: 1 + + reg: +maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | +#include +#include +clock-controller@ad0 { + compatible = "qcom,sc7180-camcc"; + reg = <0x0ad0 0x1>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_XO_CLK>; + clock-names = "bi_tcxo", "iface", "xo"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; +}; +... diff --git a/include/dt-bindings/clock/qcom,camcc-sc7180.h b/include/dt-bindings/clock/qcom,camcc-sc7180.h new file mode 100644 index 000..ef7d3a0 --- /dev/null +++ b/include/dt-bindings/clock/qcom,camcc-sc7180.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_CAM_CC_SC7180_H +#define _DT_BINDINGS_CLK_QCOM_CAM_CC_SC7180_H + +/* CAM_CC clocks */ +#define CAM_CC_PLL2_OUT_EARLY 0 +#define CAM_CC_PLL01 +#define CAM_CC_PLL12 +#define CAM_CC_PLL23 +#define CAM_CC_PLL2_OUT_AUX4 +#define CAM_CC_PLL35 +#define CAM_CC_CAMNOC_AXI_CLK 6 +#define CAM_CC_CCI_0_CLK 7 +#define CAM_CC_CCI_0_CLK_SRC 8 +#define CAM_CC_CCI_1_CLK 9 +#define CAM_CC_CCI_1_CLK_SRC 10 +#define CAM_CC_CORE_AHB_CLK11 +#define CAM_CC_CPAS_AHB_CLK12 +#define CAM_CC_CPHY_RX_CLK_SRC 13 +#define CAM_CC_CSI0PHYTIMER_CLK14 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC15 +#define CAM_CC_CSI1PHYTIMER_CLK16 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC17 +#define CAM_CC_CSI2PHYTIMER_CLK18 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC19 +#define CAM_CC_CSI3PHYTIMER_CLK20 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC21 +#define CAM_CC_CSIPHY0_CLK 22 +#define CAM_CC_CSIPHY1_CLK 23 +#define CAM_CC_CSIPHY2_CLK 24 +#define CAM_CC_CSIPHY3_CLK 25 +#define CAM_CC_FAST_AHB_CLK_SRC26 +#define CAM_CC_ICP_APB_CLK 27 +#d
[PATCH v3 2/4] clk: qcom: clk-alpha-pll: Add support for controlling Agera PLLs
Add programming sequence support for managing the Agera PLLs. Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-alpha-pll.c | 62 drivers/clk/qcom/clk-alpha-pll.h | 4 +++ 2 files changed, 66 insertions(+) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index f3b8b54..21c357c 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -116,6 +116,16 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_OPMODE] = 0x38, [PLL_OFF_ALPHA_VAL] = 0x40, }, + [CLK_ALPHA_PLL_TYPE_AGERA] = { + [PLL_OFF_L_VAL] = 0x04, + [PLL_OFF_ALPHA_VAL] = 0x08, + [PLL_OFF_USER_CTL] = 0x0c, + [PLL_OFF_CONFIG_CTL] = 0x10, + [PLL_OFF_CONFIG_CTL_U] = 0x14, + [PLL_OFF_TEST_CTL] = 0x18, + [PLL_OFF_TEST_CTL_U] = 0x1c, + [PLL_OFF_STATUS] = 0x2c, + }, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); @@ -1538,3 +1548,55 @@ const struct clk_ops clk_alpha_pll_postdiv_lucid_ops = { .set_rate = clk_alpha_pll_postdiv_fabia_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_ops); + +void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + const struct alpha_pll_config *config) +{ + clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); + clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha); + clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), + config->user_ctl_val); + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), + config->config_ctl_val); + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), + config->config_ctl_hi_val); + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), + config->test_ctl_val); + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), + config->test_ctl_hi_val); +} +EXPORT_SYMBOL_GPL(clk_agera_pll_configure); + +static int clk_alpha_pll_agera_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long prate) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 l, alpha_width = pll_alpha_width(pll); + int ret; + unsigned long rrate; + u64 a; + + rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); + ret = alpha_pll_check_rate_margin(hw, rrate, rate); + if (ret < 0) + return ret; + + /* change L_VAL without having to go through the power on sequence */ + regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); + + if (clk_hw_is_enabled(hw)) + return wait_for_pll_enable_lock(pll); + + return 0; +} + +const struct clk_ops clk_alpha_pll_agera_ops = { + .enable = clk_alpha_pll_enable, + .disable = clk_alpha_pll_disable, + .is_enabled = clk_alpha_pll_is_enabled, + .recalc_rate = alpha_pll_fabia_recalc_rate, + .round_rate = clk_alpha_pll_round_rate, + .set_rate = clk_alpha_pll_agera_set_rate, +}; +EXPORT_SYMBOL_GPL(clk_alpha_pll_agera_ops); diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index d3201b8..0ea30d2 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -15,6 +15,7 @@ enum { CLK_ALPHA_PLL_TYPE_FABIA, CLK_ALPHA_PLL_TYPE_TRION, CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION, + CLK_ALPHA_PLL_TYPE_AGERA, CLK_ALPHA_PLL_TYPE_MAX, }; @@ -141,6 +142,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_trion_ops; extern const struct clk_ops clk_alpha_pll_lucid_ops; #define clk_alpha_pll_fixed_lucid_ops clk_alpha_pll_fixed_trion_ops extern const struct clk_ops clk_alpha_pll_postdiv_lucid_ops; +extern const struct clk_ops clk_alpha_pll_agera_ops; void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); @@ -148,6 +150,8 @@ void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); +void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + const struct alpha_pll_config *config); #define clk_lucid_pll_configure(pll, regmap, config) \ clk_trion_pll_configure(pll, regmap, co
[PATCH v3 4/4] clk: qcom: camcc: Add camera clock controller driver for SC7180
Add support for the camera clock controller found on SC7180 based devices. This would allow camera drivers to probe and control their clocks. Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig|9 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sc7180.c | 1736 +++ 3 files changed, 1746 insertions(+) create mode 100644 drivers/clk/qcom/camcc-sc7180.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 3a965bd..886e861 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -290,6 +290,15 @@ config QCS_GCC_404 Say Y if you want to use multimedia devices or peripheral devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc. +config SC_CAMCC_7180 + tristate "SC7180 Camera Clock Controller" + select SC_GCC_7180 + help + Support for the camera clock controller on Qualcomm Technologies, Inc + SC7180 devices. + Say Y if you want to support camera devices and functionality such as + capturing pictures. + config SC_DISPCC_7180 tristate "SC7180 Display Clock Controller" select SC_GCC_7180 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 11ae86f..ee02faf 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o +obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o diff --git a/drivers/clk/qcom/camcc-sc7180.c b/drivers/clk/qcom/camcc-sc7180.c new file mode 100644 index 000..a623745 --- /dev/null +++ b/drivers/clk/qcom/camcc-sc7180.c @@ -0,0 +1,1736 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_AUX, + P_CAM_CC_PLL2_OUT_EARLY, + P_CAM_CC_PLL3_OUT_MAIN, + P_CORE_BI_PLL_TEST_SE, +}; + +static const struct pll_vco agera_vco[] = { + { 6, 33, 0 }, +}; + +static const struct pll_vco fabia_vco[] = { + { 24960, 20, 0 }, +}; + +/* 600MHz configuration */ +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x1F, + .alpha = 0x4000, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x2067, + .test_ctl_val = 0x4000, + .user_ctl_hi_val = 0x4805, + .user_ctl_val = 0x0001, +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +/* 860MHz configuration */ +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x2A, + .alpha = 0x1555, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x2067, + .test_ctl_val = 0x4000, + .user_ctl_hi_val = 0x4805, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +/* 1920MHz configuration */ +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x64, + .config_ctl_val = 0x2800, + .config_ctl_hi_val = 0x43D2, + .test_ctl_val = 0x04000400, + .test_ctl_hi_val = 0x4000, +
[PATCH v3 0/4] Add Camera clock controller driver for SC7180
[v3] * Introduce helper functions to be used across pll configure and pll rate margins. * Update the Agera PLL configure/set rate to use the new helper functions. * Update documentation binding to update the header inclusion. * Update the vco table to 'const'. * Fix the failure path of probe. [v2] * Update PLL set rate function : clk_alpha_pll_agera_set_rate * Remove mb() [v1] * Add support for Agera PLL which is used in the camera clock controller. * Add driver support for camera clock controller for SC7180 and also update device tree bindings for the various clocks supported in the clock controller. Taniya Das (4): clk: qcom: clk-alpha-pll: Add support for helper functions clk: qcom: clk-alpha-pll: Add support for controlling Agera PLLs dt-bindings: clock: Add YAML schemas for the QCOM Camera clock bindings. clk: qcom: camcc: Add camera clock controller driver for SC7180 .../bindings/clock/qcom,sc7180-camcc.yaml | 73 + drivers/clk/qcom/Kconfig |9 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sc7180.c| 1736 drivers/clk/qcom/clk-alpha-pll.c | 217 ++- drivers/clk/qcom/clk-alpha-pll.h |4 + include/dt-bindings/clock/qcom,camcc-sc7180.h | 121 ++ 7 files changed, 2072 insertions(+), 89 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml create mode 100644 drivers/clk/qcom/camcc-sc7180.c create mode 100644 include/dt-bindings/clock/qcom,camcc-sc7180.h -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v3 1/4] clk: qcom: clk-alpha-pll: Add support for helper functions
Introduce clk_alpha_pll_write_config and alpha_pll_check_rate_margin helper functions to be across PLL configure functions and PLL set rate functions. Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-alpha-pll.c | 155 +-- 1 file changed, 66 insertions(+), 89 deletions(-) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 5644311..f3b8b54 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -207,6 +207,13 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse, #define wait_for_pll_update_ack_clear(pll) \ wait_for_pll(pll, ALPHA_PLL_ACK_LATCH, 1, "update_ack_clear") +static void clk_alpha_pll_write_config(struct regmap *regmap, unsigned int reg, + unsigned int val) +{ + if (val) + regmap_write(regmap, reg, val); +} + void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config) { @@ -1004,33 +1011,19 @@ void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, { u32 val, mask; - if (config->l) - regmap_write(regmap, PLL_L_VAL(pll), config->l); - - if (config->alpha) - regmap_write(regmap, PLL_FRAC(pll), config->alpha); - - if (config->config_ctl_val) - regmap_write(regmap, PLL_CONFIG_CTL(pll), + clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); + clk_alpha_pll_write_config(regmap, PLL_FRAC(pll), config->alpha); + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val); - - if (config->config_ctl_hi_val) - regmap_write(regmap, PLL_CONFIG_CTL_U(pll), + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val); - - if (config->user_ctl_val) - regmap_write(regmap, PLL_USER_CTL(pll), config->user_ctl_val); - - if (config->user_ctl_hi_val) - regmap_write(regmap, PLL_USER_CTL_U(pll), + clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), + config->user_ctl_val); + clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), config->user_ctl_hi_val); - - if (config->test_ctl_val) - regmap_write(regmap, PLL_TEST_CTL(pll), + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val); - - if (config->test_ctl_hi_val) - regmap_write(regmap, PLL_TEST_CTL_U(pll), + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val); if (config->post_div_mask) { @@ -1145,25 +1138,38 @@ static unsigned long alpha_pll_fabia_recalc_rate(struct clk_hw *hw, return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width); } +/* + * Due to limited number of bits for fractional rate programming, the + * rounded up rate could be marginally higher than the requested rate. + */ +static int alpha_pll_check_rate_margin(struct clk_hw *hw, + unsigned long rrate, unsigned long rate) +{ + unsigned long rate_margin = rate + PLL_RATE_MARGIN; + + if (rrate > rate_margin || rrate < rate) { + pr_err("%s: Rounded rate %lu not within range [%lu, %lu)\n", + clk_hw_get_name(hw), rrate, rate, rate_margin); + return -EINVAL; + } + + return 0; +} + static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate) { struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); u32 l, alpha_width = pll_alpha_width(pll); + unsigned long rrate; + int ret; u64 a; - unsigned long rrate, max = rate + PLL_RATE_MARGIN; rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); - /* -* Due to limited number of bits for fractional rate programming, the -* rounded up rate could be marginally higher than the requested rate. -*/ - if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) { - pr_err("%s: Rounded rate %lu not within range [%lu, %lu)\n", - clk_hw_get_name(hw), rrate, rate, max); - return -EINVAL; - } + ret = alpha_pll_check_rate_margin(hw, rrate, rate); + if (ret < 0) + return ret; regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); regmap_write(pll->clkr.regmap, PLL_FRAC(pll),
Re: [PATCH v2 3/3] clk: qcom: camcc: Add camera clock controller driver for SC7180
Thanks for your review Stephen. On 10/14/2020 7:29 AM, Stephen Boyd wrote: Quoting Taniya Das (2020-10-13 10:11:50) diff --git a/drivers/clk/qcom/camcc-sc7180.c b/drivers/clk/qcom/camcc-sc7180.c new file mode 100644 index 000..e954d21 --- /dev/null +++ b/drivers/clk/qcom/camcc-sc7180.c @@ -0,0 +1,1737 @@ [...] + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_AUX, + P_CAM_CC_PLL2_OUT_EARLY, + P_CAM_CC_PLL3_OUT_MAIN, + P_CORE_BI_PLL_TEST_SE, +}; + +static struct pll_vco agera_vco[] = { Can this be const? + { 6, 33, 0 }, +}; + +static struct pll_vco fabia_vco[] = { Can this be const? + { 24960, 20, 0 }, +}; + [...] Will take care of the above in the next patch. + +static int cam_cc_sc7180_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret; + + pm_runtime_enable(&pdev->dev); + ret = pm_clk_create(&pdev->dev); + if (ret) + return ret; + + ret = pm_clk_add(&pdev->dev, "xo"); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to acquire XO clock\n"); + goto disable_pm_runtime; + } + + ret = pm_clk_add(&pdev->dev, "iface"); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to acquire iface clock\n"); + goto disable_pm_runtime; + } + + ret = pm_clk_runtime_resume(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "pm runtime resume failed\n"); + goto destroy_pm_clk; + } + + regmap = qcom_cc_map(pdev, &cam_cc_sc7180_desc); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + goto destroy_pm_clk; + } + + clk_fabia_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll0_config); + clk_fabia_pll_configure(&cam_cc_pll1, regmap, &cam_cc_pll1_config); + clk_agera_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll2_config); + clk_fabia_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll3_config); + + ret = qcom_cc_really_probe(pdev, &cam_cc_sc7180_desc, regmap); + if (ret) { + dev_err(&pdev->dev, "Failed to register CAM CC clocks\n"); + goto suspend_pm_runtime; ret is non-zero here + } + +suspend_pm_runtime: + ret = pm_clk_runtime_suspend(&pdev->dev); But then it is overwritten here. + if (ret) + dev_err(&pdev->dev, "pm runtime suspend failed\n"); + + return 0; And we return 0 when there was a failure to probe the clks? I will clean the error path in the next patch. + +destroy_pm_clk: + pm_clk_destroy(&pdev->dev); + +disable_pm_runtime: + pm_runtime_disable(&pdev->dev); + + return ret; +} -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
Re: [PATCH v2 2/3] dt-bindings: clock: Add YAML schemas for the QCOM Camera clock bindings.
Thanks for your review Stephen. On 10/14/2020 7:39 AM, Stephen Boyd wrote: Quoting Taniya Das (2020-10-13 10:11:49) diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml new file mode 100644 index 000..07bd38e --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sc7180-camcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Camera Clock & Reset Controller Binding for SC7180 + +maintainers: + - Taniya Das + +description: | + Qualcomm camera clock control module which supports the clocks, resets and + power domains on SC7180. + + See also: + - dt-bindings/clock/qcom,camcc-sc7180.h. Maybe just - dt-bindings/clock/qcom,camcc-sc7180.h so that us copy/pasters don't have to delete anything. Will be fixed in the next patch. + +properties: + compatible: +const: qcom,sc7180-camcc + + clocks: +items: + - description: Board XO source + - description: Camera_ahb clock from GCC + - description: Camera XO clock from GCC + -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
Re: [PATCH v2 1/3] clk: qcom: clk-alpha-pll: Add support for controlling Agera PLLs
Thanks Stephen for the review comments. On 10/14/2020 7:37 AM, Stephen Boyd wrote: Quoting Taniya Das (2020-10-13 10:11:48) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 26139ef..17e1fc0 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -1561,3 +1571,73 @@ const struct clk_ops clk_alpha_pll_postdiv_lucid_ops = { .set_rate = clk_alpha_pll_postdiv_fabia_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_ops); + +void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + const struct alpha_pll_config *config) +{ + if (config->l) + regmap_write(regmap, PLL_L_VAL(pll), config->l); Maybe make a helper function for this too. That way we can't mix up the if condition with the value in the write. Sure, I will add a helper function. clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); static void clk_alpha_pll_write_config(struct regmap *regmap, unsigned int reg, unsigned int val) { if (val) regmap_write(regmap, reg, val); } and how are we so lucky that zero isn't a value that we may need to write? + + if (config->alpha) + regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha); + + if (config->user_ctl_val) + regmap_write(regmap, PLL_USER_CTL(pll), config->user_ctl_val); + + if (config->config_ctl_val) + regmap_write(regmap, PLL_CONFIG_CTL(pll), + config->config_ctl_val); + + if (config->config_ctl_hi_val) + regmap_write(regmap, PLL_CONFIG_CTL_U(pll), + config->config_ctl_hi_val); + + if (config->test_ctl_val) + regmap_write(regmap, PLL_TEST_CTL(pll), + config->test_ctl_val); + + if (config->test_ctl_hi_val) + regmap_write(regmap, PLL_TEST_CTL_U(pll), + config->test_ctl_hi_val); +} +EXPORT_SYMBOL_GPL(clk_agera_pll_configure); + +static int clk_alpha_pll_agera_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long prate) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 l, alpha_width = pll_alpha_width(pll); + unsigned long rrate, max = rate + PLL_RATE_MARGIN; + u64 a; + + rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); + + /* +* Due to limited number of bits for fractional rate programming, the +* rounded up rate could be marginally higher than the requested rate. +*/ + if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) { + pr_err("%s: Rounded rate %lu not within range [%lu, %lu)\n", + clk_hw_get_name(hw), rrate, rate, max); + return -EINVAL; + } Can this be extracted into a helper function? Yes, I will add this too. + + /* change L_VAL without having to go through the power on sequence */ + regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); + + if (clk_hw_is_enabled(hw)) + return wait_for_pll_enable_lock(pll); + + return 0; +} + -- 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: lpasscc: Re-configure the PLL in case lost
Thanks Doug for the patch. On 10/14/2020 9:28 PM, Douglas Anderson wrote: From: Taniya Das In the case where the PLL configuration is lost, then the pm runtime resume will reconfigure before usage. Fixes: edab812d802d ("clk: qcom: lpass: Add support for LPASS clock controller for SC7180") Signed-off-by: Taniya Das Signed-off-by: Douglas Anderson --- I took the liberty of fixing my own nits that I had with Taniya's patch, AKA: https://lore.kernel.org/r/1602614008-2421-2-git-send-email-t...@codeaurora.org Changes in v2: - Don't needlessly have a 2nd copy of dev_pm_ops and jam it in. - Check the return value of pm_clk_resume() - l_val should be unsigned int. drivers/clk/qcom/lpasscorecc-sc7180.c | 23 ++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c index 228d08f5d26f..ee23eb5b9bf2 100644 --- a/drivers/clk/qcom/lpasscorecc-sc7180.c +++ b/drivers/clk/qcom/lpasscorecc-sc7180.c @@ -356,6 +356,25 @@ static const struct qcom_cc_desc lpass_audio_hm_sc7180_desc = { .num_gdscs = ARRAY_SIZE(lpass_audio_hm_sc7180_gdscs), }; +static int lpass_core_cc_pm_clk_resume(struct device *dev) +{ + struct regmap *regmap = dev_get_drvdata(dev); + unsigned int l_val; + int ret; + + ret = pm_clk_resume(dev); + if (ret) + return ret; + + /* Read PLL_L_VAL */ + regmap_read(regmap, 0x1004, &l_val); + if (!l_val) + clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap, + &lpass_lpaaudio_dig_pll_config); + + return 0; +} + static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) { const struct qcom_cc_desc *desc; @@ -373,6 +392,8 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) if (IS_ERR(regmap)) return PTR_ERR(regmap); + dev_set_drvdata(&pdev->dev, regmap); + /* * Keep the CLK always-ON * LPASS_AUDIO_CORE_SYSNOC_SWAY_CORE_CLK @@ -449,7 +470,7 @@ static int lpass_core_sc7180_probe(struct platform_device *pdev) } static const struct dev_pm_ops lpass_core_cc_pm_ops = { - SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) + SET_RUNTIME_PM_OPS(pm_clk_suspend, lpass_core_cc_pm_clk_resume, NULL) There are two devices and "lpass_hm_core" and the PLL is not part of the HM_CORE, thus was the reason to separate out the pm_ops. }; static struct platform_driver lpass_core_cc_sc7180_driver = { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
[PATCH v0] clk: qcom: lpasscc: Re-configure the PLL in case lost
In the case where the PLL configuration is lost, then the pm runtime resume will reconfigure before usage. Fixes: edab812d802d ("clk: qcom: lpass: Add support for LPASS clock controller for SC7180") Signed-off-by: Taniya Das --- drivers/clk/qcom/lpasscorecc-sc7180.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c index 228d08f..5804a93 100644 --- a/drivers/clk/qcom/lpasscorecc-sc7180.c +++ b/drivers/clk/qcom/lpasscorecc-sc7180.c @@ -356,6 +356,25 @@ static const struct qcom_cc_desc lpass_audio_hm_sc7180_desc = { .num_gdscs = ARRAY_SIZE(lpass_audio_hm_sc7180_gdscs), }; +static int lpass_core_cc_pm_clk_resume(struct device *dev) +{ + struct regmap *regmap = dev_get_drvdata(dev); + int l_val; + + pm_clk_resume(dev); + + /* Read PLL_L_VAL */ + regmap_read(regmap, 0x1004, &l_val); + if (!l_val) + clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap, + &lpass_lpaaudio_dig_pll_config); + return 0; +} + +static const struct dev_pm_ops lpass_core_pm_ops = { + SET_RUNTIME_PM_OPS(pm_clk_suspend, lpass_core_cc_pm_clk_resume, NULL) +}; + static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) { const struct qcom_cc_desc *desc; @@ -386,6 +405,9 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap, &lpass_lpaaudio_dig_pll_config); + pdev->dev.driver->pm = &lpass_core_pm_ops; + dev_set_drvdata(&pdev->dev, regmap); + return qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap); } -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v0] LPASSCC: Configure the PLL in case lost for SC7180
In the case where the LPASSCC PLL loses the PLL configuration it would fail to lock. Thus allow reconfigure the PLL from pm_resume. Taniya Das (1): clk: qcom: lpasscc: Re-configure the PLL in case lost drivers/clk/qcom/lpasscorecc-sc7180.c | 22 ++ 1 file changed, 22 insertions(+) -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v2 3/3] clk: qcom: camcc: Add camera clock controller driver for SC7180
Add support for the camera clock controller found on SC7180 based devices. This would allow camera drivers to probe and control their clocks. Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig|9 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sc7180.c | 1737 +++ 3 files changed, 1747 insertions(+) create mode 100644 drivers/clk/qcom/camcc-sc7180.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 0583273..7aeebe6 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -290,6 +290,15 @@ config QCS_GCC_404 Say Y if you want to use multimedia devices or peripheral devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc. +config SC_CAMCC_7180 + tristate "SC7180 Camera Clock Controller" + select SC_GCC_7180 + help + Support for the camera clock controller on Qualcomm Technologies, Inc + SC7180 devices. + Say Y if you want to support camera devices and functionality such as + capturing pictures. + config SC_DISPCC_7180 tristate "SC7180 Display Clock Controller" select SC_GCC_7180 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 9677e76..8e0579f 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o +obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o diff --git a/drivers/clk/qcom/camcc-sc7180.c b/drivers/clk/qcom/camcc-sc7180.c new file mode 100644 index 000..e954d21 --- /dev/null +++ b/drivers/clk/qcom/camcc-sc7180.c @@ -0,0 +1,1737 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_AUX, + P_CAM_CC_PLL2_OUT_EARLY, + P_CAM_CC_PLL3_OUT_MAIN, + P_CORE_BI_PLL_TEST_SE, +}; + +static struct pll_vco agera_vco[] = { + { 6, 33, 0 }, +}; + +static struct pll_vco fabia_vco[] = { + { 24960, 20, 0 }, +}; + +/* 600MHz configuration */ +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x1F, + .alpha = 0x4000, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x2067, + .test_ctl_val = 0x4000, + .user_ctl_hi_val = 0x4805, + .user_ctl_val = 0x0001, +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +/* 860MHz configuration */ +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x2A, + .alpha = 0x1555, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x2067, + .test_ctl_val = 0x4000, + .user_ctl_hi_val = 0x4805, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +/* 1920MHz configuration */ +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x64, + .config_ctl_val = 0x2800, + .config_ctl_hi_val = 0x43D2, + .test_ctl_val = 0x04000400, + .test_ctl_hi_val = 0x4000, + .user_ctl_va
[PATCH v2 1/3] clk: qcom: clk-alpha-pll: Add support for controlling Agera PLLs
Add programming sequence support for managing the Agera PLLs. Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-alpha-pll.c | 80 drivers/clk/qcom/clk-alpha-pll.h | 4 ++ 2 files changed, 84 insertions(+) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 26139ef..17e1fc0 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -116,6 +116,16 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_OPMODE] = 0x38, [PLL_OFF_ALPHA_VAL] = 0x40, }, + [CLK_ALPHA_PLL_TYPE_AGERA] = { + [PLL_OFF_L_VAL] = 0x04, + [PLL_OFF_ALPHA_VAL] = 0x08, + [PLL_OFF_USER_CTL] = 0x0c, + [PLL_OFF_CONFIG_CTL] = 0x10, + [PLL_OFF_CONFIG_CTL_U] = 0x14, + [PLL_OFF_TEST_CTL] = 0x18, + [PLL_OFF_TEST_CTL_U] = 0x1c, + [PLL_OFF_STATUS] = 0x2c, + }, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); @@ -1561,3 +1571,73 @@ const struct clk_ops clk_alpha_pll_postdiv_lucid_ops = { .set_rate = clk_alpha_pll_postdiv_fabia_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_ops); + +void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + const struct alpha_pll_config *config) +{ + if (config->l) + regmap_write(regmap, PLL_L_VAL(pll), config->l); + + if (config->alpha) + regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha); + + if (config->user_ctl_val) + regmap_write(regmap, PLL_USER_CTL(pll), config->user_ctl_val); + + if (config->config_ctl_val) + regmap_write(regmap, PLL_CONFIG_CTL(pll), + config->config_ctl_val); + + if (config->config_ctl_hi_val) + regmap_write(regmap, PLL_CONFIG_CTL_U(pll), + config->config_ctl_hi_val); + + if (config->test_ctl_val) + regmap_write(regmap, PLL_TEST_CTL(pll), + config->test_ctl_val); + + if (config->test_ctl_hi_val) + regmap_write(regmap, PLL_TEST_CTL_U(pll), + config->test_ctl_hi_val); +} +EXPORT_SYMBOL_GPL(clk_agera_pll_configure); + +static int clk_alpha_pll_agera_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long prate) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 l, alpha_width = pll_alpha_width(pll); + unsigned long rrate, max = rate + PLL_RATE_MARGIN; + u64 a; + + rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); + + /* +* Due to limited number of bits for fractional rate programming, the +* rounded up rate could be marginally higher than the requested rate. +*/ + if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) { + pr_err("%s: Rounded rate %lu not within range [%lu, %lu)\n", + clk_hw_get_name(hw), rrate, rate, max); + return -EINVAL; + } + + /* change L_VAL without having to go through the power on sequence */ + regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); + + if (clk_hw_is_enabled(hw)) + return wait_for_pll_enable_lock(pll); + + return 0; +} + +const struct clk_ops clk_alpha_pll_agera_ops = { + .enable = clk_alpha_pll_enable, + .disable = clk_alpha_pll_disable, + .is_enabled = clk_alpha_pll_is_enabled, + .recalc_rate = alpha_pll_fabia_recalc_rate, + .round_rate = clk_alpha_pll_round_rate, + .set_rate = clk_alpha_pll_agera_set_rate, +}; +EXPORT_SYMBOL_GPL(clk_alpha_pll_agera_ops); diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index d3201b8..0ea30d2 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -15,6 +15,7 @@ enum { CLK_ALPHA_PLL_TYPE_FABIA, CLK_ALPHA_PLL_TYPE_TRION, CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION, + CLK_ALPHA_PLL_TYPE_AGERA, CLK_ALPHA_PLL_TYPE_MAX, }; @@ -141,6 +142,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_trion_ops; extern const struct clk_ops clk_alpha_pll_lucid_ops; #define clk_alpha_pll_fixed_lucid_ops clk_alpha_pll_fixed_trion_ops extern const struct clk_ops clk_alpha_pll_postdiv_lucid_ops; +extern const struct clk_ops clk_alpha_pll_agera_ops; void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); @@ -148,6 +150,8 @@ void clk_fabia_pll_configure(struct clk_alpha
[PATCH v2 2/3] dt-bindings: clock: Add YAML schemas for the QCOM Camera clock bindings.
The Camera Subsystem clock provider have a bunch of generic properties that are needed in a device tree. Add a YAML schemas for those. Add clock ids for camera clocks which are required to bring the camera subsystem out of reset. Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sc7180-camcc.yaml | 73 + include/dt-bindings/clock/qcom,camcc-sc7180.h | 121 + 2 files changed, 194 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml create mode 100644 include/dt-bindings/clock/qcom,camcc-sc7180.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml new file mode 100644 index 000..07bd38e --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sc7180-camcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Camera Clock & Reset Controller Binding for SC7180 + +maintainers: + - Taniya Das + +description: | + Qualcomm camera clock control module which supports the clocks, resets and + power domains on SC7180. + + See also: + - dt-bindings/clock/qcom,camcc-sc7180.h. + +properties: + compatible: +const: qcom,sc7180-camcc + + clocks: +items: + - description: Board XO source + - description: Camera_ahb clock from GCC + - description: Camera XO clock from GCC + + clock-names: +items: + - const: bi_tcxo + - const: iface + - const: xo + + '#clock-cells': +const: 1 + + '#reset-cells': +const: 1 + + '#power-domain-cells': +const: 1 + + reg: +maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | +#include +#include +clock-controller@ad0 { + compatible = "qcom,sc7180-camcc"; + reg = <0x0ad0 0x1>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_XO_CLK>; + clock-names = "bi_tcxo", "iface", "xo"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; +}; +... diff --git a/include/dt-bindings/clock/qcom,camcc-sc7180.h b/include/dt-bindings/clock/qcom,camcc-sc7180.h new file mode 100644 index 000..ef7d3a0 --- /dev/null +++ b/include/dt-bindings/clock/qcom,camcc-sc7180.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_CAM_CC_SC7180_H +#define _DT_BINDINGS_CLK_QCOM_CAM_CC_SC7180_H + +/* CAM_CC clocks */ +#define CAM_CC_PLL2_OUT_EARLY 0 +#define CAM_CC_PLL01 +#define CAM_CC_PLL12 +#define CAM_CC_PLL23 +#define CAM_CC_PLL2_OUT_AUX4 +#define CAM_CC_PLL35 +#define CAM_CC_CAMNOC_AXI_CLK 6 +#define CAM_CC_CCI_0_CLK 7 +#define CAM_CC_CCI_0_CLK_SRC 8 +#define CAM_CC_CCI_1_CLK 9 +#define CAM_CC_CCI_1_CLK_SRC 10 +#define CAM_CC_CORE_AHB_CLK11 +#define CAM_CC_CPAS_AHB_CLK12 +#define CAM_CC_CPHY_RX_CLK_SRC 13 +#define CAM_CC_CSI0PHYTIMER_CLK14 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC15 +#define CAM_CC_CSI1PHYTIMER_CLK16 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC17 +#define CAM_CC_CSI2PHYTIMER_CLK18 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC19 +#define CAM_CC_CSI3PHYTIMER_CLK20 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC21 +#define CAM_CC_CSIPHY0_CLK 22 +#define CAM_CC_CSIPHY1_CLK 23 +#define CAM_CC_CSIPHY2_CLK 24 +#define CAM_CC_CSIPHY3_CLK 25 +#define CAM_CC_FAST_AHB_CLK_SRC26 +#define CAM_CC_ICP_APB_CLK 27 +#d
[PATCH v2 0/3] Add Camera clock controller driver for SC7180
[v2] * Update PLL set rate function : clk_alpha_pll_agera_set_rate * Remove mb() [v1] * Add support for Agera PLL which is used in the camera clock controller. * Add driver support for camera clock controller for SC7180 and also update device tree bindings for the various clocks supported in the clock controller. Taniya Das (3): clk: qcom: clk-alpha-pll: Add support for controlling Agera PLLs dt-bindings: clock: Add YAML schemas for the QCOM Camera clock bindings. clk: qcom: camcc: Add camera clock controller driver for SC7180 .../bindings/clock/qcom,sc7180-camcc.yaml | 73 + drivers/clk/qcom/Kconfig |9 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sc7180.c| 1737 drivers/clk/qcom/clk-alpha-pll.c | 80 + drivers/clk/qcom/clk-alpha-pll.h |4 + include/dt-bindings/clock/qcom,camcc-sc7180.h | 121 ++ 7 files changed, 2025 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml create mode 100644 drivers/clk/qcom/camcc-sc7180.c create mode 100644 include/dt-bindings/clock/qcom,camcc-sc7180.h -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
Re: [PATCH v1 1/3] clk: qcom: clk-alpha-pll: Add support for controlling Agera PLLs
Thanks for the review Stephen. On 9/15/2020 5:43 AM, Stephen Boyd wrote: Quoting Taniya Das (2020-09-08 10:07:26) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 26139ef..fb27fcf 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -1561,3 +1571,75 @@ const struct clk_ops clk_alpha_pll_postdiv_lucid_ops = { .set_rate = clk_alpha_pll_postdiv_fabia_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_ops); + +void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + const struct alpha_pll_config *config) +{ + if (config->l) + regmap_write(regmap, PLL_L_VAL(pll), config->l); + + if (config->alpha) + regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha); + + if (config->user_ctl_val) + regmap_write(regmap, PLL_USER_CTL(pll), config->user_ctl_val); + + if (config->config_ctl_val) + regmap_write(regmap, PLL_CONFIG_CTL(pll), + config->config_ctl_val); + + if (config->config_ctl_hi_val) + regmap_write(regmap, PLL_CONFIG_CTL_U(pll), + config->config_ctl_hi_val); + + if (config->test_ctl_val) + regmap_write(regmap, PLL_TEST_CTL(pll), + config->test_ctl_val); + + if (config->test_ctl_hi_val) + regmap_write(regmap, PLL_TEST_CTL_U(pll), + config->test_ctl_hi_val); +} +EXPORT_SYMBOL_GPL(clk_agera_pll_configure); + +static int alpha_pll_agera_set_rate(struct clk_hw *hw, unsigned long rate, Why not clk_alpha_pll prefix? We should prefix the other PLL functions in here with clk_alpha_ like trion and fabia Yes, I will update this in the next patch. + unsigned long prate) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 l, alpha_width = pll_alpha_width(pll); + unsigned long rrate; + u64 a; + + rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); + + /* +* Due to limited number of bits for fractional rate programming, the +* rounded up rate could be marginally higher than the requested rate. +*/ + if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) { + pr_err("Call set rate on the PLL with rounded rates!\n"); + return -EINVAL; + } See commit f78f29079327 ("clk: qcom: alpha-pll: Make error prints more informative") where I tried to make this better. Can you extract this check into a function that helps us understand the error better? Updated to follow the same. + + /* change L_VAL without having to go through the power on sequence */ + regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); + + /* Ensure that the write above goes through before proceeding. */ + mb(); regmap has an mb() in it. Remove this? Yes, will remove it. + + if (clk_hw_is_enabled(hw)) + return wait_for_pll_enable_lock(pll); + + return 0; +} + +const struct clk_ops clk_alpha_pll_agera_ops = { + .enable = clk_alpha_pll_enable, + .disable = clk_alpha_pll_disable, + .is_enabled = clk_alpha_pll_is_enabled, + .recalc_rate = alpha_pll_fabia_recalc_rate, + .round_rate = clk_alpha_pll_round_rate, + .set_rate = alpha_pll_agera_set_rate, +}; +EXPORT_SYMBOL_GPL(clk_alpha_pll_agera_ops); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
[PATCH v1 0/3] Add Camera clock controller driver for SC7180
[v1] * Add support for Agera PLL which is used in the camera clock controller. * Add driver support for camera clock controller for SC7180 and also update device tree bindings for the various clocks supported in the clock controller. Taniya Das (3): clk: qcom: clk-alpha-pll: Add support for controlling Agera PLLs dt-bindings: clock: Add YAML schemas for the QCOM Camera clock bindings. clk: qcom: camcc: Add camera clock controller driver for SC7180 .../bindings/clock/qcom,sc7180-camcc.yaml | 73 + drivers/clk/qcom/Kconfig |9 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sc7180.c| 1737 drivers/clk/qcom/clk-alpha-pll.c | 82 + drivers/clk/qcom/clk-alpha-pll.h |4 + include/dt-bindings/clock/qcom,camcc-sc7180.h | 121 ++ 7 files changed, 2027 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml create mode 100644 drivers/clk/qcom/camcc-sc7180.c create mode 100644 include/dt-bindings/clock/qcom,camcc-sc7180.h -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v1 3/3] clk: qcom: camcc: Add camera clock controller driver for SC7180
Add support for the camera clock controller found on SC7180 based devices. This would allow camera drivers to probe and control their clocks. Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig|9 + drivers/clk/qcom/Makefile |1 + drivers/clk/qcom/camcc-sc7180.c | 1737 +++ 3 files changed, 1747 insertions(+) create mode 100644 drivers/clk/qcom/camcc-sc7180.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 0583273..7aeebe6 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -290,6 +290,15 @@ config QCS_GCC_404 Say Y if you want to use multimedia devices or peripheral devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc. +config SC_CAMCC_7180 + tristate "SC7180 Camera Clock Controller" + select SC_GCC_7180 + help + Support for the camera clock controller on Qualcomm Technologies, Inc + SC7180 devices. + Say Y if you want to support camera devices and functionality such as + capturing pictures. + config SC_DISPCC_7180 tristate "SC7180 Display Clock Controller" select SC_GCC_7180 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 9677e76..8e0579f 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o +obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o diff --git a/drivers/clk/qcom/camcc-sc7180.c b/drivers/clk/qcom/camcc-sc7180.c new file mode 100644 index 000..e954d21 --- /dev/null +++ b/drivers/clk/qcom/camcc-sc7180.c @@ -0,0 +1,1737 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_AUX, + P_CAM_CC_PLL2_OUT_EARLY, + P_CAM_CC_PLL3_OUT_MAIN, + P_CORE_BI_PLL_TEST_SE, +}; + +static struct pll_vco agera_vco[] = { + { 6, 33, 0 }, +}; + +static struct pll_vco fabia_vco[] = { + { 24960, 20, 0 }, +}; + +/* 600MHz configuration */ +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x1F, + .alpha = 0x4000, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x2067, + .test_ctl_val = 0x4000, + .user_ctl_hi_val = 0x4805, + .user_ctl_val = 0x0001, +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +/* 860MHz configuration */ +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x2A, + .alpha = 0x1555, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x2067, + .test_ctl_val = 0x4000, + .user_ctl_hi_val = 0x4805, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +/* 1920MHz configuration */ +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x64, + .config_ctl_val = 0x2800, + .config_ctl_hi_val = 0x43D2, + .test_ctl_val = 0x04000400, + .test_ctl_hi_val = 0x4000, + .user_ctl_va
[PATCH v1 2/3] dt-bindings: clock: Add YAML schemas for the QCOM Camera clock bindings.
The Camera Subsystem clock provider have a bunch of generic properties that are needed in a device tree. Add a YAML schemas for those. Add clock ids for Camera clocks which are required to bring the camera subsystem out of reset. Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sc7180-camcc.yaml | 73 + include/dt-bindings/clock/qcom,camcc-sc7180.h | 121 + 2 files changed, 194 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml create mode 100644 include/dt-bindings/clock/qcom,camcc-sc7180.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml new file mode 100644 index 000..07bd38e --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sc7180-camcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Camera Clock & Reset Controller Binding for SC7180 + +maintainers: + - Taniya Das + +description: | + Qualcomm camera clock control module which supports the clocks, resets and + power domains on SC7180. + + See also: + - dt-bindings/clock/qcom,camcc-sc7180.h. + +properties: + compatible: +const: qcom,sc7180-camcc + + clocks: +items: + - description: Board XO source + - description: Camera_ahb clock from GCC + - description: Camera XO clock from GCC + + clock-names: +items: + - const: bi_tcxo + - const: iface + - const: xo + + '#clock-cells': +const: 1 + + '#reset-cells': +const: 1 + + '#power-domain-cells': +const: 1 + + reg: +maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | +#include +#include +clock-controller@ad0 { + compatible = "qcom,sc7180-camcc"; + reg = <0x0ad0 0x1>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_XO_CLK>; + clock-names = "bi_tcxo", "iface", "xo"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; +}; +... diff --git a/include/dt-bindings/clock/qcom,camcc-sc7180.h b/include/dt-bindings/clock/qcom,camcc-sc7180.h new file mode 100644 index 000..ef7d3a0 --- /dev/null +++ b/include/dt-bindings/clock/qcom,camcc-sc7180.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_CAM_CC_SC7180_H +#define _DT_BINDINGS_CLK_QCOM_CAM_CC_SC7180_H + +/* CAM_CC clocks */ +#define CAM_CC_PLL2_OUT_EARLY 0 +#define CAM_CC_PLL01 +#define CAM_CC_PLL12 +#define CAM_CC_PLL23 +#define CAM_CC_PLL2_OUT_AUX4 +#define CAM_CC_PLL35 +#define CAM_CC_CAMNOC_AXI_CLK 6 +#define CAM_CC_CCI_0_CLK 7 +#define CAM_CC_CCI_0_CLK_SRC 8 +#define CAM_CC_CCI_1_CLK 9 +#define CAM_CC_CCI_1_CLK_SRC 10 +#define CAM_CC_CORE_AHB_CLK11 +#define CAM_CC_CPAS_AHB_CLK12 +#define CAM_CC_CPHY_RX_CLK_SRC 13 +#define CAM_CC_CSI0PHYTIMER_CLK14 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC15 +#define CAM_CC_CSI1PHYTIMER_CLK16 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC17 +#define CAM_CC_CSI2PHYTIMER_CLK18 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC19 +#define CAM_CC_CSI3PHYTIMER_CLK20 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC21 +#define CAM_CC_CSIPHY0_CLK 22 +#define CAM_CC_CSIPHY1_CLK 23 +#define CAM_CC_CSIPHY2_CLK 24 +#define CAM_CC_CSIPHY3_CLK 25 +#define CAM_CC_FAST_AHB_CLK_SRC26 +#define CAM_CC_ICP_APB_CLK 27 +#d
[PATCH v1 1/3] clk: qcom: clk-alpha-pll: Add support for controlling Agera PLLs
Add programming sequence support for managing the Agera PLLs. Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-alpha-pll.c | 82 drivers/clk/qcom/clk-alpha-pll.h | 4 ++ 2 files changed, 86 insertions(+) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 26139ef..fb27fcf 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -116,6 +116,16 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_OPMODE] = 0x38, [PLL_OFF_ALPHA_VAL] = 0x40, }, + [CLK_ALPHA_PLL_TYPE_AGERA] = { + [PLL_OFF_L_VAL] = 0x04, + [PLL_OFF_ALPHA_VAL] = 0x08, + [PLL_OFF_USER_CTL] = 0x0c, + [PLL_OFF_CONFIG_CTL] = 0x10, + [PLL_OFF_CONFIG_CTL_U] = 0x14, + [PLL_OFF_TEST_CTL] = 0x18, + [PLL_OFF_TEST_CTL_U] = 0x1c, + [PLL_OFF_STATUS] = 0x2c, + }, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); @@ -1561,3 +1571,75 @@ const struct clk_ops clk_alpha_pll_postdiv_lucid_ops = { .set_rate = clk_alpha_pll_postdiv_fabia_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_ops); + +void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + const struct alpha_pll_config *config) +{ + if (config->l) + regmap_write(regmap, PLL_L_VAL(pll), config->l); + + if (config->alpha) + regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha); + + if (config->user_ctl_val) + regmap_write(regmap, PLL_USER_CTL(pll), config->user_ctl_val); + + if (config->config_ctl_val) + regmap_write(regmap, PLL_CONFIG_CTL(pll), + config->config_ctl_val); + + if (config->config_ctl_hi_val) + regmap_write(regmap, PLL_CONFIG_CTL_U(pll), + config->config_ctl_hi_val); + + if (config->test_ctl_val) + regmap_write(regmap, PLL_TEST_CTL(pll), + config->test_ctl_val); + + if (config->test_ctl_hi_val) + regmap_write(regmap, PLL_TEST_CTL_U(pll), + config->test_ctl_hi_val); +} +EXPORT_SYMBOL_GPL(clk_agera_pll_configure); + +static int alpha_pll_agera_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long prate) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 l, alpha_width = pll_alpha_width(pll); + unsigned long rrate; + u64 a; + + rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); + + /* +* Due to limited number of bits for fractional rate programming, the +* rounded up rate could be marginally higher than the requested rate. +*/ + if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) { + pr_err("Call set rate on the PLL with rounded rates!\n"); + return -EINVAL; + } + + /* change L_VAL without having to go through the power on sequence */ + regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); + + /* Ensure that the write above goes through before proceeding. */ + mb(); + + if (clk_hw_is_enabled(hw)) + return wait_for_pll_enable_lock(pll); + + return 0; +} + +const struct clk_ops clk_alpha_pll_agera_ops = { + .enable = clk_alpha_pll_enable, + .disable = clk_alpha_pll_disable, + .is_enabled = clk_alpha_pll_is_enabled, + .recalc_rate = alpha_pll_fabia_recalc_rate, + .round_rate = clk_alpha_pll_round_rate, + .set_rate = alpha_pll_agera_set_rate, +}; +EXPORT_SYMBOL_GPL(clk_alpha_pll_agera_ops); diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index d3201b8..0ea30d2 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -15,6 +15,7 @@ enum { CLK_ALPHA_PLL_TYPE_FABIA, CLK_ALPHA_PLL_TYPE_TRION, CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION, + CLK_ALPHA_PLL_TYPE_AGERA, CLK_ALPHA_PLL_TYPE_MAX, }; @@ -141,6 +142,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_trion_ops; extern const struct clk_ops clk_alpha_pll_lucid_ops; #define clk_alpha_pll_fixed_lucid_ops clk_alpha_pll_fixed_trion_ops extern const struct clk_ops clk_alpha_pll_postdiv_lucid_ops; +extern const struct clk_ops clk_alpha_pll_agera_ops; void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); @@ -148,6 +150,8 @@ void clk_fabia_pll_configure(struct clk_alpha_pll *p
Re: [PATCH v5 4/4] clk: qcom: lpass: Add support for LPASS clock controller for SC7180
Hi Stephen, On 8/6/2020 1:54 AM, Stephen Boyd wrote: Quoting Taniya Das (2020-07-24 09:07:58) + +static struct clk_rcg2 core_clk_src = { + .cmd_rcgr = 0x1d000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = lpass_core_cc_parent_map_2, + .clkr.hw.init = &(struct clk_init_data){ + .name = "core_clk_src", Any chance this can get a better name? Something with LPASS prefix? These are the exact clock names from the hardware plan. + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_rcg2_ops, + }, +}; + [...] + +static struct clk_branch lpass_audio_core_sysnoc_mport_core_clk = { + .halt_reg = 0x23000, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x23000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x23000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lpass_audio_core_sysnoc_mport_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *lpass_core_cc_sc7180_clocks[] = { + [EXT_MCLK0_CLK_SRC] = &ext_mclk0_clk_src.clkr, + [LPAIF_PRI_CLK_SRC] = &lpaif_pri_clk_src.clkr, + [LPAIF_SEC_CLK_SRC] = &lpaif_sec_clk_src.clkr, + [CORE_CLK_SRC] = &core_clk_src.clkr, And all of these, can they have LPASS_ prefix on the defines? Seems like we're missing a namespace otherwise. These are generated as they are in the HW plan. Do you still think I should update them? + [LPASS_AUDIO_CORE_EXT_MCLK0_CLK] = &lpass_audio_core_ext_mclk0_clk.clkr, + [LPASS_AUDIO_CORE_LPAIF_PRI_IBIT_CLK] = + &lpass_audio_core_lpaif_pri_ibit_clk.clkr, + [LPASS_AUDIO_CORE_LPAIF_SEC_IBIT_CLK] = + &lpass_audio_core_lpaif_sec_ibit_clk.clkr, + [LPASS_AUDIO_CORE_SYSNOC_MPORT_CORE_CLK] = + &lpass_audio_core_sysnoc_mport_core_clk.clkr, + [LPASS_LPAAUDIO_DIG_PLL] = &lpass_lpaaudio_dig_pll.clkr, + [LPASS_LPAAUDIO_DIG_PLL_OUT_ODD] = &lpass_lpaaudio_dig_pll_out_odd.clkr, +}; + -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
[PATCH v2] arm64: dts: qcom: sc7180: Add LPASS clock controller nodes
Update the clock controller nodes for Low power audio subsystem functionality. Signed-off-by: Taniya Das --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 25 + 1 file changed, 25 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index d46b383..7cf8bfe 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -3312,6 +3313,30 @@ qcom,msa-fixed-perm; status = "disabled"; }; + + lpasscc: clock-controller@62d0 { + compatible = "qcom,sc7180-lpasscorecc"; + reg = <0 0x62d0 0 0x5>, + <0 0x6278 0 0x3>; + reg-names = "lpass_core_cc", "lpass_audio_cc"; + clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>, +<&rpmhcc RPMH_CXO_CLK>; + clock-names = "iface", "bi_tcxo"; + power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>; + #clock-cells = <1>; + #power-domain-cells = <1>; + }; + + lpass_hm: clock-controller@6300 { + compatible = "qcom,sc7180-lpasshm"; + reg = <0 0x6300 0 0x28>; + clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>, +<&rpmhcc RPMH_CXO_CLK>; + clock-names = "iface", "bi_tcxo"; + #clock-cells = <1>; + #power-domain-cells = <1>; + }; + }; thermal-zones { -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v2] Add LPASS clock controller Node for SC7180
[v2] - Update the node in sorted order. - Depends on the patch https://lore.kernel.org/r/20200731133006.1.Iee81b115f5be50d6d69500fe1bda11bba6e16143@changeid [v1] - Clock controller LPASS device Node. Taniya Das (1): arm64: dts: qcom: sc7180: Add LPASS clock controller nodes arch/arm64/boot/dts/qcom/sc7180.dtsi | 25 + 1 file changed, 25 insertions(+) -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v5 4/4] clk: qcom: lpass: Add support for LPASS clock controller for SC7180
The Low Power Audio subsystem clocks are required for Audio client to be able to request for the clocks and power domains. Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/lpasscorecc-sc7180.c | 477 ++ 3 files changed, 487 insertions(+) create mode 100644 drivers/clk/qcom/lpasscorecc-sc7180.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 318c0ad..0bb5261 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -308,6 +308,15 @@ config SC_GCC_7180 Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDCC, etc. +config SC_LPASS_CORECC_7180 + tristate "SC7180 LPASS Core Clock Controller" + select SC_GCC_7180 + help + Support for the LPASS(Low Power Audio Subsystem) core clock controller + on SC7180 devices. + Say Y if you want to use LPASS clocks and power domains of the LPASS + core clock controller. + config SC_GPUCC_7180 tristate "SC7180 Graphics Clock Controller" select SC_GCC_7180 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index ae0979b..b5a706b 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -54,6 +54,7 @@ obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o +obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c new file mode 100644 index 000..e14e631 --- /dev/null +++ b/drivers/clk/qcom/lpasscorecc-sc7180.c @@ -0,0 +1,477 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, + P_SLEEP_CLK, +}; + +static struct pll_vco fabia_vco[] = { + { 24960, 20, 0 }, +}; + +static const struct alpha_pll_config lpass_lpaaudio_dig_pll_config = { + .l = 0x20, + .alpha = 0x0, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x2067, + .test_ctl_val = 0x4000, + .test_ctl_hi_val = 0x, + .user_ctl_val = 0x5105, + .user_ctl_hi_val = 0x4805, +}; + +static const u8 clk_alpha_pll_regs_offset[][PLL_OFF_MAX_REGS] = { + [CLK_ALPHA_PLL_TYPE_FABIA] = { + [PLL_OFF_L_VAL] = 0x04, + [PLL_OFF_CAL_L_VAL] = 0x8, + [PLL_OFF_USER_CTL] = 0x0c, + [PLL_OFF_USER_CTL_U] = 0x10, + [PLL_OFF_USER_CTL_U1] = 0x14, + [PLL_OFF_CONFIG_CTL] = 0x18, + [PLL_OFF_CONFIG_CTL_U] = 0x1C, + [PLL_OFF_CONFIG_CTL_U1] = 0x20, + [PLL_OFF_TEST_CTL] = 0x24, + [PLL_OFF_TEST_CTL_U] = 0x28, + [PLL_OFF_STATUS] = 0x30, + [PLL_OFF_OPMODE] = 0x38, + [PLL_OFF_FRAC] = 0x40, + }, +}; + +static struct clk_alpha_pll lpass_lpaaudio_dig_pll = { + .offset = 0x1000, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "lpass_lpaaudio_dig_pll", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table + post_div_table_lpass_lpaaudio_dig_pll_out_odd[] = { + { 0x5, 5 }, + { } +}; + +static struct clk_alpha_pll_postdiv lpass_lpaaudio_dig_pll_out_odd = { + .offset = 0x1000, + .post_div_shift = 12, + .post_div_table = post_div_table_lpass_lpaaudio_dig_pll_out_odd, + .num_post_div = + ARRAY_SIZE(post_div_table_lpass_lpaaudio_dig_pll_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "lpass_lpaaudio_dig_pll_out_odd", + .parent_data = &(const struc
[PATCH v5 3/4] clk: qcom: gcc: Add support for GCC LPASS clock for SC7180
Add the GCC lpass clock which is required to access the LPASS core clocks. Signed-off-by: Taniya Das --- drivers/clk/qcom/gcc-sc7180.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index ca4383e..8d3b161 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -2251,6 +2251,19 @@ static struct clk_branch gcc_mss_q6_memnoc_axi_clk = { }, }; +static struct clk_branch gcc_lpass_cfg_noc_sway_clk = { + .halt_reg = 0x47018, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x47018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_cfg_noc_sway_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct gdsc ufs_phy_gdsc = { .gdscr = 0x77004, .pd = { @@ -2428,6 +2441,7 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { [GCC_MSS_Q6_MEMNOC_AXI_CLK] = &gcc_mss_q6_memnoc_axi_clk.clkr, [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, [GCC_SEC_CTRL_CLK_SRC] = &gcc_sec_ctrl_clk_src.clkr, + [GCC_LPASS_CFG_NOC_SWAY_CLK] = &gcc_lpass_cfg_noc_sway_clk.clkr, }; static const struct qcom_reset_map gcc_sc7180_resets[] = { -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v5 0/4] clk: qcom: Support for Low Power Audio Clocks on SC7180
[v5] * Replace tabs with space in the documentation binding. * Remove .name from parent_data. [v4] * Fix minor comments in the documentation binding. [v3] * Update the clock-name to iface instead of gcc_lpass_sway. * Update the documentation with the reg descriptions and use maxItems. [v2] * Update retention macro name. * Update the register description in the documentation. [v1] * Add support for Retention of GDSCR. * Add YAML schema for LPASS clocks and clock IDs for LPASS. * Add clock driver for LPASS core clocks and GCC LPASS clock. Taniya Das (4): clk: qcom: gdsc: Add support to enable retention of GSDCR dt-bindings: clock: Add YAML schemas for LPASS clocks on SC7180 clk: qcom: gcc: Add support for GCC LPASS clock for SC7180 clk: qcom: lpass: Add support for LPASS clock controller for SC7180 Taniya Das (4): clk: qcom: gdsc: Add support to enable retention of GSDCR dt-bindings: clock: Add YAML schemas for LPASS clocks on SC7180 clk: qcom: gcc: Add support for GCC LPASS clock for SC7180 clk: qcom: lpass: Add support for LPASS clock controller for SC7180 .../bindings/clock/qcom,sc7180-lpasscorecc.yaml| 102 + drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-sc7180.c | 14 + drivers/clk/qcom/gdsc.c| 12 + drivers/clk/qcom/gdsc.h| 1 + drivers/clk/qcom/lpasscorecc-sc7180.c | 477 + include/dt-bindings/clock/qcom,gcc-sc7180.h| 1 + .../dt-bindings/clock/qcom,lpasscorecc-sc7180.h| 29 ++ 9 files changed, 646 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml create mode 100644 drivers/clk/qcom/lpasscorecc-sc7180.c create mode 100644 include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v5 2/4] dt-bindings: clock: Add YAML schemas for LPASS clocks on SC7180
The LPASS(Low Power Audio Subsystem) clock provider have a bunch of generic properties that are needed in a device tree. Also add clock ids for GCC LPASS and LPASS Core clock IDs for LPASS client to request for the clocks. Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sc7180-lpasscorecc.yaml| 102 + include/dt-bindings/clock/qcom,gcc-sc7180.h| 1 + .../dt-bindings/clock/qcom,lpasscorecc-sc7180.h| 29 ++ 3 files changed, 132 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml create mode 100644 include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml new file mode 100644 index 000..a838250 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml @@ -0,0 +1,102 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sc7180-lpasscorecc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm LPASS Core Clock Controller Binding for SC7180 + +maintainers: + - Taniya Das + +description: | + Qualcomm LPASS core clock control module which supports the clocks and + power domains on SC7180. + + See also: + - dt-bindings/clock/qcom,lpasscorecc-sc7180.h + +properties: + compatible: +enum: + - qcom,sc7180-lpasshm + - qcom,sc7180-lpasscorecc + + clocks: +items: + - description: gcc_lpass_sway clock from GCC + + clock-names: +items: + - const: iface + + power-domains: +maxItems: 1 + + '#clock-cells': +const: 1 + + '#power-domain-cells': +const: 1 + + reg: +minItems: 1 +items: + - description: lpass core cc register + - description: lpass audio cc register + + reg-names: +items: + - const: lpass_core_cc + - const: lpass_audio_cc + +if: + properties: +compatible: + contains: +const: qcom,sc7180-lpasshm +then: + properties: +reg: + maxItems: 1 + +else: + properties: +reg: + minItems: 2 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | +#include +#include +clock-controller@6300 { + compatible = "qcom,sc7180-lpasshm"; + reg = <0x6300 0x28>; + clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>; + clock-names = "iface"; + #clock-cells = <1>; + #power-domain-cells = <1>; +}; + + - | +clock-controller@62d0 { + compatible = "qcom,sc7180-lpasscorecc"; + reg = <0x62d0 0x5>, <0x6278 0x3>; + reg-names = "lpass_core_cc", "lpass_audio_cc"; + clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>; + clock-names = "iface"; + power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>; + #clock-cells = <1>; + #power-domain-cells = <1>; +}; +... diff --git a/include/dt-bindings/clock/qcom,gcc-sc7180.h b/include/dt-bindings/clock/qcom,gcc-sc7180.h index 992b67b..bdf43adc 100644 --- a/include/dt-bindings/clock/qcom,gcc-sc7180.h +++ b/include/dt-bindings/clock/qcom,gcc-sc7180.h @@ -138,6 +138,7 @@ #define GCC_MSS_Q6_MEMNOC_AXI_CLK 128 #define GCC_MSS_SNOC_AXI_CLK 129 #define GCC_SEC_CTRL_CLK_SRC 130 +#define GCC_LPASS_CFG_NOC_SWAY_CLK 131 /* GCC resets */ #define GCC_QUSB2PHY_PRIM_BCR 0 diff --git a/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h b/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h new file mode 100644 index 000..a55d01d --- /dev/null +++ b/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H +#define _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H + +/* LPASS_CORE_CC clocks */ +#define LPASS_LPAAUDIO_DIG_PLL 0 +#define LPASS_LPAAUDIO_DIG_PLL_OUT_ODD 1 +#define CORE_CLK_SRC 2 +#define EXT_MCLK0_CLK_SRC 3 +#define LPAIF_PRI_CLK_SRC 4 +#define LPAIF_SEC_CLK_SRC 5 +#define LPASS_AUDIO_CORE_CORE_CLK 6 +#define LPASS_AUDIO_CORE_EXT_MCLK0_CLK 7 +#define LPASS_AUDIO_CORE_LPAIF_PRI_IBIT_CLK8 +#define LPASS_AUDIO_CORE_LPAIF_SEC_IBIT_CLK9 +#define LPASS_AUDIO_CORE_SYSNOC_MPORT_CORE
[PATCH v5 1/4] clk: qcom: gdsc: Add support to enable retention of GSDCR
Add support for the RETAIN_FF_ENABLE feature which enables the usage of retention registers. These registers maintain their state after disabling and re-enabling a GDSC. Signed-off-by: Taniya Das --- drivers/clk/qcom/gdsc.c | 12 drivers/clk/qcom/gdsc.h | 1 + 2 files changed, 13 insertions(+) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index 04944f1..2502430 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -29,6 +29,7 @@ /* CFG_GDSCR */ #define GDSC_POWER_UP_COMPLETE BIT(16) #define GDSC_POWER_DOWN_COMPLETE BIT(15) +#define GDSC_RETAIN_FF_ENABLE BIT(11) #define CFG_GDSCR_OFFSET 0x4 /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */ @@ -216,6 +217,14 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc) regmap_update_bits(sc->regmap, sc->clamp_io_ctrl, GMEM_RESET_MASK, 0); } + +static void gdsc_retain_ff_on(struct gdsc *sc) +{ + u32 mask = GDSC_RETAIN_FF_ENABLE; + + regmap_update_bits(sc->regmap, sc->gdscr, mask, mask); +} + static int gdsc_enable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); @@ -268,6 +277,9 @@ static int gdsc_enable(struct generic_pm_domain *domain) udelay(1); } + if (sc->flags & RETAIN_FF_ENABLE) + gdsc_retain_ff_on(sc); + return 0; } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index c36fc26..a5076fe 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -50,6 +50,7 @@ struct gdsc { #define AON_RESET BIT(4) #define POLL_CFG_GDSCR BIT(5) #define ALWAYS_ON BIT(6) +#define RETAIN_FF_ENABLE BIT(7) struct reset_controller_dev *rcdev; unsigned int*resets; unsigned intreset_count; -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
Re: [PATCH v4 4/4] clk: qcom: lpass: Add support for LPASS clock controller for SC7180
Hi Stephen, Thanks for the review. On 7/21/2020 1:18 PM, Stephen Boyd wrote: Quoting Taniya Das (2020-07-14 23:36:50) diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c +static struct clk_alpha_pll lpass_lpaaudio_dig_pll = { + .offset = 0x1000, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "lpass_lpaaudio_dig_pll", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", We don't need .name if we have .fw_name and this is a new binding/device. My bad, will cleanup in the next patch. + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
Re: [PATCH v4 2/4] dt-bindings: clock: Add YAML schemas for LPASS clocks on SC7180
Hi Stephen, Thanks for the review. On 7/21/2020 1:21 PM, Stephen Boyd wrote: +... diff --git a/include/dt-bindings/clock/qcom,gcc-sc7180.h b/include/dt-bindings/clock/qcom,gcc-sc7180.h index 992b67b..bdf43adc 100644 --- a/include/dt-bindings/clock/qcom,gcc-sc7180.h +++ b/include/dt-bindings/clock/qcom,gcc-sc7180.h @@ -138,6 +138,7 @@ #define GCC_MSS_Q6_MEMNOC_AXI_CLK 128 #define GCC_MSS_SNOC_AXI_CLK 129 #define GCC_SEC_CTRL_CLK_SRC 130 +#define GCC_LPASS_CFG_NOC_SWAY_CLK 131 /* GCC resets */ #define GCC_QUSB2PHY_PRIM_BCR 0 This hunk should be in the next patch. Oh but then that patch should come before this one so the binding can use it. Either way, shouldn't be part of this patch. We had a problem with the bot complaining about the clock handles being used in the example. https://patchwork.ozlabs.org/project/devicetree-bindings/patch/1582540703-6328-4-git-send-email-t...@codeaurora.org/ Thus I have kept the GCC bindings in the same patch. -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
[PATCH] arm64: dts: qcom: sc7180: Add LPASS clock controller nodes
Update the clock controller nodes for Low power audio subsystem functionality. Signed-off-by: Taniya Das --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 22 ++ 1 file changed, 22 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index 2be81a2..8c30a17 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -2136,6 +2137,27 @@ }; }; + lpasscc: clock-controller@62d0 { + compatible = "qcom,sc7180-lpasscorecc"; + reg = <0 0x62d0 0 0x5>, + <0 0x6278 0 0x3>; + reg-names = "lpass_core_cc", "lpass_audio_cc"; + clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>; + clock-names = "iface"; + power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>; + #clock-cells = <1>; + #power-domain-cells = <1>; + }; + + lpass_hm: clock-controller@6300 { + compatible = "qcom,sc7180-lpasshm"; + reg = <0 0x6300 0 0x28>; + clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>; + clock-names = "iface"; + #clock-cells = <1>; + #power-domain-cells = <1>; + }; + etm@704 { compatible = "arm,coresight-etm4x", "arm,primecell"; reg = <0 0x0704 0 0x1000>; -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v0] clk: qcom: gcc: Update disp gpll0 branch for 7180/845
The display gpll0 branch clock needs to be always left enabled, thus move the clock ops to _aon branch ops. Signed-off-by: Taniya Das --- drivers/clk/qcom/gcc-sc7180.c | 2 +- drivers/clk/qcom/gcc-sdm845.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index ca4383e..538677b 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -1061,7 +1061,7 @@ static struct clk_branch gcc_disp_gpll0_clk_src = { .hw = &gpll0.clkr.hw, }, .num_parents = 1, - .ops = &clk_branch2_ops, + .ops = &clk_branch2_aon_ops, }, }, }; diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index f6ce888..90f7feb 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. */ #include @@ -1344,7 +1344,7 @@ static struct clk_branch gcc_disp_gpll0_clk_src = { "gpll0", }, .num_parents = 1, - .ops = &clk_branch2_ops, + .ops = &clk_branch2_aon_ops, }, }, }; -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v4 4/4] clk: qcom: lpass: Add support for LPASS clock controller for SC7180
The Low Power Audio subsystem clocks are required for Audio client to be able to request for the clocks and power domains. Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/lpasscorecc-sc7180.c | 478 ++ 3 files changed, 488 insertions(+) create mode 100644 drivers/clk/qcom/lpasscorecc-sc7180.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 318c0ad..0bb5261 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -308,6 +308,15 @@ config SC_GCC_7180 Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDCC, etc. +config SC_LPASS_CORECC_7180 + tristate "SC7180 LPASS Core Clock Controller" + select SC_GCC_7180 + help + Support for the LPASS(Low Power Audio Subsystem) core clock controller + on SC7180 devices. + Say Y if you want to use LPASS clocks and power domains of the LPASS + core clock controller. + config SC_GPUCC_7180 tristate "SC7180 Graphics Clock Controller" select SC_GCC_7180 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index ae0979b..b5a706b 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -54,6 +54,7 @@ obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o +obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c new file mode 100644 index 000..fd8537c --- /dev/null +++ b/drivers/clk/qcom/lpasscorecc-sc7180.c @@ -0,0 +1,478 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, + P_SLEEP_CLK, +}; + +static struct pll_vco fabia_vco[] = { + { 24960, 20, 0 }, +}; + +static const struct alpha_pll_config lpass_lpaaudio_dig_pll_config = { + .l = 0x20, + .alpha = 0x0, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x2067, + .test_ctl_val = 0x4000, + .test_ctl_hi_val = 0x, + .user_ctl_val = 0x5105, + .user_ctl_hi_val = 0x4805, +}; + +static const u8 clk_alpha_pll_regs_offset[][PLL_OFF_MAX_REGS] = { + [CLK_ALPHA_PLL_TYPE_FABIA] = { + [PLL_OFF_L_VAL] = 0x04, + [PLL_OFF_CAL_L_VAL] = 0x8, + [PLL_OFF_USER_CTL] = 0x0c, + [PLL_OFF_USER_CTL_U] = 0x10, + [PLL_OFF_USER_CTL_U1] = 0x14, + [PLL_OFF_CONFIG_CTL] = 0x18, + [PLL_OFF_CONFIG_CTL_U] = 0x1C, + [PLL_OFF_CONFIG_CTL_U1] = 0x20, + [PLL_OFF_TEST_CTL] = 0x24, + [PLL_OFF_TEST_CTL_U] = 0x28, + [PLL_OFF_STATUS] = 0x30, + [PLL_OFF_OPMODE] = 0x38, + [PLL_OFF_FRAC] = 0x40, + }, +}; + +static struct clk_alpha_pll lpass_lpaaudio_dig_pll = { + .offset = 0x1000, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "lpass_lpaaudio_dig_pll", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table + post_div_table_lpass_lpaaudio_dig_pll_out_odd[] = { + { 0x5, 5 }, + { } +}; + +static struct clk_alpha_pll_postdiv lpass_lpaaudio_dig_pll_out_odd = { + .offset = 0x1000, + .post_div_shift = 12, + .post_div_table = post_div_table_lpass_lpaaudio_dig_pll_out_odd, + .num_post_div = + ARRAY_SIZE(post_div_table_lpass_lpaaudio_dig_pll_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "lpass_lpaaudio_dig_pll_out_
[PATCH v4 2/4] dt-bindings: clock: Add YAML schemas for LPASS clocks on SC7180
The LPASS(Low Power Audio Subsystem) clock provider have a bunch of generic properties that are needed in a device tree. Also add clock ids for GCC LPASS and LPASS Core clock IDs for LPASS client to request for the clocks. Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sc7180-lpasscorecc.yaml| 103 + include/dt-bindings/clock/qcom,gcc-sc7180.h| 1 + .../dt-bindings/clock/qcom,lpasscorecc-sc7180.h| 29 ++ 3 files changed, 133 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml create mode 100644 include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml new file mode 100644 index 000..41d0a6d --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml @@ -0,0 +1,103 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sc7180-lpasscorecc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm LPASS Core Clock Controller Binding for SC7180 + +maintainers: + - Taniya Das + +description: | + Qualcomm LPASS core clock control module which supports the clocks and + power domains on SC7180. + + See also: + - dt-bindings/clock/qcom,lpasscorecc-sc7180.h + +properties: + compatible: +enum: + - qcom,sc7180-lpasshm + - qcom,sc7180-lpasscorecc + + clocks: +items: + - description: gcc_lpass_sway clock from GCC + + clock-names: +items: + - const: iface + + power-domains: +maxItems: 1 + + '#clock-cells': +const: 1 + + '#power-domain-cells': +const: 1 + + reg: +minItems: 1 +items: + - description: lpass core cc register + - description: lpass audio cc register + + reg-names: +items: + - const: lpass_core_cc + - const: lpass_audio_cc + +if: + properties: +compatible: + contains: +const: qcom,sc7180-lpasshm +then: + properties: +reg: + maxItems: 1 + +else: + properties: +reg: + minItems: 2 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | +#include +#include +clock-controller@6300 { + compatible = "qcom,sc7180-lpasshm"; +reg = <0x6300 0x28>; +clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>; +clock-names = "iface"; +#clock-cells = <1>; +#power-domain-cells = <1>; +}; + + - | +clock-controller@62d0 { +compatible = "qcom,sc7180-lpasscorecc"; +reg = <0x62d0 0x5>, +<0x6278 0x3>; +reg-names = "lpass_core_cc", "lpass_audio_cc"; +clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>; +clock-names = "iface"; +power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>; +#clock-cells = <1>; +#power-domain-cells = <1>; +}; +... diff --git a/include/dt-bindings/clock/qcom,gcc-sc7180.h b/include/dt-bindings/clock/qcom,gcc-sc7180.h index 992b67b..bdf43adc 100644 --- a/include/dt-bindings/clock/qcom,gcc-sc7180.h +++ b/include/dt-bindings/clock/qcom,gcc-sc7180.h @@ -138,6 +138,7 @@ #define GCC_MSS_Q6_MEMNOC_AXI_CLK 128 #define GCC_MSS_SNOC_AXI_CLK 129 #define GCC_SEC_CTRL_CLK_SRC 130 +#define GCC_LPASS_CFG_NOC_SWAY_CLK 131 /* GCC resets */ #define GCC_QUSB2PHY_PRIM_BCR 0 diff --git a/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h b/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h new file mode 100644 index 000..a55d01d --- /dev/null +++ b/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H +#define _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H + +/* LPASS_CORE_CC clocks */ +#define LPASS_LPAAUDIO_DIG_PLL 0 +#define LPASS_LPAAUDIO_DIG_PLL_OUT_ODD 1 +#define CORE_CLK_SRC 2 +#define EXT_MCLK0_CLK_SRC 3 +#define LPAIF_PRI_CLK_SRC 4 +#define LPAIF_SEC_CLK_SRC 5 +#define LPASS_AUDIO_CORE_CORE_CLK 6 +#define LPASS_AUDIO_CORE_EXT_MCLK0_CLK 7 +#define LPASS_AUDIO_CORE_LPAIF_PRI_IBIT_CLK8 +#define LPASS_AUDIO_CORE_LPAIF_SEC_IBIT_CLK9 +#
[PATCH v4 3/4] clk: qcom: gcc: Add support for GCC LPASS clock for SC7180
Add the GCC lpass clock which is required to access the LPASS core clocks. Signed-off-by: Taniya Das --- drivers/clk/qcom/gcc-sc7180.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index ca4383e..8d3b161 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -2251,6 +2251,19 @@ static struct clk_branch gcc_mss_q6_memnoc_axi_clk = { }, }; +static struct clk_branch gcc_lpass_cfg_noc_sway_clk = { + .halt_reg = 0x47018, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x47018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_cfg_noc_sway_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct gdsc ufs_phy_gdsc = { .gdscr = 0x77004, .pd = { @@ -2428,6 +2441,7 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { [GCC_MSS_Q6_MEMNOC_AXI_CLK] = &gcc_mss_q6_memnoc_axi_clk.clkr, [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, [GCC_SEC_CTRL_CLK_SRC] = &gcc_sec_ctrl_clk_src.clkr, + [GCC_LPASS_CFG_NOC_SWAY_CLK] = &gcc_lpass_cfg_noc_sway_clk.clkr, }; static const struct qcom_reset_map gcc_sc7180_resets[] = { -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v4 0/4] clk: qcom: Support for Low Power Audio Clocks on SC7180
[v4] * Fix minor comments in the documentation binding. [v3] * Update the clock-name to iface instead of gcc_lpass_sway. * Update the documentation with the reg descriptions and use maxItems. [v2] * Update retention macro name. * Update the register description in the documentation. [v1] * Add support for Retention of GDSCR. * Add YAML schema for LPASS clocks and clock IDs for LPASS. * Add clock driver for LPASS core clocks and GCC LPASS clock. Taniya Das (4): clk: qcom: gdsc: Add support to enable retention of GSDCR dt-bindings: clock: Add YAML schemas for LPASS clocks on SC7180 clk: qcom: gcc: Add support for GCC LPASS clock for SC7180 clk: qcom: lpass: Add support for LPASS clock controller for SC7180 .../bindings/clock/qcom,sc7180-lpasscorecc.yaml| 103 + drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-sc7180.c | 14 + drivers/clk/qcom/gdsc.c| 12 + drivers/clk/qcom/gdsc.h| 1 + drivers/clk/qcom/lpasscorecc-sc7180.c | 478 + include/dt-bindings/clock/qcom,gcc-sc7180.h| 1 + .../dt-bindings/clock/qcom,lpasscorecc-sc7180.h| 29 ++ 9 files changed, 648 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml create mode 100644 drivers/clk/qcom/lpasscorecc-sc7180.c create mode 100644 include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
Re: [PATCH v3 2/4] dt-bindings: clock: Add YAML schemas for LPASS clocks on SC7180
Hi Rob, Thanks for the review. On 6/18/2020 3:59 AM, Rob Herring wrote: On Wed, Jun 10, 2020 at 10:48:05PM +0530, Taniya Das wrote: The LPASS(Low Power Audio Subsystem) clock provider have a bunch of generic properties that are needed in a device tree. Also add clock ids for GCC LPASS and LPASS Core clock IDs for LPASS client to request for the clocks. Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sc7180-lpasscorecc.yaml| 98 ++ include/dt-bindings/clock/qcom,gcc-sc7180.h| 1 + .../dt-bindings/clock/qcom,lpasscorecc-sc7180.h| 29 +++ 3 files changed, 128 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml create mode 100644 include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml new file mode 100644 index 000..5af4048 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml @@ -0,0 +1,98 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sc7180-lpasscorecc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm LPASS Core Clock Controller Binding for SC7180 + +maintainers: + - Taniya Das + +description: | + Qualcomm LPASS core clock control module which supports the clocks and + power domains on SC7180. + + See also: + - dt-bindings/clock/qcom,lpasscorecc-sc7180.h + +properties: + compatible: +enum: + - qcom,sc7180-lpasshm + - qcom,sc7180-lpasscorecc + + clocks: +items: + - description: gcc_lpass_sway clock from GCC + + clock-names: +items: + - const: iface + + power-domains: +maxItems: 1 + + '#clock-cells': +const: 1 + + '#power-domain-cells': +const: 1 + + reg: +maxItems: 2 You need a 'minItems: 1' here instead. Will update in the next patch. +items: + - description: lpass core cc register + - description: lpass audio cc register + + reg-names: +items: + - const: lpass_core_cc + - const: lpass_audio_cc + +if: + properties: +compatible: + contains: +const: qcom,sc7180-lpasshm +then: + properties: +reg: + maxItems: 1 And need an: else: properties: reg: minItems: 2 Will take care of it. + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | +#include +#include +clock-controller@6300 { + compatible = "qcom,sc7180-lpasshm"; +reg = <0 0x6300 0 0x28>; Default sizes are 1 cell. Yes, my bad, will correct in the next patch. +clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>; +clock-names = "iface"; +#clock-cells = <1>; +#power-domain-cells = <1>; +}; + + - | +clock-controller@62d0 { +compatible = "qcom,sc7180-lpasscorecc"; +reg = <0 0x62d0 0 0x5>, +<0 0x6278 0 0x3>; +reg-names = "lpass_core_cc", "lpass_audio_cc"; +clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>; +clock-names = "iface"; +power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>; +#clock-cells = <1>; +#power-domain-cells = <1>; +}; +... diff --git a/include/dt-bindings/clock/qcom,gcc-sc7180.h b/include/dt-bindings/clock/qcom,gcc-sc7180.h index 992b67b..bdf43adc 100644 --- a/include/dt-bindings/clock/qcom,gcc-sc7180.h +++ b/include/dt-bindings/clock/qcom,gcc-sc7180.h @@ -138,6 +138,7 @@ #define GCC_MSS_Q6_MEMNOC_AXI_CLK 128 #define GCC_MSS_SNOC_AXI_CLK 129 #define GCC_SEC_CTRL_CLK_SRC 130 +#define GCC_LPASS_CFG_NOC_SWAY_CLK 131 /* GCC resets */ #define GCC_QUSB2PHY_PRIM_BCR 0 diff --git a/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h b/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h new file mode 100644 index 000..a55d01d --- /dev/null +++ b/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H +#define _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H + +/* LPASS_CORE_CC clocks */ +#define LPASS_LPAAUDIO_DIG_PLL 0 +#define LPASS_LPAAUDIO_DIG_PLL_OUT_ODD 1 +#define CORE_CLK_SRC 2 +#define EXT_MCLK0_CLK_SRC
[PATCH v4 1/4] clk: qcom: gdsc: Add support to enable retention of GSDCR
Add support for the RETAIN_FF_ENABLE feature which enables the usage of retention registers. These registers maintain their state after disabling and re-enabling a GDSC. Signed-off-by: Taniya Das --- drivers/clk/qcom/gdsc.c | 12 drivers/clk/qcom/gdsc.h | 1 + 2 files changed, 13 insertions(+) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index 04944f1..2502430 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -29,6 +29,7 @@ /* CFG_GDSCR */ #define GDSC_POWER_UP_COMPLETE BIT(16) #define GDSC_POWER_DOWN_COMPLETE BIT(15) +#define GDSC_RETAIN_FF_ENABLE BIT(11) #define CFG_GDSCR_OFFSET 0x4 /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */ @@ -216,6 +217,14 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc) regmap_update_bits(sc->regmap, sc->clamp_io_ctrl, GMEM_RESET_MASK, 0); } + +static void gdsc_retain_ff_on(struct gdsc *sc) +{ + u32 mask = GDSC_RETAIN_FF_ENABLE; + + regmap_update_bits(sc->regmap, sc->gdscr, mask, mask); +} + static int gdsc_enable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); @@ -268,6 +277,9 @@ static int gdsc_enable(struct generic_pm_domain *domain) udelay(1); } + if (sc->flags & RETAIN_FF_ENABLE) + gdsc_retain_ff_on(sc); + return 0; } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index c36fc26..a5076fe 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -50,6 +50,7 @@ struct gdsc { #define AON_RESET BIT(4) #define POLL_CFG_GDSCR BIT(5) #define ALWAYS_ON BIT(6) +#define RETAIN_FF_ENABLE BIT(7) struct reset_controller_dev *rcdev; unsigned int*resets; unsigned intreset_count; -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v3 0/4] clk: qcom: Support for Low Power Audio Clocks on SC7180
[v3] * Update the clock-name to iface instead of gcc_lpass_sway. * Update the documentation with the reg descriptions and use maxItems. [v2] * Update retention macro name. * Update the register description in the documentation. [v1] * Add support for Retention of GDSCR. * Add YAML schema for LPASS clocks and clock IDs for LPASS. * Add clock driver for LPASS core clocks and GCC LPASS clock. Taniya Das (4): clk: qcom: gdsc: Add support to enable retention of GSDCR dt-bindings: clock: Add YAML schemas for LPASS clocks on SC7180 clk: qcom: gcc: Add support for GCC LPASS clock for SC7180 clk: qcom: lpass: Add support for LPASS clock controller for SC7180 .../bindings/clock/qcom,sc7180-lpasscorecc.yaml| 98 + drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-sc7180.c | 14 + drivers/clk/qcom/gdsc.c| 12 + drivers/clk/qcom/gdsc.h| 1 + drivers/clk/qcom/lpasscorecc-sc7180.c | 478 + include/dt-bindings/clock/qcom,gcc-sc7180.h| 1 + .../dt-bindings/clock/qcom,lpasscorecc-sc7180.h| 29 ++ 9 files changed, 643 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml create mode 100644 drivers/clk/qcom/lpasscorecc-sc7180.c create mode 100644 include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v3 1/4] clk: qcom: gdsc: Add support to enable retention of GSDCR
Add support for the RETAIN_FF_ENABLE feature which enables the usage of retention registers. These registers maintain their state after disabling and re-enabling a GDSC. Signed-off-by: Taniya Das --- drivers/clk/qcom/gdsc.c | 12 drivers/clk/qcom/gdsc.h | 1 + 2 files changed, 13 insertions(+) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index 04944f1..2502430 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -29,6 +29,7 @@ /* CFG_GDSCR */ #define GDSC_POWER_UP_COMPLETE BIT(16) #define GDSC_POWER_DOWN_COMPLETE BIT(15) +#define GDSC_RETAIN_FF_ENABLE BIT(11) #define CFG_GDSCR_OFFSET 0x4 /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */ @@ -216,6 +217,14 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc) regmap_update_bits(sc->regmap, sc->clamp_io_ctrl, GMEM_RESET_MASK, 0); } + +static void gdsc_retain_ff_on(struct gdsc *sc) +{ + u32 mask = GDSC_RETAIN_FF_ENABLE; + + regmap_update_bits(sc->regmap, sc->gdscr, mask, mask); +} + static int gdsc_enable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); @@ -268,6 +277,9 @@ static int gdsc_enable(struct generic_pm_domain *domain) udelay(1); } + if (sc->flags & RETAIN_FF_ENABLE) + gdsc_retain_ff_on(sc); + return 0; } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index c36fc26..a5076fe 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -50,6 +50,7 @@ struct gdsc { #define AON_RESET BIT(4) #define POLL_CFG_GDSCR BIT(5) #define ALWAYS_ON BIT(6) +#define RETAIN_FF_ENABLE BIT(7) struct reset_controller_dev *rcdev; unsigned int*resets; unsigned intreset_count; -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v3 2/4] dt-bindings: clock: Add YAML schemas for LPASS clocks on SC7180
The LPASS(Low Power Audio Subsystem) clock provider have a bunch of generic properties that are needed in a device tree. Also add clock ids for GCC LPASS and LPASS Core clock IDs for LPASS client to request for the clocks. Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sc7180-lpasscorecc.yaml| 98 ++ include/dt-bindings/clock/qcom,gcc-sc7180.h| 1 + .../dt-bindings/clock/qcom,lpasscorecc-sc7180.h| 29 +++ 3 files changed, 128 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml create mode 100644 include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml new file mode 100644 index 000..5af4048 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml @@ -0,0 +1,98 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sc7180-lpasscorecc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm LPASS Core Clock Controller Binding for SC7180 + +maintainers: + - Taniya Das + +description: | + Qualcomm LPASS core clock control module which supports the clocks and + power domains on SC7180. + + See also: + - dt-bindings/clock/qcom,lpasscorecc-sc7180.h + +properties: + compatible: +enum: + - qcom,sc7180-lpasshm + - qcom,sc7180-lpasscorecc + + clocks: +items: + - description: gcc_lpass_sway clock from GCC + + clock-names: +items: + - const: iface + + power-domains: +maxItems: 1 + + '#clock-cells': +const: 1 + + '#power-domain-cells': +const: 1 + + reg: +maxItems: 2 +items: + - description: lpass core cc register + - description: lpass audio cc register + + reg-names: +items: + - const: lpass_core_cc + - const: lpass_audio_cc + +if: + properties: +compatible: + contains: +const: qcom,sc7180-lpasshm +then: + properties: +reg: + maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | +#include +#include +clock-controller@6300 { + compatible = "qcom,sc7180-lpasshm"; +reg = <0 0x6300 0 0x28>; +clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>; +clock-names = "iface"; +#clock-cells = <1>; +#power-domain-cells = <1>; +}; + + - | +clock-controller@62d0 { +compatible = "qcom,sc7180-lpasscorecc"; +reg = <0 0x62d0 0 0x5>, +<0 0x6278 0 0x3>; +reg-names = "lpass_core_cc", "lpass_audio_cc"; +clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>; +clock-names = "iface"; +power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>; +#clock-cells = <1>; +#power-domain-cells = <1>; +}; +... diff --git a/include/dt-bindings/clock/qcom,gcc-sc7180.h b/include/dt-bindings/clock/qcom,gcc-sc7180.h index 992b67b..bdf43adc 100644 --- a/include/dt-bindings/clock/qcom,gcc-sc7180.h +++ b/include/dt-bindings/clock/qcom,gcc-sc7180.h @@ -138,6 +138,7 @@ #define GCC_MSS_Q6_MEMNOC_AXI_CLK 128 #define GCC_MSS_SNOC_AXI_CLK 129 #define GCC_SEC_CTRL_CLK_SRC 130 +#define GCC_LPASS_CFG_NOC_SWAY_CLK 131 /* GCC resets */ #define GCC_QUSB2PHY_PRIM_BCR 0 diff --git a/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h b/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h new file mode 100644 index 000..a55d01d --- /dev/null +++ b/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H +#define _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H + +/* LPASS_CORE_CC clocks */ +#define LPASS_LPAAUDIO_DIG_PLL 0 +#define LPASS_LPAAUDIO_DIG_PLL_OUT_ODD 1 +#define CORE_CLK_SRC 2 +#define EXT_MCLK0_CLK_SRC 3 +#define LPAIF_PRI_CLK_SRC 4 +#define LPAIF_SEC_CLK_SRC 5 +#define LPASS_AUDIO_CORE_CORE_CLK 6 +#define LPASS_AUDIO_CORE_EXT_MCLK0_CLK 7 +#define LPASS_AUDIO_CORE_LPAIF_PRI_IBIT_CLK8 +#define LPASS_AUDIO_CORE_LPAIF_SEC_IBIT_CLK9 +#define LPASS_AUDIO_CORE_SYSNOC_MPORT_CORE
[PATCH v3 4/4] clk: qcom: lpass: Add support for LPASS clock controller for SC7180
The Low Power Audio subsystem clocks are required for Audio client to be able to request for the clocks and power domains. Signed-off-by: Taniya Das --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/lpasscorecc-sc7180.c | 478 ++ 3 files changed, 488 insertions(+) create mode 100644 drivers/clk/qcom/lpasscorecc-sc7180.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index cde6ca9..d92166a 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -280,6 +280,15 @@ config SC_GCC_7180 Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDCC, etc. +config SC_LPASS_CORECC_7180 + tristate "SC7180 LPASS Core Clock Controller" + select SC_GCC_7180 + help + Support for the LPASS(Low Power Audio Subsystem) core clock controller + on SC7180 devices. + Say Y if you want to use LPASS clocks and power domains of the LPASS + core clock controller. + config SC_GPUCC_7180 tristate "SC7180 Graphics Clock Controller" select SC_GCC_7180 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 7ec8561..5668797 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o +obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c new file mode 100644 index 000..fd8537c --- /dev/null +++ b/drivers/clk/qcom/lpasscorecc-sc7180.c @@ -0,0 +1,478 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, + P_SLEEP_CLK, +}; + +static struct pll_vco fabia_vco[] = { + { 24960, 20, 0 }, +}; + +static const struct alpha_pll_config lpass_lpaaudio_dig_pll_config = { + .l = 0x20, + .alpha = 0x0, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x2067, + .test_ctl_val = 0x4000, + .test_ctl_hi_val = 0x, + .user_ctl_val = 0x5105, + .user_ctl_hi_val = 0x4805, +}; + +static const u8 clk_alpha_pll_regs_offset[][PLL_OFF_MAX_REGS] = { + [CLK_ALPHA_PLL_TYPE_FABIA] = { + [PLL_OFF_L_VAL] = 0x04, + [PLL_OFF_CAL_L_VAL] = 0x8, + [PLL_OFF_USER_CTL] = 0x0c, + [PLL_OFF_USER_CTL_U] = 0x10, + [PLL_OFF_USER_CTL_U1] = 0x14, + [PLL_OFF_CONFIG_CTL] = 0x18, + [PLL_OFF_CONFIG_CTL_U] = 0x1C, + [PLL_OFF_CONFIG_CTL_U1] = 0x20, + [PLL_OFF_TEST_CTL] = 0x24, + [PLL_OFF_TEST_CTL_U] = 0x28, + [PLL_OFF_STATUS] = 0x30, + [PLL_OFF_OPMODE] = 0x38, + [PLL_OFF_FRAC] = 0x40, + }, +}; + +static struct clk_alpha_pll lpass_lpaaudio_dig_pll = { + .offset = 0x1000, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "lpass_lpaaudio_dig_pll", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table + post_div_table_lpass_lpaaudio_dig_pll_out_odd[] = { + { 0x5, 5 }, + { } +}; + +static struct clk_alpha_pll_postdiv lpass_lpaaudio_dig_pll_out_odd = { + .offset = 0x1000, + .post_div_shift = 12, + .post_div_table = post_div_table_lpass_lpaaudio_dig_pll_out_odd, + .num_post_div = + ARRAY_SIZE(post_div_table_lpass_lpaaudio_dig_pll_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "lpass_lpaaudio_dig_pll_out_
[PATCH v3 3/4] clk: qcom: gcc: Add support for GCC LPASS clock for SC7180
Add the GCC lpass clock which is required to access the LPASS core clocks. Signed-off-by: Taniya Das --- drivers/clk/qcom/gcc-sc7180.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index ca4383e..8d3b161 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -2251,6 +2251,19 @@ static struct clk_branch gcc_mss_q6_memnoc_axi_clk = { }, }; +static struct clk_branch gcc_lpass_cfg_noc_sway_clk = { + .halt_reg = 0x47018, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x47018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_cfg_noc_sway_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct gdsc ufs_phy_gdsc = { .gdscr = 0x77004, .pd = { @@ -2428,6 +2441,7 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { [GCC_MSS_Q6_MEMNOC_AXI_CLK] = &gcc_mss_q6_memnoc_axi_clk.clkr, [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, [GCC_SEC_CTRL_CLK_SRC] = &gcc_sec_ctrl_clk_src.clkr, + [GCC_LPASS_CFG_NOC_SWAY_CLK] = &gcc_lpass_cfg_noc_sway_clk.clkr, }; static const struct qcom_reset_map gcc_sc7180_resets[] = { -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
Re: [PATCH v2 4/4] clk: qcom: lpass: Add support for LPASS clock controller for SC7180
Thanks for your review. On 5/27/2020 8:40 AM, Stephen Boyd wrote: Quoting Taniya Das (2020-05-17 02:22:24) diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c new file mode 100644 index 000..86e3599 --- /dev/null +++ b/drivers/clk/qcom/lpasscorecc-sc7180.c @@ -0,0 +1,479 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, + P_SLEEP_CLK, +}; + +static struct pll_vco fabia_vco[] = { + { 24960, 20, 0 }, +}; + +static const struct alpha_pll_config lpass_lpaaudio_dig_pll_config = { + .l = 0x20, [...] + +static struct regmap_config lpass_core_cc_sc7180_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, +}; + +static const struct qcom_cc_desc lpass_core_hm_sc7180_desc = { + .config = &lpass_core_cc_sc7180_regmap_config, + .gdscs = lpass_core_hm_sc7180_gdscs, + .num_gdscs = ARRAY_SIZE(lpass_core_hm_sc7180_gdscs), +}; + +static const struct qcom_cc_desc lpass_core_cc_sc7180_desc = { + .config = &lpass_core_cc_sc7180_regmap_config, + .clks = lpass_core_cc_sc7180_clocks, + .num_clks = ARRAY_SIZE(lpass_core_cc_sc7180_clocks), +}; + +static const struct qcom_cc_desc lpass_audio_hm_sc7180_desc = { + .config = &lpass_core_cc_sc7180_regmap_config, + .gdscs = lpass_audio_hm_sc7180_gdscs, + .num_gdscs = ARRAY_SIZE(lpass_audio_hm_sc7180_gdscs), +}; + + Drop double newline please. Done. +static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) +{ + const struct qcom_cc_desc *desc; + struct regmap *regmap; + int ret; + + lpass_core_cc_sc7180_regmap_config.name = "lpass_audio_cc"; + desc = &lpass_audio_hm_sc7180_desc; + ret = qcom_cc_probe_by_index(pdev, 1, desc); + if (ret) + return ret; + + lpass_core_cc_sc7180_regmap_config.name = "lpass_core_cc"; + regmap = qcom_cc_map(pdev, &lpass_core_cc_sc7180_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* +* Keep the CLK always-ON Why? Presumably to make sure we can access the lpass sysnoc path all the time? This is an always ON clock from HW, just making sure to keep it enabled. +* LPASS_AUDIO_CORE_SYSNOC_SWAY_CORE_CLK +*/ + regmap_update_bits(regmap, 0x24000, BIT(0), BIT(0)); + + /* PLL settings */ + regmap_write(regmap, 0x1008, 0x20); + regmap_update_bits(regmap, 0x1014, BIT(0), BIT(0)); + + clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap, + &lpass_lpaaudio_dig_pll_config); + + return qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap); +} + +static int lpass_hm_core_probe(struct platform_device *pdev) +{ + const struct qcom_cc_desc *desc; + int ret; + + lpass_core_cc_sc7180_regmap_config.name = "lpass_hm_core"; + desc = &lpass_core_hm_sc7180_desc; + + return qcom_cc_probe_by_index(pdev, 0, desc); +} + +static const struct of_device_id lpass_core_cc_sc7180_match_table[] = { + { + .compatible = "qcom,sc7180-lpasshm", + .data = lpass_hm_core_probe, + }, + { + .compatible = "qcom,sc7180-lpasscorecc", + .data = lpass_core_cc_sc7180_probe, + }, + { } +}; +MODULE_DEVICE_TABLE(of, lpass_core_cc_sc7180_match_table); + +static int lpass_core_sc7180_probe(struct platform_device *pdev) +{ + int (*clk_probe)(struct platform_device *p); + int ret; + + pm_runtime_enable(&pdev->dev); + ret = pm_clk_create(&pdev->dev); + if (ret) + return ret; + + ret = pm_clk_add(&pdev->dev, "gcc_lpass_sway"); + if (ret < 0) { + dev_err(&pdev->dev, "failed to acquire iface clock\n"); Can the clk name be 'iface' if it's actually the interface clk? "gcc_lpass_sway" looks to be the actual clk name which we shouldn't care about here. It should be whatever clk name we consider it to be, which would mean iface probably. Yes would use "iface". + goto disable_pm_runtime; + } + + clk_probe = of_device_get_match_data(&pdev->dev); + if (!clk_probe) + return -EINVAL; + + ret = clk_probe(pdev); + if (ret) + goto destroy_pm_clk; + + return 0; -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
Re: [PATCH v2 2/4] dt-bindings: clock: Add YAML schemas for LPASS clocks on SC7180
Thanks for your review. On 5/29/2020 1:55 AM, Rob Herring wrote: On Sun, May 17, 2020 at 02:52:22PM +0530, Taniya Das wrote: The LPASS(Low Power Audio Subsystem) clock provider have a bunch of generic properties that are needed in a device tree. Also add clock ids for GCC LPASS and LPASS Core clock IDs for LPASS client to request for the clocks. Signed-off-by: Taniya Das --- .../bindings/clock/qcom,sc7180-lpasscorecc.yaml| 101 + include/dt-bindings/clock/qcom,gcc-sc7180.h| 1 + .../dt-bindings/clock/qcom,lpasscorecc-sc7180.h| 29 ++ 3 files changed, 131 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml create mode 100644 include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml new file mode 100644 index 000..c025a0ae --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sc7180-lpasscorecc.yaml @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sc7180-lpasscorecc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm LPASS Core Clock Controller Binding for SC7180 + +maintainers: + - Taniya Das + +description: | + Qualcomm LPASS core clock control module which supports the clocks and + power domains on SC7180. + + See also: + - dt-bindings/clock/qcom,lpasscorecc-sc7180.h + +properties: + compatible: +enum: + - qcom,sc7180-lpasshm + - qcom,sc7180-lpasscorecc + + clocks: +items: + - description: gcc_lpass_sway clock from GCC + + clock-names: +items: + - const: gcc_lpass_sway + + power-domains: +items: + - description: LPASS CORE HM GSDCR For single entry, 'maxItems: 1' is enough. Will take of it in the next patch. + + '#clock-cells': +const: 1 + + '#power-domain-cells': +const: 1 + + reg: +minItems: 1 +maxItems: 2 +items: + - description: lpass audio cc register + - description: lpass core cc register audio then core + + reg-names: +items: + - const: lpass_core_cc + - const: lpass_audio_cc core then audio? My bad, will take care of it. 2 reg-names required, but 1 reg allowed? Update to use maxItems: 2 in the next patch. + +if: + properties: +compatible: + contains: +const: qcom,sc7180-lpasshm +then: + properties: +reg: + items: +- description: lpass hm core register reg-names allowed in this case? Ideally, this would have just 'maxItems: 1' to just disallow the 2nd entry above. Yes, I would take care of this too. + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | +#include +#include +clock-controller@6300 { + compatible = "qcom,sc7180-lpasshm"; +reg = <0 0x6300 0 0x28>; +clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>; +clock-names = "gcc_lpass_sway"; +#clock-cells = <1>; +#power-domain-cells = <1>; +}; + + - | +clock-controller@62d0 { +compatible = "qcom,sc7180-lpasscorecc"; +reg = <0 0x62d0 0 0x5>, +<0 0x6278 0 0x3>; +reg-names = "lpass_core_cc", "lpass_audio_cc"; +clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>; +clock-names = "gcc_lpass_sway"; +power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>; +#clock-cells = <1>; +#power-domain-cells = <1>; +}; +... diff --git a/include/dt-bindings/clock/qcom,gcc-sc7180.h b/include/dt-bindings/clock/qcom,gcc-sc7180.h index 1258fd0..439476c 100644 --- a/include/dt-bindings/clock/qcom,gcc-sc7180.h +++ b/include/dt-bindings/clock/qcom,gcc-sc7180.h @@ -137,6 +137,7 @@ #define GCC_MSS_NAV_AXI_CLK 127 #define GCC_MSS_Q6_MEMNOC_AXI_CLK 128 #define GCC_MSS_SNOC_AXI_CLK 129 +#define GCC_LPASS_CFG_NOC_SWAY_CLK 130 /* GCC resets */ #define GCC_QUSB2PHY_PRIM_BCR 0 diff --git a/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h b/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h new file mode 100644 index 000..a55d01d --- /dev/null +++ b/include/dt-bindings/clock/qcom,lpasscorecc-sc7180.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_LPASS_CORE_CC_SC7180_H +#define _DT_BIN
Re: [PATCH v2 2/4] dt-bindings: clock: Add YAML schemas for LPASS clocks on SC7180
Thanks for the review. On 5/27/2020 8:41 AM, Stephen Boyd wrote: + clocks: +items: + - description: gcc_lpass_sway clock from GCC + + clock-names: +items: + - const: gcc_lpass_sway As said on patch #4, maybe "iface" instead? Will take care in the next patch. + + power-domains: +items: + - description: LPASS CORE HM GSDCR + -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
[PATCH v2 1/3] clk: qcom: gcc: Add support for a new frequency for SC7180
There is a requirement to support 51.2MHz from GPLL6 for qup clocks, thus update the frequency table and parent data/map to use the GPLL6 source PLL. Fixes: 17269568f7267 ("clk: qcom: Add Global Clock controller (GCC) driver for SC7180") Signed-off-by: Taniya Das --- drivers/clk/qcom/gcc-sc7180.c | 73 ++- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index 6a51b5b..7338052 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -390,6 +390,7 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { F(29491200, P_GPLL0_OUT_EVEN, 1, 1536, 15625), F(3200, P_GPLL0_OUT_EVEN, 1, 8, 75), F(4800, P_GPLL0_OUT_EVEN, 1, 4, 25), + F(5120, P_GPLL6_OUT_MAIN, 7.5, 0, 0), F(6400, P_GPLL0_OUT_EVEN, 1, 16, 75), F(7500, P_GPLL0_OUT_EVEN, 4, 0, 0), F(8000, P_GPLL0_OUT_EVEN, 1, 4, 15), @@ -405,8 +406,8 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { .name = "gcc_qupv3_wrap0_s0_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = 4, + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), .ops = &clk_rcg2_ops, }; @@ -414,15 +415,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { .cmd_rcgr = 0x17034, .mnd_width = 16, .hid_width = 5, - .parent_map = gcc_parent_map_0, + .parent_map = gcc_parent_map_1, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init, }; static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { .name = "gcc_qupv3_wrap0_s1_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = 4, + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), .ops = &clk_rcg2_ops, }; @@ -430,15 +431,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { .cmd_rcgr = 0x17164, .mnd_width = 16, .hid_width = 5, - .parent_map = gcc_parent_map_0, + .parent_map = gcc_parent_map_1, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init, }; static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { .name = "gcc_qupv3_wrap0_s2_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = 4, + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), .ops = &clk_rcg2_ops, }; @@ -446,15 +447,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { .cmd_rcgr = 0x17294, .mnd_width = 16, .hid_width = 5, - .parent_map = gcc_parent_map_0, + .parent_map = gcc_parent_map_1, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init, }; static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { .name = "gcc_qupv3_wrap0_s3_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = 4, + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), .ops = &clk_rcg2_ops, }; @@ -462,15 +463,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { .cmd_rcgr = 0x173c4, .mnd_width = 16, .hid_width = 5, - .parent_map = gcc_parent_map_0, + .parent_map = gcc_parent_map_1, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init, }; static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { .name = "gcc_qupv3_wrap0_s4_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = 4, + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), .ops = &clk_rcg2_ops, }; @@ -478,15 +479,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { .cmd_rcgr = 0x174f4, .mnd_width = 16, .hid_width = 5, - .parent_map = gcc_parent_map_0, + .parent_map = gcc_parent_map_1, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init, }; static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { .name = "gcc_qupv3_wrap0_s5_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = 4, + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), .ops = &clk_rcg2_ops, }; @@ -494,15 +495,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { .cmd_rcgr = 0x17624, .mnd_width = 16,
[PATCH v2 2/3] dt-bindings: clock: Add gcc_sec_ctrl_clk_src clock ID
The gcc_sec_ctrl_clk_src clock is required to be controlled by the secure controller driver. Signed-off-by: Taniya Das --- include/dt-bindings/clock/qcom,gcc-sc7180.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/clock/qcom,gcc-sc7180.h b/include/dt-bindings/clock/qcom,gcc-sc7180.h index 1258fd0..992b67b 100644 --- a/include/dt-bindings/clock/qcom,gcc-sc7180.h +++ b/include/dt-bindings/clock/qcom,gcc-sc7180.h @@ -137,6 +137,7 @@ #define GCC_MSS_NAV_AXI_CLK127 #define GCC_MSS_Q6_MEMNOC_AXI_CLK 128 #define GCC_MSS_SNOC_AXI_CLK 129 +#define GCC_SEC_CTRL_CLK_SRC 130 /* GCC resets */ #define GCC_QUSB2PHY_PRIM_BCR 0 -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v2 3/3] clk: qcom: gcc: Add support for Secure control source clock
The secure controller driver requires to request for various frequencies on the source clock, thus add support for the same. Signed-off-by: Taniya Das --- drivers/clk/qcom/gcc-sc7180.c | 21 + 1 file changed, 21 insertions(+) diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index 7338052..ca4383e 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -817,6 +817,26 @@ static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { }, }; +static const struct freq_tbl ftbl_gcc_sec_ctrl_clk_src[] = { + F(480, P_BI_TCXO, 4, 0, 0), + F(1920, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sec_ctrl_clk_src = { + .cmd_rcgr = 0x3d030, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_sec_ctrl_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sec_ctrl_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_ops, + }, +}; + static struct clk_branch gcc_aggre_ufs_phy_axi_clk = { .halt_reg = 0x82024, .halt_check = BRANCH_HALT_DELAY, @@ -2407,6 +2427,7 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { [GCC_MSS_NAV_AXI_CLK] = &gcc_mss_nav_axi_clk.clkr, [GCC_MSS_Q6_MEMNOC_AXI_CLK] = &gcc_mss_q6_memnoc_axi_clk.clkr, [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, + [GCC_SEC_CTRL_CLK_SRC] = &gcc_sec_ctrl_clk_src.clkr, }; static const struct qcom_reset_map gcc_sc7180_resets[] = { -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v2 0/3] Add Misc GCC clock driver support for SC7180
[v2] * Update to use ARRAY_SIZE instead of hard-coded values for num_parents. Also add the fixes tag. [v1] * Add a new frequency of 51.2MHz for QUP clock. * Add support for gcc_sec_ctrl_clk_src RCG for client to be able to request various frequencies. Taniya Das (3): clk: qcom: gcc: Add support for a new frequency for SC7180 dt-bindings: clock: Add gcc_sec_ctrl_clk_src clock ID clk: qcom: gcc: Add support for Secure control source clock drivers/clk/qcom/gcc-sc7180.c | 94 ++--- include/dt-bindings/clock/qcom,gcc-sc7180.h | 1 + 2 files changed, 59 insertions(+), 36 deletions(-) -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
Re: [PATCH v1 3/3] clk: qcom: gcc: Add support for Secure control source clock
Hello Stephen, Thanks for your review. On 3/16/2020 11:19 PM, Stephen Boyd wrote: Quoting Taniya Das (2020-03-16 03:54:42) diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index ad75847..3302f19 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -817,6 +817,26 @@ static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { }, }; +static const struct freq_tbl ftbl_gcc_sec_ctrl_clk_src[] = { + F(480, P_BI_TCXO, 4, 0, 0), + F(1920, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sec_ctrl_clk_src = { + .cmd_rcgr = 0x3d030, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_sec_ctrl_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sec_ctrl_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = 3, ARRAY_SIZE please. Will take care of the same. + .ops = &clk_rcg2_ops, + }, +}; + static struct clk_branch gcc_aggre_ufs_phy_axi_clk = { .halt_reg = 0x82024, .halt_check = BRANCH_HALT_DELAY, -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation. --
Re: [PATCH v1 1/3] clk: qcom: gcc: Add support for a new frequency for SC7180
Hello Stephen, Thanks for your review. On 3/16/2020 11:19 PM, Stephen Boyd wrote: Quoting Taniya Das (2020-03-16 03:54:40) There is a requirement to support 51.2MHz from GPLL6 for qup clocks, thus update the frequency table and parent data/map to use the GPLL6 source PLL. Signed-off-by: Taniya Das --- Any Fixes: tag for this? I guess the beginning of this driver being introduced? Sure, will add the same. drivers/clk/qcom/gcc-sc7180.c | 73 ++- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index 7f59fb8..ad75847 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -405,8 +406,8 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { .name = "gcc_qupv3_wrap0_s0_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = 4, + .parent_data = gcc_parent_data_1, This should have been done initially. We shouldn't need to describe "new" parents when they have always been there. Are there other clks in this driver that actually have more parents than we've currently described? If so, please fix them. The auto generation script does not consider to define the parent unless it is used in the frequency table to derive a frequency. For now I didn't find any other sources missed. + .num_parents = 5, Can you use ARRAY_SIZE(gcc_parent_data_1) instead? That way this isn't a hard-coded value. Yes will take care of it too. .ops = &clk_rcg2_ops, }; -- 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 retention of GSDCR
Add support for the RETAIN_FF_ENABLE feature which enables the usage of retention registers. These registers maintain their state after disabling and re-enabling a GDSC. Signed-off-by: Taniya Das --- drivers/clk/qcom/gdsc.c | 12 drivers/clk/qcom/gdsc.h | 1 + 2 files changed, 13 insertions(+) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index a250f59..9983456 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -28,6 +28,7 @@ /* CFG_GDSCR */ #define GDSC_POWER_UP_COMPLETE BIT(16) #define GDSC_POWER_DOWN_COMPLETE BIT(15) +#define GDSC_RETAIN_FF_ENABLE BIT(11) #define CFG_GDSCR_OFFSET 0x4 /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */ @@ -202,6 +203,14 @@ static inline void gdsc_assert_reset_aon(struct gdsc *sc) regmap_update_bits(sc->regmap, sc->clamp_io_ctrl, GMEM_RESET_MASK, 0); } + +static void gdsc_retain_ff_on(struct gdsc *sc) +{ + u32 mask = GDSC_RETAIN_FF_ENABLE; + + regmap_update_bits(sc->regmap, sc->gdscr, mask, mask); +} + static int gdsc_enable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); @@ -254,6 +263,9 @@ static int gdsc_enable(struct generic_pm_domain *domain) udelay(1); } + if (sc->flags & RETAIN_FF_ENABLE) + gdsc_retain_ff_on(sc); + return 0; } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index 64cdc8c..8604d44 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -49,6 +49,7 @@ struct gdsc { #define AON_RESET BIT(4) #define POLL_CFG_GDSCR BIT(5) #define ALWAYS_ON BIT(6) +#define RETAIN_FF_ENABLE BIT(7) struct reset_controller_dev *rcdev; unsigned int*resets; unsigned intreset_count; -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v2 3/4] clk: qcom: gcc: Add support for GCC LPASS clock for SC7180
Add the GCC lpass clock which is required to access the LPASS core clocks. Signed-off-by: Taniya Das --- drivers/clk/qcom/gcc-sc7180.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index 6a51b5b..d970647 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -2230,6 +2230,19 @@ static struct clk_branch gcc_mss_q6_memnoc_axi_clk = { }, }; +static struct clk_branch gcc_lpass_cfg_noc_sway_clk = { + .halt_reg = 0x47018, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x47018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_cfg_noc_sway_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct gdsc ufs_phy_gdsc = { .gdscr = 0x77004, .pd = { @@ -2406,6 +2419,7 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { [GCC_MSS_NAV_AXI_CLK] = &gcc_mss_nav_axi_clk.clkr, [GCC_MSS_Q6_MEMNOC_AXI_CLK] = &gcc_mss_q6_memnoc_axi_clk.clkr, [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, + [GCC_LPASS_CFG_NOC_SWAY_CLK] = &gcc_lpass_cfg_noc_sway_clk.clkr, }; static const struct qcom_reset_map gcc_sc7180_resets[] = { -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.