^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2018, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <dt-bindings/clock/qcom,apss-ipq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "clk-regmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "clk-branch.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "clk-alpha-pll.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "clk-regmap-mux.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) P_XO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) P_APSS_PLL_EARLY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static const struct clk_parent_data parents_apcs_alias0_clk_src[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) { .fw_name = "xo" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) { .fw_name = "pll" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static const struct parent_map parents_apcs_alias0_clk_src_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) { P_XO, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) { P_APSS_PLL_EARLY, 5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static struct clk_regmap_mux apcs_alias0_clk_src = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .reg = 0x0050,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .width = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .shift = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .parent_map = parents_apcs_alias0_clk_src_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .clkr.hw.init = &(struct clk_init_data){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .name = "apcs_alias0_clk_src",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .parent_data = parents_apcs_alias0_clk_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .num_parents = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .ops = &clk_regmap_mux_closest_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .flags = CLK_SET_RATE_PARENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static struct clk_branch apcs_alias0_core_clk = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .halt_reg = 0x0058,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .clkr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .enable_reg = 0x0058,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .enable_mask = BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .hw.init = &(struct clk_init_data){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .name = "apcs_alias0_core_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .parent_hws = (const struct clk_hw *[]){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) &apcs_alias0_clk_src.clkr.hw },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .num_parents = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .flags = CLK_SET_RATE_PARENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .ops = &clk_branch2_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static const struct regmap_config apss_ipq6018_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .max_register = 0x1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .fast_io = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static struct clk_regmap *apss_ipq6018_clks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) [APCS_ALIAS0_CLK_SRC] = &apcs_alias0_clk_src.clkr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) [APCS_ALIAS0_CORE_CLK] = &apcs_alias0_core_clk.clkr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static const struct qcom_cc_desc apss_ipq6018_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .config = &apss_ipq6018_regmap_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .clks = apss_ipq6018_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .num_clks = ARRAY_SIZE(apss_ipq6018_clks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static int apss_ipq6018_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) regmap = dev_get_regmap(pdev->dev.parent, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (!regmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return qcom_cc_really_probe(pdev, &apss_ipq6018_desc, regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static struct platform_driver apss_ipq6018_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .probe = apss_ipq6018_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .name = "qcom,apss-ipq6018-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) module_platform_driver(apss_ipq6018_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) MODULE_DESCRIPTION("QCOM APSS IPQ 6018 CLK Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) MODULE_LICENSE("GPL v2");