Commit 691a0180 authored by Stephen Boyd's avatar Stephen Boyd

Merge tag 'qcom-clk-for-6.11-2' of...

Merge tag 'qcom-clk-for-6.11-2' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into clk-qcom

Pull more qcom clk driver updates from Bjorn Andersson:

 - Introduces helper logic to expose clock controllers as simple
   interconnect providers
 - Use the interconnect helper above on Qualcomm ipq9574
 - Add CLK_SET_RATE_PARENT to the remaining USB pipe clocks on Qualcomm
   X1Elite.
 - Improve error handling in Qualcomm kpss-xcc driver
 - Mark Qualcomm SC8280XP LPASS clock controller regmap_config const

* tag 'qcom-clk-for-6.11-2' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux:
  clk: qcom: ipq9574: Use icc-clk for enabling NoC related clocks
  clk: qcom: common: Add interconnect clocks support
  interconnect: icc-clk: Add devm_icc_clk_register
  interconnect: icc-clk: Specify master/slave ids
  dt-bindings: clock: qcom: Add AHB clock for SM8150
  clk: qcom: gcc-x1e80100: Set parent rate for USB3 sec and tert PHY pipe clks
  dt-bindings: interconnect: Add Qualcomm IPQ9574 support
  clk: qcom: kpss-xcc: Return of_clk_add_hw_provider to transfer the error
  clk: qcom: lpasscc-sc8280xp: Constify struct regmap_config
parents 01a0a6cc 23711cab
...@@ -35,6 +35,9 @@ properties: ...@@ -35,6 +35,9 @@ properties:
'#power-domain-cells': false '#power-domain-cells': false
'#interconnect-cells':
const: 1
required: required:
- compatible - compatible
- clocks - clocks
......
...@@ -62,7 +62,6 @@ allOf: ...@@ -62,7 +62,6 @@ allOf:
enum: enum:
- qcom,sc7180-videocc - qcom,sc7180-videocc
- qcom,sdm845-videocc - qcom,sdm845-videocc
- qcom,sm8150-videocc
then: then:
properties: properties:
clocks: clocks:
...@@ -88,6 +87,22 @@ allOf: ...@@ -88,6 +87,22 @@ allOf:
- const: bi_tcxo - const: bi_tcxo
- const: bi_tcxo_ao - const: bi_tcxo_ao
- if:
properties:
compatible:
enum:
- qcom,sm8150-videocc
then:
properties:
clocks:
items:
- description: AHB
- description: Board XO source
clock-names:
items:
- const: iface
- const: bi_tcxo
- if: - if:
properties: properties:
compatible: compatible:
......
...@@ -14,6 +14,8 @@ menuconfig COMMON_CLK_QCOM ...@@ -14,6 +14,8 @@ menuconfig COMMON_CLK_QCOM
select RATIONAL select RATIONAL
select REGMAP_MMIO select REGMAP_MMIO
select RESET_CONTROLLER select RESET_CONTROLLER
select INTERCONNECT
select INTERCONNECT_CLK
if COMMON_CLK_QCOM if COMMON_CLK_QCOM
......
...@@ -226,7 +226,12 @@ static int qcom_msm8996_cbf_icc_register(struct platform_device *pdev, struct cl ...@@ -226,7 +226,12 @@ static int qcom_msm8996_cbf_icc_register(struct platform_device *pdev, struct cl
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct clk *clk = devm_clk_hw_get_clk(dev, cbf_hw, "cbf"); struct clk *clk = devm_clk_hw_get_clk(dev, cbf_hw, "cbf");
const struct icc_clk_data data[] = { const struct icc_clk_data data[] = {
{ .clk = clk, .name = "cbf", }, {
.clk = clk,
.name = "cbf",
.master_id = MASTER_CBF_M4M,
.slave_id = SLAVE_CBF_M4M,
},
}; };
struct icc_provider *provider; struct icc_provider *provider;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/interconnect-clk.h>
#include <linux/reset-controller.h> #include <linux/reset-controller.h>
#include <linux/of.h> #include <linux/of.h>
...@@ -252,6 +253,38 @@ static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec, ...@@ -252,6 +253,38 @@ static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec,
return cc->rclks[idx] ? &cc->rclks[idx]->hw : NULL; return cc->rclks[idx] ? &cc->rclks[idx]->hw : NULL;
} }
static int qcom_cc_icc_register(struct device *dev,
const struct qcom_cc_desc *desc)
{
struct icc_clk_data *icd;
struct clk_hw *hws;
int i;
if (!IS_ENABLED(CONFIG_INTERCONNECT_CLK))
return 0;
if (!desc->icc_hws)
return 0;
icd = devm_kcalloc(dev, desc->num_icc_hws, sizeof(*icd), GFP_KERNEL);
if (!icd)
return -ENOMEM;
for (i = 0; i < desc->num_icc_hws; i++) {
icd[i].master_id = desc->icc_hws[i].master_id;
icd[i].slave_id = desc->icc_hws[i].slave_id;
hws = &desc->clks[desc->icc_hws[i].clk_id]->hw;
icd[i].clk = devm_clk_hw_get_clk(dev, hws, "icc");
if (!icd[i].clk)
return dev_err_probe(dev, -ENOENT,
"(%d) clock entry is null\n", i);
icd[i].name = clk_hw_get_name(hws);
}
return devm_icc_clk_register(dev, desc->icc_first_node_id,
desc->num_icc_hws, icd);
}
int qcom_cc_really_probe(struct device *dev, int qcom_cc_really_probe(struct device *dev,
const struct qcom_cc_desc *desc, struct regmap *regmap) const struct qcom_cc_desc *desc, struct regmap *regmap)
{ {
...@@ -320,7 +353,7 @@ int qcom_cc_really_probe(struct device *dev, ...@@ -320,7 +353,7 @@ int qcom_cc_really_probe(struct device *dev,
if (ret) if (ret)
return ret; return ret;
return 0; return qcom_cc_icc_register(dev, desc);
} }
EXPORT_SYMBOL_GPL(qcom_cc_really_probe); EXPORT_SYMBOL_GPL(qcom_cc_really_probe);
......
...@@ -19,6 +19,12 @@ struct clk_hw; ...@@ -19,6 +19,12 @@ struct clk_hw;
#define PLL_VOTE_FSM_ENA BIT(20) #define PLL_VOTE_FSM_ENA BIT(20)
#define PLL_VOTE_FSM_RESET BIT(21) #define PLL_VOTE_FSM_RESET BIT(21)
struct qcom_icc_hws_data {
int master_id;
int slave_id;
int clk_id;
};
struct qcom_cc_desc { struct qcom_cc_desc {
const struct regmap_config *config; const struct regmap_config *config;
struct clk_regmap **clks; struct clk_regmap **clks;
...@@ -29,6 +35,9 @@ struct qcom_cc_desc { ...@@ -29,6 +35,9 @@ struct qcom_cc_desc {
size_t num_gdscs; size_t num_gdscs;
struct clk_hw **clk_hws; struct clk_hw **clk_hws;
size_t num_clk_hws; size_t num_clk_hws;
struct qcom_icc_hws_data *icc_hws;
size_t num_icc_hws;
unsigned int icc_first_node_id;
}; };
/** /**
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
*/ */
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/interconnect-clk.h>
#include <linux/interconnect-provider.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
...@@ -12,6 +14,7 @@ ...@@ -12,6 +14,7 @@
#include <dt-bindings/clock/qcom,ipq9574-gcc.h> #include <dt-bindings/clock/qcom,ipq9574-gcc.h>
#include <dt-bindings/reset/qcom,ipq9574-gcc.h> #include <dt-bindings/reset/qcom,ipq9574-gcc.h>
#include <dt-bindings/interconnect/qcom,ipq9574.h>
#include "clk-alpha-pll.h" #include "clk-alpha-pll.h"
#include "clk-branch.h" #include "clk-branch.h"
...@@ -4377,6 +4380,32 @@ static const struct qcom_reset_map gcc_ipq9574_resets[] = { ...@@ -4377,6 +4380,32 @@ static const struct qcom_reset_map gcc_ipq9574_resets[] = {
[GCC_WCSS_Q6_TBU_BCR] = { 0x12054, 0 }, [GCC_WCSS_Q6_TBU_BCR] = { 0x12054, 0 },
}; };
#define IPQ_APPS_ID 9574 /* some unique value */
static struct qcom_icc_hws_data icc_ipq9574_hws[] = {
{ MASTER_ANOC_PCIE0, SLAVE_ANOC_PCIE0, GCC_ANOC_PCIE0_1LANE_M_CLK },
{ MASTER_SNOC_PCIE0, SLAVE_SNOC_PCIE0, GCC_SNOC_PCIE0_1LANE_S_CLK },
{ MASTER_ANOC_PCIE1, SLAVE_ANOC_PCIE1, GCC_ANOC_PCIE1_1LANE_M_CLK },
{ MASTER_SNOC_PCIE1, SLAVE_SNOC_PCIE1, GCC_SNOC_PCIE1_1LANE_S_CLK },
{ MASTER_ANOC_PCIE2, SLAVE_ANOC_PCIE2, GCC_ANOC_PCIE2_2LANE_M_CLK },
{ MASTER_SNOC_PCIE2, SLAVE_SNOC_PCIE2, GCC_SNOC_PCIE2_2LANE_S_CLK },
{ MASTER_ANOC_PCIE3, SLAVE_ANOC_PCIE3, GCC_ANOC_PCIE3_2LANE_M_CLK },
{ MASTER_SNOC_PCIE3, SLAVE_SNOC_PCIE3, GCC_SNOC_PCIE3_2LANE_S_CLK },
{ MASTER_USB, SLAVE_USB, GCC_SNOC_USB_CLK },
{ MASTER_USB_AXI, SLAVE_USB_AXI, GCC_ANOC_USB_AXI_CLK },
{ MASTER_NSSNOC_NSSCC, SLAVE_NSSNOC_NSSCC, GCC_NSSNOC_NSSCC_CLK },
{ MASTER_NSSNOC_SNOC_0, SLAVE_NSSNOC_SNOC_0, GCC_NSSNOC_SNOC_CLK },
{ MASTER_NSSNOC_SNOC_1, SLAVE_NSSNOC_SNOC_1, GCC_NSSNOC_SNOC_1_CLK },
{ MASTER_NSSNOC_PCNOC_1, SLAVE_NSSNOC_PCNOC_1, GCC_NSSNOC_PCNOC_1_CLK },
{ MASTER_NSSNOC_QOSGEN_REF, SLAVE_NSSNOC_QOSGEN_REF, GCC_NSSNOC_QOSGEN_REF_CLK },
{ MASTER_NSSNOC_TIMEOUT_REF, SLAVE_NSSNOC_TIMEOUT_REF, GCC_NSSNOC_TIMEOUT_REF_CLK },
{ MASTER_NSSNOC_XO_DCD, SLAVE_NSSNOC_XO_DCD, GCC_NSSNOC_XO_DCD_CLK },
{ MASTER_NSSNOC_ATB, SLAVE_NSSNOC_ATB, GCC_NSSNOC_ATB_CLK },
{ MASTER_MEM_NOC_NSSNOC, SLAVE_MEM_NOC_NSSNOC, GCC_MEM_NOC_NSSNOC_CLK },
{ MASTER_NSSNOC_MEMNOC, SLAVE_NSSNOC_MEMNOC, GCC_NSSNOC_MEMNOC_CLK },
{ MASTER_NSSNOC_MEM_NOC_1, SLAVE_NSSNOC_MEM_NOC_1, GCC_NSSNOC_MEM_NOC_1_CLK },
};
static const struct of_device_id gcc_ipq9574_match_table[] = { static const struct of_device_id gcc_ipq9574_match_table[] = {
{ .compatible = "qcom,ipq9574-gcc" }, { .compatible = "qcom,ipq9574-gcc" },
{ } { }
...@@ -4399,6 +4428,9 @@ static const struct qcom_cc_desc gcc_ipq9574_desc = { ...@@ -4399,6 +4428,9 @@ static const struct qcom_cc_desc gcc_ipq9574_desc = {
.num_resets = ARRAY_SIZE(gcc_ipq9574_resets), .num_resets = ARRAY_SIZE(gcc_ipq9574_resets),
.clk_hws = gcc_ipq9574_hws, .clk_hws = gcc_ipq9574_hws,
.num_clk_hws = ARRAY_SIZE(gcc_ipq9574_hws), .num_clk_hws = ARRAY_SIZE(gcc_ipq9574_hws),
.icc_hws = icc_ipq9574_hws,
.num_icc_hws = ARRAY_SIZE(icc_ipq9574_hws),
.icc_first_node_id = IPQ_APPS_ID,
}; };
static int gcc_ipq9574_probe(struct platform_device *pdev) static int gcc_ipq9574_probe(struct platform_device *pdev)
...@@ -4411,6 +4443,7 @@ static struct platform_driver gcc_ipq9574_driver = { ...@@ -4411,6 +4443,7 @@ static struct platform_driver gcc_ipq9574_driver = {
.driver = { .driver = {
.name = "qcom,gcc-ipq9574", .name = "qcom,gcc-ipq9574",
.of_match_table = gcc_ipq9574_match_table, .of_match_table = gcc_ipq9574_match_table,
.sync_state = icc_sync_state,
}, },
}; };
......
...@@ -5269,6 +5269,7 @@ static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { ...@@ -5269,6 +5269,7 @@ static struct clk_branch gcc_usb3_sec_phy_pipe_clk = {
&gcc_usb3_sec_phy_pipe_clk_src.clkr.hw, &gcc_usb3_sec_phy_pipe_clk_src.clkr.hw,
}, },
.num_parents = 1, .num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops, .ops = &clk_branch2_ops,
}, },
}, },
...@@ -5339,6 +5340,7 @@ static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { ...@@ -5339,6 +5340,7 @@ static struct clk_branch gcc_usb3_tert_phy_pipe_clk = {
&gcc_usb3_tert_phy_pipe_clk_src.clkr.hw, &gcc_usb3_tert_phy_pipe_clk_src.clkr.hw,
}, },
.num_parents = 1, .num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops, .ops = &clk_branch2_ops,
}, },
}, },
......
...@@ -58,9 +58,7 @@ static int kpss_xcc_driver_probe(struct platform_device *pdev) ...@@ -58,9 +58,7 @@ static int kpss_xcc_driver_probe(struct platform_device *pdev)
if (IS_ERR(hw)) if (IS_ERR(hw))
return PTR_ERR(hw); return PTR_ERR(hw);
of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, hw); return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, hw);
return 0;
} }
static struct platform_driver kpss_xcc_driver = { static struct platform_driver kpss_xcc_driver = {
......
...@@ -23,7 +23,7 @@ static const struct qcom_reset_map lpass_audiocc_sc8280xp_resets[] = { ...@@ -23,7 +23,7 @@ static const struct qcom_reset_map lpass_audiocc_sc8280xp_resets[] = {
[LPASS_AUDIO_SWR_WSA2_CGCR] = { 0xd8, 1 }, [LPASS_AUDIO_SWR_WSA2_CGCR] = { 0xd8, 1 },
}; };
static struct regmap_config lpass_audiocc_sc8280xp_regmap_config = { static const struct regmap_config lpass_audiocc_sc8280xp_regmap_config = {
.reg_bits = 32, .reg_bits = 32,
.reg_stride = 4, .reg_stride = 4,
.val_bits = 32, .val_bits = 32,
...@@ -41,7 +41,7 @@ static const struct qcom_reset_map lpasscc_sc8280xp_resets[] = { ...@@ -41,7 +41,7 @@ static const struct qcom_reset_map lpasscc_sc8280xp_resets[] = {
[LPASS_AUDIO_SWR_TX_CGCR] = { 0xc010, 1 }, [LPASS_AUDIO_SWR_TX_CGCR] = { 0xc010, 1 },
}; };
static struct regmap_config lpasscc_sc8280xp_regmap_config = { static const struct regmap_config lpasscc_sc8280xp_regmap_config = {
.reg_bits = 32, .reg_bits = 32,
.reg_stride = 4, .reg_stride = 4,
.val_bits = 32, .val_bits = 32,
......
...@@ -108,7 +108,7 @@ struct icc_provider *icc_clk_register(struct device *dev, ...@@ -108,7 +108,7 @@ struct icc_provider *icc_clk_register(struct device *dev,
for (i = 0, j = 0; i < num_clocks; i++) { for (i = 0, j = 0; i < num_clocks; i++) {
qp->clocks[i].clk = data[i].clk; qp->clocks[i].clk = data[i].clk;
node = icc_node_create(first_id + j); node = icc_node_create(first_id + data[i].master_id);
if (IS_ERR(node)) { if (IS_ERR(node)) {
ret = PTR_ERR(node); ret = PTR_ERR(node);
goto err; goto err;
...@@ -118,10 +118,10 @@ struct icc_provider *icc_clk_register(struct device *dev, ...@@ -118,10 +118,10 @@ struct icc_provider *icc_clk_register(struct device *dev,
node->data = &qp->clocks[i]; node->data = &qp->clocks[i];
icc_node_add(node, provider); icc_node_add(node, provider);
/* link to the next node, slave */ /* link to the next node, slave */
icc_link_create(node, first_id + j + 1); icc_link_create(node, first_id + data[i].slave_id);
onecell->nodes[j++] = node; onecell->nodes[j++] = node;
node = icc_node_create(first_id + j); node = icc_node_create(first_id + data[i].slave_id);
if (IS_ERR(node)) { if (IS_ERR(node)) {
ret = PTR_ERR(node); ret = PTR_ERR(node);
goto err; goto err;
...@@ -148,6 +148,24 @@ struct icc_provider *icc_clk_register(struct device *dev, ...@@ -148,6 +148,24 @@ struct icc_provider *icc_clk_register(struct device *dev,
} }
EXPORT_SYMBOL_GPL(icc_clk_register); EXPORT_SYMBOL_GPL(icc_clk_register);
static void devm_icc_release(void *res)
{
icc_clk_unregister(res);
}
int devm_icc_clk_register(struct device *dev, unsigned int first_id,
unsigned int num_clocks, const struct icc_clk_data *data)
{
struct icc_provider *prov;
prov = icc_clk_register(dev, first_id, num_clocks, data);
if (IS_ERR(prov))
return PTR_ERR(prov);
return devm_add_action_or_reset(dev, devm_icc_release, prov);
}
EXPORT_SYMBOL_GPL(devm_icc_clk_register);
/** /**
* icc_clk_unregister() - unregister a previously registered clk interconnect provider * icc_clk_unregister() - unregister a previously registered clk interconnect provider
* @provider: provider returned by icc_clk_register() * @provider: provider returned by icc_clk_register()
......
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
#ifndef INTERCONNECT_QCOM_IPQ9574_H
#define INTERCONNECT_QCOM_IPQ9574_H
#define MASTER_ANOC_PCIE0 0
#define SLAVE_ANOC_PCIE0 1
#define MASTER_SNOC_PCIE0 2
#define SLAVE_SNOC_PCIE0 3
#define MASTER_ANOC_PCIE1 4
#define SLAVE_ANOC_PCIE1 5
#define MASTER_SNOC_PCIE1 6
#define SLAVE_SNOC_PCIE1 7
#define MASTER_ANOC_PCIE2 8
#define SLAVE_ANOC_PCIE2 9
#define MASTER_SNOC_PCIE2 10
#define SLAVE_SNOC_PCIE2 11
#define MASTER_ANOC_PCIE3 12
#define SLAVE_ANOC_PCIE3 13
#define MASTER_SNOC_PCIE3 14
#define SLAVE_SNOC_PCIE3 15
#define MASTER_USB 16
#define SLAVE_USB 17
#define MASTER_USB_AXI 18
#define SLAVE_USB_AXI 19
#define MASTER_NSSNOC_NSSCC 20
#define SLAVE_NSSNOC_NSSCC 21
#define MASTER_NSSNOC_SNOC_0 22
#define SLAVE_NSSNOC_SNOC_0 23
#define MASTER_NSSNOC_SNOC_1 24
#define SLAVE_NSSNOC_SNOC_1 25
#define MASTER_NSSNOC_PCNOC_1 26
#define SLAVE_NSSNOC_PCNOC_1 27
#define MASTER_NSSNOC_QOSGEN_REF 28
#define SLAVE_NSSNOC_QOSGEN_REF 29
#define MASTER_NSSNOC_TIMEOUT_REF 30
#define SLAVE_NSSNOC_TIMEOUT_REF 31
#define MASTER_NSSNOC_XO_DCD 32
#define SLAVE_NSSNOC_XO_DCD 33
#define MASTER_NSSNOC_ATB 34
#define SLAVE_NSSNOC_ATB 35
#define MASTER_MEM_NOC_NSSNOC 36
#define SLAVE_MEM_NOC_NSSNOC 37
#define MASTER_NSSNOC_MEMNOC 38
#define SLAVE_NSSNOC_MEMNOC 39
#define MASTER_NSSNOC_MEM_NOC_1 40
#define SLAVE_NSSNOC_MEM_NOC_1 41
#define MASTER_NSSNOC_PPE 0
#define SLAVE_NSSNOC_PPE 1
#define MASTER_NSSNOC_PPE_CFG 2
#define SLAVE_NSSNOC_PPE_CFG 3
#define MASTER_NSSNOC_NSS_CSR 4
#define SLAVE_NSSNOC_NSS_CSR 5
#define MASTER_NSSNOC_IMEM_QSB 6
#define SLAVE_NSSNOC_IMEM_QSB 7
#define MASTER_NSSNOC_IMEM_AHB 8
#define SLAVE_NSSNOC_IMEM_AHB 9
#endif /* INTERCONNECT_QCOM_IPQ9574_H */
...@@ -11,12 +11,16 @@ struct device; ...@@ -11,12 +11,16 @@ struct device;
struct icc_clk_data { struct icc_clk_data {
struct clk *clk; struct clk *clk;
const char *name; const char *name;
unsigned int master_id;
unsigned int slave_id;
}; };
struct icc_provider *icc_clk_register(struct device *dev, struct icc_provider *icc_clk_register(struct device *dev,
unsigned int first_id, unsigned int first_id,
unsigned int num_clocks, unsigned int num_clocks,
const struct icc_clk_data *data); const struct icc_clk_data *data);
int devm_icc_clk_register(struct device *dev, unsigned int first_id,
unsigned int num_clocks, const struct icc_clk_data *data);
void icc_clk_unregister(struct icc_provider *provider); void icc_clk_unregister(struct icc_provider *provider);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment