Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
0004  */
0005 
0006 #include <linux/kernel.h>
0007 #include <linux/err.h>
0008 #include <linux/platform_device.h>
0009 #include <linux/clk-provider.h>
0010 #include <linux/regmap.h>
0011 #include <linux/module.h>
0012 
0013 #include <dt-bindings/clock/qcom,apss-ipq.h>
0014 
0015 #include "common.h"
0016 #include "clk-regmap.h"
0017 #include "clk-branch.h"
0018 #include "clk-alpha-pll.h"
0019 #include "clk-regmap-mux.h"
0020 
0021 enum {
0022     P_XO,
0023     P_APSS_PLL_EARLY,
0024 };
0025 
0026 static const struct clk_parent_data parents_apcs_alias0_clk_src[] = {
0027     { .fw_name = "xo" },
0028     { .fw_name = "pll" },
0029 };
0030 
0031 static const struct parent_map parents_apcs_alias0_clk_src_map[] = {
0032     { P_XO, 0 },
0033     { P_APSS_PLL_EARLY, 5 },
0034 };
0035 
0036 static struct clk_regmap_mux apcs_alias0_clk_src = {
0037     .reg = 0x0050,
0038     .width = 3,
0039     .shift = 7,
0040     .parent_map = parents_apcs_alias0_clk_src_map,
0041     .clkr.hw.init = &(struct clk_init_data){
0042         .name = "apcs_alias0_clk_src",
0043         .parent_data = parents_apcs_alias0_clk_src,
0044         .num_parents = 2,
0045         .ops = &clk_regmap_mux_closest_ops,
0046         .flags = CLK_SET_RATE_PARENT,
0047     },
0048 };
0049 
0050 static struct clk_branch apcs_alias0_core_clk = {
0051     .halt_reg = 0x0058,
0052     .clkr = {
0053         .enable_reg = 0x0058,
0054         .enable_mask = BIT(0),
0055         .hw.init = &(struct clk_init_data){
0056             .name = "apcs_alias0_core_clk",
0057             .parent_hws = (const struct clk_hw *[]){
0058                 &apcs_alias0_clk_src.clkr.hw },
0059             .num_parents = 1,
0060             .flags = CLK_SET_RATE_PARENT,
0061             .ops = &clk_branch2_ops,
0062         },
0063     },
0064 };
0065 
0066 static const struct regmap_config apss_ipq6018_regmap_config = {
0067     .reg_bits       = 32,
0068     .reg_stride     = 4,
0069     .val_bits       = 32,
0070     .max_register   = 0x1000,
0071     .fast_io        = true,
0072 };
0073 
0074 static struct clk_regmap *apss_ipq6018_clks[] = {
0075     [APCS_ALIAS0_CLK_SRC] = &apcs_alias0_clk_src.clkr,
0076     [APCS_ALIAS0_CORE_CLK] = &apcs_alias0_core_clk.clkr,
0077 };
0078 
0079 static const struct qcom_cc_desc apss_ipq6018_desc = {
0080     .config = &apss_ipq6018_regmap_config,
0081     .clks = apss_ipq6018_clks,
0082     .num_clks = ARRAY_SIZE(apss_ipq6018_clks),
0083 };
0084 
0085 static int apss_ipq6018_probe(struct platform_device *pdev)
0086 {
0087     struct regmap *regmap;
0088 
0089     regmap = dev_get_regmap(pdev->dev.parent, NULL);
0090     if (!regmap)
0091         return -ENODEV;
0092 
0093     return qcom_cc_really_probe(pdev, &apss_ipq6018_desc, regmap);
0094 }
0095 
0096 static struct platform_driver apss_ipq6018_driver = {
0097     .probe = apss_ipq6018_probe,
0098     .driver = {
0099         .name   = "qcom,apss-ipq6018-clk",
0100     },
0101 };
0102 
0103 module_platform_driver(apss_ipq6018_driver);
0104 
0105 MODULE_DESCRIPTION("QCOM APSS IPQ 6018 CLK Driver");
0106 MODULE_LICENSE("GPL v2");