15e77b4efSSivaprakash Murugesan // SPDX-License-Identifier: GPL-2.0 25e77b4efSSivaprakash Murugesan /* 35e77b4efSSivaprakash Murugesan * Copyright (c) 2018, The Linux Foundation. All rights reserved. 45e77b4efSSivaprakash Murugesan */ 55e77b4efSSivaprakash Murugesan 65e77b4efSSivaprakash Murugesan #include <linux/kernel.h> 75e77b4efSSivaprakash Murugesan #include <linux/err.h> 85e77b4efSSivaprakash Murugesan #include <linux/platform_device.h> 95e77b4efSSivaprakash Murugesan #include <linux/clk-provider.h> 105e77b4efSSivaprakash Murugesan #include <linux/regmap.h> 115e77b4efSSivaprakash Murugesan #include <linux/module.h> 125e77b4efSSivaprakash Murugesan 135e77b4efSSivaprakash Murugesan #include <dt-bindings/clock/qcom,apss-ipq.h> 145e77b4efSSivaprakash Murugesan 155e77b4efSSivaprakash Murugesan #include "common.h" 165e77b4efSSivaprakash Murugesan #include "clk-regmap.h" 175e77b4efSSivaprakash Murugesan #include "clk-branch.h" 185e77b4efSSivaprakash Murugesan #include "clk-alpha-pll.h" 195e77b4efSSivaprakash Murugesan #include "clk-regmap-mux.h" 205e77b4efSSivaprakash Murugesan 215e77b4efSSivaprakash Murugesan enum { 225e77b4efSSivaprakash Murugesan P_XO, 235e77b4efSSivaprakash Murugesan P_APSS_PLL_EARLY, 245e77b4efSSivaprakash Murugesan }; 255e77b4efSSivaprakash Murugesan 265e77b4efSSivaprakash Murugesan static const struct clk_parent_data parents_apcs_alias0_clk_src[] = { 275e77b4efSSivaprakash Murugesan { .fw_name = "xo" }, 285e77b4efSSivaprakash Murugesan { .fw_name = "pll" }, 295e77b4efSSivaprakash Murugesan }; 305e77b4efSSivaprakash Murugesan 315e77b4efSSivaprakash Murugesan static const struct parent_map parents_apcs_alias0_clk_src_map[] = { 325e77b4efSSivaprakash Murugesan { P_XO, 0 }, 335e77b4efSSivaprakash Murugesan { P_APSS_PLL_EARLY, 5 }, 345e77b4efSSivaprakash Murugesan }; 355e77b4efSSivaprakash Murugesan 365e77b4efSSivaprakash Murugesan static struct clk_regmap_mux apcs_alias0_clk_src = { 375e77b4efSSivaprakash Murugesan .reg = 0x0050, 385e77b4efSSivaprakash Murugesan .width = 3, 395e77b4efSSivaprakash Murugesan .shift = 7, 405e77b4efSSivaprakash Murugesan .parent_map = parents_apcs_alias0_clk_src_map, 415e77b4efSSivaprakash Murugesan .clkr.hw.init = &(struct clk_init_data){ 425e77b4efSSivaprakash Murugesan .name = "apcs_alias0_clk_src", 435e77b4efSSivaprakash Murugesan .parent_data = parents_apcs_alias0_clk_src, 445e77b4efSSivaprakash Murugesan .num_parents = 2, 455e77b4efSSivaprakash Murugesan .ops = &clk_regmap_mux_closest_ops, 465e77b4efSSivaprakash Murugesan .flags = CLK_SET_RATE_PARENT, 475e77b4efSSivaprakash Murugesan }, 485e77b4efSSivaprakash Murugesan }; 495e77b4efSSivaprakash Murugesan 505e77b4efSSivaprakash Murugesan static struct clk_branch apcs_alias0_core_clk = { 515e77b4efSSivaprakash Murugesan .halt_reg = 0x0058, 525e77b4efSSivaprakash Murugesan .clkr = { 535e77b4efSSivaprakash Murugesan .enable_reg = 0x0058, 545e77b4efSSivaprakash Murugesan .enable_mask = BIT(0), 555e77b4efSSivaprakash Murugesan .hw.init = &(struct clk_init_data){ 565e77b4efSSivaprakash Murugesan .name = "apcs_alias0_core_clk", 575e77b4efSSivaprakash Murugesan .parent_hws = (const struct clk_hw *[]){ 585e77b4efSSivaprakash Murugesan &apcs_alias0_clk_src.clkr.hw }, 595e77b4efSSivaprakash Murugesan .num_parents = 1, 605e77b4efSSivaprakash Murugesan .flags = CLK_SET_RATE_PARENT, 615e77b4efSSivaprakash Murugesan .ops = &clk_branch2_ops, 625e77b4efSSivaprakash Murugesan }, 635e77b4efSSivaprakash Murugesan }, 645e77b4efSSivaprakash Murugesan }; 655e77b4efSSivaprakash Murugesan 665e77b4efSSivaprakash Murugesan static const struct regmap_config apss_ipq6018_regmap_config = { 675e77b4efSSivaprakash Murugesan .reg_bits = 32, 685e77b4efSSivaprakash Murugesan .reg_stride = 4, 695e77b4efSSivaprakash Murugesan .val_bits = 32, 705e77b4efSSivaprakash Murugesan .max_register = 0x1000, 715e77b4efSSivaprakash Murugesan .fast_io = true, 725e77b4efSSivaprakash Murugesan }; 735e77b4efSSivaprakash Murugesan 745e77b4efSSivaprakash Murugesan static struct clk_regmap *apss_ipq6018_clks[] = { 755e77b4efSSivaprakash Murugesan [APCS_ALIAS0_CLK_SRC] = &apcs_alias0_clk_src.clkr, 765e77b4efSSivaprakash Murugesan [APCS_ALIAS0_CORE_CLK] = &apcs_alias0_core_clk.clkr, 775e77b4efSSivaprakash Murugesan }; 785e77b4efSSivaprakash Murugesan 795e77b4efSSivaprakash Murugesan static const struct qcom_cc_desc apss_ipq6018_desc = { 805e77b4efSSivaprakash Murugesan .config = &apss_ipq6018_regmap_config, 815e77b4efSSivaprakash Murugesan .clks = apss_ipq6018_clks, 825e77b4efSSivaprakash Murugesan .num_clks = ARRAY_SIZE(apss_ipq6018_clks), 835e77b4efSSivaprakash Murugesan }; 845e77b4efSSivaprakash Murugesan 855e77b4efSSivaprakash Murugesan static int apss_ipq6018_probe(struct platform_device *pdev) 865e77b4efSSivaprakash Murugesan { 875e77b4efSSivaprakash Murugesan struct regmap *regmap; 885e77b4efSSivaprakash Murugesan 895e77b4efSSivaprakash Murugesan regmap = dev_get_regmap(pdev->dev.parent, NULL); 90dbb988b4SWei Yongjun if (!regmap) 91dbb988b4SWei Yongjun return -ENODEV; 925e77b4efSSivaprakash Murugesan 935e77b4efSSivaprakash Murugesan return qcom_cc_really_probe(pdev, &apss_ipq6018_desc, regmap); 945e77b4efSSivaprakash Murugesan } 955e77b4efSSivaprakash Murugesan 965e77b4efSSivaprakash Murugesan static struct platform_driver apss_ipq6018_driver = { 975e77b4efSSivaprakash Murugesan .probe = apss_ipq6018_probe, 985e77b4efSSivaprakash Murugesan .driver = { 995e77b4efSSivaprakash Murugesan .name = "qcom,apss-ipq6018-clk", 1005e77b4efSSivaprakash Murugesan }, 1015e77b4efSSivaprakash Murugesan }; 1025e77b4efSSivaprakash Murugesan 1035e77b4efSSivaprakash Murugesan module_platform_driver(apss_ipq6018_driver); 1045e77b4efSSivaprakash Murugesan 1055e77b4efSSivaprakash Murugesan MODULE_DESCRIPTION("QCOM APSS IPQ 6018 CLK Driver"); 1065e77b4efSSivaprakash Murugesan MODULE_LICENSE("GPL v2"); 107