cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hfpll.c (2729B)


      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		.num_parents = 1,
     57		.ops = &clk_ops_hfpll,
     58		/*
     59		 * rather than marking the clock critical and forcing the clock
     60		 * to be always enabled, we make sure that the clock is not
     61		 * disabled: the firmware remains responsible of enabling this
     62		 * clock (for more info check the commit log)
     63		 */
     64		.flags = CLK_IGNORE_UNUSED,
     65	};
     66	int ret;
     67	struct clk_parent_data pdata = { .index = 0 };
     68
     69	h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL);
     70	if (!h)
     71		return -ENOMEM;
     72
     73	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
     74	base = devm_ioremap_resource(dev, res);
     75	if (IS_ERR(base))
     76		return PTR_ERR(base);
     77
     78	regmap = devm_regmap_init_mmio(&pdev->dev, base, &hfpll_regmap_config);
     79	if (IS_ERR(regmap))
     80		return PTR_ERR(regmap);
     81
     82	if (of_property_read_string_index(dev->of_node, "clock-output-names",
     83					  0, &init.name))
     84		return -ENODEV;
     85
     86	init.parent_data = &pdata;
     87
     88	h->d = &hdata;
     89	h->clkr.hw.init = &init;
     90	spin_lock_init(&h->lock);
     91
     92	ret = devm_clk_register_regmap(dev, &h->clkr);
     93	if (ret) {
     94		dev_err(dev, "failed to register regmap clock: %d\n", ret);
     95		return ret;
     96	}
     97
     98	return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
     99					   &h->clkr.hw);
    100}
    101
    102static struct platform_driver qcom_hfpll_driver = {
    103	.probe		= qcom_hfpll_probe,
    104	.driver		= {
    105		.name	= "qcom-hfpll",
    106		.of_match_table = qcom_hfpll_match_table,
    107	},
    108};
    109module_platform_driver(qcom_hfpll_driver);
    110
    111MODULE_DESCRIPTION("QCOM HFPLL Clock Driver");
    112MODULE_LICENSE("GPL v2");
    113MODULE_ALIAS("platform:qcom-hfpll");