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

abx500-clk.c (3613B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * abx500 clock implementation for ux500 platform.
      4 *
      5 * Copyright (C) 2012 ST-Ericsson SA
      6 * Author: Ulf Hansson <ulf.hansson@linaro.org>
      7 */
      8
      9#include <linux/err.h>
     10#include <linux/module.h>
     11#include <linux/device.h>
     12#include <linux/of.h>
     13#include <linux/platform_device.h>
     14#include <linux/mfd/abx500/ab8500.h>
     15#include <linux/mfd/abx500/ab8500-sysctrl.h>
     16#include <linux/clkdev.h>
     17#include <linux/clk-provider.h>
     18#include <dt-bindings/clock/ste-ab8500.h>
     19#include "clk.h"
     20
     21#define AB8500_NUM_CLKS 6
     22
     23static struct clk *ab8500_clks[AB8500_NUM_CLKS];
     24static struct clk_onecell_data ab8500_clk_data;
     25
     26/* Clock definitions for ab8500 */
     27static int ab8500_reg_clks(struct device *dev)
     28{
     29	int ret;
     30	struct clk *clk;
     31	struct device_node *np = dev->of_node;
     32	const char *intclk_parents[] = {"ab8500_sysclk", "ulpclk"};
     33	u16 intclk_reg_sel[] = {0 , AB8500_SYSULPCLKCTRL1};
     34	u8 intclk_reg_mask[] = {0 , AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK};
     35	u8 intclk_reg_bits[] = {
     36		0 ,
     37		(1 << AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT)
     38	};
     39
     40	/* Enable SWAT */
     41	ret = ab8500_sysctrl_set(AB8500_SWATCTRL, AB8500_SWATCTRL_SWATENABLE);
     42	if (ret)
     43		return ret;
     44
     45	/* ab8500_sysclk2 */
     46	clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk2", "ab8500_sysclk",
     47		AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ,
     48		AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, 0, 0);
     49	ab8500_clks[AB8500_SYSCLK_BUF2] = clk;
     50
     51	/* ab8500_sysclk3 */
     52	clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk3", "ab8500_sysclk",
     53		AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ,
     54		AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, 0, 0);
     55	ab8500_clks[AB8500_SYSCLK_BUF3] = clk;
     56
     57	/* ab8500_sysclk4 */
     58	clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk4", "ab8500_sysclk",
     59		AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ,
     60		AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, 0, 0);
     61	ab8500_clks[AB8500_SYSCLK_BUF4] = clk;
     62
     63	/* ab_ulpclk */
     64	clk = clk_reg_sysctrl_gate_fixed_rate(dev, "ulpclk", NULL,
     65		AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ,
     66		AB8500_SYSULPCLKCTRL1_ULPCLKREQ,
     67		38400000, 9000, 0);
     68	ab8500_clks[AB8500_SYSCLK_ULP] = clk;
     69
     70	/* ab8500_intclk */
     71	clk = clk_reg_sysctrl_set_parent(dev , "intclk", intclk_parents, 2,
     72		intclk_reg_sel, intclk_reg_mask, intclk_reg_bits, 0);
     73	ab8500_clks[AB8500_SYSCLK_INT] = clk;
     74
     75	/* ab8500_audioclk */
     76	clk = clk_reg_sysctrl_gate(dev , "audioclk", "intclk",
     77		AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_AUDIOCLKENA,
     78		AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, 0, 0);
     79	ab8500_clks[AB8500_SYSCLK_AUDIO] = clk;
     80
     81	ab8500_clk_data.clks = ab8500_clks;
     82	ab8500_clk_data.clk_num = ARRAY_SIZE(ab8500_clks);
     83	of_clk_add_provider(np, of_clk_src_onecell_get, &ab8500_clk_data);
     84
     85	dev_info(dev, "registered clocks for ab850x\n");
     86
     87	return 0;
     88}
     89
     90static int abx500_clk_probe(struct platform_device *pdev)
     91{
     92	struct ab8500 *parent = dev_get_drvdata(pdev->dev.parent);
     93	int ret;
     94
     95	if (is_ab8500(parent) || is_ab8505(parent)) {
     96		ret = ab8500_reg_clks(&pdev->dev);
     97	} else {
     98		dev_err(&pdev->dev, "non supported plf id\n");
     99		return -ENODEV;
    100	}
    101
    102	return ret;
    103}
    104
    105static const struct of_device_id abx500_clk_match[] = {
    106	{ .compatible = "stericsson,ab8500-clk", },
    107	{}
    108};
    109
    110static struct platform_driver abx500_clk_driver = {
    111	.driver = {
    112		.name = "abx500-clk",
    113		.of_match_table = abx500_clk_match,
    114	},
    115	.probe	= abx500_clk_probe,
    116};
    117
    118static int __init abx500_clk_init(void)
    119{
    120	return platform_driver_register(&abx500_clk_driver);
    121}
    122arch_initcall(abx500_clk_init);
    123
    124MODULE_AUTHOR("Ulf Hansson <ulf.hansson@linaro.org");
    125MODULE_DESCRIPTION("ABX500 clk driver");
    126MODULE_LICENSE("GPL v2");