root/arch/ia64/kernel/cyclone.c

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

DEFINITIONS

This source file includes following definitions.
  1. cyclone_setup
  2. read_cyclone
  3. init_cyclone_clock

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <linux/module.h>
   3 #include <linux/smp.h>
   4 #include <linux/time.h>
   5 #include <linux/errno.h>
   6 #include <linux/timex.h>
   7 #include <linux/clocksource.h>
   8 #include <linux/io.h>
   9 
  10 /* IBM Summit (EXA) Cyclone counter code*/
  11 #define CYCLONE_CBAR_ADDR 0xFEB00CD0
  12 #define CYCLONE_PMCC_OFFSET 0x51A0
  13 #define CYCLONE_MPMC_OFFSET 0x51D0
  14 #define CYCLONE_MPCS_OFFSET 0x51A8
  15 #define CYCLONE_TIMER_FREQ 100000000
  16 
  17 int use_cyclone;
  18 void __init cyclone_setup(void)
  19 {
  20         use_cyclone = 1;
  21 }
  22 
  23 static void __iomem *cyclone_mc;
  24 
  25 static u64 read_cyclone(struct clocksource *cs)
  26 {
  27         return (u64)readq((void __iomem *)cyclone_mc);
  28 }
  29 
  30 static struct clocksource clocksource_cyclone = {
  31         .name           = "cyclone",
  32         .rating         = 300,
  33         .read           = read_cyclone,
  34         .mask           = (1LL << 40) - 1,
  35         .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
  36 };
  37 
  38 int __init init_cyclone_clock(void)
  39 {
  40         u64 __iomem *reg;
  41         u64 base;       /* saved cyclone base address */
  42         u64 offset;     /* offset from pageaddr to cyclone_timer register */
  43         int i;
  44         u32 __iomem *cyclone_timer;     /* Cyclone MPMC0 register */
  45 
  46         if (!use_cyclone)
  47                 return 0;
  48 
  49         printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n");
  50 
  51         /* find base address */
  52         offset = (CYCLONE_CBAR_ADDR);
  53         reg = ioremap_nocache(offset, sizeof(u64));
  54         if(!reg){
  55                 printk(KERN_ERR "Summit chipset: Could not find valid CBAR"
  56                                 " register.\n");
  57                 use_cyclone = 0;
  58                 return -ENODEV;
  59         }
  60         base = readq(reg);
  61         iounmap(reg);
  62         if(!base){
  63                 printk(KERN_ERR "Summit chipset: Could not find valid CBAR"
  64                                 " value.\n");
  65                 use_cyclone = 0;
  66                 return -ENODEV;
  67         }
  68 
  69         /* setup PMCC */
  70         offset = (base + CYCLONE_PMCC_OFFSET);
  71         reg = ioremap_nocache(offset, sizeof(u64));
  72         if(!reg){
  73                 printk(KERN_ERR "Summit chipset: Could not find valid PMCC"
  74                                 " register.\n");
  75                 use_cyclone = 0;
  76                 return -ENODEV;
  77         }
  78         writel(0x00000001,reg);
  79         iounmap(reg);
  80 
  81         /* setup MPCS */
  82         offset = (base + CYCLONE_MPCS_OFFSET);
  83         reg = ioremap_nocache(offset, sizeof(u64));
  84         if(!reg){
  85                 printk(KERN_ERR "Summit chipset: Could not find valid MPCS"
  86                                 " register.\n");
  87                 use_cyclone = 0;
  88                 return -ENODEV;
  89         }
  90         writel(0x00000001,reg);
  91         iounmap(reg);
  92 
  93         /* map in cyclone_timer */
  94         offset = (base + CYCLONE_MPMC_OFFSET);
  95         cyclone_timer = ioremap_nocache(offset, sizeof(u32));
  96         if(!cyclone_timer){
  97                 printk(KERN_ERR "Summit chipset: Could not find valid MPMC"
  98                                 " register.\n");
  99                 use_cyclone = 0;
 100                 return -ENODEV;
 101         }
 102 
 103         /*quick test to make sure its ticking*/
 104         for(i=0; i<3; i++){
 105                 u32 old = readl(cyclone_timer);
 106                 int stall = 100;
 107                 while(stall--) barrier();
 108                 if(readl(cyclone_timer) == old){
 109                         printk(KERN_ERR "Summit chipset: Counter not counting!"
 110                                         " DISABLED\n");
 111                         iounmap(cyclone_timer);
 112                         cyclone_timer = NULL;
 113                         use_cyclone = 0;
 114                         return -ENODEV;
 115                 }
 116         }
 117         /* initialize last tick */
 118         cyclone_mc = cyclone_timer;
 119         clocksource_cyclone.archdata.fsys_mmio = cyclone_timer;
 120         clocksource_register_hz(&clocksource_cyclone, CYCLONE_TIMER_FREQ);
 121 
 122         return 0;
 123 }
 124 
 125 __initcall(init_cyclone_clock);

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