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

clk-pll.c (2242B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright 2012 Freescale Semiconductor, Inc.
      4 */
      5
      6#include <linux/clk-provider.h>
      7#include <linux/delay.h>
      8#include <linux/err.h>
      9#include <linux/io.h>
     10#include <linux/slab.h>
     11#include "clk.h"
     12
     13/**
     14 * struct clk_pll - mxs pll clock
     15 * @hw: clk_hw for the pll
     16 * @base: base address of the pll
     17 * @power: the shift of power bit
     18 * @rate: the clock rate of the pll
     19 *
     20 * The mxs pll is a fixed rate clock with power and gate control,
     21 * and the shift of gate bit is always 31.
     22 */
     23struct clk_pll {
     24	struct clk_hw hw;
     25	void __iomem *base;
     26	u8 power;
     27	unsigned long rate;
     28};
     29
     30#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
     31
     32static int clk_pll_prepare(struct clk_hw *hw)
     33{
     34	struct clk_pll *pll = to_clk_pll(hw);
     35
     36	writel_relaxed(1 << pll->power, pll->base + SET);
     37
     38	udelay(10);
     39
     40	return 0;
     41}
     42
     43static void clk_pll_unprepare(struct clk_hw *hw)
     44{
     45	struct clk_pll *pll = to_clk_pll(hw);
     46
     47	writel_relaxed(1 << pll->power, pll->base + CLR);
     48}
     49
     50static int clk_pll_enable(struct clk_hw *hw)
     51{
     52	struct clk_pll *pll = to_clk_pll(hw);
     53
     54	writel_relaxed(1 << 31, pll->base + CLR);
     55
     56	return 0;
     57}
     58
     59static void clk_pll_disable(struct clk_hw *hw)
     60{
     61	struct clk_pll *pll = to_clk_pll(hw);
     62
     63	writel_relaxed(1 << 31, pll->base + SET);
     64}
     65
     66static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
     67					 unsigned long parent_rate)
     68{
     69	struct clk_pll *pll = to_clk_pll(hw);
     70
     71	return pll->rate;
     72}
     73
     74static const struct clk_ops clk_pll_ops = {
     75	.prepare = clk_pll_prepare,
     76	.unprepare = clk_pll_unprepare,
     77	.enable = clk_pll_enable,
     78	.disable = clk_pll_disable,
     79	.recalc_rate = clk_pll_recalc_rate,
     80};
     81
     82struct clk *mxs_clk_pll(const char *name, const char *parent_name,
     83			void __iomem *base, u8 power, unsigned long rate)
     84{
     85	struct clk_pll *pll;
     86	struct clk *clk;
     87	struct clk_init_data init;
     88
     89	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
     90	if (!pll)
     91		return ERR_PTR(-ENOMEM);
     92
     93	init.name = name;
     94	init.ops = &clk_pll_ops;
     95	init.flags = 0;
     96	init.parent_names = (parent_name ? &parent_name: NULL);
     97	init.num_parents = (parent_name ? 1 : 0);
     98
     99	pll->base = base;
    100	pll->rate = rate;
    101	pll->power = power;
    102	pll->hw.init = &init;
    103
    104	clk = clk_register(NULL, &pll->hw);
    105	if (IS_ERR(clk))
    106		kfree(pll);
    107
    108	return clk;
    109}