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);
v5.9
  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
 17int use_cyclone;
 18void __init cyclone_setup(void)
 19{
 20	use_cyclone = 1;
 21}
 22
 23static void __iomem *cyclone_mc;
 24
 25static u64 read_cyclone(struct clocksource *cs)
 26{
 27	return (u64)readq((void __iomem *)cyclone_mc);
 28}
 29
 30static 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
 38int __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(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(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(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(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);