diff options
-rw-r--r-- | drivers/interconnect/qcom/icc-rpm.c | 42 | ||||
-rw-r--r-- | drivers/interconnect/qcom/icc-rpm.h | 14 | ||||
-rw-r--r-- | drivers/interconnect/qcom/msm8996.c | 22 | ||||
-rw-r--r-- | drivers/interconnect/qcom/sdm660.c | 16 |
4 files changed, 59 insertions, 35 deletions
diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c index d79e508cb717..c34f75703a66 100644 --- a/drivers/interconnect/qcom/icc-rpm.c +++ b/drivers/interconnect/qcom/icc-rpm.c @@ -409,7 +409,7 @@ int qnoc_probe(struct platform_device *pdev) struct qcom_icc_provider *qp; struct icc_node *node; size_t num_nodes, i; - const char * const *cds; + const char * const *cds = NULL; int cd_num; int ret; @@ -424,21 +424,20 @@ int qnoc_probe(struct platform_device *pdev) qnodes = desc->nodes; num_nodes = desc->num_nodes; - if (desc->num_bus_clocks) { - cds = desc->bus_clocks; - cd_num = desc->num_bus_clocks; + if (desc->num_intf_clocks) { + cds = desc->intf_clocks; + cd_num = desc->num_intf_clocks; } else { - cds = bus_clocks; - cd_num = ARRAY_SIZE(bus_clocks); + /* 0 intf clocks is perfectly fine */ + cd_num = 0; } - qp = devm_kzalloc(dev, struct_size(qp, bus_clks, cd_num), GFP_KERNEL); + qp = devm_kzalloc(dev, sizeof(*qp), GFP_KERNEL); if (!qp) return -ENOMEM; - qp->bus_clk_rate = devm_kcalloc(dev, cd_num, sizeof(*qp->bus_clk_rate), - GFP_KERNEL); - if (!qp->bus_clk_rate) + qp->intf_clks = devm_kzalloc(dev, sizeof(qp->intf_clks), GFP_KERNEL); + if (!qp->intf_clks) return -ENOMEM; data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes), @@ -446,6 +445,18 @@ int qnoc_probe(struct platform_device *pdev) if (!data) return -ENOMEM; + qp->num_intf_clks = cd_num; + for (i = 0; i < cd_num; i++) + qp->intf_clks[i].id = cds[i]; + + if (desc->num_bus_clocks) { + cds = desc->bus_clocks; + cd_num = desc->num_bus_clocks; + } else { + cds = bus_clocks; + cd_num = ARRAY_SIZE(bus_clocks); + } + for (i = 0; i < cd_num; i++) qp->bus_clks[i].id = cds[i]; qp->num_bus_clks = cd_num; @@ -486,6 +497,10 @@ regmap_done: if (ret) return ret; + ret = devm_clk_bulk_get(dev, qp->num_intf_clks, qp->intf_clks); + if (ret) + return ret; + provider = &qp->provider; provider->dev = dev; provider->set = qcom_icc_set; @@ -496,6 +511,11 @@ regmap_done: icc_provider_init(provider); + /* If this fails, bus accesses will crash the platform! */ + ret = clk_bulk_prepare_enable(qp->num_intf_clks, qp->intf_clks); + if (ret) + return ret; + for (i = 0; i < num_nodes; i++) { size_t j; @@ -524,6 +544,8 @@ regmap_done: } data->num_nodes = num_nodes; + clk_bulk_disable_unprepare(qp->num_intf_clks, qp->intf_clks); + ret = icc_provider_register(provider); if (ret) goto err_remove_nodes; diff --git a/drivers/interconnect/qcom/icc-rpm.h b/drivers/interconnect/qcom/icc-rpm.h index 2436777820a4..b9b63860042f 100644 --- a/drivers/interconnect/qcom/icc-rpm.h +++ b/drivers/interconnect/qcom/icc-rpm.h @@ -20,24 +20,32 @@ enum qcom_icc_type { QCOM_ICC_QNOC, }; +#define NUM_BUS_CLKS 2 + /** * 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 + * @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 + * @intf_clks: a clk_bulk_data array of interface 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; - struct clk_bulk_data bus_clks[]; + u64 bus_clk_rate[NUM_BUS_CLKS]; + struct clk_bulk_data bus_clks[NUM_BUS_CLKS]; + struct clk_bulk_data *intf_clks; + bool is_on; }; /** @@ -93,6 +101,8 @@ struct qcom_icc_desc { size_t num_nodes; const char * const *bus_clocks; size_t num_bus_clocks; + const char * const *intf_clocks; + size_t num_intf_clocks; enum qcom_icc_type type; const struct regmap_config *regmap_cfg; unsigned int qos_offset; diff --git a/drivers/interconnect/qcom/msm8996.c b/drivers/interconnect/qcom/msm8996.c index 21f998cd19f0..9aedfc8de4bf 100644 --- a/drivers/interconnect/qcom/msm8996.c +++ b/drivers/interconnect/qcom/msm8996.c @@ -21,21 +21,17 @@ #include "smd-rpm.h" #include "msm8996.h" -static const char * const bus_mm_clocks[] = { - "bus", - "bus_a", +static const char * const mm_intf_clocks[] = { "iface" }; -static const char * const bus_a0noc_clocks[] = { +static const char * const a0noc_intf_clocks[] = { "aggre0_snoc_axi", "aggre0_cnoc_ahb", "aggre0_noc_mpu_cfg" }; -static const char * const bus_a2noc_clocks[] = { - "bus", - "bus_a", +static const char * const a2noc_intf_clocks[] = { "aggre2_ufs_axi", "ufs_axi" }; @@ -1821,8 +1817,8 @@ static const struct qcom_icc_desc msm8996_a0noc = { .type = QCOM_ICC_NOC, .nodes = a0noc_nodes, .num_nodes = ARRAY_SIZE(a0noc_nodes), - .bus_clocks = bus_a0noc_clocks, - .num_bus_clocks = ARRAY_SIZE(bus_a0noc_clocks), + .intf_clocks = a0noc_intf_clocks, + .num_intf_clocks = ARRAY_SIZE(a0noc_intf_clocks), .regmap_cfg = &msm8996_a0noc_regmap_config }; @@ -1865,8 +1861,8 @@ static const struct qcom_icc_desc msm8996_a2noc = { .type = QCOM_ICC_NOC, .nodes = a2noc_nodes, .num_nodes = ARRAY_SIZE(a2noc_nodes), - .bus_clocks = bus_a2noc_clocks, - .num_bus_clocks = ARRAY_SIZE(bus_a2noc_clocks), + .intf_clocks = a2noc_intf_clocks, + .num_intf_clocks = ARRAY_SIZE(a2noc_intf_clocks), .regmap_cfg = &msm8996_a2noc_regmap_config }; @@ -2004,8 +2000,8 @@ static const struct qcom_icc_desc msm8996_mnoc = { .type = QCOM_ICC_NOC, .nodes = mnoc_nodes, .num_nodes = ARRAY_SIZE(mnoc_nodes), - .bus_clocks = bus_mm_clocks, - .num_bus_clocks = ARRAY_SIZE(bus_mm_clocks), + .intf_clocks = mm_intf_clocks, + .num_intf_clocks = ARRAY_SIZE(mm_intf_clocks), .regmap_cfg = &msm8996_mnoc_regmap_config }; diff --git a/drivers/interconnect/qcom/sdm660.c b/drivers/interconnect/qcom/sdm660.c index a22ba821efbf..0e8a96f4ce90 100644 --- a/drivers/interconnect/qcom/sdm660.c +++ b/drivers/interconnect/qcom/sdm660.c @@ -127,15 +127,11 @@ enum { SDM660_SNOC, }; -static const char * const bus_mm_clocks[] = { - "bus", - "bus_a", +static const char * const mm_intf_clocks[] = { "iface", }; -static const char * const bus_a2noc_clocks[] = { - "bus", - "bus_a", +static const char * const a2noc_intf_clocks[] = { "ipa", "ufs_axi", "aggre2_ufs_axi", @@ -1516,8 +1512,8 @@ static const struct qcom_icc_desc sdm660_a2noc = { .type = QCOM_ICC_NOC, .nodes = sdm660_a2noc_nodes, .num_nodes = ARRAY_SIZE(sdm660_a2noc_nodes), - .bus_clocks = bus_a2noc_clocks, - .num_bus_clocks = ARRAY_SIZE(bus_a2noc_clocks), + .intf_clocks = a2noc_intf_clocks, + .num_intf_clocks = ARRAY_SIZE(a2noc_intf_clocks), .regmap_cfg = &sdm660_a2noc_regmap_config, }; @@ -1659,8 +1655,8 @@ static const struct qcom_icc_desc sdm660_mnoc = { .type = QCOM_ICC_NOC, .nodes = sdm660_mnoc_nodes, .num_nodes = ARRAY_SIZE(sdm660_mnoc_nodes), - .bus_clocks = bus_mm_clocks, - .num_bus_clocks = ARRAY_SIZE(bus_mm_clocks), + .intf_clocks = mm_intf_clocks, + .num_intf_clocks = ARRAY_SIZE(mm_intf_clocks), .regmap_cfg = &sdm660_mnoc_regmap_config, }; |