root/arch/mips/lantiq/clk.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. clkdev_add_static
  2. clk_get_cpu
  3. clk_get_fpi
  4. clk_get_io
  5. clk_get_ppe
  6. clk_good
  7. clk_get_rate
  8. clk_set_rate
  9. clk_round_rate
  10. clk_enable
  11. clk_disable
  12. clk_activate
  13. clk_deactivate
  14. get_counter_resolution
  15. plat_time_init

   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 */
  27 static struct clk cpu_clk_generic[4];
  28 
  29 void 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 
  38 struct clk *clk_get_cpu(void)
  39 {
  40         return &cpu_clk_generic[0];
  41 }
  42 
  43 struct clk *clk_get_fpi(void)
  44 {
  45         return &cpu_clk_generic[1];
  46 }
  47 EXPORT_SYMBOL_GPL(clk_get_fpi);
  48 
  49 struct clk *clk_get_io(void)
  50 {
  51         return &cpu_clk_generic[2];
  52 }
  53 
  54 struct clk *clk_get_ppe(void)
  55 {
  56         return &cpu_clk_generic[3];
  57 }
  58 EXPORT_SYMBOL_GPL(clk_get_ppe);
  59 
  60 static inline int clk_good(struct clk *clk)
  61 {
  62         return clk && !IS_ERR(clk);
  63 }
  64 
  65 unsigned 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 }
  78 EXPORT_SYMBOL(clk_get_rate);
  79 
  80 int 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 }
  98 EXPORT_SYMBOL(clk_set_rate);
  99 
 100 long 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 }
 115 EXPORT_SYMBOL(clk_round_rate);
 116 
 117 int 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 }
 127 EXPORT_SYMBOL(clk_enable);
 128 
 129 void clk_disable(struct clk *clk)
 130 {
 131         if (unlikely(!clk_good(clk)))
 132                 return;
 133 
 134         if (clk->disable)
 135                 clk->disable(clk);
 136 }
 137 EXPORT_SYMBOL(clk_disable);
 138 
 139 int 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 }
 149 EXPORT_SYMBOL(clk_activate);
 150 
 151 void clk_deactivate(struct clk *clk)
 152 {
 153         if (unlikely(!clk_good(clk)))
 154                 return;
 155 
 156         if (clk->deactivate)
 157                 clk->deactivate(clk);
 158 }
 159 EXPORT_SYMBOL(clk_deactivate);
 160 
 161 static inline u32 get_counter_resolution(void)
 162 {
 163         u32 res;
 164 
 165         __asm__ __volatile__(
 166                 ".set   push\n"
 167                 ".set   mips32r2\n"
 168                 "rdhwr  %0, $3\n"
 169                 ".set pop\n"
 170                 : "=&r" (res)
 171                 : /* no input */
 172                 : "memory");
 173 
 174         return res;
 175 }
 176 
 177 void __init plat_time_init(void)
 178 {
 179         struct clk *clk;
 180 
 181         ltq_soc_init();
 182 
 183         clk = clk_get_cpu();
 184         mips_hpt_frequency = clk_get_rate(clk) / get_counter_resolution();
 185         write_c0_compare(read_c0_count());
 186         pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
 187         clk_put(clk);
 188 }

/* [<][>][^][v][top][bottom][index][help] */