Linux Audio

Check our new training course

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