]> www.infradead.org Git - linux.git/commitdiff
clk: qcom: gcc-sm8450: Add SM8475 support
authorDanila Tikhonov <danila@jiaxyga.com>
Sun, 18 Aug 2024 20:43:40 +0000 (23:43 +0300)
committerBjorn Andersson <andersson@kernel.org>
Sun, 6 Oct 2024 03:09:48 +0000 (22:09 -0500)
Add support to the SM8475 global clock controller by extending the
SM8450 global clock controller, which is almost identical but has some
minor differences.

Signed-off-by: Danila Tikhonov <danila@jiaxyga.com>
Link: https://lore.kernel.org/r/20240818204348.197788-3-danila@jiaxyga.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
drivers/clk/qcom/Kconfig
drivers/clk/qcom/gcc-sm8450.c

index a3e2a09e2105b2f0a43afce7987fdd65f9b08c92..b0c28d5cf6213daac457fd4ff10d8bf34ef26c74 100644 (file)
@@ -1050,7 +1050,8 @@ config SM_GCC_8450
        depends on ARM64 || COMPILE_TEST
        select QCOM_GDSC
        help
-         Support for the global clock controller on SM8450 devices.
+         Support for the global clock controller on SM8450 or SM8475
+         devices.
          Say Y if you want to use peripheral devices such as UART,
          SPI, I2C, USB, SD/UFS, PCIe etc.
 
index c445c271678a5f46b31854593a28bf6be414e6da..65d7d52bce034335707014797fe9002429212a14 100644 (file)
@@ -26,6 +26,8 @@ enum {
        P_BI_TCXO,
        P_GCC_GPLL0_OUT_EVEN,
        P_GCC_GPLL0_OUT_MAIN,
+       P_SM8475_GCC_GPLL2_OUT_EVEN,
+       P_SM8475_GCC_GPLL3_OUT_EVEN,
        P_GCC_GPLL4_OUT_MAIN,
        P_GCC_GPLL9_OUT_MAIN,
        P_PCIE_1_PHY_AUX_CLK,
@@ -36,6 +38,15 @@ enum {
        P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK,
 };
 
+static struct clk_init_data sm8475_gcc_gpll0_init = {
+       .name = "gcc_gpll0",
+       .parent_data = &(const struct clk_parent_data){
+               .fw_name = "bi_tcxo",
+       },
+       .num_parents = 1,
+       .ops = &clk_alpha_pll_fixed_lucid_ole_ops,
+};
+
 static struct clk_alpha_pll gcc_gpll0 = {
        .offset = 0x0,
        .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
@@ -53,6 +64,15 @@ static struct clk_alpha_pll gcc_gpll0 = {
        },
 };
 
+static struct clk_init_data sm8475_gcc_gpll0_out_even_init = {
+       .name = "gcc_gpll0_out_even",
+       .parent_hws = (const struct clk_hw*[]) {
+               &gcc_gpll0.clkr.hw,
+       },
+       .num_parents = 1,
+       .ops = &clk_alpha_pll_postdiv_lucid_ole_ops,
+};
+
 static const struct clk_div_table post_div_table_gcc_gpll0_out_even[] = {
        { 0x1, 2 },
        { }
@@ -75,6 +95,49 @@ static struct clk_alpha_pll_postdiv gcc_gpll0_out_even = {
        },
 };
 
+static struct clk_alpha_pll sm8475_gcc_gpll2 = {
+       .offset = 0x2000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+       .clkr = {
+               .enable_reg = 0x62018,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpll2",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_lucid_ole_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll sm8475_gcc_gpll3 = {
+       .offset = 0x3000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+       .clkr = {
+               .enable_reg = 0x62018,
+               .enable_mask = BIT(3),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpll3",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_lucid_ole_ops,
+               },
+       },
+};
+
+static struct clk_init_data sm8475_gcc_gpll4_init = {
+       .name = "gcc_gpll4",
+       .parent_data = &(const struct clk_parent_data){
+               .fw_name = "bi_tcxo",
+       },
+       .num_parents = 1,
+       .ops = &clk_alpha_pll_fixed_lucid_ole_ops,
+};
+
 static struct clk_alpha_pll gcc_gpll4 = {
        .offset = 0x4000,
        .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
@@ -92,6 +155,15 @@ static struct clk_alpha_pll gcc_gpll4 = {
        },
 };
 
+static struct clk_init_data sm8475_gcc_gpll9_init = {
+       .name = "gcc_gpll9",
+       .parent_data = &(const struct clk_parent_data){
+               .fw_name = "bi_tcxo",
+       },
+       .num_parents = 1,
+       .ops = &clk_alpha_pll_fixed_lucid_ole_ops,
+};
+
 static struct clk_alpha_pll gcc_gpll9 = {
        .offset = 0x9000,
        .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
@@ -153,6 +225,22 @@ static const struct clk_parent_data gcc_parent_data_3[] = {
        { .fw_name = "bi_tcxo" },
 };
 
+static const struct parent_map sm8475_gcc_parent_map_3[] = {
+       { P_BI_TCXO, 0 },
+       { P_GCC_GPLL0_OUT_MAIN, 1 },
+       { P_SM8475_GCC_GPLL2_OUT_EVEN, 2 },
+       { P_SM8475_GCC_GPLL3_OUT_EVEN, 3 },
+       { P_GCC_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data sm8475_gcc_parent_data_3[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gcc_gpll0.clkr.hw },
+       { .hw = &sm8475_gcc_gpll2.clkr.hw },
+       { .hw = &sm8475_gcc_gpll3.clkr.hw },
+       { .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
 static const struct parent_map gcc_parent_map_5[] = {
        { P_PCIE_1_PHY_AUX_CLK, 0 },
        { P_BI_TCXO, 2 },
@@ -915,6 +1003,16 @@ static struct clk_rcg2 gcc_qupv3_wrap2_s6_clk_src = {
        .clkr.hw.init = &gcc_qupv3_wrap2_s6_clk_src_init,
 };
 
+static const struct freq_tbl sm8475_ftbl_gcc_sdcc2_apps_clk_src[] = {
+       F(400000, P_BI_TCXO, 12, 1, 4),
+       F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(37000000, P_GCC_GPLL9_OUT_MAIN, 16, 0, 0),
+       F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0),
+       F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0),
+       F(148000000, P_GCC_GPLL9_OUT_MAIN, 4, 0, 0),
+       { }
+};
+
 static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
        F(400000, P_BI_TCXO, 12, 1, 4),
        F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0),
@@ -963,6 +1061,25 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = {
        },
 };
 
+static const struct freq_tbl sm8475_ftbl_gcc_ufs_phy_axi_clk_src[] = {
+       F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(150000000, P_GCC_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(300000000, P_GCC_GPLL0_OUT_MAIN, 2, 0, 0),
+       F(600000000, P_GCC_GPLL0_OUT_MAIN, 1, 0, 0),
+       F(806400000, P_SM8475_GCC_GPLL2_OUT_EVEN, 1, 0, 0),
+       F(850000000, P_SM8475_GCC_GPLL2_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_init_data sm8475_gcc_ufs_phy_axi_clk_src_init = {
+       .name = "gcc_ufs_phy_axi_clk_src",
+       .parent_data = sm8475_gcc_parent_data_3,
+       .num_parents = ARRAY_SIZE(sm8475_gcc_parent_map_3),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
 static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
        F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0),
        F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0),
@@ -987,6 +1104,24 @@ static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = {
        },
 };
 
+static const struct freq_tbl sm8475_ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+       F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(150000000, P_GCC_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(300000000, P_GCC_GPLL0_OUT_MAIN, 2, 0, 0),
+       F(600000000, P_GCC_GPLL0_OUT_MAIN, 1, 0, 0),
+       F(806400000, P_SM8475_GCC_GPLL2_OUT_EVEN, 1, 0, 0),
+       F(850000000, P_SM8475_GCC_GPLL2_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_init_data sm8475_gcc_ufs_phy_ice_core_clk_src_init = {
+       .name = "gcc_ufs_phy_ice_core_clk_src",
+       .parent_data = sm8475_gcc_parent_data_3,
+       .num_parents = ARRAY_SIZE(sm8475_gcc_parent_map_3),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
 static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
        F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0),
        F(150000000, P_GCC_GPLL0_OUT_MAIN, 4, 0, 0),
@@ -1032,6 +1167,14 @@ static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = {
        },
 };
 
+static struct clk_init_data sm8475_gcc_ufs_phy_unipro_core_clk_src_init = {
+       .name = "gcc_ufs_phy_unipro_core_clk_src",
+       .parent_data = sm8475_gcc_parent_data_3,
+       .num_parents = ARRAY_SIZE(sm8475_gcc_parent_map_3),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
 static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = {
        .cmd_rcgr = 0x8708c,
        .mnd_width = 0,
@@ -3166,6 +3309,8 @@ static struct clk_regmap *gcc_sm8450_clocks[] = {
        [GCC_USB3_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb3_prim_phy_pipe_clk_src.clkr,
        [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr,
        [GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr,
+       [SM8475_GCC_GPLL2] = NULL,
+       [SM8475_GCC_GPLL3] = NULL,
 };
 
 static const struct qcom_reset_map gcc_sm8450_resets[] = {
@@ -3259,6 +3404,7 @@ static const struct qcom_cc_desc gcc_sm8450_desc = {
 
 static const struct of_device_id gcc_sm8450_match_table[] = {
        { .compatible = "qcom,gcc-sm8450" },
+       { .compatible = "qcom,sm8475-gcc" },
        { }
 };
 MODULE_DEVICE_TABLE(of, gcc_sm8450_match_table);
@@ -3277,6 +3423,39 @@ static int gcc_sm8450_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
+       if (of_device_is_compatible(pdev->dev.of_node, "qcom,sm8475-gcc")) {
+               /* Update GCC PLL0 */
+               gcc_gpll0.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE];
+               gcc_gpll0.clkr.hw.init = &sm8475_gcc_gpll0_init;
+               gcc_gpll0_out_even.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE];
+               gcc_gpll0_out_even.clkr.hw.init = &sm8475_gcc_gpll0_out_even_init;
+
+               /* Update GCC PLL4 */
+               gcc_gpll4.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE];
+               gcc_gpll4.clkr.hw.init = &sm8475_gcc_gpll4_init;
+
+               /* Update GCC PLL9 */
+               gcc_gpll9.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE];
+               gcc_gpll9.clkr.hw.init = &sm8475_gcc_gpll9_init;
+
+               gcc_sdcc2_apps_clk_src.freq_tbl = sm8475_ftbl_gcc_sdcc2_apps_clk_src;
+
+               gcc_ufs_phy_axi_clk_src.parent_map = sm8475_gcc_parent_map_3;
+               gcc_ufs_phy_axi_clk_src.freq_tbl = sm8475_ftbl_gcc_ufs_phy_axi_clk_src;
+               gcc_ufs_phy_axi_clk_src.clkr.hw.init = &sm8475_gcc_ufs_phy_axi_clk_src_init;
+
+               gcc_ufs_phy_ice_core_clk_src.parent_map = sm8475_gcc_parent_map_3;
+               gcc_ufs_phy_ice_core_clk_src.freq_tbl = sm8475_ftbl_gcc_ufs_phy_ice_core_clk_src;
+               gcc_ufs_phy_ice_core_clk_src.clkr.hw.init = &sm8475_gcc_ufs_phy_ice_core_clk_src_init;
+
+               gcc_ufs_phy_unipro_core_clk_src.parent_map = sm8475_gcc_parent_map_3;
+               gcc_ufs_phy_unipro_core_clk_src.freq_tbl = sm8475_ftbl_gcc_ufs_phy_ice_core_clk_src;
+               gcc_ufs_phy_unipro_core_clk_src.clkr.hw.init = &sm8475_gcc_ufs_phy_unipro_core_clk_src_init;
+
+               gcc_sm8450_desc.clks[SM8475_GCC_GPLL2] = &sm8475_gcc_gpll2.clkr;
+               gcc_sm8450_desc.clks[SM8475_GCC_GPLL3] = &sm8475_gcc_gpll3.clkr;
+       }
+
        /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */
        regmap_update_bits(regmap, gcc_ufs_phy_ice_core_clk.halt_reg, BIT(14), BIT(14));
 
@@ -3312,5 +3491,5 @@ static void __exit gcc_sm8450_exit(void)
 }
 module_exit(gcc_sm8450_exit);
 
-MODULE_DESCRIPTION("QTI GCC SM8450 Driver");
+MODULE_DESCRIPTION("QTI GCC SM8450 / SM8475 Driver");
 MODULE_LICENSE("GPL v2");