Message ID | 20231106103027.3988871-1-quic_imrashai@quicinc.com |
---|---|
Headers | show |
Series | Add support for Qualcomm ECPRI clock controller | expand |
On Mon, 6 Nov 2023 at 12:31, Imran Shaik <quic_imrashai@quicinc.com> wrote: > > From: Taniya Das <quic_tdas@quicinc.com> > > Clock CBCRs with memories need an update for memory before enable/disable > of the clock, which helps retain the respective block's register contents. > Add support for the mem ops to handle this sequence. > > Signed-off-by: Taniya Das <quic_tdas@quicinc.com> > Signed-off-by: Imran Shaik <quic_imrashai@quicinc.com> It would be nice to have a description of what is 'CBCR with memories' and how does it differ from CBCR_FORCE_MEM_CORE_ON? > --- > drivers/clk/qcom/clk-branch.c | 39 +++++++++++++++++++++++++++++++++++ > drivers/clk/qcom/clk-branch.h | 21 +++++++++++++++++++ > 2 files changed, 60 insertions(+) > > diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c > index fc4735f74f0f..61bdd2147bed 100644 > --- a/drivers/clk/qcom/clk-branch.c > +++ b/drivers/clk/qcom/clk-branch.c > @@ -1,6 +1,7 @@ > // SPDX-License-Identifier: GPL-2.0 > /* > * Copyright (c) 2013, The Linux Foundation. All rights reserved. > + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. > */ > > #include <linux/kernel.h> > @@ -134,6 +135,44 @@ static void clk_branch2_disable(struct clk_hw *hw) > clk_branch_toggle(hw, false, clk_branch2_check_halt); > } > > +static int clk_branch2_mem_enable(struct clk_hw *hw) > +{ > + struct clk_mem_branch *mem_br = to_clk_mem_branch(hw); > + struct clk_branch branch = mem_br->branch; > + const char *name = clk_hw_get_name(&branch.clkr.hw); > + u32 val; > + int ret; > + > + regmap_update_bits(branch.clkr.regmap, mem_br->mem_enable_reg, > + mem_br->mem_enable_ack_mask, mem_br->mem_enable_ack_mask); > + > + ret = regmap_read_poll_timeout(branch.clkr.regmap, mem_br->mem_ack_reg, > + val, val & mem_br->mem_enable_ack_mask, 0, 200); > + if (ret) { > + WARN(1, "%s mem enable failed\n", name); > + return ret; > + } > + > + return clk_branch2_enable(hw); > +} > + > +static void clk_branch2_mem_disable(struct clk_hw *hw) > +{ > + struct clk_mem_branch *mem_br = to_clk_mem_branch(hw); > + > + regmap_update_bits(mem_br->branch.clkr.regmap, mem_br->mem_enable_reg, > + mem_br->mem_enable_ack_mask, 0); > + > + return clk_branch2_disable(hw); > +} > + > +const struct clk_ops clk_branch2_mem_ops = { > + .enable = clk_branch2_mem_enable, > + .disable = clk_branch2_mem_disable, > + .is_enabled = clk_is_enabled_regmap, > +}; > +EXPORT_SYMBOL_GPL(clk_branch2_mem_ops); > + > const struct clk_ops clk_branch2_ops = { > .enable = clk_branch2_enable, > .disable = clk_branch2_disable, > diff --git a/drivers/clk/qcom/clk-branch.h b/drivers/clk/qcom/clk-branch.h > index 0cf800b9d08d..8ffed603c050 100644 > --- a/drivers/clk/qcom/clk-branch.h > +++ b/drivers/clk/qcom/clk-branch.h > @@ -38,6 +38,23 @@ struct clk_branch { > struct clk_regmap clkr; > }; > > +/** > + * struct clk_mem_branch - gating clock which are associated with memories > + * > + * @mem_enable_reg: branch clock memory gating register > + * @mem_ack_reg: branch clock memory ack register > + * @mem_enable_ack_mask: branch clock memory enable and ack field in @mem_ack_reg > + * @branch: branch clock gating handle > + * > + * Clock which can gate its memories. > + */ > +struct clk_mem_branch { > + u32 mem_enable_reg; > + u32 mem_ack_reg; > + u32 mem_enable_ack_mask; > + struct clk_branch branch; > +}; > + > /* Branch clock common bits for HLOS-owned clocks */ > #define CBCR_CLK_OFF BIT(31) > #define CBCR_NOC_FSM_STATUS GENMASK(30, 28) > @@ -85,8 +102,12 @@ extern const struct clk_ops clk_branch_ops; > extern const struct clk_ops clk_branch2_ops; > extern const struct clk_ops clk_branch_simple_ops; > extern const struct clk_ops clk_branch2_aon_ops; > +extern const struct clk_ops clk_branch2_mem_ops; > > #define to_clk_branch(_hw) \ > container_of(to_clk_regmap(_hw), struct clk_branch, clkr) > > +#define to_clk_mem_branch(_hw) \ > + container_of(to_clk_branch(_hw), struct clk_mem_branch, branch) > + > #endif > -- > 2.25.1 >
On Mon, 6 Nov 2023 at 12:32, Imran Shaik <quic_imrashai@quicinc.com> wrote: > > Add ECPRI Clock Controller (ECPRICC) support for QDU1000 and QRU1000 SoCs. After reading this series I have one main question. What is ECPRI? You've never expanded this acronym. > > Signed-off-by: Imran Shaik <quic_imrashai@quicinc.com> > --- > drivers/clk/qcom/Kconfig | 9 + > drivers/clk/qcom/Makefile | 1 + > drivers/clk/qcom/ecpricc-qdu1000.c | 2456 ++++++++++++++++++++++++++++ > 3 files changed, 2466 insertions(+) > create mode 100644 drivers/clk/qcom/ecpricc-qdu1000.c > > diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig > index ad1acd9b7426..9e54afc67519 100644 > --- a/drivers/clk/qcom/Kconfig > +++ b/drivers/clk/qcom/Kconfig > @@ -668,6 +668,15 @@ config QDU_GCC_1000 > QRU1000 devices. Say Y if you want to use peripheral > devices such as UART, SPI, I2C, USB, SD, PCIe, etc. > > +config QDU_ECPRICC_1000 > + tristate "QDU1000/QRU1000 ECPRI Clock Controller" > + depends on ARM64 || COMPILE_TEST > + select QDU_GCC_1000 > + help > + Support for the ECPRI clock controller on QDU1000 and > + QRU1000 devices. Say Y if you want to support the ECPRI > + clock controller functionality such as Ethernet. > + > config SDM_GCC_845 > tristate "SDM845/SDM670 Global Clock Controller" > depends on ARM64 || COMPILE_TEST > diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile > index 17edd73f9839..607ed0fabf36 100644 > --- a/drivers/clk/qcom/Makefile > +++ b/drivers/clk/qcom/Makefile > @@ -65,6 +65,7 @@ obj-$(CONFIG_QCM_DISPCC_2290) += dispcc-qcm2290.o > obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o > obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o > obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o > +obj-$(CONFIG_QDU_ECPRICC_1000) += ecpricc-qdu1000.o > obj-$(CONFIG_QDU_GCC_1000) += gcc-qdu1000.o > obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o > obj-$(CONFIG_SC_CAMCC_7280) += camcc-sc7280.o > diff --git a/drivers/clk/qcom/ecpricc-qdu1000.c b/drivers/clk/qcom/ecpricc-qdu1000.c > new file mode 100644 > index 000000000000..a430b7228c26 > --- /dev/null > +++ b/drivers/clk/qcom/ecpricc-qdu1000.c > @@ -0,0 +1,2456 @@ > +// SPDX-License-Identifier: GPL-2.0-only [skipped] > + > +static struct clk_mem_branch ecpri_cc_eth_phy_0_ock_sram_clk = { > + .mem_enable_reg = 0x8404, > + .mem_ack_reg = 0x8418, > + .mem_enable_ack_mask = BIT(6), > + .branch = { > + .halt_reg = 0xd140, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd140, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_eth_phy_0_ock_sram_clk", > + .ops = &clk_branch2_mem_ops, This (and several following branch clocks) do not have a parent defined. From which clock are they derived from? > + }, > + }, > + }, > +}; > + > +static struct clk_mem_branch ecpri_cc_eth_phy_1_ock_sram_clk = { > + .mem_enable_reg = 0x8408, > + .mem_ack_reg = 0x841C, > + .mem_enable_ack_mask = BIT(6), > + .branch = { > + .halt_reg = 0xd148, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd148, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_eth_phy_1_ock_sram_clk", > + .ops = &clk_branch2_mem_ops, > + }, > + }, > + }, > +}; > + > +static struct clk_mem_branch ecpri_cc_eth_phy_2_ock_sram_clk = { > + .mem_enable_reg = 0x840c, > + .mem_ack_reg = 0x8420, > + .mem_enable_ack_mask = BIT(6), > + .branch = { > + .halt_reg = 0xd150, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd150, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_eth_phy_2_ock_sram_clk", > + .ops = &clk_branch2_mem_ops, > + }, > + }, > + }, > +}; > + > +static struct clk_mem_branch ecpri_cc_eth_phy_3_ock_sram_clk = { > + .mem_enable_reg = 0x8410, > + .mem_ack_reg = 0x8424, > + .mem_enable_ack_mask = BIT(6), > + .branch = { > + .halt_reg = 0xd158, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd158, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_eth_phy_3_ock_sram_clk", > + .ops = &clk_branch2_mem_ops, > + }, > + }, > + }, > +}; > + > +static struct clk_mem_branch ecpri_cc_eth_phy_4_ock_sram_clk = { > + .mem_enable_reg = 0x8414, > + .mem_ack_reg = 0x8428, > + .mem_enable_ack_mask = BIT(6), > + .branch = { > + .halt_reg = 0xd160, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd160, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_eth_phy_4_ock_sram_clk", > + .ops = &clk_branch2_mem_ops, > + }, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_mss_emac_clk = { > + .halt_reg = 0xe008, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xe008, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_mss_emac_clk", > + .parent_hws = (const struct clk_hw*[]) { > + &ecpri_cc_mss_emac_clk_src.clkr.hw, > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_mss_oran_clk = { > + .halt_reg = 0xe004, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xe004, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_mss_oran_clk", > + .parent_hws = (const struct clk_hw*[]) { > + &ecpri_cc_ecpri_oran_clk_src.clkr.hw, > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy0_lane0_rx_clk = { > + .halt_reg = 0xd000, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd000, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy0_lane0_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy0_lane0_tx_clk = { > + .halt_reg = 0xd050, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd050, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy0_lane0_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy0_lane1_rx_clk = { > + .halt_reg = 0xd004, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd004, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy0_lane1_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy0_lane1_tx_clk = { > + .halt_reg = 0xd054, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd054, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy0_lane1_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy0_lane2_rx_clk = { > + .halt_reg = 0xd008, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd008, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy0_lane2_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy0_lane2_tx_clk = { > + .halt_reg = 0xd058, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd058, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy0_lane2_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy0_lane3_rx_clk = { > + .halt_reg = 0xd00c, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd00c, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy0_lane3_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy0_lane3_tx_clk = { > + .halt_reg = 0xd05c, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd05c, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy0_lane3_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy1_lane0_rx_clk = { > + .halt_reg = 0xd010, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd010, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy1_lane0_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy1_lane0_tx_clk = { > + .halt_reg = 0xd060, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd060, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy1_lane0_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy1_lane1_rx_clk = { > + .halt_reg = 0xd014, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd014, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy1_lane1_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy1_lane1_tx_clk = { > + .halt_reg = 0xd064, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd064, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy1_lane1_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy1_lane2_rx_clk = { > + .halt_reg = 0xd018, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd018, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy1_lane2_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy1_lane2_tx_clk = { > + .halt_reg = 0xd068, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd068, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy1_lane2_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy1_lane3_rx_clk = { > + .halt_reg = 0xd01c, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd01c, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy1_lane3_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy1_lane3_tx_clk = { > + .halt_reg = 0xd06c, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd06c, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy1_lane3_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy2_lane0_rx_clk = { > + .halt_reg = 0xd020, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd020, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy2_lane0_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy2_lane0_tx_clk = { > + .halt_reg = 0xd070, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd070, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy2_lane0_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy2_lane1_rx_clk = { > + .halt_reg = 0xd024, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd024, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy2_lane1_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy2_lane1_tx_clk = { > + .halt_reg = 0xd074, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd074, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy2_lane1_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy2_lane2_rx_clk = { > + .halt_reg = 0xd028, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd028, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy2_lane2_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy2_lane2_tx_clk = { > + .halt_reg = 0xd078, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd078, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy2_lane2_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy2_lane3_rx_clk = { > + .halt_reg = 0xd02c, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd02c, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy2_lane3_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy2_lane3_tx_clk = { > + .halt_reg = 0xd07c, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd07c, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy2_lane3_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy3_lane0_rx_clk = { > + .halt_reg = 0xd030, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd030, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy3_lane0_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy3_lane0_tx_clk = { > + .halt_reg = 0xd080, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd080, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy3_lane0_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy3_lane1_rx_clk = { > + .halt_reg = 0xd034, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd034, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy3_lane1_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy3_lane1_tx_clk = { > + .halt_reg = 0xd084, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd084, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy3_lane1_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy3_lane2_rx_clk = { > + .halt_reg = 0xd038, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd038, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy3_lane2_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy3_lane2_tx_clk = { > + .halt_reg = 0xd088, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd088, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy3_lane2_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy3_lane3_rx_clk = { > + .halt_reg = 0xd03c, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd03c, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy3_lane3_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy3_lane3_tx_clk = { > + .halt_reg = 0xd08c, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd08c, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy3_lane3_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy4_lane0_rx_clk = { > + .halt_reg = 0xd040, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd040, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy4_lane0_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy4_lane0_tx_clk = { > + .halt_reg = 0xd090, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd090, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy4_lane0_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy4_lane1_rx_clk = { > + .halt_reg = 0xd044, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd044, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy4_lane1_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy4_lane1_tx_clk = { > + .halt_reg = 0xd094, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd094, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy4_lane1_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy4_lane2_rx_clk = { > + .halt_reg = 0xd048, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd048, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy4_lane2_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy4_lane2_tx_clk = { > + .halt_reg = 0xd098, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd098, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy4_lane2_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy4_lane3_rx_clk = { > + .halt_reg = 0xd04c, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd04c, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy4_lane3_rx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; > + > +static struct clk_branch ecpri_cc_phy4_lane3_tx_clk = { > + .halt_reg = 0xd09c, > + .halt_check = BRANCH_HALT, > + .clkr = { > + .enable_reg = 0xd09c, > + .enable_mask = BIT(0), > + .hw.init = &(const struct clk_init_data) { > + .name = "ecpri_cc_phy4_lane3_tx_clk", > + .ops = &clk_branch2_ops, > + }, > + }, > +}; [skipped] > +static int ecpri_cc_qdu1000_probe(struct platform_device *pdev) > +{ > + struct regmap *regmap; > + > + regmap = qcom_cc_map(pdev, &ecpri_cc_qdu1000_desc); > + if (IS_ERR(regmap)) > + return PTR_ERR(regmap); > + > + clk_lucid_evo_pll_configure(&ecpri_cc_pll0, regmap, &ecpri_cc_pll0_config); > + clk_lucid_evo_pll_configure(&ecpri_cc_pll1, regmap, &ecpri_cc_pll1_config); > + > + return qcom_cc_really_probe(pdev, &ecpri_cc_qdu1000_desc, regmap); > +} > + > +static struct platform_driver ecpri_cc_qdu1000_driver = { > + .probe = ecpri_cc_qdu1000_probe, > + .driver = { > + .name = "ecpri_cc-qdu1000", > + .of_match_table = ecpri_cc_qdu1000_match_table, > + }, > +}; > + > +module_platform_driver(ecpri_cc_qdu1000_driver); > + > +MODULE_DESCRIPTION("QTI ECPRICC QDU1000 Driver"); > +MODULE_LICENSE("GPL"); > -- > 2.25.1 >
On 11/6/2023 6:30 PM, Dmitry Baryshkov wrote: > On Mon, 6 Nov 2023 at 12:31, Imran Shaik <quic_imrashai@quicinc.com> wrote: >> >> From: Taniya Das <quic_tdas@quicinc.com> >> >> Clock CBCRs with memories need an update for memory before enable/disable >> of the clock, which helps retain the respective block's register contents. >> Add support for the mem ops to handle this sequence. >> >> Signed-off-by: Taniya Das <quic_tdas@quicinc.com> >> Signed-off-by: Imran Shaik <quic_imrashai@quicinc.com> > > It would be nice to have a description of what is 'CBCR with memories' > and how does it differ from CBCR_FORCE_MEM_CORE_ON? > This mem_ops implementation is to enable/disable the memories in ethernet PHY, prior to turning on the respective clocks. Where as the FORCE_MEM_CORE_ON is to keep the memories awake even if the clock is gated. >> --- >> drivers/clk/qcom/clk-branch.c | 39 +++++++++++++++++++++++++++++++++++ >> drivers/clk/qcom/clk-branch.h | 21 +++++++++++++++++++ >> 2 files changed, 60 insertions(+) >> >> diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c >> index fc4735f74f0f..61bdd2147bed 100644 >> --- a/drivers/clk/qcom/clk-branch.c >> +++ b/drivers/clk/qcom/clk-branch.c >> @@ -1,6 +1,7 @@ >> // SPDX-License-Identifier: GPL-2.0 >> /* >> * Copyright (c) 2013, The Linux Foundation. All rights reserved. >> + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. >> */ >> >> #include <linux/kernel.h> >> @@ -134,6 +135,44 @@ static void clk_branch2_disable(struct clk_hw *hw) >> clk_branch_toggle(hw, false, clk_branch2_check_halt); >> } >> >> +static int clk_branch2_mem_enable(struct clk_hw *hw) >> +{ >> + struct clk_mem_branch *mem_br = to_clk_mem_branch(hw); >> + struct clk_branch branch = mem_br->branch; >> + const char *name = clk_hw_get_name(&branch.clkr.hw); >> + u32 val; >> + int ret; >> + >> + regmap_update_bits(branch.clkr.regmap, mem_br->mem_enable_reg, >> + mem_br->mem_enable_ack_mask, mem_br->mem_enable_ack_mask); >> + >> + ret = regmap_read_poll_timeout(branch.clkr.regmap, mem_br->mem_ack_reg, >> + val, val & mem_br->mem_enable_ack_mask, 0, 200); >> + if (ret) { >> + WARN(1, "%s mem enable failed\n", name); >> + return ret; >> + } >> + >> + return clk_branch2_enable(hw); >> +} >> + >> +static void clk_branch2_mem_disable(struct clk_hw *hw) >> +{ >> + struct clk_mem_branch *mem_br = to_clk_mem_branch(hw); >> + >> + regmap_update_bits(mem_br->branch.clkr.regmap, mem_br->mem_enable_reg, >> + mem_br->mem_enable_ack_mask, 0); >> + >> + return clk_branch2_disable(hw); >> +} >> + >> +const struct clk_ops clk_branch2_mem_ops = { >> + .enable = clk_branch2_mem_enable, >> + .disable = clk_branch2_mem_disable, >> + .is_enabled = clk_is_enabled_regmap, >> +}; >> +EXPORT_SYMBOL_GPL(clk_branch2_mem_ops); >> + >> const struct clk_ops clk_branch2_ops = { >> .enable = clk_branch2_enable, >> .disable = clk_branch2_disable, >> diff --git a/drivers/clk/qcom/clk-branch.h b/drivers/clk/qcom/clk-branch.h >> index 0cf800b9d08d..8ffed603c050 100644 >> --- a/drivers/clk/qcom/clk-branch.h >> +++ b/drivers/clk/qcom/clk-branch.h >> @@ -38,6 +38,23 @@ struct clk_branch { >> struct clk_regmap clkr; >> }; >> >> +/** >> + * struct clk_mem_branch - gating clock which are associated with memories >> + * >> + * @mem_enable_reg: branch clock memory gating register >> + * @mem_ack_reg: branch clock memory ack register >> + * @mem_enable_ack_mask: branch clock memory enable and ack field in @mem_ack_reg >> + * @branch: branch clock gating handle >> + * >> + * Clock which can gate its memories. >> + */ >> +struct clk_mem_branch { >> + u32 mem_enable_reg; >> + u32 mem_ack_reg; >> + u32 mem_enable_ack_mask; >> + struct clk_branch branch; >> +}; >> + >> /* Branch clock common bits for HLOS-owned clocks */ >> #define CBCR_CLK_OFF BIT(31) >> #define CBCR_NOC_FSM_STATUS GENMASK(30, 28) >> @@ -85,8 +102,12 @@ extern const struct clk_ops clk_branch_ops; >> extern const struct clk_ops clk_branch2_ops; >> extern const struct clk_ops clk_branch_simple_ops; >> extern const struct clk_ops clk_branch2_aon_ops; >> +extern const struct clk_ops clk_branch2_mem_ops; >> >> #define to_clk_branch(_hw) \ >> container_of(to_clk_regmap(_hw), struct clk_branch, clkr) >> >> +#define to_clk_mem_branch(_hw) \ >> + container_of(to_clk_branch(_hw), struct clk_mem_branch, branch) >> + >> #endif >> -- >> 2.25.1 >> > >
On 11/6/2023 6:34 PM, Dmitry Baryshkov wrote: > On Mon, 6 Nov 2023 at 12:32, Imran Shaik <quic_imrashai@quicinc.com> wrote: >> >> Add ECPRI Clock Controller (ECPRICC) support for QDU1000 and QRU1000 SoCs. > > After reading this series I have one main question. What is ECPRI? > You've never expanded this acronym. > This is a clock controller for eCPRI Specification V2.0 Common Public Radio Interface. >> >> Signed-off-by: Imran Shaik <quic_imrashai@quicinc.com> >> --- >> drivers/clk/qcom/Kconfig | 9 + >> drivers/clk/qcom/Makefile | 1 + >> drivers/clk/qcom/ecpricc-qdu1000.c | 2456 ++++++++++++++++++++++++++++ >> 3 files changed, 2466 insertions(+) >> create mode 100644 drivers/clk/qcom/ecpricc-qdu1000.c >> >> diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig >> index ad1acd9b7426..9e54afc67519 100644 >> --- a/drivers/clk/qcom/Kconfig >> +++ b/drivers/clk/qcom/Kconfig >> @@ -668,6 +668,15 @@ config QDU_GCC_1000 >> QRU1000 devices. Say Y if you want to use peripheral >> devices such as UART, SPI, I2C, USB, SD, PCIe, etc. >> >> +config QDU_ECPRICC_1000 >> + tristate "QDU1000/QRU1000 ECPRI Clock Controller" >> + depends on ARM64 || COMPILE_TEST >> + select QDU_GCC_1000 >> + help >> + Support for the ECPRI clock controller on QDU1000 and >> + QRU1000 devices. Say Y if you want to support the ECPRI >> + clock controller functionality such as Ethernet. >> + >> config SDM_GCC_845 >> tristate "SDM845/SDM670 Global Clock Controller" >> depends on ARM64 || COMPILE_TEST >> diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile >> index 17edd73f9839..607ed0fabf36 100644 >> --- a/drivers/clk/qcom/Makefile >> +++ b/drivers/clk/qcom/Makefile >> @@ -65,6 +65,7 @@ obj-$(CONFIG_QCM_DISPCC_2290) += dispcc-qcm2290.o >> obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o >> obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o >> obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o >> +obj-$(CONFIG_QDU_ECPRICC_1000) += ecpricc-qdu1000.o >> obj-$(CONFIG_QDU_GCC_1000) += gcc-qdu1000.o >> obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o >> obj-$(CONFIG_SC_CAMCC_7280) += camcc-sc7280.o >> diff --git a/drivers/clk/qcom/ecpricc-qdu1000.c b/drivers/clk/qcom/ecpricc-qdu1000.c >> new file mode 100644 >> index 000000000000..a430b7228c26 >> --- /dev/null >> +++ b/drivers/clk/qcom/ecpricc-qdu1000.c >> @@ -0,0 +1,2456 @@ >> +// SPDX-License-Identifier: GPL-2.0-only > > [skipped] > > >> + >> +static struct clk_mem_branch ecpri_cc_eth_phy_0_ock_sram_clk = { >> + .mem_enable_reg = 0x8404, >> + .mem_ack_reg = 0x8418, >> + .mem_enable_ack_mask = BIT(6), >> + .branch = { >> + .halt_reg = 0xd140, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd140, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_eth_phy_0_ock_sram_clk", >> + .ops = &clk_branch2_mem_ops, > > This (and several following branch clocks) do not have a parent > defined. From which clock are they derived from? > These branch clocks are connected to the Muxes, that are sourced from the PoR ON external clocks which are not required to be controlled from the SW side. Thanks, Imran >> + }, >> + }, >> + }, >> +}; >> + >> +static struct clk_mem_branch ecpri_cc_eth_phy_1_ock_sram_clk = { >> + .mem_enable_reg = 0x8408, >> + .mem_ack_reg = 0x841C, >> + .mem_enable_ack_mask = BIT(6), >> + .branch = { >> + .halt_reg = 0xd148, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd148, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_eth_phy_1_ock_sram_clk", >> + .ops = &clk_branch2_mem_ops, >> + }, >> + }, >> + }, >> +}; >> + >> +static struct clk_mem_branch ecpri_cc_eth_phy_2_ock_sram_clk = { >> + .mem_enable_reg = 0x840c, >> + .mem_ack_reg = 0x8420, >> + .mem_enable_ack_mask = BIT(6), >> + .branch = { >> + .halt_reg = 0xd150, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd150, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_eth_phy_2_ock_sram_clk", >> + .ops = &clk_branch2_mem_ops, >> + }, >> + }, >> + }, >> +}; >> + >> +static struct clk_mem_branch ecpri_cc_eth_phy_3_ock_sram_clk = { >> + .mem_enable_reg = 0x8410, >> + .mem_ack_reg = 0x8424, >> + .mem_enable_ack_mask = BIT(6), >> + .branch = { >> + .halt_reg = 0xd158, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd158, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_eth_phy_3_ock_sram_clk", >> + .ops = &clk_branch2_mem_ops, >> + }, >> + }, >> + }, >> +}; >> + >> +static struct clk_mem_branch ecpri_cc_eth_phy_4_ock_sram_clk = { >> + .mem_enable_reg = 0x8414, >> + .mem_ack_reg = 0x8428, >> + .mem_enable_ack_mask = BIT(6), >> + .branch = { >> + .halt_reg = 0xd160, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd160, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_eth_phy_4_ock_sram_clk", >> + .ops = &clk_branch2_mem_ops, >> + }, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_mss_emac_clk = { >> + .halt_reg = 0xe008, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xe008, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_mss_emac_clk", >> + .parent_hws = (const struct clk_hw*[]) { >> + &ecpri_cc_mss_emac_clk_src.clkr.hw, >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_mss_oran_clk = { >> + .halt_reg = 0xe004, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xe004, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_mss_oran_clk", >> + .parent_hws = (const struct clk_hw*[]) { >> + &ecpri_cc_ecpri_oran_clk_src.clkr.hw, >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy0_lane0_rx_clk = { >> + .halt_reg = 0xd000, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd000, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy0_lane0_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy0_lane0_tx_clk = { >> + .halt_reg = 0xd050, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd050, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy0_lane0_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy0_lane1_rx_clk = { >> + .halt_reg = 0xd004, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd004, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy0_lane1_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy0_lane1_tx_clk = { >> + .halt_reg = 0xd054, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd054, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy0_lane1_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy0_lane2_rx_clk = { >> + .halt_reg = 0xd008, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd008, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy0_lane2_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy0_lane2_tx_clk = { >> + .halt_reg = 0xd058, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd058, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy0_lane2_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy0_lane3_rx_clk = { >> + .halt_reg = 0xd00c, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd00c, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy0_lane3_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy0_lane3_tx_clk = { >> + .halt_reg = 0xd05c, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd05c, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy0_lane3_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy1_lane0_rx_clk = { >> + .halt_reg = 0xd010, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd010, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy1_lane0_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy1_lane0_tx_clk = { >> + .halt_reg = 0xd060, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd060, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy1_lane0_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy1_lane1_rx_clk = { >> + .halt_reg = 0xd014, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd014, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy1_lane1_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy1_lane1_tx_clk = { >> + .halt_reg = 0xd064, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd064, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy1_lane1_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy1_lane2_rx_clk = { >> + .halt_reg = 0xd018, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd018, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy1_lane2_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy1_lane2_tx_clk = { >> + .halt_reg = 0xd068, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd068, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy1_lane2_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy1_lane3_rx_clk = { >> + .halt_reg = 0xd01c, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd01c, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy1_lane3_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy1_lane3_tx_clk = { >> + .halt_reg = 0xd06c, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd06c, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy1_lane3_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy2_lane0_rx_clk = { >> + .halt_reg = 0xd020, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd020, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy2_lane0_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy2_lane0_tx_clk = { >> + .halt_reg = 0xd070, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd070, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy2_lane0_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy2_lane1_rx_clk = { >> + .halt_reg = 0xd024, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd024, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy2_lane1_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy2_lane1_tx_clk = { >> + .halt_reg = 0xd074, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd074, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy2_lane1_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy2_lane2_rx_clk = { >> + .halt_reg = 0xd028, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd028, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy2_lane2_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy2_lane2_tx_clk = { >> + .halt_reg = 0xd078, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd078, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy2_lane2_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy2_lane3_rx_clk = { >> + .halt_reg = 0xd02c, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd02c, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy2_lane3_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy2_lane3_tx_clk = { >> + .halt_reg = 0xd07c, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd07c, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy2_lane3_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy3_lane0_rx_clk = { >> + .halt_reg = 0xd030, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd030, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy3_lane0_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy3_lane0_tx_clk = { >> + .halt_reg = 0xd080, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd080, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy3_lane0_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy3_lane1_rx_clk = { >> + .halt_reg = 0xd034, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd034, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy3_lane1_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy3_lane1_tx_clk = { >> + .halt_reg = 0xd084, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd084, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy3_lane1_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy3_lane2_rx_clk = { >> + .halt_reg = 0xd038, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd038, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy3_lane2_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy3_lane2_tx_clk = { >> + .halt_reg = 0xd088, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd088, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy3_lane2_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy3_lane3_rx_clk = { >> + .halt_reg = 0xd03c, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd03c, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy3_lane3_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy3_lane3_tx_clk = { >> + .halt_reg = 0xd08c, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd08c, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy3_lane3_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy4_lane0_rx_clk = { >> + .halt_reg = 0xd040, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd040, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy4_lane0_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy4_lane0_tx_clk = { >> + .halt_reg = 0xd090, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd090, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy4_lane0_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy4_lane1_rx_clk = { >> + .halt_reg = 0xd044, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd044, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy4_lane1_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy4_lane1_tx_clk = { >> + .halt_reg = 0xd094, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd094, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy4_lane1_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy4_lane2_rx_clk = { >> + .halt_reg = 0xd048, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd048, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy4_lane2_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy4_lane2_tx_clk = { >> + .halt_reg = 0xd098, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd098, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy4_lane2_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy4_lane3_rx_clk = { >> + .halt_reg = 0xd04c, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd04c, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy4_lane3_rx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; >> + >> +static struct clk_branch ecpri_cc_phy4_lane3_tx_clk = { >> + .halt_reg = 0xd09c, >> + .halt_check = BRANCH_HALT, >> + .clkr = { >> + .enable_reg = 0xd09c, >> + .enable_mask = BIT(0), >> + .hw.init = &(const struct clk_init_data) { >> + .name = "ecpri_cc_phy4_lane3_tx_clk", >> + .ops = &clk_branch2_ops, >> + }, >> + }, >> +}; > > [skipped] > >> +static int ecpri_cc_qdu1000_probe(struct platform_device *pdev) >> +{ >> + struct regmap *regmap; >> + >> + regmap = qcom_cc_map(pdev, &ecpri_cc_qdu1000_desc); >> + if (IS_ERR(regmap)) >> + return PTR_ERR(regmap); >> + >> + clk_lucid_evo_pll_configure(&ecpri_cc_pll0, regmap, &ecpri_cc_pll0_config); >> + clk_lucid_evo_pll_configure(&ecpri_cc_pll1, regmap, &ecpri_cc_pll1_config); >> + >> + return qcom_cc_really_probe(pdev, &ecpri_cc_qdu1000_desc, regmap); >> +} >> + >> +static struct platform_driver ecpri_cc_qdu1000_driver = { >> + .probe = ecpri_cc_qdu1000_probe, >> + .driver = { >> + .name = "ecpri_cc-qdu1000", >> + .of_match_table = ecpri_cc_qdu1000_match_table, >> + }, >> +}; >> + >> +module_platform_driver(ecpri_cc_qdu1000_driver); >> + >> +MODULE_DESCRIPTION("QTI ECPRICC QDU1000 Driver"); >> +MODULE_LICENSE("GPL"); >> -- >> 2.25.1 >> > >
On 11/10/23 09:34, Imran Shaik wrote: > > > On 11/6/2023 6:34 PM, Dmitry Baryshkov wrote: >> On Mon, 6 Nov 2023 at 12:32, Imran Shaik <quic_imrashai@quicinc.com> wrote: >>> >>> Add ECPRI Clock Controller (ECPRICC) support for QDU1000 and QRU1000 SoCs. >> >> After reading this series I have one main question. What is ECPRI? >> You've never expanded this acronym. >> > > This is a clock controller for eCPRI Specification V2.0 Common Public Radio Interface. This should be under description: in bindings Konrad
On 11/6/23 11:30, Imran Shaik wrote: > Add ECPRI Clock Controller (ECPRICC) support for QDU1000 and QRU1000 SoCs. > > Signed-off-by: Imran Shaik <quic_imrashai@quicinc.com> > --- [...] > +/* 700 MHz configuration */ > +static struct alpha_pll_config ecpri_cc_pll0_config = { const Acked-by: Konrad Dybcio <konrad.dybcio@linaro.org> Konrad
On 11/6/23 11:30, Imran Shaik wrote: > Add device node for ECPRI clock controller on qcom QDU1000 > and QRU1000 SoCs. > > Signed-off-by: Imran Shaik <quic_imrashai@quicinc.com> > --- Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org> Konrad
On 11/16/2023 8:31 PM, Konrad Dybcio wrote: > > > On 11/10/23 09:34, Imran Shaik wrote: >> >> >> On 11/6/2023 6:34 PM, Dmitry Baryshkov wrote: >>> On Mon, 6 Nov 2023 at 12:32, Imran Shaik <quic_imrashai@quicinc.com> >>> wrote: >>>> >>>> Add ECPRI Clock Controller (ECPRICC) support for QDU1000 and QRU1000 >>>> SoCs. >>> >>> After reading this series I have one main question. What is ECPRI? >>> You've never expanded this acronym. >>> >> >> This is a clock controller for eCPRI Specification V2.0 Common Public >> Radio Interface. > This should be under description: in bindings > > Konrad Sure, will update the bindings description and post the next series. Thanks, Imran