diff options
45 files changed, 635 insertions, 396 deletions
diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml index 5d17bdcfdf70..73f809cdb783 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml @@ -25,14 +25,20 @@ properties: - const: qcom,msm8998-bwmon # BWMON v4 - items: - enum: + - qcom,sc7180-cpu-bwmon - qcom,sc7280-cpu-bwmon - qcom,sc8280xp-cpu-bwmon - qcom,sdm845-cpu-bwmon + - qcom,sm6350-llcc-bwmon + - qcom,sm8250-cpu-bwmon - qcom,sm8550-cpu-bwmon - const: qcom,sdm845-bwmon # BWMON v4, unified register space - items: - enum: + - qcom,sc7180-llcc-bwmon - qcom,sc8280xp-llcc-bwmon + - qcom,sm6350-cpu-bwmon + - qcom,sm8250-llcc-bwmon - qcom,sm8550-llcc-bwmon - const: qcom,sc7280-llcc-bwmon - const: qcom,sc7280-llcc-bwmon # BWMON v5 diff --git a/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml b/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml index 9d0a98d77ae9..21dae0b92819 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml @@ -21,6 +21,7 @@ properties: - enum: - qcom,sc7180-osm-l3 - qcom,sc8180x-osm-l3 + - qcom,sdm670-osm-l3 - qcom,sdm845-osm-l3 - qcom,sm6350-osm-l3 - qcom,sm8150-osm-l3 diff --git a/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml index 4d93ad415e0b..a46497af1fd8 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml @@ -18,9 +18,6 @@ description: | least one RPMh device child node pertaining to their RSC and each provider can map to multiple RPMh resources. -allOf: - - $ref: qcom,rpmh-common.yaml# - properties: reg: maxItems: 1 @@ -91,6 +88,7 @@ properties: - qcom,sm8250-mc-virt - qcom,sm8250-mmss-noc - qcom,sm8250-npu-noc + - qcom,sm8250-qup-virt - qcom,sm8250-system-noc - qcom,sm8350-aggre1-noc - qcom,sm8350-aggre2-noc @@ -107,7 +105,19 @@ properties: required: - compatible - - reg + +allOf: + - $ref: qcom,rpmh-common.yaml# + - if: + not: + properties: + compatible: + enum: + - qcom,sm8250-qup-virt + then: + required: + - reg + unevaluatedProperties: false diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index e4de74b68797..997c2b89a5d1 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -18,13 +18,6 @@ #include <dt-bindings/clock/qcom,rpmcc.h> -#define QCOM_RPM_KEY_SOFTWARE_ENABLE 0x6e657773 -#define QCOM_RPM_KEY_PIN_CTRL_CLK_BUFFER_ENABLE_KEY 0x62636370 -#define QCOM_RPM_SMD_KEY_RATE 0x007a484b -#define QCOM_RPM_SMD_KEY_ENABLE 0x62616e45 -#define QCOM_RPM_SMD_KEY_STATE 0x54415453 -#define QCOM_RPM_SCALING_ENABLE_ID 0x2 - #define __DEFINE_CLK_SMD_RPM_PREFIX(_prefix, _name, _active, \ type, r_id, key) \ static struct clk_smd_rpm clk_smd_rpm_##_prefix##_active; \ @@ -171,21 +164,23 @@ struct clk_smd_rpm { unsigned long rate; }; -struct clk_smd_rpm_req { - __le32 key; - __le32 nbytes; - __le32 value; -}; - struct rpm_smd_clk_desc { struct clk_smd_rpm **clks; size_t num_clks; + + /* + * Interconnect clocks are managed by the icc framework, this driver + * only kickstarts them so that they don't get gated between + * clk_smd_rpm_enable_scaling() and interconnect driver initialization. + */ + const struct clk_smd_rpm ** const icc_clks; + size_t num_icc_clks; bool scaling_before_handover; }; static DEFINE_MUTEX(rpm_smd_clk_lock); -static int clk_smd_rpm_handoff(struct clk_smd_rpm *r) +static int clk_smd_rpm_handoff(const struct clk_smd_rpm *r) { int ret; struct clk_smd_rpm_req req = { @@ -511,13 +506,69 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER(div_clk1, 11, 19200000); DEFINE_CLK_SMD_RPM_XO_BUFFER(div_clk2, 12, 19200000); DEFINE_CLK_SMD_RPM_XO_BUFFER(div_clk3, 13, 19200000); +static const struct clk_smd_rpm *bimc_pcnoc_icc_clks[] = { + &clk_smd_rpm_bimc_clk, + &clk_smd_rpm_bus_0_pcnoc_clk, +}; + +static const struct clk_smd_rpm *bimc_pcnoc_snoc_icc_clks[] = { + &clk_smd_rpm_bimc_clk, + &clk_smd_rpm_bus_0_pcnoc_clk, + &clk_smd_rpm_bus_1_snoc_clk, +}; + +static const struct clk_smd_rpm *bimc_pcnoc_snoc_smmnoc_icc_clks[] = { + &clk_smd_rpm_bimc_clk, + &clk_smd_rpm_bus_0_pcnoc_clk, + &clk_smd_rpm_bus_1_snoc_clk, + &clk_smd_rpm_bus_2_sysmmnoc_clk, +}; + +static const struct clk_smd_rpm *bimc_pcnoc_snoc_cnoc_ocmem_icc_clks[] = { + &clk_smd_rpm_bimc_clk, + &clk_smd_rpm_bus_0_pcnoc_clk, + &clk_smd_rpm_bus_1_snoc_clk, + &clk_smd_rpm_bus_2_cnoc_clk, + &clk_smd_rpm_ocmemgx_clk, +}; + +static const struct clk_smd_rpm *msm8996_icc_clks[] = { + &clk_smd_rpm_bimc_clk, + &clk_smd_rpm_branch_aggre1_noc_clk, + &clk_smd_rpm_branch_aggre2_noc_clk, + &clk_smd_rpm_bus_0_pcnoc_clk, + &clk_smd_rpm_bus_1_snoc_clk, + &clk_smd_rpm_bus_2_cnoc_clk, + &clk_smd_rpm_mmssnoc_axi_rpm_clk, +}; + +static const struct clk_smd_rpm *msm8998_icc_clks[] = { + &clk_smd_rpm_aggre1_noc_clk, + &clk_smd_rpm_aggre2_noc_clk, + &clk_smd_rpm_bimc_clk, + &clk_smd_rpm_bus_1_snoc_clk, + &clk_smd_rpm_bus_2_cnoc_clk, + &clk_smd_rpm_mmssnoc_axi_rpm_clk, +}; + +static const struct clk_smd_rpm *sdm660_icc_clks[] = { + &clk_smd_rpm_aggre2_noc_clk, + &clk_smd_rpm_bimc_clk, + &clk_smd_rpm_bus_1_snoc_clk, + &clk_smd_rpm_bus_2_cnoc_clk, + &clk_smd_rpm_mmssnoc_axi_rpm_clk, +}; + +static const struct clk_smd_rpm *sm_qnoc_icc_clks[] = { + &clk_smd_rpm_bimc_clk, + &clk_smd_rpm_bus_1_cnoc_clk, + &clk_smd_rpm_mmnrt_clk, + &clk_smd_rpm_mmrt_clk, + &clk_smd_rpm_qup_clk, + &clk_smd_rpm_bus_2_snoc_clk, +}; + static struct clk_smd_rpm *msm8909_clks[] = { - [RPM_SMD_PCNOC_CLK] = &clk_smd_rpm_bus_0_pcnoc_clk, - [RPM_SMD_PCNOC_A_CLK] = &clk_smd_rpm_bus_0_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_1_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_1_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, [RPM_SMD_QPIC_CLK] = &clk_smd_rpm_qpic_clk, [RPM_SMD_QPIC_CLK_A] = &clk_smd_rpm_qpic_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk, @@ -543,15 +594,11 @@ static struct clk_smd_rpm *msm8909_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_msm8909 = { .clks = msm8909_clks, .num_clks = ARRAY_SIZE(msm8909_clks), + .icc_clks = bimc_pcnoc_snoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_icc_clks), }; static struct clk_smd_rpm *msm8916_clks[] = { - [RPM_SMD_PCNOC_CLK] = &clk_smd_rpm_bus_0_pcnoc_clk, - [RPM_SMD_PCNOC_A_CLK] = &clk_smd_rpm_bus_0_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_1_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_1_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk, [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_qdss_a_clk, [RPM_SMD_BB_CLK1] = &clk_smd_rpm_bb_clk1, @@ -575,21 +622,15 @@ static struct clk_smd_rpm *msm8916_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_msm8916 = { .clks = msm8916_clks, .num_clks = ARRAY_SIZE(msm8916_clks), + .icc_clks = bimc_pcnoc_snoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_icc_clks), }; static struct clk_smd_rpm *msm8917_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_PNOC_CLK] = &clk_smd_rpm_bus_0_pcnoc_clk, - [RPM_SMD_PNOC_A_CLK] = &clk_smd_rpm_bus_0_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_1_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_1_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, [RPM_SMD_BIMC_GPU_CLK] = &clk_smd_rpm_bimc_gpu_clk, [RPM_SMD_BIMC_GPU_A_CLK] = &clk_smd_rpm_bimc_gpu_a_clk, - [RPM_SMD_SYSMMNOC_CLK] = &clk_smd_rpm_bus_2_sysmmnoc_clk, - [RPM_SMD_SYSMMNOC_A_CLK] = &clk_smd_rpm_bus_2_sysmmnoc_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk, [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_qdss_a_clk, [RPM_SMD_BB_CLK1] = &clk_smd_rpm_bb_clk1, @@ -609,19 +650,13 @@ static struct clk_smd_rpm *msm8917_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_msm8917 = { .clks = msm8917_clks, .num_clks = ARRAY_SIZE(msm8917_clks), + .icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks), }; static struct clk_smd_rpm *msm8936_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_PCNOC_CLK] = &clk_smd_rpm_bus_0_pcnoc_clk, - [RPM_SMD_PCNOC_A_CLK] = &clk_smd_rpm_bus_0_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_1_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_1_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, - [RPM_SMD_SYSMMNOC_CLK] = &clk_smd_rpm_bus_2_sysmmnoc_clk, - [RPM_SMD_SYSMMNOC_A_CLK] = &clk_smd_rpm_bus_2_sysmmnoc_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk, [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_qdss_a_clk, [RPM_SMD_BB_CLK1] = &clk_smd_rpm_bb_clk1, @@ -645,25 +680,17 @@ static struct clk_smd_rpm *msm8936_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_msm8936 = { .clks = msm8936_clks, .num_clks = ARRAY_SIZE(msm8936_clks), + .icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks), }; static struct clk_smd_rpm *msm8974_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_PNOC_CLK] = &clk_smd_rpm_bus_0_pcnoc_clk, - [RPM_SMD_PNOC_A_CLK] = &clk_smd_rpm_bus_0_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_1_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_1_snoc_a_clk, - [RPM_SMD_CNOC_CLK] = &clk_smd_rpm_bus_2_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &clk_smd_rpm_bus_2_cnoc_a_clk, [RPM_SMD_MMSSNOC_AHB_CLK] = &clk_smd_rpm_bus_3_mmssnoc_ahb_clk, [RPM_SMD_MMSSNOC_AHB_A_CLK] = &clk_smd_rpm_bus_3_mmssnoc_ahb_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, [RPM_SMD_GFX3D_CLK_SRC] = &clk_smd_rpm_gfx3d_clk_src, [RPM_SMD_GFX3D_A_CLK_SRC] = &clk_smd_rpm_gfx3d_a_clk_src, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, - [RPM_SMD_OCMEMGX_CLK] = &clk_smd_rpm_ocmemgx_clk, - [RPM_SMD_OCMEMGX_A_CLK] = &clk_smd_rpm_ocmemgx_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk, [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_qdss_a_clk, [RPM_SMD_CXO_D0] = &clk_smd_rpm_cxo_d0, @@ -697,20 +724,14 @@ static struct clk_smd_rpm *msm8974_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_msm8974 = { .clks = msm8974_clks, .num_clks = ARRAY_SIZE(msm8974_clks), + .icc_clks = bimc_pcnoc_snoc_cnoc_ocmem_icc_clks, + .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_cnoc_ocmem_icc_clks), .scaling_before_handover = true, }; static struct clk_smd_rpm *msm8976_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_PCNOC_CLK] = &clk_smd_rpm_bus_0_pcnoc_clk, - [RPM_SMD_PCNOC_A_CLK] = &clk_smd_rpm_bus_0_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_1_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_1_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, - [RPM_SMD_SYSMMNOC_CLK] = &clk_smd_rpm_bus_2_sysmmnoc_clk, - [RPM_SMD_SYSMMNOC_A_CLK] = &clk_smd_rpm_bus_2_sysmmnoc_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk, [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_qdss_a_clk, [RPM_SMD_BB_CLK1] = &clk_smd_rpm_bb_clk1, @@ -731,24 +752,15 @@ static struct clk_smd_rpm *msm8976_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_msm8976 = { .clks = msm8976_clks, - .num_clks = ARRAY_SIZE(msm8976_clks), + .icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks), }; static struct clk_smd_rpm *msm8992_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_PNOC_CLK] = &clk_smd_rpm_bus_0_pcnoc_clk, - [RPM_SMD_PNOC_A_CLK] = &clk_smd_rpm_bus_0_pcnoc_a_clk, - [RPM_SMD_OCMEMGX_CLK] = &clk_smd_rpm_ocmemgx_clk, - [RPM_SMD_OCMEMGX_A_CLK] = &clk_smd_rpm_ocmemgx_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, - [RPM_SMD_CNOC_CLK] = &clk_smd_rpm_bus_2_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &clk_smd_rpm_bus_2_cnoc_a_clk, [RPM_SMD_GFX3D_CLK_SRC] = &clk_smd_rpm_gfx3d_clk_src, [RPM_SMD_GFX3D_A_CLK_SRC] = &clk_smd_rpm_gfx3d_a_clk_src, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_1_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_1_snoc_a_clk, [RPM_SMD_BB_CLK1] = &clk_smd_rpm_bb_clk1, [RPM_SMD_BB_CLK1_A] = &clk_smd_rpm_bb_clk1_a, [RPM_SMD_BB_CLK1_PIN] = &clk_smd_rpm_bb_clk1_pin, @@ -790,23 +802,15 @@ static struct clk_smd_rpm *msm8992_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_msm8992 = { .clks = msm8992_clks, .num_clks = ARRAY_SIZE(msm8992_clks), + .icc_clks = bimc_pcnoc_snoc_cnoc_ocmem_icc_clks, + .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_cnoc_ocmem_icc_clks), }; static struct clk_smd_rpm *msm8994_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_PNOC_CLK] = &clk_smd_rpm_bus_0_pcnoc_clk, - [RPM_SMD_PNOC_A_CLK] = &clk_smd_rpm_bus_0_pcnoc_a_clk, - [RPM_SMD_OCMEMGX_CLK] = &clk_smd_rpm_ocmemgx_clk, - [RPM_SMD_OCMEMGX_A_CLK] = &clk_smd_rpm_ocmemgx_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, - [RPM_SMD_CNOC_CLK] = &clk_smd_rpm_bus_2_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &clk_smd_rpm_bus_2_cnoc_a_clk, [RPM_SMD_GFX3D_CLK_SRC] = &clk_smd_rpm_gfx3d_clk_src, [RPM_SMD_GFX3D_A_CLK_SRC] = &clk_smd_rpm_gfx3d_a_clk_src, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_1_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_1_snoc_a_clk, [RPM_SMD_BB_CLK1] = &clk_smd_rpm_bb_clk1, [RPM_SMD_BB_CLK1_A] = &clk_smd_rpm_bb_clk1_a, [RPM_SMD_BB_CLK1_PIN] = &clk_smd_rpm_bb_clk1_pin, @@ -850,29 +854,17 @@ static struct clk_smd_rpm *msm8994_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_msm8994 = { .clks = msm8994_clks, .num_clks = ARRAY_SIZE(msm8994_clks), + .icc_clks = bimc_pcnoc_snoc_cnoc_ocmem_icc_clks, + .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_cnoc_ocmem_icc_clks), }; static struct clk_smd_rpm *msm8996_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_PCNOC_CLK] = &clk_smd_rpm_bus_0_pcnoc_clk, - [RPM_SMD_PCNOC_A_CLK] = &clk_smd_rpm_bus_0_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_1_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_1_snoc_a_clk, - [RPM_SMD_CNOC_CLK] = &clk_smd_rpm_bus_2_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &clk_smd_rpm_bus_2_cnoc_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, - [RPM_SMD_MMAXI_CLK] = &clk_smd_rpm_mmssnoc_axi_rpm_clk, - [RPM_SMD_MMAXI_A_CLK] = &clk_smd_rpm_mmssnoc_axi_rpm_a_clk, [RPM_SMD_IPA_CLK] = &clk_smd_rpm_ipa_clk, [RPM_SMD_IPA_A_CLK] = &clk_smd_rpm_ipa_a_clk, [RPM_SMD_CE1_CLK] = &clk_smd_rpm_ce1_clk, [RPM_SMD_CE1_A_CLK] = &clk_smd_rpm_ce1_a_clk, - [RPM_SMD_AGGR1_NOC_CLK] = &clk_smd_rpm_branch_aggre1_noc_clk, - [RPM_SMD_AGGR1_NOC_A_CLK] = &clk_smd_rpm_branch_aggre1_noc_a_clk, - [RPM_SMD_AGGR2_NOC_CLK] = &clk_smd_rpm_branch_aggre2_noc_clk, - [RPM_SMD_AGGR2_NOC_A_CLK] = &clk_smd_rpm_branch_aggre2_noc_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk, [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_qdss_a_clk, [RPM_SMD_BB_CLK1] = &clk_smd_rpm_bb_clk1, @@ -904,6 +896,8 @@ static struct clk_smd_rpm *msm8996_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_msm8996 = { .clks = msm8996_clks, .num_clks = ARRAY_SIZE(msm8996_clks), + .icc_clks = msm8996_icc_clks, + .num_icc_clks = ARRAY_SIZE(msm8996_icc_clks), }; static struct clk_smd_rpm *qcs404_clks[] = { @@ -932,19 +926,15 @@ static struct clk_smd_rpm *qcs404_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_qcs404 = { .clks = qcs404_clks, .num_clks = ARRAY_SIZE(qcs404_clks), + .icc_clks = bimc_pcnoc_snoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_icc_clks), }; static struct clk_smd_rpm *msm8998_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, [RPM_SMD_PCNOC_CLK] = &clk_smd_rpm_bus_0_pcnoc_clk, [RPM_SMD_PCNOC_A_CLK] = &clk_smd_rpm_bus_0_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_1_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_1_snoc_a_clk, - [RPM_SMD_CNOC_CLK] = &clk_smd_rpm_bus_2_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &clk_smd_rpm_bus_2_cnoc_a_clk, [RPM_SMD_CE1_CLK] = &clk_smd_rpm_ce1_clk, [RPM_SMD_CE1_A_CLK] = &clk_smd_rpm_ce1_a_clk, [RPM_SMD_DIV_CLK1] = &clk_smd_rpm_div_clk1, @@ -967,12 +957,6 @@ static struct clk_smd_rpm *msm8998_clks[] = { [RPM_SMD_LN_BB_CLK2_A_PIN] = &clk_smd_rpm_ln_bb_clk2_a_pin, [RPM_SMD_LN_BB_CLK3_PIN] = &clk_smd_rpm_ln_bb_clk3_pin, [RPM_SMD_LN_BB_CLK3_A_PIN] = &clk_smd_rpm_ln_bb_clk3_a_pin, - [RPM_SMD_MMAXI_CLK] = &clk_smd_rpm_mmssnoc_axi_rpm_clk, - [RPM_SMD_MMAXI_A_CLK] = &clk_smd_rpm_mmssnoc_axi_rpm_a_clk, - [RPM_SMD_AGGR1_NOC_CLK] = &clk_smd_rpm_aggre1_noc_clk, - [RPM_SMD_AGGR1_NOC_A_CLK] = &clk_smd_rpm_aggre1_noc_a_clk, - [RPM_SMD_AGGR2_NOC_CLK] = &clk_smd_rpm_aggre2_noc_clk, - [RPM_SMD_AGGR2_NOC_A_CLK] = &clk_smd_rpm_aggre2_noc_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk, [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_qdss_a_clk, [RPM_SMD_RF_CLK1] = &clk_smd_rpm_rf_clk1, @@ -992,27 +976,19 @@ static struct clk_smd_rpm *msm8998_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_msm8998 = { .clks = msm8998_clks, .num_clks = ARRAY_SIZE(msm8998_clks), + .icc_clks = msm8998_icc_clks, + .num_icc_clks = ARRAY_SIZE(msm8998_icc_clks), }; static struct clk_smd_rpm *sdm660_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_1_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_1_snoc_a_clk, - [RPM_SMD_CNOC_CLK] = &clk_smd_rpm_bus_2_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &clk_smd_rpm_bus_2_cnoc_a_clk, [RPM_SMD_CNOC_PERIPH_CLK] = &clk_smd_rpm_bus_0_pcnoc_clk, [RPM_SMD_CNOC_PERIPH_A_CLK] = &clk_smd_rpm_bus_0_pcnoc_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, - [RPM_SMD_MMSSNOC_AXI_CLK] = &clk_smd_rpm_mmssnoc_axi_rpm_clk, - [RPM_SMD_MMSSNOC_AXI_CLK_A] = &clk_smd_rpm_mmssnoc_axi_rpm_a_clk, [RPM_SMD_IPA_CLK] = &clk_smd_rpm_ipa_clk, [RPM_SMD_IPA_A_CLK] = &clk_smd_rpm_ipa_a_clk, [RPM_SMD_CE1_CLK] = &clk_smd_rpm_ce1_clk, [RPM_SMD_CE1_A_CLK] = &clk_smd_rpm_ce1_a_clk, - [RPM_SMD_AGGR2_NOC_CLK] = &clk_smd_rpm_aggre2_noc_clk, - [RPM_SMD_AGGR2_NOC_A_CLK] = &clk_smd_rpm_aggre2_noc_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk, [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_qdss_a_clk, [RPM_SMD_RF_CLK1] = &clk_smd_rpm_rf_clk1, @@ -1038,15 +1014,13 @@ static struct clk_smd_rpm *sdm660_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_sdm660 = { .clks = sdm660_clks, .num_clks = ARRAY_SIZE(sdm660_clks), + .icc_clks = sdm660_icc_clks, + .num_icc_clks = ARRAY_SIZE(sdm660_icc_clks), }; static struct clk_smd_rpm *mdm9607_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_PCNOC_CLK] = &clk_smd_rpm_bus_0_pcnoc_clk, - [RPM_SMD_PCNOC_A_CLK] = &clk_smd_rpm_bus_0_pcnoc_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, [RPM_SMD_QPIC_CLK] = &clk_smd_rpm_qpic_clk, [RPM_SMD_QPIC_CLK_A] = &clk_smd_rpm_qpic_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk, @@ -1060,21 +1034,15 @@ static struct clk_smd_rpm *mdm9607_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_mdm9607 = { .clks = mdm9607_clks, .num_clks = ARRAY_SIZE(mdm9607_clks), + .icc_clks = bimc_pcnoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_icc_clks), }; static struct clk_smd_rpm *msm8953_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_PCNOC_CLK] = &clk_smd_rpm_bus_0_pcnoc_clk, - [RPM_SMD_PCNOC_A_CLK] = &clk_smd_rpm_bus_0_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_1_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_1_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, [RPM_SMD_IPA_CLK] = &clk_smd_rpm_ipa_clk, [RPM_SMD_IPA_A_CLK] = &clk_smd_rpm_ipa_a_clk, - [RPM_SMD_SYSMMNOC_CLK] = &clk_smd_rpm_bus_2_sysmmnoc_clk, - [RPM_SMD_SYSMMNOC_A_CLK] = &clk_smd_rpm_bus_2_sysmmnoc_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk, [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_qdss_a_clk, [RPM_SMD_BB_CLK1] = &clk_smd_rpm_bb_clk1, @@ -1096,23 +1064,19 @@ static struct clk_smd_rpm *msm8953_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_msm8953 = { .clks = msm8953_clks, .num_clks = ARRAY_SIZE(msm8953_clks), + .icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks), }; static struct clk_smd_rpm *sm6125_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_2_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_2_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_branch_qdss_clk, [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_branch_qdss_a_clk, [RPM_SMD_RF_CLK1] = &clk_smd_rpm_rf_clk1, [RPM_SMD_RF_CLK1_A] = &clk_smd_rpm_rf_clk1_a, [RPM_SMD_RF_CLK2] = &clk_smd_rpm_rf_clk2, [RPM_SMD_RF_CLK2_A] = &clk_smd_rpm_rf_clk2_a, - [RPM_SMD_CNOC_CLK] = &clk_smd_rpm_bus_1_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &clk_smd_rpm_bus_1_cnoc_a_clk, [RPM_SMD_IPA_CLK] = &clk_smd_rpm_ipa_clk, [RPM_SMD_IPA_A_CLK] = &clk_smd_rpm_ipa_a_clk, [RPM_SMD_CE1_CLK] = &clk_smd_rpm_ce1_clk, @@ -1123,12 +1087,6 @@ static struct clk_smd_rpm *sm6125_clks[] = { [RPM_SMD_LN_BB_CLK2_A] = &clk_smd_rpm_ln_bb_clk2_a, [RPM_SMD_LN_BB_CLK3] = &clk_smd_rpm_ln_bb_clk3, [RPM_SMD_LN_BB_CLK3_A] = &clk_smd_rpm_ln_bb_clk3_a, - [RPM_SMD_QUP_CLK] = &clk_smd_rpm_qup_clk, - [RPM_SMD_QUP_A_CLK] = &clk_smd_rpm_qup_a_clk, - [RPM_SMD_MMRT_CLK] = &clk_smd_rpm_mmrt_clk, - [RPM_SMD_MMRT_A_CLK] = &clk_smd_rpm_mmrt_a_clk, - [RPM_SMD_MMNRT_CLK] = &clk_smd_rpm_mmnrt_clk, - [RPM_SMD_MMNRT_A_CLK] = &clk_smd_rpm_mmnrt_a_clk, [RPM_SMD_SNOC_PERIPH_CLK] = &clk_smd_rpm_bus_0_snoc_periph_clk, [RPM_SMD_SNOC_PERIPH_A_CLK] = &clk_smd_rpm_bus_0_snoc_periph_a_clk, [RPM_SMD_SNOC_LPASS_CLK] = &clk_smd_rpm_bus_5_snoc_lpass_clk, @@ -1138,34 +1096,24 @@ static struct clk_smd_rpm *sm6125_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_sm6125 = { .clks = sm6125_clks, .num_clks = ARRAY_SIZE(sm6125_clks), + .icc_clks = sm_qnoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(sm_qnoc_icc_clks) }; /* SM6115 */ static struct clk_smd_rpm *sm6115_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_2_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_2_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_branch_qdss_clk, [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_branch_qdss_a_clk, [RPM_SMD_RF_CLK1] = &clk_smd_rpm_rf_clk1, [RPM_SMD_RF_CLK1_A] = &clk_smd_rpm_rf_clk1_a, [RPM_SMD_RF_CLK2] = &clk_smd_rpm_rf_clk2, [RPM_SMD_RF_CLK2_A] = &clk_smd_rpm_rf_clk2_a, - [RPM_SMD_CNOC_CLK] = &clk_smd_rpm_bus_1_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &clk_smd_rpm_bus_1_cnoc_a_clk, [RPM_SMD_IPA_CLK] = &clk_smd_rpm_ipa_clk, [RPM_SMD_IPA_A_CLK] = &clk_smd_rpm_ipa_a_clk, [RPM_SMD_CE1_CLK] = &clk_smd_rpm_ce1_clk, [RPM_SMD_CE1_A_CLK] = &clk_smd_rpm_ce1_a_clk, - [RPM_SMD_QUP_CLK] = &clk_smd_rpm_qup_clk, - [RPM_SMD_QUP_A_CLK] = &clk_smd_rpm_qup_a_clk, - [RPM_SMD_MMRT_CLK] = &clk_smd_rpm_mmrt_clk, - [RPM_SMD_MMRT_A_CLK] = &clk_smd_rpm_mmrt_a_clk, - [RPM_SMD_MMNRT_CLK] = &clk_smd_rpm_mmnrt_clk, - [RPM_SMD_MMNRT_A_CLK] = &clk_smd_rpm_mmnrt_a_clk, [RPM_SMD_SNOC_PERIPH_CLK] = &clk_smd_rpm_bus_0_snoc_periph_clk, [RPM_SMD_SNOC_PERIPH_A_CLK] = &clk_smd_rpm_bus_0_snoc_periph_a_clk, [RPM_SMD_SNOC_LPASS_CLK] = &clk_smd_rpm_bus_5_snoc_lpass_clk, @@ -1179,27 +1127,17 @@ static struct clk_smd_rpm *sm6115_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_sm6115 = { .clks = sm6115_clks, .num_clks = ARRAY_SIZE(sm6115_clks), + .icc_clks = sm_qnoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(sm_qnoc_icc_clks) }; static struct clk_smd_rpm *sm6375_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_2_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_2_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_branch_qdss_clk, [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_branch_qdss_a_clk, - [RPM_SMD_CNOC_CLK] = &clk_smd_rpm_bus_1_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &clk_smd_rpm_bus_1_cnoc_a_clk, [RPM_SMD_IPA_CLK] = &clk_smd_rpm_ipa_clk, [RPM_SMD_IPA_A_CLK] = &clk_smd_rpm_ipa_a_clk, - [RPM_SMD_QUP_CLK] = &clk_smd_rpm_qup_clk, - [RPM_SMD_QUP_A_CLK] = &clk_smd_rpm_qup_a_clk, - [RPM_SMD_MMRT_CLK] = &clk_smd_rpm_mmrt_clk, - [RPM_SMD_MMRT_A_CLK] = &clk_smd_rpm_mmrt_a_clk, - [RPM_SMD_MMNRT_CLK] = &clk_smd_rpm_mmnrt_clk, - [RPM_SMD_MMNRT_A_CLK] = &clk_smd_rpm_mmnrt_a_clk, [RPM_SMD_SNOC_PERIPH_CLK] = &clk_smd_rpm_bus_0_snoc_periph_clk, [RPM_SMD_SNOC_PERIPH_A_CLK] = &clk_smd_rpm_bus_0_snoc_periph_a_clk, [RPM_SMD_SNOC_LPASS_CLK] = &clk_smd_rpm_bus_5_snoc_lpass_clk, @@ -1216,31 +1154,21 @@ static struct clk_smd_rpm *sm6375_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_sm6375 = { .clks = sm6375_clks, .num_clks = ARRAY_SIZE(sm6375_clks), + .icc_clks = sm_qnoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(sm_qnoc_icc_clks) }; static struct clk_smd_rpm *qcm2290_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, - [RPM_SMD_SNOC_CLK] = &clk_smd_rpm_bus_2_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &clk_smd_rpm_bus_2_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &clk_smd_rpm_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &clk_smd_rpm_bimc_a_clk, [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_branch_qdss_clk, [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_branch_qdss_a_clk, [RPM_SMD_LN_BB_CLK2] = &clk_smd_rpm_ln_bb_clk2, [RPM_SMD_LN_BB_CLK2_A] = &clk_smd_rpm_ln_bb_clk2_a, [RPM_SMD_RF_CLK3] = &clk_smd_rpm_38m4_rf_clk3, [RPM_SMD_RF_CLK3_A] = &clk_smd_rpm_38m4_rf_clk3_a, - [RPM_SMD_CNOC_CLK] = &clk_smd_rpm_bus_1_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &clk_smd_rpm_bus_1_cnoc_a_clk, [RPM_SMD_IPA_CLK] = &clk_smd_rpm_ipa_clk, [RPM_SMD_IPA_A_CLK] = &clk_smd_rpm_ipa_a_clk, - [RPM_SMD_QUP_CLK] = &clk_smd_rpm_qup_clk, - [RPM_SMD_QUP_A_CLK] = &clk_smd_rpm_qup_a_clk, - [RPM_SMD_MMRT_CLK] = &clk_smd_rpm_mmrt_clk, - [RPM_SMD_MMRT_A_CLK] = &clk_smd_rpm_mmrt_a_clk, - [RPM_SMD_MMNRT_CLK] = &clk_smd_rpm_mmnrt_clk, - [RPM_SMD_MMNRT_A_CLK] = &clk_smd_rpm_mmnrt_a_clk, [RPM_SMD_SNOC_PERIPH_CLK] = &clk_smd_rpm_bus_0_snoc_periph_clk, [RPM_SMD_SNOC_PERIPH_A_CLK] = &clk_smd_rpm_bus_0_snoc_periph_a_clk, [RPM_SMD_SNOC_LPASS_CLK] = &clk_smd_rpm_bus_5_snoc_lpass_clk, @@ -1262,6 +1190,8 @@ static struct clk_smd_rpm *qcm2290_clks[] = { static const struct rpm_smd_clk_desc rpm_clk_qcm2290 = { .clks = qcm2290_clks, .num_clks = ARRAY_SIZE(qcm2290_clks), + .icc_clks = sm_qnoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(sm_qnoc_icc_clks) }; static const struct of_device_id rpm_smd_clk_match_table[] = { @@ -1302,12 +1232,20 @@ static struct clk_hw *qcom_smdrpm_clk_hw_get(struct of_phandle_args *clkspec, return desc->clks[idx] ? &desc->clks[idx]->hw : ERR_PTR(-ENOENT); } +static void rpm_smd_unregister_icc(void *data) +{ + struct platform_device *icc_pdev = data; + + platform_device_unregister(icc_pdev); +} + static int rpm_smd_clk_probe(struct platform_device *pdev) { int ret; size_t num_clks, i; struct clk_smd_rpm **rpm_smd_clks; const struct rpm_smd_clk_desc *desc; + struct platform_device *icc_pdev; rpmcc_smd_rpm = dev_get_drvdata(pdev->dev.parent); if (!rpmcc_smd_rpm) { @@ -1337,6 +1275,15 @@ static int rpm_smd_clk_probe(struct platform_device *pdev) goto err; } + for (i = 0; i < desc->num_icc_clks; i++) { + if (!desc->icc_clks[i]) + continue; + + ret = clk_smd_rpm_handoff(desc->icc_clks[i]); + if (ret) + goto err; + } + if (!desc->scaling_before_handover) { ret = clk_smd_rpm_enable_scaling(); if (ret) @@ -1357,6 +1304,19 @@ static int rpm_smd_clk_probe(struct platform_device *pdev) if (ret) goto err; + icc_pdev = platform_device_register_data(pdev->dev.parent, + "icc_smd_rpm", -1, NULL, 0); + if (IS_ERR(icc_pdev)) { + dev_err(&pdev->dev, "Failed to register icc_smd_rpm device: %pE\n", + icc_pdev); + /* No need to unregister clocks because of this */ + } else { + ret = devm_add_action_or_reset(&pdev->dev, rpm_smd_unregister_icc, + icc_pdev); + if (ret) + goto err; + } + return 0; err: dev_err(&pdev->dev, "Error registering SMD clock driver (%d)\n", ret); diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c index 5fac448c28fd..1afbc4f7c6e7 100644 --- a/drivers/interconnect/core.c +++ b/drivers/interconnect/core.c @@ -28,6 +28,7 @@ static LIST_HEAD(icc_providers); static int providers_count; static bool synced_state; static DEFINE_MUTEX(icc_lock); +static DEFINE_MUTEX(icc_bw_lock); static struct dentry *icc_debugfs_dir; static void icc_summary_show_one(struct seq_file *s, struct icc_node *n) @@ -631,7 +632,7 @@ int icc_set_bw(struct icc_path *path, u32 avg_bw, u32 peak_bw) if (WARN_ON(IS_ERR(path) || !path->num_nodes)) return -EINVAL; - mutex_lock(&icc_lock); + mutex_lock(&icc_bw_lock); old_avg = path->reqs[0].avg_bw; old_peak = path->reqs[0].peak_bw; @@ -663,7 +664,7 @@ int icc_set_bw(struct icc_path *path, u32 avg_bw, u32 peak_bw) apply_constraints(path); } - mutex_unlock(&icc_lock); + mutex_unlock(&icc_bw_lock); trace_icc_set_bw_end(path, ret); @@ -872,6 +873,7 @@ void icc_node_add(struct icc_node *node, struct icc_provider *provider) return; mutex_lock(&icc_lock); + mutex_lock(&icc_bw_lock); node->provider = provider; list_add_tail(&node->node_list, &provider->nodes); @@ -900,6 +902,7 @@ void icc_node_add(struct icc_node *node, struct icc_provider *provider) node->avg_bw = 0; node->peak_bw = 0; + mutex_unlock(&icc_bw_lock); mutex_unlock(&icc_lock); } EXPORT_SYMBOL_GPL(icc_node_add); @@ -1025,6 +1028,7 @@ void icc_sync_state(struct device *dev) return; mutex_lock(&icc_lock); + mutex_lock(&icc_bw_lock); synced_state = true; list_for_each_entry(p, &icc_providers, provider_list) { dev_dbg(p->dev, "interconnect provider is in synced state\n"); @@ -1037,13 +1041,21 @@ void icc_sync_state(struct device *dev) } } } + mutex_unlock(&icc_bw_lock); mutex_unlock(&icc_lock); } EXPORT_SYMBOL_GPL(icc_sync_state); static int __init icc_init(void) { - struct device_node *root = of_find_node_by_path("/"); + struct device_node *root; + + /* Teach lockdep about lock ordering wrt. shrinker: */ + fs_reclaim_acquire(GFP_KERNEL); + might_lock(&icc_bw_lock); + fs_reclaim_release(GFP_KERNEL); + + root = of_find_node_by_path("/"); providers_count = of_count_icc_providers(root); of_node_put(root); diff --git a/drivers/interconnect/icc-clk.c b/drivers/interconnect/icc-clk.c index 4d43ebff4257..d787f2ea36d9 100644 --- a/drivers/interconnect/icc-clk.c +++ b/drivers/interconnect/icc-clk.c @@ -16,7 +16,7 @@ struct icc_clk_node { struct icc_clk_provider { struct icc_provider provider; int num_clocks; - struct icc_clk_node clocks[]; + struct icc_clk_node clocks[] __counted_by(num_clocks); }; #define to_icc_clk_provider(_provider) \ diff --git a/drivers/interconnect/imx/imx8mp.c b/drivers/interconnect/imx/imx8mp.c index 8bfaf173f1da..a66ae3638b18 100644 --- a/drivers/interconnect/imx/imx8mp.c +++ b/drivers/interconnect/imx/imx8mp.c @@ -7,7 +7,6 @@ */ #include <linux/module.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <dt-bindings/interconnect/fsl,imx8mp.h> diff --git a/drivers/interconnect/internal.h b/drivers/interconnect/internal.h index f5f82a5c939e..b30856db523d 100644 --- a/drivers/interconnect/internal.h +++ b/drivers/interconnect/internal.h @@ -38,7 +38,7 @@ struct icc_req { struct icc_path { const char *name; size_t num_nodes; - struct icc_req reqs[]; + struct icc_req reqs[] __counted_by(num_nodes); }; #endif diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile index ab988926433c..80d9d2da95d1 100644 --- a/drivers/interconnect/qcom/Makefile +++ b/drivers/interconnect/qcom/Makefile @@ -29,7 +29,7 @@ qnoc-sm8250-objs := sm8250.o qnoc-sm8350-objs := sm8350.o qnoc-sm8450-objs := sm8450.o qnoc-sm8550-objs := sm8550.o -icc-smd-rpm-objs := smd-rpm.o icc-rpm.o +icc-smd-rpm-objs := smd-rpm.o icc-rpm.o icc-rpm-clocks.o obj-$(CONFIG_INTERCONNECT_QCOM_BCM_VOTER) += icc-bcm-voter.o obj-$(CONFIG_INTERCONNECT_QCOM_MSM8916) += qnoc-msm8916.o diff --git a/drivers/interconnect/qcom/icc-rpm-clocks.c b/drivers/interconnect/qcom/icc-rpm-clocks.c new file mode 100644 index 000000000000..63c82a91bbc7 --- /dev/null +++ b/drivers/interconnect/qcom/icc-rpm-clocks.c @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2023 Linaro Ltd + */ + +#include <linux/soc/qcom/smd-rpm.h> + +#include "icc-rpm.h" + +const struct rpm_clk_resource aggre1_clk = { + .resource_type = QCOM_SMD_RPM_AGGR_CLK, + .clock_id = 1, +}; +EXPORT_SYMBOL_GPL(aggre1_clk); + +const struct rpm_clk_resource aggre2_clk = { + .resource_type = QCOM_SMD_RPM_AGGR_CLK, + .clock_id = 2, +}; +EXPORT_SYMBOL_GPL(aggre2_clk); + +const struct rpm_clk_resource bimc_clk = { + .resource_type = QCOM_SMD_RPM_MEM_CLK, + .clock_id = 0, +}; +EXPORT_SYMBOL_GPL(bimc_clk); + +const struct rpm_clk_resource bus_0_clk = { + .resource_type = QCOM_SMD_RPM_BUS_CLK, + .clock_id = 0, +}; +EXPORT_SYMBOL_GPL(bus_0_clk); + +const struct rpm_clk_resource bus_1_clk = { + .resource_type = QCOM_SMD_RPM_BUS_CLK, + .clock_id = 1, +}; +EXPORT_SYMBOL_GPL(bus_1_clk); + +const struct rpm_clk_resource bus_2_clk = { + .resource_type = QCOM_SMD_RPM_BUS_CLK, + .clock_id = 2, +}; +EXPORT_SYMBOL_GPL(bus_2_clk); + +const struct rpm_clk_resource mmaxi_0_clk = { + .resource_type = QCOM_SMD_RPM_MMAXI_CLK, + .clock_id = 0, +}; +EXPORT_SYMBOL_GPL(mmaxi_0_clk); + +const struct rpm_clk_resource mmaxi_1_clk = { + .resource_type = QCOM_SMD_RPM_MMAXI_CLK, + .clock_id = 1, +}; +EXPORT_SYMBOL_GPL(mmaxi_1_clk); + +const struct rpm_clk_resource qup_clk = { + .resource_type = QCOM_SMD_RPM_QUP_CLK, + .clock_id = 0, +}; +EXPORT_SYMBOL_GPL(qup_clk); + +/* Branch clocks */ +const struct rpm_clk_resource aggre1_branch_clk = { + .resource_type = QCOM_SMD_RPM_AGGR_CLK, + .clock_id = 1, + .branch = true, +}; +EXPORT_SYMBOL_GPL(aggre1_branch_clk); + +const struct rpm_clk_resource aggre2_branch_clk = { + .resource_type = QCOM_SMD_RPM_AGGR_CLK, + .clock_id = 2, + .branch = true, +}; +EXPORT_SYMBOL_GPL(aggre2_branch_clk); diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c index 6acc7686ed38..2c16917ba1fd 100644 --- a/drivers/interconnect/qcom/icc-rpm.c +++ b/drivers/interconnect/qcom/icc-rpm.c @@ -3,18 +3,16 @@ * Copyright (C) 2020 Linaro Ltd */ -#include <linux/clk.h> #include <linux/device.h> #include <linux/interconnect-provider.h> #include <linux/io.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/slab.h> -#include "smd-rpm.h" #include "icc-common.h" #include "icc-rpm.h" @@ -50,6 +48,8 @@ #define NOC_QOS_MODE_FIXED_VAL 0x0 #define NOC_QOS_MODE_BYPASS_VAL 0x2 +#define ICC_BUS_CLK_MIN_RATE 19200ULL /* kHz */ + static int qcom_icc_set_qnoc_qos(struct icc_node *src) { struct icc_provider *provider = src->provider; @@ -204,38 +204,43 @@ static int qcom_icc_qos_set(struct icc_node *node) } } -static int qcom_icc_rpm_set(struct qcom_icc_node *qn, u64 sum_bw) +static int qcom_icc_rpm_set(struct qcom_icc_node *qn, u64 *bw) { - int ret = 0; + int ret, rpm_ctx = 0; + u64 bw_bps; if (qn->qos.ap_owned) return 0; - if (qn->mas_rpm_id != -1) { - ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE, - RPM_BUS_MASTER_REQ, - qn->mas_rpm_id, - sum_bw); - if (ret) { - pr_err("qcom_icc_rpm_smd_send mas %d error %d\n", - qn->mas_rpm_id, ret); - return ret; + for (rpm_ctx = 0; rpm_ctx < QCOM_SMD_RPM_STATE_NUM; rpm_ctx++) { + bw_bps = icc_units_to_bps(bw[rpm_ctx]); + + if (qn->mas_rpm_id != -1) { + ret = qcom_icc_rpm_smd_send(rpm_ctx, + RPM_BUS_MASTER_REQ, + qn->mas_rpm_id, + bw_bps); + if (ret) { + pr_err("qcom_icc_rpm_smd_send mas %d error %d\n", + qn->mas_rpm_id, ret); + return ret; + } } - } - if (qn->slv_rpm_id != -1) { - ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE, - RPM_BUS_SLAVE_REQ, - qn->slv_rpm_id, - sum_bw); - if (ret) { - pr_err("qcom_icc_rpm_smd_send slv %d error %d\n", - qn->slv_rpm_id, ret); - return ret; + if (qn->slv_rpm_id != -1) { + ret = qcom_icc_rpm_smd_send(rpm_ctx, + RPM_BUS_SLAVE_REQ, + qn->slv_rpm_id, + bw_bps); + if (ret) { + pr_err("qcom_icc_rpm_smd_send slv %d error %d\n", + qn->slv_rpm_id, ret); + return ret; + } } } - return ret; + return 0; } /** @@ -248,7 +253,7 @@ static void qcom_icc_pre_bw_aggregate(struct icc_node *node) size_t i; qn = node->data; - for (i = 0; i < QCOM_ICC_NUM_BUCKETS; i++) { + for (i = 0; i < QCOM_SMD_RPM_STATE_NUM; i++) { qn->sum_avg[i] = 0; qn->max_peak[i] = 0; } @@ -272,9 +277,9 @@ static int qcom_icc_bw_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, qn = node->data; if (!tag) - tag = QCOM_ICC_TAG_ALWAYS; + tag = RPM_ALWAYS_TAG; - for (i = 0; i < QCOM_ICC_NUM_BUCKETS; i++) { + for (i = 0; i < QCOM_SMD_RPM_STATE_NUM; i++) { if (tag & BIT(i)) { qn->sum_avg[i] += avg_bw; qn->max_peak[i] = max_t(u32, qn->max_peak[i], peak_bw); @@ -287,61 +292,45 @@ static int qcom_icc_bw_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, } /** - * qcom_icc_bus_aggregate - aggregate bandwidth by traversing all nodes + * qcom_icc_bus_aggregate - calculate bus clock rates by traversing all nodes * @provider: generic interconnect provider - * @agg_avg: an array for aggregated average bandwidth of buckets - * @agg_peak: an array for aggregated peak bandwidth of buckets - * @max_agg_avg: pointer to max value of aggregated average bandwidth + * @agg_clk_rate: array containing the aggregated clock rates in kHz */ -static void qcom_icc_bus_aggregate(struct icc_provider *provider, - u64 *agg_avg, u64 *agg_peak, - u64 *max_agg_avg) +static void qcom_icc_bus_aggregate(struct icc_provider *provider, u64 *agg_clk_rate) { - struct icc_node *node; + u64 agg_avg_rate, agg_rate; struct qcom_icc_node *qn; - u64 sum_avg[QCOM_ICC_NUM_BUCKETS]; + struct icc_node *node; int i; - /* Initialise aggregate values */ - for (i = 0; i < QCOM_ICC_NUM_BUCKETS; i++) { - agg_avg[i] = 0; - agg_peak[i] = 0; - } - - *max_agg_avg = 0; - /* - * Iterate nodes on the interconnect and aggregate bandwidth - * requests for every bucket. + * Iterate nodes on the provider, aggregate bandwidth requests for + * every bucket and convert them into bus clock rates. */ list_for_each_entry(node, &provider->nodes, node_list) { qn = node->data; - for (i = 0; i < QCOM_ICC_NUM_BUCKETS; i++) { + for (i = 0; i < QCOM_SMD_RPM_STATE_NUM; i++) { if (qn->channels) - sum_avg[i] = div_u64(qn->sum_avg[i], qn->channels); + agg_avg_rate = div_u64(qn->sum_avg[i], qn->channels); else - sum_avg[i] = qn->sum_avg[i]; - agg_avg[i] += sum_avg[i]; - agg_peak[i] = max_t(u64, agg_peak[i], qn->max_peak[i]); + agg_avg_rate = qn->sum_avg[i]; + + agg_rate = max_t(u64, agg_avg_rate, qn->max_peak[i]); + do_div(agg_rate, qn->buswidth); + + agg_clk_rate[i] = max_t(u64, agg_clk_rate[i], agg_rate); } } - - /* Find maximum values across all buckets */ - for (i = 0; i < QCOM_ICC_NUM_BUCKETS; i++) - *max_agg_avg = max_t(u64, *max_agg_avg, agg_avg[i]); } static int qcom_icc_set(struct icc_node *src, struct icc_node *dst) { - struct qcom_icc_provider *qp; struct qcom_icc_node *src_qn = NULL, *dst_qn = NULL; + u64 agg_clk_rate[QCOM_SMD_RPM_STATE_NUM] = { 0 }; struct icc_provider *provider; - u64 sum_bw; - u64 rate; - u64 agg_avg[QCOM_ICC_NUM_BUCKETS], agg_peak[QCOM_ICC_NUM_BUCKETS]; - u64 max_agg_avg; - int ret, i; - int bucket; + struct qcom_icc_provider *qp; + u64 active_rate, sleep_rate; + int ret; src_qn = src->data; if (dst) @@ -349,56 +338,66 @@ static int qcom_icc_set(struct icc_node *src, struct icc_node *dst) provider = src->provider; qp = to_qcom_provider(provider); - qcom_icc_bus_aggregate(provider, agg_avg, agg_peak, &max_agg_avg); - - sum_bw = icc_units_to_bps(max_agg_avg); + qcom_icc_bus_aggregate(provider, agg_clk_rate); + active_rate = agg_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE]; + sleep_rate = agg_clk_rate[QCOM_SMD_RPM_SLEEP_STATE]; - ret = qcom_icc_rpm_set(src_qn, sum_bw); + ret = qcom_icc_rpm_set(src_qn, src_qn->sum_avg); if (ret) return ret; if (dst_qn) { - ret = qcom_icc_rpm_set(dst_qn, sum_bw); + ret = qcom_icc_rpm_set(dst_qn, dst_qn->sum_avg); + if (ret) + return ret; + } + + /* Some providers don't have a bus clock to scale */ + if (!qp->bus_clk_desc && !qp->bus_clk) + return 0; + + /* + * Downstream checks whether the requested rate is zero, but it makes little sense + * to vote for a value that's below the lower threshold, so let's not do so. + */ + if (qp->keep_alive) + active_rate = max(ICC_BUS_CLK_MIN_RATE, active_rate); + + /* Some providers have a non-RPM-owned bus clock - convert kHz->Hz for the CCF */ + if (qp->bus_clk) { + active_rate = max_t(u64, active_rate, sleep_rate); + /* ARM32 caps clk_set_rate arg to u32.. Nothing we can do about that! */ + active_rate = min_t(u64, 1000ULL * active_rate, ULONG_MAX); + return clk_set_rate(qp->bus_clk, active_rate); + } + + /* RPM only accepts <=INT_MAX rates */ + active_rate = min_t(u64, active_rate, INT_MAX); + sleep_rate = min_t(u64, sleep_rate, INT_MAX); + + if (active_rate != qp->bus_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE]) { + ret = qcom_icc_rpm_set_bus_rate(qp->bus_clk_desc, QCOM_SMD_RPM_ACTIVE_STATE, + active_rate); if (ret) return ret; + + /* Cache the rate after we've successfully commited it to RPM */ + qp->bus_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE] = active_rate; } - for (i = 0; i < qp->num_bus_clks; i++) { - /* - * Use WAKE bucket for active clock, otherwise, use SLEEP bucket - * for other clocks. If a platform doesn't set interconnect - * path tags, by default use sleep bucket for all clocks. - * - * Note, AMC bucket is not supported yet. - */ - if (!strcmp(qp->bus_clks[i].id, "bus_a")) - bucket = QCOM_ICC_BUCKET_WAKE; - else - bucket = QCOM_ICC_BUCKET_SLEEP; - - rate = icc_units_to_bps(max(agg_avg[bucket], agg_peak[bucket])); - do_div(rate, src_qn->buswidth); - rate = min_t(u64, rate, LONG_MAX); - - if (qp->bus_clk_rate[i] == rate) - continue; - - ret = clk_set_rate(qp->bus_clks[i].clk, rate); - if (ret) { - pr_err("%s clk_set_rate error: %d\n", - qp->bus_clks[i].id, ret); + if (sleep_rate != qp->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE]) { + ret = qcom_icc_rpm_set_bus_rate(qp->bus_clk_desc, QCOM_SMD_RPM_SLEEP_STATE, + sleep_rate); + if (ret) return ret; - } - qp->bus_clk_rate[i] = rate; + + /* Cache the rate after we've successfully commited it to RPM */ + qp->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE] = sleep_rate; } return 0; } -static const char * const bus_clocks[] = { - "bus", "bus_a", -}; - int qnoc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -440,6 +439,20 @@ int qnoc_probe(struct platform_device *pdev) if (!qp->intf_clks) return -ENOMEM; + if (desc->bus_clk_desc) { + qp->bus_clk_desc = devm_kzalloc(dev, sizeof(*qp->bus_clk_desc), + GFP_KERNEL); + if (!qp->bus_clk_desc) + return -ENOMEM; + + qp->bus_clk_desc = desc->bus_clk_desc; + } else { + /* Some older SoCs may have a single non-RPM-owned bus clock. */ + qp->bus_clk = devm_clk_get_optional(dev, "bus"); + if (IS_ERR(qp->bus_clk)) + return PTR_ERR(qp->bus_clk); + } + data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes), GFP_KERNEL); if (!data) @@ -449,10 +462,7 @@ int qnoc_probe(struct platform_device *pdev) for (i = 0; i < cd_num; i++) qp->intf_clks[i].id = cds[i]; - qp->num_bus_clks = desc->no_clk_scaling ? 0 : NUM_BUS_CLKS; - for (i = 0; i < qp->num_bus_clks; i++) - qp->bus_clks[i].id = bus_clocks[i]; - + qp->keep_alive = desc->keep_alive; qp->type = desc->type; qp->qos_offset = desc->qos_offset; @@ -481,11 +491,7 @@ int qnoc_probe(struct platform_device *pdev) } regmap_done: - ret = devm_clk_bulk_get(dev, qp->num_bus_clks, qp->bus_clks); - if (ret) - return ret; - - ret = clk_bulk_prepare_enable(qp->num_bus_clks, qp->bus_clks); + ret = clk_prepare_enable(qp->bus_clk); if (ret) return ret; @@ -557,7 +563,7 @@ err_deregister_provider: icc_provider_deregister(provider); err_remove_nodes: icc_nodes_remove(provider); - clk_bulk_disable_unprepare(qp->num_bus_clks, qp->bus_clks); + clk_disable_unprepare(qp->bus_clk); return ret; } @@ -569,7 +575,7 @@ int qnoc_remove(struct platform_device *pdev) icc_provider_deregister(&qp->provider); icc_nodes_remove(&qp->provider); - clk_bulk_disable_unprepare(qp->num_bus_clks, qp->bus_clks); + clk_disable_unprepare(qp->bus_clk); return 0; } diff --git a/drivers/interconnect/qcom/icc-rpm.h b/drivers/interconnect/qcom/icc-rpm.h index ee705edf19dd..eed3451af3e6 100644 --- a/drivers/interconnect/qcom/icc-rpm.h +++ b/drivers/interconnect/qcom/icc-rpm.h @@ -6,7 +6,12 @@ #ifndef __DRIVERS_INTERCONNECT_QCOM_ICC_RPM_H #define __DRIVERS_INTERCONNECT_QCOM_ICC_RPM_H -#include <dt-bindings/interconnect/qcom,icc.h> +#include <linux/soc/qcom/smd-rpm.h> + +#include <dt-bindings/interconnect/qcom,rpm-icc.h> +#include <linux/clk.h> +#include <linux/interconnect-provider.h> +#include <linux/platform_device.h> #define RPM_BUS_MASTER_REQ 0x73616d62 #define RPM_BUS_SLAVE_REQ 0x766c7362 @@ -20,31 +25,43 @@ enum qcom_icc_type { QCOM_ICC_QNOC, }; -#define NUM_BUS_CLKS 2 +/** + * struct rpm_clk_resource - RPM bus clock resource + * @resource_type: RPM resource type of the clock resource + * @clock_id: index of the clock resource of a specific resource type + * @branch: whether the resource represents a branch clock +*/ +struct rpm_clk_resource { + u32 resource_type; + u32 clock_id; + bool branch; +}; /** * struct qcom_icc_provider - Qualcomm specific interconnect provider * @provider: generic interconnect provider - * @num_bus_clks: the total number of bus_clks clk_bulk_data entries (0 or 2) * @num_intf_clks: the total number of intf_clks clk_bulk_data entries * @type: the ICC provider type * @regmap: regmap for QoS registers read/write access * @qos_offset: offset to QoS registers * @bus_clk_rate: bus clock rate in Hz - * @bus_clks: the clk_bulk_data table of bus clocks + * @bus_clk_desc: a pointer to a rpm_clk_resource description of bus clocks + * @bus_clk: a pointer to a HLOS-owned bus clock * @intf_clks: a clk_bulk_data array of interface clocks + * @keep_alive: whether to always keep a minimum vote on the bus clocks * @is_on: whether the bus is powered on */ struct qcom_icc_provider { struct icc_provider provider; - int num_bus_clks; int num_intf_clks; enum qcom_icc_type type; struct regmap *regmap; unsigned int qos_offset; - u64 bus_clk_rate[NUM_BUS_CLKS]; - struct clk_bulk_data bus_clks[NUM_BUS_CLKS]; + u32 bus_clk_rate[QCOM_SMD_RPM_STATE_NUM]; + const struct rpm_clk_resource *bus_clk_desc; + struct clk *bus_clk; struct clk_bulk_data *intf_clks; + bool keep_alive; bool is_on; }; @@ -89,8 +106,8 @@ struct qcom_icc_node { u16 num_links; u16 channels; u16 buswidth; - u64 sum_avg[QCOM_ICC_NUM_BUCKETS]; - u64 max_peak[QCOM_ICC_NUM_BUCKETS]; + u64 sum_avg[QCOM_SMD_RPM_STATE_NUM]; + u64 max_peak[QCOM_SMD_RPM_STATE_NUM]; int mas_rpm_id; int slv_rpm_id; struct qcom_icc_qos qos; @@ -99,10 +116,10 @@ struct qcom_icc_node { struct qcom_icc_desc { struct qcom_icc_node * const *nodes; size_t num_nodes; - const char * const *bus_clocks; + const struct rpm_clk_resource *bus_clk_desc; const char * const *intf_clocks; size_t num_intf_clocks; - bool no_clk_scaling; + bool keep_alive; enum qcom_icc_type type; const struct regmap_config *regmap_cfg; unsigned int qos_offset; @@ -115,7 +132,24 @@ enum qos_mode { NOC_QOS_MODE_BYPASS, }; +extern const struct rpm_clk_resource aggre1_clk; +extern const struct rpm_clk_resource aggre2_clk; +extern const struct rpm_clk_resource bimc_clk; +extern const struct rpm_clk_resource bus_0_clk; +extern const struct rpm_clk_resource bus_1_clk; +extern const struct rpm_clk_resource bus_2_clk; +extern const struct rpm_clk_resource mmaxi_0_clk; +extern const struct rpm_clk_resource mmaxi_1_clk; +extern const struct rpm_clk_resource qup_clk; + +extern const struct rpm_clk_resource aggre1_branch_clk; +extern const struct rpm_clk_resource aggre2_branch_clk; + int qnoc_probe(struct platform_device *pdev); int qnoc_remove(struct platform_device *pdev); +bool qcom_icc_rpm_smd_available(void); +int qcom_icc_rpm_smd_send(int ctx, int rsc_type, int id, u32 val); +int qcom_icc_rpm_set_bus_rate(const struct rpm_clk_resource *clk, int ctx, u32 rate); + #endif diff --git a/drivers/interconnect/qcom/icc-rpmh.c b/drivers/interconnect/qcom/icc-rpmh.c index fdb5e58e408b..b9f27ce3b607 100644 --- a/drivers/interconnect/qcom/icc-rpmh.c +++ b/drivers/interconnect/qcom/icc-rpmh.c @@ -7,7 +7,7 @@ #include <linux/interconnect-provider.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> +#include <linux/of_platform.h> #include <linux/slab.h> #include "bcm-voter.h" @@ -185,6 +185,7 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev) data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes), GFP_KERNEL); if (!data) return -ENOMEM; + data->num_nodes = num_nodes; provider = &qp->provider; provider->dev = dev; @@ -228,8 +229,6 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev) data->nodes[i] = node; } - data->num_nodes = num_nodes; - ret = icc_provider_register(provider); if (ret) goto err_remove_nodes; diff --git a/drivers/interconnect/qcom/msm8916.c b/drivers/interconnect/qcom/msm8916.c index 5c4ba2f37c8e..35148880b3e8 100644 --- a/drivers/interconnect/qcom/msm8916.c +++ b/drivers/interconnect/qcom/msm8916.c @@ -4,18 +4,16 @@ * Author: Georgi Djakov <georgi.djakov@linaro.org> */ -#include <linux/clk.h> #include <linux/device.h> #include <linux/interconnect-provider.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/regmap.h> -#include <linux/of_device.h> #include <dt-bindings/interconnect/qcom,msm8916.h> -#include "smd-rpm.h" #include "icc-rpm.h" enum { @@ -1232,6 +1230,7 @@ static const struct qcom_icc_desc msm8916_snoc = { .type = QCOM_ICC_NOC, .nodes = msm8916_snoc_nodes, .num_nodes = ARRAY_SIZE(msm8916_snoc_nodes), + .bus_clk_desc = &bus_1_clk, .regmap_cfg = &msm8916_snoc_regmap_config, .qos_offset = 0x7000, }; @@ -1260,6 +1259,7 @@ static const struct qcom_icc_desc msm8916_bimc = { .type = QCOM_ICC_BIMC, .nodes = msm8916_bimc_nodes, .num_nodes = ARRAY_SIZE(msm8916_bimc_nodes), + .bus_clk_desc = &bimc_clk, .regmap_cfg = &msm8916_bimc_regmap_config, .qos_offset = 0x8000, }; @@ -1329,6 +1329,7 @@ static const struct qcom_icc_desc msm8916_pcnoc = { .type = QCOM_ICC_NOC, .nodes = msm8916_pcnoc_nodes, .num_nodes = ARRAY_SIZE(msm8916_pcnoc_nodes), + .bus_clk_desc = &bus_0_clk, .regmap_cfg = &msm8916_pcnoc_regmap_config, .qos_offset = 0x7000, }; diff --git a/drivers/interconnect/qcom/msm8939.c b/drivers/interconnect/qcom/msm8939.c index caf0aefad668..b52c5ac1175c 100644 --- a/drivers/interconnect/qcom/msm8939.c +++ b/drivers/interconnect/qcom/msm8939.c @@ -5,18 +5,16 @@ * With reference of msm8916 interconnect driver of Georgi Djakov. */ -#include <linux/clk.h> #include <linux/device.h> #include <linux/interconnect-provider.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/platform_device.h> #include <linux/regmap.h> -#include <linux/of_device.h> #include <dt-bindings/interconnect/qcom,msm8939.h> -#include "smd-rpm.h" #include "icc-rpm.h" enum { @@ -1285,6 +1283,7 @@ static const struct qcom_icc_desc msm8939_snoc = { .type = QCOM_ICC_NOC, .nodes = msm8939_snoc_nodes, .num_nodes = ARRAY_SIZE(msm8939_snoc_nodes), + .bus_clk_desc = &bus_1_clk, .regmap_cfg = &msm8939_snoc_regmap_config, .qos_offset = 0x7000, }; @@ -1305,6 +1304,7 @@ static const struct qcom_icc_desc msm8939_snoc_mm = { .type = QCOM_ICC_NOC, .nodes = msm8939_snoc_mm_nodes, .num_nodes = ARRAY_SIZE(msm8939_snoc_mm_nodes), + .bus_clk_desc = &bus_2_clk, .regmap_cfg = &msm8939_snoc_regmap_config, .qos_offset = 0x7000, }; @@ -1333,6 +1333,7 @@ static const struct qcom_icc_desc msm8939_bimc = { .type = QCOM_ICC_BIMC, .nodes = msm8939_bimc_nodes, .num_nodes = ARRAY_SIZE(msm8939_bimc_nodes), + .bus_clk_desc = &bimc_clk, .regmap_cfg = &msm8939_bimc_regmap_config, .qos_offset = 0x8000, }; @@ -1404,6 +1405,7 @@ static const struct qcom_icc_desc msm8939_pcnoc = { .type = QCOM_ICC_NOC, .nodes = msm8939_pcnoc_nodes, .num_nodes = ARRAY_SIZE(msm8939_pcnoc_nodes), + .bus_clk_desc = &bus_0_clk, .regmap_cfg = &msm8939_pcnoc_regmap_config, .qos_offset = 0x7000, }; diff --git a/drivers/interconnect/qcom/msm8974.c b/drivers/interconnect/qcom/msm8974.c index 1828deaca443..885ca9d6d4ed 100644 --- a/drivers/interconnect/qcom/msm8974.c +++ b/drivers/interconnect/qcom/msm8974.c @@ -33,12 +33,11 @@ #include <linux/interconnect-provider.h> #include <linux/io.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_platform.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/slab.h> -#include "smd-rpm.h" +#include "icc-rpm.h" enum { MSM8974_BIMC_MAS_AMPSS_M0 = 1, @@ -676,6 +675,7 @@ static int msm8974_icc_probe(struct platform_device *pdev) GFP_KERNEL); if (!data) return -ENOMEM; + data->num_nodes = num_nodes; qp->bus_clks = devm_kmemdup(dev, msm8974_icc_bus_clocks, sizeof(msm8974_icc_bus_clocks), GFP_KERNEL); @@ -722,7 +722,6 @@ static int msm8974_icc_probe(struct platform_device *pdev) data->nodes[i] = node; } - data->num_nodes = num_nodes; ret = icc_provider_register(provider); if (ret) diff --git a/drivers/interconnect/qcom/msm8996.c b/drivers/interconnect/qcom/msm8996.c index 20340fb62fe6..88683dfa468f 100644 --- a/drivers/interconnect/qcom/msm8996.c +++ b/drivers/interconnect/qcom/msm8996.c @@ -5,20 +5,17 @@ * Copyright (c) 2021 Yassine Oudjana <y.oudjana@protonmail.com> */ -#include <linux/clk.h> #include <linux/device.h> #include <linux/interconnect-provider.h> #include <linux/io.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/regmap.h> #include <dt-bindings/interconnect/qcom,msm8996.h> #include "icc-rpm.h" -#include "smd-rpm.h" #include "msm8996.h" static const char * const mm_intf_clocks[] = { @@ -1819,7 +1816,6 @@ static const struct qcom_icc_desc msm8996_a0noc = { .num_nodes = ARRAY_SIZE(a0noc_nodes), .intf_clocks = a0noc_intf_clocks, .num_intf_clocks = ARRAY_SIZE(a0noc_intf_clocks), - .no_clk_scaling = true, .regmap_cfg = &msm8996_a0noc_regmap_config }; @@ -1841,6 +1837,7 @@ static const struct qcom_icc_desc msm8996_a1noc = { .type = QCOM_ICC_NOC, .nodes = a1noc_nodes, .num_nodes = ARRAY_SIZE(a1noc_nodes), + .bus_clk_desc = &aggre1_branch_clk, .regmap_cfg = &msm8996_a1noc_regmap_config }; @@ -1862,6 +1859,7 @@ static const struct qcom_icc_desc msm8996_a2noc = { .type = QCOM_ICC_NOC, .nodes = a2noc_nodes, .num_nodes = ARRAY_SIZE(a2noc_nodes), + .bus_clk_desc = &aggre2_branch_clk, .intf_clocks = a2noc_intf_clocks, .num_intf_clocks = ARRAY_SIZE(a2noc_intf_clocks), .regmap_cfg = &msm8996_a2noc_regmap_config @@ -1890,6 +1888,7 @@ static const struct qcom_icc_desc msm8996_bimc = { .type = QCOM_ICC_BIMC, .nodes = bimc_nodes, .num_nodes = ARRAY_SIZE(bimc_nodes), + .bus_clk_desc = &bimc_clk, .regmap_cfg = &msm8996_bimc_regmap_config }; @@ -1948,6 +1947,7 @@ static const struct qcom_icc_desc msm8996_cnoc = { .type = QCOM_ICC_NOC, .nodes = cnoc_nodes, .num_nodes = ARRAY_SIZE(cnoc_nodes), + .bus_clk_desc = &bus_2_clk, .regmap_cfg = &msm8996_cnoc_regmap_config }; @@ -2001,6 +2001,7 @@ static const struct qcom_icc_desc msm8996_mnoc = { .type = QCOM_ICC_NOC, .nodes = mnoc_nodes, .num_nodes = ARRAY_SIZE(mnoc_nodes), + .bus_clk_desc = &mmaxi_0_clk, .intf_clocks = mm_intf_clocks, .num_intf_clocks = ARRAY_SIZE(mm_intf_clocks), .regmap_cfg = &msm8996_mnoc_regmap_config @@ -2039,6 +2040,7 @@ static const struct qcom_icc_desc msm8996_pnoc = { .type = QCOM_ICC_NOC, .nodes = pnoc_nodes, .num_nodes = ARRAY_SIZE(pnoc_nodes), + .bus_clk_desc = &bus_0_clk, .regmap_cfg = &msm8996_pnoc_regmap_config }; @@ -2083,6 +2085,7 @@ static const struct qcom_icc_desc msm8996_snoc = { .type = QCOM_ICC_NOC, .nodes = snoc_nodes, .num_nodes = ARRAY_SIZE(snoc_nodes), + .bus_clk_desc = &bus_1_clk, .regmap_cfg = &msm8996_snoc_regmap_config }; diff --git a/drivers/interconnect/qcom/osm-l3.c b/drivers/interconnect/qcom/osm-l3.c index a1f4f918b911..dc321bb86d0b 100644 --- a/drivers/interconnect/qcom/osm-l3.c +++ b/drivers/interconnect/qcom/osm-l3.c @@ -9,7 +9,7 @@ #include <linux/io.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,osm-l3.h> @@ -232,6 +232,7 @@ static int qcom_osm_l3_probe(struct platform_device *pdev) data = devm_kzalloc(&pdev->dev, struct_size(data, nodes, num_nodes), GFP_KERNEL); if (!data) return -ENOMEM; + data->num_nodes = num_nodes; provider = &qp->provider; provider->dev = &pdev->dev; @@ -261,7 +262,6 @@ static int qcom_osm_l3_probe(struct platform_device *pdev) data->nodes[i] = node; } - data->num_nodes = num_nodes; ret = icc_provider_register(provider); if (ret) diff --git a/drivers/interconnect/qcom/qcm2290.c b/drivers/interconnect/qcom/qcm2290.c index a29cdb4fac03..5bc4b7516608 100644 --- a/drivers/interconnect/qcom/qcm2290.c +++ b/drivers/interconnect/qcom/qcm2290.c @@ -7,19 +7,16 @@ */ #include <dt-bindings/interconnect/qcom,qcm2290.h> -#include <linux/clk.h> #include <linux/device.h> #include <linux/interconnect-provider.h> #include <linux/io.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/slab.h> #include "icc-rpm.h" -#include "smd-rpm.h" enum { QCM2290_MASTER_APPSS_PROC = 1, @@ -1197,7 +1194,9 @@ static const struct qcom_icc_desc qcm2290_bimc = { .type = QCOM_ICC_BIMC, .nodes = qcm2290_bimc_nodes, .num_nodes = ARRAY_SIZE(qcm2290_bimc_nodes), + .bus_clk_desc = &bimc_clk, .regmap_cfg = &qcm2290_bimc_regmap_config, + .keep_alive = true, /* M_REG_BASE() in vendor msm_bus_bimc_adhoc driver */ .qos_offset = 0x8000, }; @@ -1252,7 +1251,9 @@ static const struct qcom_icc_desc qcm2290_cnoc = { .type = QCOM_ICC_NOC, .nodes = qcm2290_cnoc_nodes, .num_nodes = ARRAY_SIZE(qcm2290_cnoc_nodes), + .bus_clk_desc = &bus_1_clk, .regmap_cfg = &qcm2290_cnoc_regmap_config, + .keep_alive = true, }; static struct qcom_icc_node * const qcm2290_snoc_nodes[] = { @@ -1293,7 +1294,9 @@ static const struct qcom_icc_desc qcm2290_snoc = { .type = QCOM_ICC_QNOC, .nodes = qcm2290_snoc_nodes, .num_nodes = ARRAY_SIZE(qcm2290_snoc_nodes), + .bus_clk_desc = &bus_2_clk, .regmap_cfg = &qcm2290_snoc_regmap_config, + .keep_alive = true, /* Vendor DT node fab-sys_noc property 'qcom,base-offset' */ .qos_offset = 0x15000, }; @@ -1307,6 +1310,8 @@ static const struct qcom_icc_desc qcm2290_qup_virt = { .type = QCOM_ICC_QNOC, .nodes = qcm2290_qup_virt_nodes, .num_nodes = ARRAY_SIZE(qcm2290_qup_virt_nodes), + .bus_clk_desc = &qup_clk, + .keep_alive = true, }; static struct qcom_icc_node * const qcm2290_mmnrt_virt_nodes[] = { @@ -1320,7 +1325,9 @@ static const struct qcom_icc_desc qcm2290_mmnrt_virt = { .type = QCOM_ICC_QNOC, .nodes = qcm2290_mmnrt_virt_nodes, .num_nodes = ARRAY_SIZE(qcm2290_mmnrt_virt_nodes), + .bus_clk_desc = &mmaxi_0_clk, .regmap_cfg = &qcm2290_snoc_regmap_config, + .keep_alive = true, .qos_offset = 0x15000, }; @@ -1334,7 +1341,9 @@ static const struct qcom_icc_desc qcm2290_mmrt_virt = { .type = QCOM_ICC_QNOC, .nodes = qcm2290_mmrt_virt_nodes, .num_nodes = ARRAY_SIZE(qcm2290_mmrt_virt_nodes), + .bus_clk_desc = &mmaxi_1_clk, .regmap_cfg = &qcm2290_snoc_regmap_config, + .keep_alive = true, .qos_offset = 0x15000, }; @@ -1355,6 +1364,7 @@ static struct platform_driver qcm2290_noc_driver = { .driver = { .name = "qnoc-qcm2290", .of_match_table = qcm2290_noc_of_match, + .sync_state = icc_sync_state, }, }; module_platform_driver(qcm2290_noc_driver); diff --git a/drivers/interconnect/qcom/qcs404.c b/drivers/interconnect/qcom/qcs404.c index fae155344332..9fa1da70c843 100644 --- a/drivers/interconnect/qcom/qcs404.c +++ b/drivers/interconnect/qcom/qcs404.c @@ -4,16 +4,14 @@ */ #include <dt-bindings/interconnect/qcom,qcs404.h> -#include <linux/clk.h> #include <linux/device.h> #include <linux/interconnect-provider.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/platform_device.h> -#include <linux/of_device.h> -#include "smd-rpm.h" #include "icc-rpm.h" enum { @@ -985,6 +983,7 @@ static struct qcom_icc_node * const qcs404_bimc_nodes[] = { }; static const struct qcom_icc_desc qcs404_bimc = { + .bus_clk_desc = &bimc_clk, .nodes = qcs404_bimc_nodes, .num_nodes = ARRAY_SIZE(qcs404_bimc_nodes), }; @@ -1039,6 +1038,7 @@ static struct qcom_icc_node * const qcs404_pcnoc_nodes[] = { }; static const struct qcom_icc_desc qcs404_pcnoc = { + .bus_clk_desc = &bus_0_clk, .nodes = qcs404_pcnoc_nodes, .num_nodes = ARRAY_SIZE(qcs404_pcnoc_nodes), }; @@ -1067,6 +1067,7 @@ static struct qcom_icc_node * const qcs404_snoc_nodes[] = { }; static const struct qcom_icc_desc qcs404_snoc = { + .bus_clk_desc = &bus_1_clk, .nodes = qcs404_snoc_nodes, .num_nodes = ARRAY_SIZE(qcs404_snoc_nodes), }; diff --git a/drivers/interconnect/qcom/qdu1000.c b/drivers/interconnect/qcom/qdu1000.c index a4cf559de2b0..bf800dd7d4ba 100644 --- a/drivers/interconnect/qcom/qdu1000.c +++ b/drivers/interconnect/qcom/qdu1000.c @@ -7,8 +7,9 @@ #include <linux/device.h> #include <linux/interconnect.h> #include <linux/interconnect-provider.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,qdu1000-rpmh.h> #include "bcm-voter.h" diff --git a/drivers/interconnect/qcom/sa8775p.c b/drivers/interconnect/qcom/sa8775p.c index f56538669de0..ef1b5e326089 100644 --- a/drivers/interconnect/qcom/sa8775p.c +++ b/drivers/interconnect/qcom/sa8775p.c @@ -7,8 +7,9 @@ #include <linux/device.h> #include <linux/interconnect.h> #include <linux/interconnect-provider.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,sa8775p-rpmh.h> #include "bcm-voter.h" diff --git a/drivers/interconnect/qcom/sc7180.c b/drivers/interconnect/qcom/sc7180.c index ef4e13fb4983..d16298e77906 100644 --- a/drivers/interconnect/qcom/sc7180.c +++ b/drivers/interconnect/qcom/sc7180.c @@ -7,8 +7,9 @@ #include <linux/device.h> #include <linux/interconnect.h> #include <linux/interconnect-provider.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,sc7180.h> #include "bcm-voter.h" diff --git a/drivers/interconnect/qcom/sc7280.c b/drivers/interconnect/qcom/sc7280.c index 971f538bc98a..6592839b4d94 100644 --- a/drivers/interconnect/qcom/sc7280.c +++ b/drivers/interconnect/qcom/sc7280.c @@ -7,8 +7,9 @@ #include <linux/device.h> #include <linux/interconnect.h> #include <linux/interconnect-provider.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,sc7280.h> #include "bcm-voter.h" diff --git a/drivers/interconnect/qcom/sc8180x.c b/drivers/interconnect/qcom/sc8180x.c index c76e3a6a98cd..0fb4898dabcf 100644 --- a/drivers/interconnect/qcom/sc8180x.c +++ b/drivers/interconnect/qcom/sc8180x.c @@ -7,7 +7,8 @@ #include <linux/device.h> #include <linux/interconnect-provider.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> +#include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,sc8180x.h> diff --git a/drivers/interconnect/qcom/sc8280xp.c b/drivers/interconnect/qcom/sc8280xp.c index e56df893ec3e..b82c5493cbb5 100644 --- a/drivers/interconnect/qcom/sc8280xp.c +++ b/drivers/interconnect/qcom/sc8280xp.c @@ -7,8 +7,9 @@ #include <linux/device.h> #include <linux/interconnect.h> #include <linux/interconnect-provider.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,sc8280xp.h> #include "bcm-voter.h" diff --git a/drivers/interconnect/qcom/sdm660.c b/drivers/interconnect/qcom/sdm660.c index 7ffaf70d62d3..36962f7bd7bb 100644 --- a/drivers/interconnect/qcom/sdm660.c +++ b/drivers/interconnect/qcom/sdm660.c @@ -5,19 +5,16 @@ */ #include <dt-bindings/interconnect/qcom,sdm660.h> -#include <linux/clk.h> #include <linux/device.h> #include <linux/interconnect-provider.h> #include <linux/io.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/slab.h> #include "icc-rpm.h" -#include "smd-rpm.h" enum { SDM660_MASTER_IPA = 1, @@ -1512,6 +1509,7 @@ static const struct qcom_icc_desc sdm660_a2noc = { .type = QCOM_ICC_NOC, .nodes = sdm660_a2noc_nodes, .num_nodes = ARRAY_SIZE(sdm660_a2noc_nodes), + .bus_clk_desc = &aggre2_clk, .intf_clocks = a2noc_intf_clocks, .num_intf_clocks = ARRAY_SIZE(a2noc_intf_clocks), .regmap_cfg = &sdm660_a2noc_regmap_config, @@ -1540,6 +1538,7 @@ static const struct qcom_icc_desc sdm660_bimc = { .type = QCOM_ICC_BIMC, .nodes = sdm660_bimc_nodes, .num_nodes = ARRAY_SIZE(sdm660_bimc_nodes), + .bus_clk_desc = &bimc_clk, .regmap_cfg = &sdm660_bimc_regmap_config, }; @@ -1594,6 +1593,7 @@ static const struct qcom_icc_desc sdm660_cnoc = { .type = QCOM_ICC_NOC, .nodes = sdm660_cnoc_nodes, .num_nodes = ARRAY_SIZE(sdm660_cnoc_nodes), + .bus_clk_desc = &bus_2_clk, .regmap_cfg = &sdm660_cnoc_regmap_config, }; @@ -1616,7 +1616,6 @@ static const struct qcom_icc_desc sdm660_gnoc = { .nodes = sdm660_gnoc_nodes, .num_nodes = ARRAY_SIZE(sdm660_gnoc_nodes), .regmap_cfg = &sdm660_gnoc_regmap_config, - .no_clk_scaling = true, }; static struct qcom_icc_node * const sdm660_mnoc_nodes[] = { @@ -1656,6 +1655,7 @@ static const struct qcom_icc_desc sdm660_mnoc = { .type = QCOM_ICC_NOC, .nodes = sdm660_mnoc_nodes, .num_nodes = ARRAY_SIZE(sdm660_mnoc_nodes), + .bus_clk_desc = &mmaxi_0_clk, .intf_clocks = mm_intf_clocks, .num_intf_clocks = ARRAY_SIZE(mm_intf_clocks), .regmap_cfg = &sdm660_mnoc_regmap_config, @@ -1693,6 +1693,7 @@ static const struct qcom_icc_desc sdm660_snoc = { .type = QCOM_ICC_NOC, .nodes = sdm660_snoc_nodes, .num_nodes = ARRAY_SIZE(sdm660_snoc_nodes), + .bus_clk_desc = &bus_1_clk, .regmap_cfg = &sdm660_snoc_regmap_config, }; diff --git a/drivers/interconnect/qcom/sdm670.c b/drivers/interconnect/qcom/sdm670.c index bda955035518..29128a9b63ae 100644 --- a/drivers/interconnect/qcom/sdm670.c +++ b/drivers/interconnect/qcom/sdm670.c @@ -6,8 +6,9 @@ #include <linux/device.h> #include <linux/interconnect.h> #include <linux/interconnect-provider.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,sdm670-rpmh.h> #include "bcm-voter.h" diff --git a/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c index 954e7bd13fc4..b6e76cb43b0d 100644 --- a/drivers/interconnect/qcom/sdm845.c +++ b/drivers/interconnect/qcom/sdm845.c @@ -7,7 +7,8 @@ #include <linux/interconnect.h> #include <linux/interconnect-provider.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> +#include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,sdm845.h> diff --git a/drivers/interconnect/qcom/sdx55.c b/drivers/interconnect/qcom/sdx55.c index 130a828c3873..cf4cde512613 100644 --- a/drivers/interconnect/qcom/sdx55.c +++ b/drivers/interconnect/qcom/sdx55.c @@ -10,8 +10,9 @@ #include <linux/device.h> #include <linux/interconnect.h> #include <linux/interconnect-provider.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,sdx55.h> #include "bcm-voter.h" diff --git a/drivers/interconnect/qcom/sdx65.c b/drivers/interconnect/qcom/sdx65.c index b16d31d53e9b..f42392d505dd 100644 --- a/drivers/interconnect/qcom/sdx65.c +++ b/drivers/interconnect/qcom/sdx65.c @@ -6,8 +6,9 @@ #include <linux/device.h> #include <linux/interconnect.h> #include <linux/interconnect-provider.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,sdx65.h> #include "bcm-voter.h" diff --git a/drivers/interconnect/qcom/sm6350.c b/drivers/interconnect/qcom/sm6350.c index a3d46e59444e..15c647c0e987 100644 --- a/drivers/interconnect/qcom/sm6350.c +++ b/drivers/interconnect/qcom/sm6350.c @@ -6,8 +6,9 @@ #include <linux/device.h> #include <linux/interconnect.h> #include <linux/interconnect-provider.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,sm6350.h> #include "bcm-voter.h" diff --git a/drivers/interconnect/qcom/sm8150.c b/drivers/interconnect/qcom/sm8150.c index c5ab29322164..7fd19721e458 100644 --- a/drivers/interconnect/qcom/sm8150.c +++ b/drivers/interconnect/qcom/sm8150.c @@ -7,8 +7,9 @@ #include <linux/device.h> #include <linux/interconnect.h> #include <linux/interconnect-provider.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,sm8150.h> #include "bcm-voter.h" diff --git a/drivers/interconnect/qcom/sm8250.c b/drivers/interconnect/qcom/sm8250.c index e3bb008cb219..b8d265f2c176 100644 --- a/drivers/interconnect/qcom/sm8250.c +++ b/drivers/interconnect/qcom/sm8250.c @@ -7,8 +7,9 @@ #include <linux/device.h> #include <linux/interconnect.h> #include <linux/interconnect-provider.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,sm8250.h> #include "bcm-voter.h" @@ -164,6 +165,54 @@ DEFINE_QNODE(xs_pcie_modem, SM8250_SLAVE_PCIE_2, 1, 8); DEFINE_QNODE(xs_qdss_stm, SM8250_SLAVE_QDSS_STM, 1, 4); DEFINE_QNODE(xs_sys_tcu_cfg, SM8250_SLAVE_TCU, 1, 8); +static struct qcom_icc_node qup0_core_master = { + .name = "qup0_core_master", + .id = SM8250_MASTER_QUP_CORE_0, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { SM8250_SLAVE_QUP_CORE_0 }, +}; + +static struct qcom_icc_node qup1_core_master = { + .name = "qup1_core_master", + .id = SM8250_MASTER_QUP_CORE_1, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { SM8250_SLAVE_QUP_CORE_1 }, +}; + +static struct qcom_icc_node qup2_core_master = { + .name = "qup2_core_master", + .id = SM8250_MASTER_QUP_CORE_2, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { SM8250_SLAVE_QUP_CORE_2 }, +}; + +static struct qcom_icc_node qup0_core_slave = { + .name = "qup0_core_slave", + .id = SM8250_SLAVE_QUP_CORE_0, + .channels = 1, + .buswidth = 4, +}; + +static struct qcom_icc_node qup1_core_slave = { + .name = "qup1_core_slave", + .id = SM8250_SLAVE_QUP_CORE_1, + .channels = 1, + .buswidth = 4, +}; + +static struct qcom_icc_node qup2_core_slave = { + .name = "qup2_core_slave", + .id = SM8250_SLAVE_QUP_CORE_2, + .channels = 1, + .buswidth = 4, +}; + DEFINE_QBCM(bcm_acv, "ACV", false, &ebi); DEFINE_QBCM(bcm_mc0, "MC0", true, &ebi); DEFINE_QBCM(bcm_sh0, "SH0", true, &qns_llcc); @@ -172,7 +221,7 @@ DEFINE_QBCM(bcm_ce0, "CE0", false, &qxm_crypto); DEFINE_QBCM(bcm_mm1, "MM1", false, &qnm_camnoc_hf, &qxm_mdp0, &qxm_mdp1); DEFINE_QBCM(bcm_sh2, "SH2", false, &alm_gpu_tcu, &alm_sys_tcu); DEFINE_QBCM(bcm_mm2, "MM2", false, &qns_mem_noc_sf); -DEFINE_QBCM(bcm_qup0, "QUP0", false, &qhm_qup1, &qhm_qup2, &qhm_qup0); +DEFINE_QBCM(bcm_qup0, "QUP0", false, &qup0_core_master, &qup1_core_master, &qup2_core_master); DEFINE_QBCM(bcm_sh3, "SH3", false, &qnm_cmpnoc); DEFINE_QBCM(bcm_mm3, "MM3", false, &qnm_camnoc_icp, &qnm_camnoc_sf, &qnm_video0, &qnm_video1, &qnm_video_cvp); DEFINE_QBCM(bcm_sh4, "SH4", false, &chm_apps); @@ -193,7 +242,6 @@ DEFINE_QBCM(bcm_sn11, "SN11", false, &qnm_gemnoc); DEFINE_QBCM(bcm_sn12, "SN12", false, &qns_pcie_modem_mem_noc, &qns_pcie_mem_noc); static struct qcom_icc_bcm * const aggre1_noc_bcms[] = { - &bcm_qup0, &bcm_sn12, }; @@ -222,10 +270,29 @@ static const struct qcom_icc_desc sm8250_aggre1_noc = { static struct qcom_icc_bcm * const aggre2_noc_bcms[] = { &bcm_ce0, - &bcm_qup0, &bcm_sn12, }; +static struct qcom_icc_bcm * const qup_virt_bcms[] = { + &bcm_qup0, +}; + +static struct qcom_icc_node *qup_virt_nodes[] = { + [MASTER_QUP_CORE_0] = &qup0_core_master, + [MASTER_QUP_CORE_1] = &qup1_core_master, + [MASTER_QUP_CORE_2] = &qup2_core_master, + [SLAVE_QUP_CORE_0] = &qup0_core_slave, + [SLAVE_QUP_CORE_1] = &qup1_core_slave, + [SLAVE_QUP_CORE_2] = &qup2_core_slave, +}; + +static const struct qcom_icc_desc sm8250_qup_virt = { + .nodes = qup_virt_nodes, + .num_nodes = ARRAY_SIZE(qup_virt_nodes), + .bcms = qup_virt_bcms, + .num_bcms = ARRAY_SIZE(qup_virt_bcms), +}; + static struct qcom_icc_node * const aggre2_noc_nodes[] = { [MASTER_A2NOC_CFG] = &qhm_a2noc_cfg, [MASTER_QDSS_BAM] = &qhm_qdss_bam, @@ -518,6 +585,8 @@ static const struct of_device_id qnoc_of_match[] = { .data = &sm8250_mmss_noc}, { .compatible = "qcom,sm8250-npu-noc", .data = &sm8250_npu_noc}, + { .compatible = "qcom,sm8250-qup-virt", + .data = &sm8250_qup_virt }, { .compatible = "qcom,sm8250-system-noc", .data = &sm8250_system_noc}, { } diff --git a/drivers/interconnect/qcom/sm8250.h b/drivers/interconnect/qcom/sm8250.h index 209ab195f21f..032665093c5b 100644 --- a/drivers/interconnect/qcom/sm8250.h +++ b/drivers/interconnect/qcom/sm8250.h @@ -158,5 +158,11 @@ #define SM8250_SLAVE_VSENSE_CTRL_CFG 147 #define SM8250_SNOC_CNOC_MAS 148 #define SM8250_SNOC_CNOC_SLV 149 +#define SM8250_MASTER_QUP_CORE_0 150 +#define SM8250_MASTER_QUP_CORE_1 151 +#define SM8250_MASTER_QUP_CORE_2 152 +#define SM8250_SLAVE_QUP_CORE_0 153 +#define SM8250_SLAVE_QUP_CORE_1 154 +#define SM8250_SLAVE_QUP_CORE_2 155 #endif diff --git a/drivers/interconnect/qcom/sm8350.c b/drivers/interconnect/qcom/sm8350.c index 5398e7c8d826..0e02e1800e0c 100644 --- a/drivers/interconnect/qcom/sm8350.c +++ b/drivers/interconnect/qcom/sm8350.c @@ -7,7 +7,8 @@ #include <linux/interconnect-provider.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> +#include <linux/platform_device.h> #include <dt-bindings/interconnect/qcom,sm8350.h> #include "bcm-voter.h" diff --git a/drivers/interconnect/qcom/sm8450.c b/drivers/interconnect/qcom/sm8450.c index e64c214b4020..eb7e17df32ba 100644 --- a/drivers/interconnect/qcom/sm8450.c +++ b/drivers/interconnect/qcom/sm8450.c @@ -8,7 +8,9 @@ #include <linux/interconnect.h> #include <linux/interconnect-provider.h> #include <linux/module.h> -#include <linux/of_platform.h> +#include <linux/mod_devicetable.h> +#include <linux/platform_device.h> +#include <linux/property.h> #include <dt-bindings/interconnect/qcom,sm8450.h> #include "bcm-voter.h" @@ -1886,6 +1888,7 @@ static struct platform_driver qnoc_driver = { .driver = { .name = "qnoc-sm8450", .of_match_table = qnoc_of_match, + .sync_state = icc_sync_state, }, }; diff --git a/drivers/interconnect/qcom/sm8550.c b/drivers/interconnect/qcom/sm8550.c index 0864ed285375..a10c8b6549ee 100644 --- a/drivers/interconnect/qcom/sm8550.c +++ b/drivers/interconnect/qcom/sm8550.c @@ -10,7 +10,9 @@ #include <linux/interconnect.h> #include <linux/interconnect-provider.h> #include <linux/module.h> -#include <linux/of_platform.h> +#include <linux/mod_devicetable.h> +#include <linux/platform_device.h> +#include <linux/property.h> #include <dt-bindings/interconnect/qcom,sm8550-rpmh.h> #include "bcm-voter.h" diff --git a/drivers/interconnect/qcom/smd-rpm.c b/drivers/interconnect/qcom/smd-rpm.c index dc8ff8d133a9..16a145a3c914 100644 --- a/drivers/interconnect/qcom/smd-rpm.c +++ b/drivers/interconnect/qcom/smd-rpm.c @@ -8,14 +8,13 @@ #include <linux/interconnect-provider.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/soc/qcom/smd-rpm.h> -#include "smd-rpm.h" +#include "icc-rpm.h" #define RPM_KEY_BW 0x00007762 +#define QCOM_RPM_SMD_KEY_RATE 0x007a484b static struct qcom_smd_rpm *icc_smd_rpm; @@ -44,6 +43,26 @@ int qcom_icc_rpm_smd_send(int ctx, int rsc_type, int id, u32 val) } EXPORT_SYMBOL_GPL(qcom_icc_rpm_smd_send); +int qcom_icc_rpm_set_bus_rate(const struct rpm_clk_resource *clk, int ctx, u32 rate) +{ + struct clk_smd_rpm_req req = { + .key = cpu_to_le32(QCOM_RPM_SMD_KEY_RATE), + .nbytes = cpu_to_le32(sizeof(u32)), + }; + + /* Branch clocks are only on/off */ + if (clk->branch) + rate = !!rate; + + req.value = cpu_to_le32(rate); + return qcom_rpm_smd_write(icc_smd_rpm, + ctx, + clk->resource_type, + clk->clock_id, + &req, sizeof(req)); +} +EXPORT_SYMBOL_GPL(qcom_icc_rpm_set_bus_rate); + static int qcom_icc_rpm_smd_remove(struct platform_device *pdev) { icc_smd_rpm = NULL; diff --git a/drivers/interconnect/qcom/smd-rpm.h b/drivers/interconnect/qcom/smd-rpm.h deleted file mode 100644 index ca9d0327b8ac..000000000000 --- a/drivers/interconnect/qcom/smd-rpm.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2019, Linaro Ltd. - * Author: Georgi Djakov <georgi.djakov@linaro.org> - */ - -#ifndef __DRIVERS_INTERCONNECT_QCOM_SMD_RPM_H -#define __DRIVERS_INTERCONNECT_QCOM_SMD_RPM_H - -#include <linux/soc/qcom/smd-rpm.h> - -bool qcom_icc_rpm_smd_available(void); -int qcom_icc_rpm_smd_send(int ctx, int rsc_type, int id, u32 val); - -#endif diff --git a/drivers/soc/qcom/smd-rpm.c b/drivers/soc/qcom/smd-rpm.c index 0c1aa809cc4e..577f1f25ab10 100644 --- a/drivers/soc/qcom/smd-rpm.c +++ b/drivers/soc/qcom/smd-rpm.c @@ -19,7 +19,6 @@ /** * struct qcom_smd_rpm - state of the rpm device driver * @rpm_channel: reference to the smd channel - * @icc: interconnect proxy device * @dev: rpm device * @ack: completion for acks * @lock: mutual exclusion around the send/complete pair @@ -27,7 +26,6 @@ */ struct qcom_smd_rpm { struct rpmsg_endpoint *rpm_channel; - struct platform_device *icc; struct device *dev; struct completion ack; @@ -197,7 +195,6 @@ static int qcom_smd_rpm_callback(struct rpmsg_device *rpdev, static int qcom_smd_rpm_probe(struct rpmsg_device *rpdev) { struct qcom_smd_rpm *rpm; - int ret; rpm = devm_kzalloc(&rpdev->dev, sizeof(*rpm), GFP_KERNEL); if (!rpm) @@ -210,23 +207,11 @@ static int qcom_smd_rpm_probe(struct rpmsg_device *rpdev) rpm->rpm_channel = rpdev->ept; dev_set_drvdata(&rpdev->dev, rpm); - rpm->icc = platform_device_register_data(&rpdev->dev, "icc_smd_rpm", -1, - NULL, 0); - if (IS_ERR(rpm->icc)) - return PTR_ERR(rpm->icc); - - ret = of_platform_populate(rpdev->dev.of_node, NULL, NULL, &rpdev->dev); - if (ret) - platform_device_unregister(rpm->icc); - - return ret; + return of_platform_populate(rpdev->dev.of_node, NULL, NULL, &rpdev->dev); } static void qcom_smd_rpm_remove(struct rpmsg_device *rpdev) { - struct qcom_smd_rpm *rpm = dev_get_drvdata(&rpdev->dev); - - platform_device_unregister(rpm->icc); of_platform_depopulate(&rpdev->dev); } diff --git a/include/dt-bindings/interconnect/qcom,rpm-icc.h b/include/dt-bindings/interconnect/qcom,rpm-icc.h new file mode 100644 index 000000000000..2cd56f91e5c5 --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,rpm-icc.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2023, Linaro Limited + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_RPM_ICC_H +#define __DT_BINDINGS_INTERCONNECT_QCOM_RPM_ICC_H + +#define RPM_ACTIVE_TAG (1 << 0) +#define RPM_SLEEP_TAG (1 << 1) +#define RPM_ALWAYS_TAG (RPM_ACTIVE_TAG | RPM_SLEEP_TAG) + +#endif diff --git a/include/dt-bindings/interconnect/qcom,sm8250.h b/include/dt-bindings/interconnect/qcom,sm8250.h index a4af5cc19271..2a656c02df4b 100644 --- a/include/dt-bindings/interconnect/qcom,sm8250.h +++ b/include/dt-bindings/interconnect/qcom,sm8250.h @@ -166,4 +166,11 @@ #define SLAVE_QDSS_STM 17 #define SLAVE_TCU 18 +#define MASTER_QUP_CORE_0 0 +#define MASTER_QUP_CORE_1 1 +#define MASTER_QUP_CORE_2 2 +#define SLAVE_QUP_CORE_0 3 +#define SLAVE_QUP_CORE_1 4 +#define SLAVE_QUP_CORE_2 5 + #endif diff --git a/include/linux/interconnect-provider.h b/include/linux/interconnect-provider.h index e6d8aca6886d..7ba183f221f1 100644 --- a/include/linux/interconnect-provider.h +++ b/include/linux/interconnect-provider.h @@ -33,7 +33,7 @@ struct icc_node_data { */ struct icc_onecell_data { unsigned int num_nodes; - struct icc_node *nodes[]; + struct icc_node *nodes[] __counted_by(num_nodes); }; struct icc_node *of_icc_xlate_onecell(struct of_phandle_args *spec, diff --git a/include/linux/soc/qcom/smd-rpm.h b/include/linux/soc/qcom/smd-rpm.h index 2990f425fdef..8190878645f9 100644 --- a/include/linux/soc/qcom/smd-rpm.h +++ b/include/linux/soc/qcom/smd-rpm.h @@ -2,10 +2,13 @@ #ifndef __QCOM_SMD_RPM_H__ #define __QCOM_SMD_RPM_H__ +#include <linux/types.h> + struct qcom_smd_rpm; -#define QCOM_SMD_RPM_ACTIVE_STATE 0 -#define QCOM_SMD_RPM_SLEEP_STATE 1 +#define QCOM_SMD_RPM_ACTIVE_STATE 0 +#define QCOM_SMD_RPM_SLEEP_STATE 1 +#define QCOM_SMD_RPM_STATE_NUM 2 /* * Constants used for addressing resources in the RPM. @@ -44,6 +47,19 @@ struct qcom_smd_rpm; #define QCOM_SMD_RPM_PKA_CLK 0x616b70 #define QCOM_SMD_RPM_MCFG_CLK 0x6766636d +#define QCOM_RPM_KEY_SOFTWARE_ENABLE 0x6e657773 +#define QCOM_RPM_KEY_PIN_CTRL_CLK_BUFFER_ENABLE_KEY 0x62636370 +#define QCOM_RPM_SMD_KEY_RATE 0x007a484b +#define QCOM_RPM_SMD_KEY_ENABLE 0x62616e45 +#define QCOM_RPM_SMD_KEY_STATE 0x54415453 +#define QCOM_RPM_SCALING_ENABLE_ID 0x2 + +struct clk_smd_rpm_req { + __le32 key; + __le32 nbytes; + __le32 value; +}; + int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm, int state, u32 resource_type, u32 resource_id, |