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-muxgrf.c (2253B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2
      3#include <linux/slab.h>
      4#include <linux/bitops.h>
      5#include <linux/regmap.h>
      6#include <linux/clk.h>
      7#include <linux/clk-provider.h>
      8#include "clk.h"
      9
     10struct rockchip_muxgrf_clock {
     11	struct clk_hw		hw;
     12	struct regmap		*regmap;
     13	u32			reg;
     14	u32			shift;
     15	u32			width;
     16	int			flags;
     17};
     18
     19#define to_muxgrf_clock(_hw) container_of(_hw, struct rockchip_muxgrf_clock, hw)
     20
     21static u8 rockchip_muxgrf_get_parent(struct clk_hw *hw)
     22{
     23	struct rockchip_muxgrf_clock *mux = to_muxgrf_clock(hw);
     24	unsigned int mask = GENMASK(mux->width - 1, 0);
     25	unsigned int val;
     26
     27	regmap_read(mux->regmap, mux->reg, &val);
     28
     29	val >>= mux->shift;
     30	val &= mask;
     31
     32	return val;
     33}
     34
     35static int rockchip_muxgrf_set_parent(struct clk_hw *hw, u8 index)
     36{
     37	struct rockchip_muxgrf_clock *mux = to_muxgrf_clock(hw);
     38	unsigned int mask = GENMASK(mux->width + mux->shift - 1, mux->shift);
     39	unsigned int val;
     40
     41	val = index;
     42	val <<= mux->shift;
     43
     44	if (mux->flags & CLK_MUX_HIWORD_MASK)
     45		return regmap_write(mux->regmap, mux->reg, val | (mask << 16));
     46	else
     47		return regmap_update_bits(mux->regmap, mux->reg, mask, val);
     48}
     49
     50static const struct clk_ops rockchip_muxgrf_clk_ops = {
     51	.get_parent = rockchip_muxgrf_get_parent,
     52	.set_parent = rockchip_muxgrf_set_parent,
     53	.determine_rate = __clk_mux_determine_rate,
     54};
     55
     56struct clk *rockchip_clk_register_muxgrf(const char *name,
     57				const char *const *parent_names, u8 num_parents,
     58				int flags, struct regmap *regmap, int reg,
     59				int shift, int width, int mux_flags)
     60{
     61	struct rockchip_muxgrf_clock *muxgrf_clock;
     62	struct clk_init_data init;
     63	struct clk *clk;
     64
     65	if (IS_ERR(regmap)) {
     66		pr_err("%s: regmap not available\n", __func__);
     67		return ERR_PTR(-ENOTSUPP);
     68	}
     69
     70	muxgrf_clock = kmalloc(sizeof(*muxgrf_clock), GFP_KERNEL);
     71	if (!muxgrf_clock)
     72		return ERR_PTR(-ENOMEM);
     73
     74	init.name = name;
     75	init.flags = flags;
     76	init.num_parents = num_parents;
     77	init.parent_names = parent_names;
     78	init.ops = &rockchip_muxgrf_clk_ops;
     79
     80	muxgrf_clock->hw.init = &init;
     81	muxgrf_clock->regmap = regmap;
     82	muxgrf_clock->reg = reg;
     83	muxgrf_clock->shift = shift;
     84	muxgrf_clock->width = width;
     85	muxgrf_clock->flags = mux_flags;
     86
     87	clk = clk_register(NULL, &muxgrf_clock->hw);
     88	if (IS_ERR(clk))
     89		kfree(muxgrf_clock);
     90
     91	return clk;
     92}