Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.7-rc2 164 lines 3.8 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4 */ 5 6#include <linux/kernel.h> 7#include <linux/err.h> 8#include <linux/platform_device.h> 9#include <linux/clk-provider.h> 10#include <linux/regmap.h> 11#include <linux/module.h> 12#include <linux/clk.h> 13#include <linux/soc/qcom/smem.h> 14 15#include <dt-bindings/clock/qcom,apss-ipq.h> 16#include <dt-bindings/arm/qcom,ids.h> 17 18#include "common.h" 19#include "clk-regmap.h" 20#include "clk-branch.h" 21#include "clk-alpha-pll.h" 22#include "clk-rcg.h" 23 24enum { 25 P_XO, 26 P_GPLL0, 27 P_APSS_PLL_EARLY, 28}; 29 30static const struct clk_parent_data parents_apcs_alias0_clk_src[] = { 31 { .fw_name = "xo" }, 32 { .fw_name = "gpll0" }, 33 { .fw_name = "pll" }, 34}; 35 36static const struct parent_map parents_apcs_alias0_clk_src_map[] = { 37 { P_XO, 0 }, 38 { P_GPLL0, 4 }, 39 { P_APSS_PLL_EARLY, 5 }, 40}; 41 42static struct clk_rcg2 apcs_alias0_clk_src = { 43 .cmd_rcgr = 0x0050, 44 .hid_width = 5, 45 .parent_map = parents_apcs_alias0_clk_src_map, 46 .clkr.hw.init = &(struct clk_init_data){ 47 .name = "apcs_alias0_clk_src", 48 .parent_data = parents_apcs_alias0_clk_src, 49 .num_parents = ARRAY_SIZE(parents_apcs_alias0_clk_src), 50 .ops = &clk_rcg2_mux_closest_ops, 51 .flags = CLK_SET_RATE_PARENT, 52 }, 53}; 54 55static struct clk_branch apcs_alias0_core_clk = { 56 .halt_reg = 0x0058, 57 .clkr = { 58 .enable_reg = 0x0058, 59 .enable_mask = BIT(0), 60 .hw.init = &(struct clk_init_data){ 61 .name = "apcs_alias0_core_clk", 62 .parent_hws = (const struct clk_hw *[]){ 63 &apcs_alias0_clk_src.clkr.hw }, 64 .num_parents = 1, 65 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 66 .ops = &clk_branch2_ops, 67 }, 68 }, 69}; 70 71static const struct regmap_config apss_ipq6018_regmap_config = { 72 .reg_bits = 32, 73 .reg_stride = 4, 74 .val_bits = 32, 75 .max_register = 0x1000, 76 .fast_io = true, 77}; 78 79static struct clk_regmap *apss_ipq6018_clks[] = { 80 [APCS_ALIAS0_CLK_SRC] = &apcs_alias0_clk_src.clkr, 81 [APCS_ALIAS0_CORE_CLK] = &apcs_alias0_core_clk.clkr, 82}; 83 84static const struct qcom_cc_desc apss_ipq6018_desc = { 85 .config = &apss_ipq6018_regmap_config, 86 .clks = apss_ipq6018_clks, 87 .num_clks = ARRAY_SIZE(apss_ipq6018_clks), 88}; 89 90static int cpu_clk_notifier_fn(struct notifier_block *nb, unsigned long action, 91 void *data) 92{ 93 struct clk_hw *hw; 94 u8 index; 95 int err; 96 97 if (action == PRE_RATE_CHANGE) 98 index = P_GPLL0; 99 else if (action == POST_RATE_CHANGE || action == ABORT_RATE_CHANGE) 100 index = P_APSS_PLL_EARLY; 101 else 102 return NOTIFY_OK; 103 104 hw = &apcs_alias0_clk_src.clkr.hw; 105 err = clk_rcg2_mux_closest_ops.set_parent(hw, index); 106 107 return notifier_from_errno(err); 108} 109 110static int apss_ipq6018_probe(struct platform_device *pdev) 111{ 112 struct clk_hw *hw = &apcs_alias0_clk_src.clkr.hw; 113 struct notifier_block *cpu_clk_notifier; 114 struct regmap *regmap; 115 u32 soc_id; 116 int ret; 117 118 ret = qcom_smem_get_soc_id(&soc_id); 119 if (ret) 120 return ret; 121 122 regmap = dev_get_regmap(pdev->dev.parent, NULL); 123 if (!regmap) 124 return -ENODEV; 125 126 ret = qcom_cc_really_probe(pdev, &apss_ipq6018_desc, regmap); 127 if (ret) 128 return ret; 129 130 switch (soc_id) { 131 /* Only below variants of IPQ53xx support scaling */ 132 case QCOM_ID_IPQ5332: 133 case QCOM_ID_IPQ5322: 134 case QCOM_ID_IPQ5300: 135 cpu_clk_notifier = devm_kzalloc(&pdev->dev, 136 sizeof(*cpu_clk_notifier), 137 GFP_KERNEL); 138 if (!cpu_clk_notifier) 139 return -ENOMEM; 140 141 cpu_clk_notifier->notifier_call = cpu_clk_notifier_fn; 142 143 ret = devm_clk_notifier_register(&pdev->dev, hw->clk, cpu_clk_notifier); 144 if (ret) 145 return ret; 146 break; 147 default: 148 break; 149 } 150 151 return 0; 152} 153 154static struct platform_driver apss_ipq6018_driver = { 155 .probe = apss_ipq6018_probe, 156 .driver = { 157 .name = "qcom,apss-ipq6018-clk", 158 }, 159}; 160 161module_platform_driver(apss_ipq6018_driver); 162 163MODULE_DESCRIPTION("QCOM APSS IPQ 6018 CLK Driver"); 164MODULE_LICENSE("GPL v2");