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-sysctrl.c (5677B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Sysctrl clock implementation for ux500 platform.
      4 *
      5 * Copyright (C) 2013 ST-Ericsson SA
      6 * Author: Ulf Hansson <ulf.hansson@linaro.org>
      7 */
      8
      9#include <linux/clk-provider.h>
     10#include <linux/mfd/abx500/ab8500-sysctrl.h>
     11#include <linux/device.h>
     12#include <linux/slab.h>
     13#include <linux/delay.h>
     14#include <linux/io.h>
     15#include <linux/err.h>
     16#include "clk.h"
     17
     18#define SYSCTRL_MAX_NUM_PARENTS 4
     19
     20#define to_clk_sysctrl(_hw) container_of(_hw, struct clk_sysctrl, hw)
     21
     22struct clk_sysctrl {
     23	struct clk_hw hw;
     24	struct device *dev;
     25	u8 parent_index;
     26	u16 reg_sel[SYSCTRL_MAX_NUM_PARENTS];
     27	u8 reg_mask[SYSCTRL_MAX_NUM_PARENTS];
     28	u8 reg_bits[SYSCTRL_MAX_NUM_PARENTS];
     29	unsigned long rate;
     30	unsigned long enable_delay_us;
     31};
     32
     33/* Sysctrl clock operations. */
     34
     35static int clk_sysctrl_prepare(struct clk_hw *hw)
     36{
     37	int ret;
     38	struct clk_sysctrl *clk = to_clk_sysctrl(hw);
     39
     40	ret = ab8500_sysctrl_write(clk->reg_sel[0], clk->reg_mask[0],
     41				clk->reg_bits[0]);
     42
     43	if (!ret && clk->enable_delay_us)
     44		usleep_range(clk->enable_delay_us, clk->enable_delay_us +
     45			     (clk->enable_delay_us >> 2));
     46
     47	return ret;
     48}
     49
     50static void clk_sysctrl_unprepare(struct clk_hw *hw)
     51{
     52	struct clk_sysctrl *clk = to_clk_sysctrl(hw);
     53	if (ab8500_sysctrl_clear(clk->reg_sel[0], clk->reg_mask[0]))
     54		dev_err(clk->dev, "clk_sysctrl: %s fail to clear %s.\n",
     55			__func__, clk_hw_get_name(hw));
     56}
     57
     58static unsigned long clk_sysctrl_recalc_rate(struct clk_hw *hw,
     59					unsigned long parent_rate)
     60{
     61	struct clk_sysctrl *clk = to_clk_sysctrl(hw);
     62	return clk->rate;
     63}
     64
     65static int clk_sysctrl_set_parent(struct clk_hw *hw, u8 index)
     66{
     67	struct clk_sysctrl *clk = to_clk_sysctrl(hw);
     68	u8 old_index = clk->parent_index;
     69	int ret = 0;
     70
     71	if (clk->reg_sel[old_index]) {
     72		ret = ab8500_sysctrl_clear(clk->reg_sel[old_index],
     73					clk->reg_mask[old_index]);
     74		if (ret)
     75			return ret;
     76	}
     77
     78	if (clk->reg_sel[index]) {
     79		ret = ab8500_sysctrl_write(clk->reg_sel[index],
     80					clk->reg_mask[index],
     81					clk->reg_bits[index]);
     82		if (ret) {
     83			if (clk->reg_sel[old_index])
     84				ab8500_sysctrl_write(clk->reg_sel[old_index],
     85						clk->reg_mask[old_index],
     86						clk->reg_bits[old_index]);
     87			return ret;
     88		}
     89	}
     90	clk->parent_index = index;
     91
     92	return ret;
     93}
     94
     95static u8 clk_sysctrl_get_parent(struct clk_hw *hw)
     96{
     97	struct clk_sysctrl *clk = to_clk_sysctrl(hw);
     98	return clk->parent_index;
     99}
    100
    101static const struct clk_ops clk_sysctrl_gate_ops = {
    102	.prepare = clk_sysctrl_prepare,
    103	.unprepare = clk_sysctrl_unprepare,
    104};
    105
    106static const struct clk_ops clk_sysctrl_gate_fixed_rate_ops = {
    107	.prepare = clk_sysctrl_prepare,
    108	.unprepare = clk_sysctrl_unprepare,
    109	.recalc_rate = clk_sysctrl_recalc_rate,
    110};
    111
    112static const struct clk_ops clk_sysctrl_set_parent_ops = {
    113	.set_parent = clk_sysctrl_set_parent,
    114	.get_parent = clk_sysctrl_get_parent,
    115};
    116
    117static struct clk *clk_reg_sysctrl(struct device *dev,
    118				const char *name,
    119				const char **parent_names,
    120				u8 num_parents,
    121				u16 *reg_sel,
    122				u8 *reg_mask,
    123				u8 *reg_bits,
    124				unsigned long rate,
    125				unsigned long enable_delay_us,
    126				unsigned long flags,
    127				const struct clk_ops *clk_sysctrl_ops)
    128{
    129	struct clk_sysctrl *clk;
    130	struct clk_init_data clk_sysctrl_init;
    131	struct clk *clk_reg;
    132	int i;
    133
    134	if (!dev)
    135		return ERR_PTR(-EINVAL);
    136
    137	if (!name || (num_parents > SYSCTRL_MAX_NUM_PARENTS)) {
    138		dev_err(dev, "clk_sysctrl: invalid arguments passed\n");
    139		return ERR_PTR(-EINVAL);
    140	}
    141
    142	clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
    143	if (!clk)
    144		return ERR_PTR(-ENOMEM);
    145
    146	/* set main clock registers */
    147	clk->reg_sel[0] = reg_sel[0];
    148	clk->reg_bits[0] = reg_bits[0];
    149	clk->reg_mask[0] = reg_mask[0];
    150
    151	/* handle clocks with more than one parent */
    152	for (i = 1; i < num_parents; i++) {
    153		clk->reg_sel[i] = reg_sel[i];
    154		clk->reg_bits[i] = reg_bits[i];
    155		clk->reg_mask[i] = reg_mask[i];
    156	}
    157
    158	clk->parent_index = 0;
    159	clk->rate = rate;
    160	clk->enable_delay_us = enable_delay_us;
    161	clk->dev = dev;
    162
    163	clk_sysctrl_init.name = name;
    164	clk_sysctrl_init.ops = clk_sysctrl_ops;
    165	clk_sysctrl_init.flags = flags;
    166	clk_sysctrl_init.parent_names = parent_names;
    167	clk_sysctrl_init.num_parents = num_parents;
    168	clk->hw.init = &clk_sysctrl_init;
    169
    170	clk_reg = devm_clk_register(clk->dev, &clk->hw);
    171	if (IS_ERR(clk_reg))
    172		dev_err(dev, "clk_sysctrl: clk_register failed\n");
    173
    174	return clk_reg;
    175}
    176
    177struct clk *clk_reg_sysctrl_gate(struct device *dev,
    178				const char *name,
    179				const char *parent_name,
    180				u16 reg_sel,
    181				u8 reg_mask,
    182				u8 reg_bits,
    183				unsigned long enable_delay_us,
    184				unsigned long flags)
    185{
    186	const char **parent_names = (parent_name ? &parent_name : NULL);
    187	u8 num_parents = (parent_name ? 1 : 0);
    188
    189	return clk_reg_sysctrl(dev, name, parent_names, num_parents,
    190			&reg_sel, &reg_mask, &reg_bits, 0, enable_delay_us,
    191			flags, &clk_sysctrl_gate_ops);
    192}
    193
    194struct clk *clk_reg_sysctrl_gate_fixed_rate(struct device *dev,
    195					const char *name,
    196					const char *parent_name,
    197					u16 reg_sel,
    198					u8 reg_mask,
    199					u8 reg_bits,
    200					unsigned long rate,
    201					unsigned long enable_delay_us,
    202					unsigned long flags)
    203{
    204	const char **parent_names = (parent_name ? &parent_name : NULL);
    205	u8 num_parents = (parent_name ? 1 : 0);
    206
    207	return clk_reg_sysctrl(dev, name, parent_names, num_parents,
    208			&reg_sel, &reg_mask, &reg_bits,
    209			rate, enable_delay_us, flags,
    210			&clk_sysctrl_gate_fixed_rate_ops);
    211}
    212
    213struct clk *clk_reg_sysctrl_set_parent(struct device *dev,
    214				const char *name,
    215				const char **parent_names,
    216				u8 num_parents,
    217				u16 *reg_sel,
    218				u8 *reg_mask,
    219				u8 *reg_bits,
    220				unsigned long flags)
    221{
    222	return clk_reg_sysctrl(dev, name, parent_names, num_parents,
    223			reg_sel, reg_mask, reg_bits, 0, 0, flags,
    224			&clk_sysctrl_set_parent_ops);
    225}