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

mux.c (1810B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// Spreadtrum multiplexer clock driver
      4//
      5// Copyright (C) 2017 Spreadtrum, Inc.
      6// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
      7
      8#include <linux/clk.h>
      9#include <linux/clk-provider.h>
     10#include <linux/regmap.h>
     11
     12#include "mux.h"
     13
     14u8 sprd_mux_helper_get_parent(const struct sprd_clk_common *common,
     15			      const struct sprd_mux_ssel *mux)
     16{
     17	unsigned int reg;
     18	u8 parent;
     19	int num_parents;
     20	int i;
     21
     22	regmap_read(common->regmap, common->reg, &reg);
     23	parent = reg >> mux->shift;
     24	parent &= (1 << mux->width) - 1;
     25
     26	if (!mux->table)
     27		return parent;
     28
     29	num_parents = clk_hw_get_num_parents(&common->hw);
     30
     31	for (i = 0; i < num_parents - 1; i++)
     32		if (parent >= mux->table[i] && parent < mux->table[i + 1])
     33			return i;
     34
     35	return num_parents - 1;
     36}
     37EXPORT_SYMBOL_GPL(sprd_mux_helper_get_parent);
     38
     39static u8 sprd_mux_get_parent(struct clk_hw *hw)
     40{
     41	struct sprd_mux *cm = hw_to_sprd_mux(hw);
     42
     43	return sprd_mux_helper_get_parent(&cm->common, &cm->mux);
     44}
     45
     46int sprd_mux_helper_set_parent(const struct sprd_clk_common *common,
     47			       const struct sprd_mux_ssel *mux,
     48			       u8 index)
     49{
     50	unsigned int reg;
     51
     52	if (mux->table)
     53		index = mux->table[index];
     54
     55	regmap_read(common->regmap, common->reg, &reg);
     56	reg &= ~GENMASK(mux->width + mux->shift - 1, mux->shift);
     57	regmap_write(common->regmap, common->reg,
     58			  reg | (index << mux->shift));
     59
     60	return 0;
     61}
     62EXPORT_SYMBOL_GPL(sprd_mux_helper_set_parent);
     63
     64static int sprd_mux_set_parent(struct clk_hw *hw, u8 index)
     65{
     66	struct sprd_mux *cm = hw_to_sprd_mux(hw);
     67
     68	return sprd_mux_helper_set_parent(&cm->common, &cm->mux, index);
     69}
     70
     71const struct clk_ops sprd_mux_ops = {
     72	.get_parent = sprd_mux_get_parent,
     73	.set_parent = sprd_mux_set_parent,
     74	.determine_rate = __clk_mux_determine_rate,
     75};
     76EXPORT_SYMBOL_GPL(sprd_mux_ops);