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"
1943a56cbfSRobert Marko #include "clk-rcg.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
3643a56cbfSRobert Marko static struct clk_rcg2 apcs_alias0_clk_src = {
3743a56cbfSRobert Marko .cmd_rcgr = 0x0050,
3843a56cbfSRobert Marko .hid_width = 5,
395e77b4efSSivaprakash Murugesan .parent_map = parents_apcs_alias0_clk_src_map,
405e77b4efSSivaprakash Murugesan .clkr.hw.init = &(struct clk_init_data){
415e77b4efSSivaprakash Murugesan .name = "apcs_alias0_clk_src",
425e77b4efSSivaprakash Murugesan .parent_data = parents_apcs_alias0_clk_src,
4343a56cbfSRobert Marko .num_parents = ARRAY_SIZE(parents_apcs_alias0_clk_src),
4443a56cbfSRobert Marko .ops = &clk_rcg2_mux_closest_ops,
455e77b4efSSivaprakash Murugesan .flags = CLK_SET_RATE_PARENT,
465e77b4efSSivaprakash Murugesan },
475e77b4efSSivaprakash Murugesan };
485e77b4efSSivaprakash Murugesan
495e77b4efSSivaprakash Murugesan static struct clk_branch apcs_alias0_core_clk = {
505e77b4efSSivaprakash Murugesan .halt_reg = 0x0058,
515e77b4efSSivaprakash Murugesan .clkr = {
525e77b4efSSivaprakash Murugesan .enable_reg = 0x0058,
535e77b4efSSivaprakash Murugesan .enable_mask = BIT(0),
545e77b4efSSivaprakash Murugesan .hw.init = &(struct clk_init_data){
555e77b4efSSivaprakash Murugesan .name = "apcs_alias0_core_clk",
565e77b4efSSivaprakash Murugesan .parent_hws = (const struct clk_hw *[]){
575e77b4efSSivaprakash Murugesan &apcs_alias0_clk_src.clkr.hw },
585e77b4efSSivaprakash Murugesan .num_parents = 1,
59*86e78995SRobert Marko .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
605e77b4efSSivaprakash Murugesan .ops = &clk_branch2_ops,
615e77b4efSSivaprakash Murugesan },
625e77b4efSSivaprakash Murugesan },
635e77b4efSSivaprakash Murugesan };
645e77b4efSSivaprakash Murugesan
655e77b4efSSivaprakash Murugesan static const struct regmap_config apss_ipq6018_regmap_config = {
665e77b4efSSivaprakash Murugesan .reg_bits = 32,
675e77b4efSSivaprakash Murugesan .reg_stride = 4,
685e77b4efSSivaprakash Murugesan .val_bits = 32,
695e77b4efSSivaprakash Murugesan .max_register = 0x1000,
705e77b4efSSivaprakash Murugesan .fast_io = true,
715e77b4efSSivaprakash Murugesan };
725e77b4efSSivaprakash Murugesan
735e77b4efSSivaprakash Murugesan static struct clk_regmap *apss_ipq6018_clks[] = {
745e77b4efSSivaprakash Murugesan [APCS_ALIAS0_CLK_SRC] = &apcs_alias0_clk_src.clkr,
755e77b4efSSivaprakash Murugesan [APCS_ALIAS0_CORE_CLK] = &apcs_alias0_core_clk.clkr,
765e77b4efSSivaprakash Murugesan };
775e77b4efSSivaprakash Murugesan
785e77b4efSSivaprakash Murugesan static const struct qcom_cc_desc apss_ipq6018_desc = {
795e77b4efSSivaprakash Murugesan .config = &apss_ipq6018_regmap_config,
805e77b4efSSivaprakash Murugesan .clks = apss_ipq6018_clks,
815e77b4efSSivaprakash Murugesan .num_clks = ARRAY_SIZE(apss_ipq6018_clks),
825e77b4efSSivaprakash Murugesan };
835e77b4efSSivaprakash Murugesan
apss_ipq6018_probe(struct platform_device * pdev)845e77b4efSSivaprakash Murugesan static int apss_ipq6018_probe(struct platform_device *pdev)
855e77b4efSSivaprakash Murugesan {
865e77b4efSSivaprakash Murugesan struct regmap *regmap;
875e77b4efSSivaprakash Murugesan
885e77b4efSSivaprakash Murugesan regmap = dev_get_regmap(pdev->dev.parent, NULL);
89dbb988b4SWei Yongjun if (!regmap)
90dbb988b4SWei Yongjun return -ENODEV;
915e77b4efSSivaprakash Murugesan
925e77b4efSSivaprakash Murugesan return qcom_cc_really_probe(pdev, &apss_ipq6018_desc, regmap);
935e77b4efSSivaprakash Murugesan }
945e77b4efSSivaprakash Murugesan
955e77b4efSSivaprakash Murugesan static struct platform_driver apss_ipq6018_driver = {
965e77b4efSSivaprakash Murugesan .probe = apss_ipq6018_probe,
975e77b4efSSivaprakash Murugesan .driver = {
985e77b4efSSivaprakash Murugesan .name = "qcom,apss-ipq6018-clk",
995e77b4efSSivaprakash Murugesan },
1005e77b4efSSivaprakash Murugesan };
1015e77b4efSSivaprakash Murugesan
1025e77b4efSSivaprakash Murugesan module_platform_driver(apss_ipq6018_driver);
1035e77b4efSSivaprakash Murugesan
1045e77b4efSSivaprakash Murugesan MODULE_DESCRIPTION("QCOM APSS IPQ 6018 CLK Driver");
1055e77b4efSSivaprakash Murugesan MODULE_LICENSE("GPL v2");
106