root/arch/mips/vr41xx/common/bcu.c

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

DEFINITIONS

This source file includes following definitions.
  1. vr41xx_get_vtclock_frequency
  2. vr41xx_get_tclock_frequency
  3. read_clkspeed
  4. calculate_pclock
  5. calculate_vtclock
  6. calculate_tclock
  7. vr41xx_calculate_clock_frequency

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  bcu.c, Bus Control Unit routines for the NEC VR4100 series.
   4  *
   5  *  Copyright (C) 2002  MontaVista Software Inc.
   6  *    Author: Yoichi Yuasa <source@mvista.com>
   7  *  Copyright (C) 2003-2005  Yoichi Yuasa <yuasa@linux-mips.org>
   8  */
   9 /*
  10  * Changes:
  11  *  MontaVista Software Inc. <source@mvista.com>
  12  *  - New creation, NEC VR4122 and VR4131 are supported.
  13  *  - Added support for NEC VR4111 and VR4121.
  14  *
  15  *  Yoichi Yuasa <yuasa@linux-mips.org>
  16  *  - Added support for NEC VR4133.
  17  */
  18 #include <linux/export.h>
  19 #include <linux/kernel.h>
  20 #include <linux/smp.h>
  21 #include <linux/types.h>
  22 
  23 #include <asm/cpu-type.h>
  24 #include <asm/cpu.h>
  25 #include <asm/io.h>
  26 
  27 #define CLKSPEEDREG_TYPE1       (void __iomem *)KSEG1ADDR(0x0b000014)
  28 #define CLKSPEEDREG_TYPE2       (void __iomem *)KSEG1ADDR(0x0f000014)
  29  #define CLKSP(x)               ((x) & 0x001f)
  30  #define CLKSP_VR4133(x)        ((x) & 0x0007)
  31 
  32  #define DIV2B                  0x8000
  33  #define DIV3B                  0x4000
  34  #define DIV4B                  0x2000
  35 
  36  #define DIVT(x)                (((x) & 0xf000) >> 12)
  37  #define DIVVT(x)               (((x) & 0x0f00) >> 8)
  38 
  39  #define TDIVMODE(x)            (2 << (((x) & 0x1000) >> 12))
  40  #define VTDIVMODE(x)           (((x) & 0x0700) >> 8)
  41 
  42 static unsigned long vr41xx_vtclock;
  43 static unsigned long vr41xx_tclock;
  44 
  45 unsigned long vr41xx_get_vtclock_frequency(void)
  46 {
  47         return vr41xx_vtclock;
  48 }
  49 
  50 EXPORT_SYMBOL_GPL(vr41xx_get_vtclock_frequency);
  51 
  52 unsigned long vr41xx_get_tclock_frequency(void)
  53 {
  54         return vr41xx_tclock;
  55 }
  56 
  57 EXPORT_SYMBOL_GPL(vr41xx_get_tclock_frequency);
  58 
  59 static inline uint16_t read_clkspeed(void)
  60 {
  61         switch (current_cpu_type()) {
  62         case CPU_VR4111:
  63         case CPU_VR4121: return readw(CLKSPEEDREG_TYPE1);
  64         case CPU_VR4122:
  65         case CPU_VR4131:
  66         case CPU_VR4133: return readw(CLKSPEEDREG_TYPE2);
  67         default:
  68                 printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
  69                 break;
  70         }
  71 
  72         return 0;
  73 }
  74 
  75 static inline unsigned long calculate_pclock(uint16_t clkspeed)
  76 {
  77         unsigned long pclock = 0;
  78 
  79         switch (current_cpu_type()) {
  80         case CPU_VR4111:
  81         case CPU_VR4121:
  82                 pclock = 18432000 * 64;
  83                 pclock /= CLKSP(clkspeed);
  84                 break;
  85         case CPU_VR4122:
  86                 pclock = 18432000 * 98;
  87                 pclock /= CLKSP(clkspeed);
  88                 break;
  89         case CPU_VR4131:
  90                 pclock = 18432000 * 108;
  91                 pclock /= CLKSP(clkspeed);
  92                 break;
  93         case CPU_VR4133:
  94                 switch (CLKSP_VR4133(clkspeed)) {
  95                 case 0:
  96                         pclock = 133000000;
  97                         break;
  98                 case 1:
  99                         pclock = 149000000;
 100                         break;
 101                 case 2:
 102                         pclock = 165900000;
 103                         break;
 104                 case 3:
 105                         pclock = 199100000;
 106                         break;
 107                 case 4:
 108                         pclock = 265900000;
 109                         break;
 110                 default:
 111                         printk(KERN_INFO "Unknown PClock speed for NEC VR4133\n");
 112                         break;
 113                 }
 114                 break;
 115         default:
 116                 printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
 117                 break;
 118         }
 119 
 120         printk(KERN_INFO "PClock: %ldHz\n", pclock);
 121 
 122         return pclock;
 123 }
 124 
 125 static inline unsigned long calculate_vtclock(uint16_t clkspeed, unsigned long pclock)
 126 {
 127         unsigned long vtclock = 0;
 128 
 129         switch (current_cpu_type()) {
 130         case CPU_VR4111:
 131                 /* The NEC VR4111 doesn't have the VTClock. */
 132                 break;
 133         case CPU_VR4121:
 134                 vtclock = pclock;
 135                 /* DIVVT == 9 Divide by 1.5 . VTClock = (PClock * 6) / 9 */
 136                 if (DIVVT(clkspeed) == 9)
 137                         vtclock = pclock * 6;
 138                 /* DIVVT == 10 Divide by 2.5 . VTClock = (PClock * 4) / 10 */
 139                 else if (DIVVT(clkspeed) == 10)
 140                         vtclock = pclock * 4;
 141                 vtclock /= DIVVT(clkspeed);
 142                 printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
 143                 break;
 144         case CPU_VR4122:
 145                 if(VTDIVMODE(clkspeed) == 7)
 146                         vtclock = pclock / 1;
 147                 else if(VTDIVMODE(clkspeed) == 1)
 148                         vtclock = pclock / 2;
 149                 else
 150                         vtclock = pclock / VTDIVMODE(clkspeed);
 151                 printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
 152                 break;
 153         case CPU_VR4131:
 154         case CPU_VR4133:
 155                 vtclock = pclock / VTDIVMODE(clkspeed);
 156                 printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
 157                 break;
 158         default:
 159                 printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
 160                 break;
 161         }
 162 
 163         return vtclock;
 164 }
 165 
 166 static inline unsigned long calculate_tclock(uint16_t clkspeed, unsigned long pclock,
 167                                              unsigned long vtclock)
 168 {
 169         unsigned long tclock = 0;
 170 
 171         switch (current_cpu_type()) {
 172         case CPU_VR4111:
 173                 if (!(clkspeed & DIV2B))
 174                         tclock = pclock / 2;
 175                 else if (!(clkspeed & DIV3B))
 176                         tclock = pclock / 3;
 177                 else if (!(clkspeed & DIV4B))
 178                         tclock = pclock / 4;
 179                 break;
 180         case CPU_VR4121:
 181                 tclock = pclock / DIVT(clkspeed);
 182                 break;
 183         case CPU_VR4122:
 184         case CPU_VR4131:
 185         case CPU_VR4133:
 186                 tclock = vtclock / TDIVMODE(clkspeed);
 187                 break;
 188         default:
 189                 printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
 190                 break;
 191         }
 192 
 193         printk(KERN_INFO "TClock: %ldHz\n", tclock);
 194 
 195         return tclock;
 196 }
 197 
 198 void vr41xx_calculate_clock_frequency(void)
 199 {
 200         unsigned long pclock;
 201         uint16_t clkspeed;
 202 
 203         clkspeed = read_clkspeed();
 204 
 205         pclock = calculate_pclock(clkspeed);
 206         vr41xx_vtclock = calculate_vtclock(clkspeed, pclock);
 207         vr41xx_tclock = calculate_tclock(clkspeed, pclock, vr41xx_vtclock);
 208 }
 209 
 210 EXPORT_SYMBOL_GPL(vr41xx_calculate_clock_frequency);

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