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


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *
      4 * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
      5 * Copyright (C) 2010 John Crispin <john@phrozen.org>
      6 */
      7#include <linux/io.h>
      8#include <linux/export.h>
      9#include <linux/init.h>
     10#include <linux/kernel.h>
     11#include <linux/types.h>
     12#include <linux/clk.h>
     13#include <linux/clkdev.h>
     14#include <linux/err.h>
     15#include <linux/list.h>
     16
     17#include <asm/time.h>
     18#include <asm/irq.h>
     19#include <asm/div64.h>
     20
     21#include <lantiq_soc.h>
     22
     23#include "clk.h"
     24#include "prom.h"
     25
     26/* lantiq socs have 3 static clocks */
     27static struct clk cpu_clk_generic[4];
     28
     29void clkdev_add_static(unsigned long cpu, unsigned long fpi,
     30			unsigned long io, unsigned long ppe)
     31{
     32	cpu_clk_generic[0].rate = cpu;
     33	cpu_clk_generic[1].rate = fpi;
     34	cpu_clk_generic[2].rate = io;
     35	cpu_clk_generic[3].rate = ppe;
     36}
     37
     38struct clk *clk_get_cpu(void)
     39{
     40	return &cpu_clk_generic[0];
     41}
     42
     43struct clk *clk_get_fpi(void)
     44{
     45	return &cpu_clk_generic[1];
     46}
     47EXPORT_SYMBOL_GPL(clk_get_fpi);
     48
     49struct clk *clk_get_io(void)
     50{
     51	return &cpu_clk_generic[2];
     52}
     53
     54struct clk *clk_get_ppe(void)
     55{
     56	return &cpu_clk_generic[3];
     57}
     58EXPORT_SYMBOL_GPL(clk_get_ppe);
     59
     60static inline int clk_good(struct clk *clk)
     61{
     62	return clk && !IS_ERR(clk);
     63}
     64
     65unsigned long clk_get_rate(struct clk *clk)
     66{
     67	if (unlikely(!clk_good(clk)))
     68		return 0;
     69
     70	if (clk->rate != 0)
     71		return clk->rate;
     72
     73	if (clk->get_rate != NULL)
     74		return clk->get_rate();
     75
     76	return 0;
     77}
     78EXPORT_SYMBOL(clk_get_rate);
     79
     80int clk_set_rate(struct clk *clk, unsigned long rate)
     81{
     82	if (unlikely(!clk_good(clk)))
     83		return 0;
     84	if (clk->rates && *clk->rates) {
     85		unsigned long *r = clk->rates;
     86
     87		while (*r && (*r != rate))
     88			r++;
     89		if (!*r) {
     90			pr_err("clk %s.%s: trying to set invalid rate %ld\n",
     91				clk->cl.dev_id, clk->cl.con_id, rate);
     92			return -1;
     93		}
     94	}
     95	clk->rate = rate;
     96	return 0;
     97}
     98EXPORT_SYMBOL(clk_set_rate);
     99
    100long clk_round_rate(struct clk *clk, unsigned long rate)
    101{
    102	if (unlikely(!clk_good(clk)))
    103		return 0;
    104	if (clk->rates && *clk->rates) {
    105		unsigned long *r = clk->rates;
    106
    107		while (*r && (*r != rate))
    108			r++;
    109		if (!*r) {
    110			return clk->rate;
    111		}
    112	}
    113	return rate;
    114}
    115EXPORT_SYMBOL(clk_round_rate);
    116
    117int clk_enable(struct clk *clk)
    118{
    119	if (unlikely(!clk_good(clk)))
    120		return -1;
    121
    122	if (clk->enable)
    123		return clk->enable(clk);
    124
    125	return -1;
    126}
    127EXPORT_SYMBOL(clk_enable);
    128
    129void clk_disable(struct clk *clk)
    130{
    131	if (unlikely(!clk_good(clk)))
    132		return;
    133
    134	if (clk->disable)
    135		clk->disable(clk);
    136}
    137EXPORT_SYMBOL(clk_disable);
    138
    139int clk_activate(struct clk *clk)
    140{
    141	if (unlikely(!clk_good(clk)))
    142		return -1;
    143
    144	if (clk->activate)
    145		return clk->activate(clk);
    146
    147	return -1;
    148}
    149EXPORT_SYMBOL(clk_activate);
    150
    151void clk_deactivate(struct clk *clk)
    152{
    153	if (unlikely(!clk_good(clk)))
    154		return;
    155
    156	if (clk->deactivate)
    157		clk->deactivate(clk);
    158}
    159EXPORT_SYMBOL(clk_deactivate);
    160
    161struct clk *clk_get_parent(struct clk *clk)
    162{
    163	return NULL;
    164}
    165EXPORT_SYMBOL(clk_get_parent);
    166
    167int clk_set_parent(struct clk *clk, struct clk *parent)
    168{
    169	return 0;
    170}
    171EXPORT_SYMBOL(clk_set_parent);
    172
    173static inline u32 get_counter_resolution(void)
    174{
    175	u32 res;
    176
    177	__asm__ __volatile__(
    178		".set	push\n"
    179		".set	mips32r2\n"
    180		"rdhwr	%0, $3\n"
    181		".set pop\n"
    182		: "=&r" (res)
    183		: /* no input */
    184		: "memory");
    185
    186	return res;
    187}
    188
    189void __init plat_time_init(void)
    190{
    191	struct clk *clk;
    192
    193	ltq_soc_init();
    194
    195	clk = clk_get_cpu();
    196	mips_hpt_frequency = clk_get_rate(clk) / get_counter_resolution();
    197	write_c0_compare(read_c0_count());
    198	pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
    199	clk_put(clk);
    200}