linux/drivers/clk/qcom/hfpll.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (c) 2018, The Linux Foundation. All rights reserved.
   3
   4#include <linux/kernel.h>
   5#include <linux/init.h>
   6#include <linux/module.h>
   7#include <linux/platform_device.h>
   8#include <linux/of.h>
   9#include <linux/clk.h>
  10#include <linux/clk-provider.h>
  11#include <linux/regmap.h>
  12
  13#include "clk-regmap.h"
  14#include "clk-hfpll.h"
  15
  16static const struct hfpll_data hdata = {
  17        .mode_reg = 0x00,
  18        .l_reg = 0x04,
  19        .m_reg = 0x08,
  20        .n_reg = 0x0c,
  21        .user_reg = 0x10,
  22        .config_reg = 0x14,
  23        .config_val = 0x430405d,
  24        .status_reg = 0x1c,
  25        .lock_bit = 16,
  26
  27        .user_val = 0x8,
  28        .user_vco_mask = 0x100000,
  29        .low_vco_max_rate = 1248000000,
  30        .min_rate = 537600000UL,
  31        .max_rate = 2900000000UL,
  32};
  33
  34static const struct of_device_id qcom_hfpll_match_table[] = {
  35        { .compatible = "qcom,hfpll" },
  36        { }
  37};
  38MODULE_DEVICE_TABLE(of, qcom_hfpll_match_table);
  39
  40static const struct regmap_config hfpll_regmap_config = {
  41        .reg_bits       = 32,
  42        .reg_stride     = 4,
  43        .val_bits       = 32,
  44        .max_register   = 0x30,
  45        .fast_io        = true,
  46};
  47
  48static int qcom_hfpll_probe(struct platform_device *pdev)
  49{
  50        struct resource *res;
  51        struct device *dev = &pdev->dev;
  52        void __iomem *base;
  53        struct regmap *regmap;
  54        struct clk_hfpll *h;
  55        struct clk_init_data init = {
  56                .parent_names = (const char *[]){ "xo" },
  57                .num_parents = 1,
  58                .ops = &clk_ops_hfpll,
  59        };
  60
  61        h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL);
  62        if (!h)
  63                return -ENOMEM;
  64
  65        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  66        base = devm_ioremap_resource(dev, res);
  67        if (IS_ERR(base))
  68                return PTR_ERR(base);
  69
  70        regmap = devm_regmap_init_mmio(&pdev->dev, base, &hfpll_regmap_config);
  71        if (IS_ERR(regmap))
  72                return PTR_ERR(regmap);
  73
  74        if (of_property_read_string_index(dev->of_node, "clock-output-names",
  75                                          0, &init.name))
  76                return -ENODEV;
  77
  78        h->d = &hdata;
  79        h->clkr.hw.init = &init;
  80        spin_lock_init(&h->lock);
  81
  82        return devm_clk_register_regmap(&pdev->dev, &h->clkr);
  83}
  84
  85static struct platform_driver qcom_hfpll_driver = {
  86        .probe          = qcom_hfpll_probe,
  87        .driver         = {
  88                .name   = "qcom-hfpll",
  89                .of_match_table = qcom_hfpll_match_table,
  90        },
  91};
  92module_platform_driver(qcom_hfpll_driver);
  93
  94MODULE_DESCRIPTION("QCOM HFPLL Clock Driver");
  95MODULE_LICENSE("GPL v2");
  96MODULE_ALIAS("platform:qcom-hfpll");
  97