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

owl-divider.c (2493B)


      1// SPDX-License-Identifier: GPL-2.0+
      2//
      3// OWL divider clock driver
      4//
      5// Copyright (c) 2014 Actions Semi Inc.
      6// Author: David Liu <liuwei@actions-semi.com>
      7//
      8// Copyright (c) 2018 Linaro Ltd.
      9// Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
     10
     11#include <linux/clk-provider.h>
     12#include <linux/regmap.h>
     13
     14#include "owl-divider.h"
     15
     16long owl_divider_helper_round_rate(struct owl_clk_common *common,
     17				const struct owl_divider_hw *div_hw,
     18				unsigned long rate,
     19				unsigned long *parent_rate)
     20{
     21	return divider_round_rate(&common->hw, rate, parent_rate,
     22				  div_hw->table, div_hw->width,
     23				  div_hw->div_flags);
     24}
     25
     26static long owl_divider_round_rate(struct clk_hw *hw, unsigned long rate,
     27				unsigned long *parent_rate)
     28{
     29	struct owl_divider *div = hw_to_owl_divider(hw);
     30
     31	return owl_divider_helper_round_rate(&div->common, &div->div_hw,
     32					     rate, parent_rate);
     33}
     34
     35unsigned long owl_divider_helper_recalc_rate(struct owl_clk_common *common,
     36					 const struct owl_divider_hw *div_hw,
     37					 unsigned long parent_rate)
     38{
     39	unsigned long val;
     40	unsigned int reg;
     41
     42	regmap_read(common->regmap, div_hw->reg, &reg);
     43	val = reg >> div_hw->shift;
     44	val &= (1 << div_hw->width) - 1;
     45
     46	return divider_recalc_rate(&common->hw, parent_rate,
     47				   val, div_hw->table,
     48				   div_hw->div_flags,
     49				   div_hw->width);
     50}
     51
     52static unsigned long owl_divider_recalc_rate(struct clk_hw *hw,
     53					  unsigned long parent_rate)
     54{
     55	struct owl_divider *div = hw_to_owl_divider(hw);
     56
     57	return owl_divider_helper_recalc_rate(&div->common,
     58					      &div->div_hw, parent_rate);
     59}
     60
     61int owl_divider_helper_set_rate(const struct owl_clk_common *common,
     62				const struct owl_divider_hw *div_hw,
     63				unsigned long rate,
     64				unsigned long parent_rate)
     65{
     66	unsigned long val;
     67	unsigned int reg;
     68
     69	val = divider_get_val(rate, parent_rate, div_hw->table,
     70			      div_hw->width, 0);
     71
     72	regmap_read(common->regmap, div_hw->reg, &reg);
     73	reg &= ~GENMASK(div_hw->width + div_hw->shift - 1, div_hw->shift);
     74
     75	regmap_write(common->regmap, div_hw->reg,
     76			  reg | (val << div_hw->shift));
     77
     78	return 0;
     79}
     80
     81static int owl_divider_set_rate(struct clk_hw *hw, unsigned long rate,
     82				unsigned long parent_rate)
     83{
     84	struct owl_divider *div = hw_to_owl_divider(hw);
     85
     86	return owl_divider_helper_set_rate(&div->common, &div->div_hw,
     87					rate, parent_rate);
     88}
     89
     90const struct clk_ops owl_divider_ops = {
     91	.recalc_rate = owl_divider_recalc_rate,
     92	.round_rate = owl_divider_round_rate,
     93	.set_rate = owl_divider_set_rate,
     94};