root/arch/mips/kernel/cevt-txx9.c

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

DEFINITIONS

This source file includes following definitions.
  1. txx9_cs_read
  2. txx9_read_sched_clock
  3. txx9_clocksource_init
  4. txx9tmr_stop_and_clear
  5. txx9tmr_set_state_periodic
  6. txx9tmr_set_state_oneshot
  7. txx9tmr_set_state_shutdown
  8. txx9tmr_tick_resume
  9. txx9tmr_set_next_event
  10. txx9tmr_interrupt
  11. txx9_clockevent_init
  12. txx9_tmr_init

   1 /*
   2  * This file is subject to the terms and conditions of the GNU General Public
   3  * License.  See the file "COPYING" in the main directory of this archive
   4  * for more details.
   5  *
   6  * Based on linux/arch/mips/kernel/cevt-r4k.c,
   7  *          linux/arch/mips/jmr3927/rbhma3100/setup.c
   8  *
   9  * Copyright 2001 MontaVista Software Inc.
  10  * Copyright (C) 2000-2001 Toshiba Corporation
  11  * Copyright (C) 2007 MIPS Technologies, Inc.
  12  * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
  13  */
  14 #include <linux/init.h>
  15 #include <linux/interrupt.h>
  16 #include <linux/irq.h>
  17 #include <linux/sched_clock.h>
  18 #include <asm/time.h>
  19 #include <asm/txx9tmr.h>
  20 
  21 #define TCR_BASE (TXx9_TMTCR_CCDE | TXx9_TMTCR_CRE | TXx9_TMTCR_TMODE_ITVL)
  22 #define TIMER_CCD       0       /* 1/2 */
  23 #define TIMER_CLK(imclk)        ((imclk) / (2 << TIMER_CCD))
  24 
  25 struct txx9_clocksource {
  26         struct clocksource cs;
  27         struct txx9_tmr_reg __iomem *tmrptr;
  28 };
  29 
  30 static u64 txx9_cs_read(struct clocksource *cs)
  31 {
  32         struct txx9_clocksource *txx9_cs =
  33                 container_of(cs, struct txx9_clocksource, cs);
  34         return __raw_readl(&txx9_cs->tmrptr->trr);
  35 }
  36 
  37 /* Use 1 bit smaller width to use full bits in that width */
  38 #define TXX9_CLOCKSOURCE_BITS (TXX9_TIMER_BITS - 1)
  39 
  40 static struct txx9_clocksource txx9_clocksource = {
  41         .cs = {
  42                 .name           = "TXx9",
  43                 .rating         = 200,
  44                 .read           = txx9_cs_read,
  45                 .mask           = CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS),
  46                 .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
  47         },
  48 };
  49 
  50 static u64 notrace txx9_read_sched_clock(void)
  51 {
  52         return __raw_readl(&txx9_clocksource.tmrptr->trr);
  53 }
  54 
  55 void __init txx9_clocksource_init(unsigned long baseaddr,
  56                                   unsigned int imbusclk)
  57 {
  58         struct txx9_tmr_reg __iomem *tmrptr;
  59 
  60         clocksource_register_hz(&txx9_clocksource.cs, TIMER_CLK(imbusclk));
  61 
  62         tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
  63         __raw_writel(TCR_BASE, &tmrptr->tcr);
  64         __raw_writel(0, &tmrptr->tisr);
  65         __raw_writel(TIMER_CCD, &tmrptr->ccdr);
  66         __raw_writel(TXx9_TMITMR_TZCE, &tmrptr->itmr);
  67         __raw_writel(1 << TXX9_CLOCKSOURCE_BITS, &tmrptr->cpra);
  68         __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
  69         txx9_clocksource.tmrptr = tmrptr;
  70 
  71         sched_clock_register(txx9_read_sched_clock, TXX9_CLOCKSOURCE_BITS,
  72                              TIMER_CLK(imbusclk));
  73 }
  74 
  75 struct txx9_clock_event_device {
  76         struct clock_event_device cd;
  77         struct txx9_tmr_reg __iomem *tmrptr;
  78 };
  79 
  80 static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr)
  81 {
  82         /* stop and reset counter */
  83         __raw_writel(TCR_BASE, &tmrptr->tcr);
  84         /* clear pending interrupt */
  85         __raw_writel(0, &tmrptr->tisr);
  86 }
  87 
  88 static int txx9tmr_set_state_periodic(struct clock_event_device *evt)
  89 {
  90         struct txx9_clock_event_device *txx9_cd =
  91                 container_of(evt, struct txx9_clock_event_device, cd);
  92         struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
  93 
  94         txx9tmr_stop_and_clear(tmrptr);
  95 
  96         __raw_writel(TXx9_TMITMR_TIIE | TXx9_TMITMR_TZCE, &tmrptr->itmr);
  97         /* start timer */
  98         __raw_writel(((u64)(NSEC_PER_SEC / HZ) * evt->mult) >> evt->shift,
  99                      &tmrptr->cpra);
 100         __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
 101         return 0;
 102 }
 103 
 104 static int txx9tmr_set_state_oneshot(struct clock_event_device *evt)
 105 {
 106         struct txx9_clock_event_device *txx9_cd =
 107                 container_of(evt, struct txx9_clock_event_device, cd);
 108         struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
 109 
 110         txx9tmr_stop_and_clear(tmrptr);
 111         __raw_writel(TXx9_TMITMR_TIIE, &tmrptr->itmr);
 112         return 0;
 113 }
 114 
 115 static int txx9tmr_set_state_shutdown(struct clock_event_device *evt)
 116 {
 117         struct txx9_clock_event_device *txx9_cd =
 118                 container_of(evt, struct txx9_clock_event_device, cd);
 119         struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
 120 
 121         txx9tmr_stop_and_clear(tmrptr);
 122         __raw_writel(0, &tmrptr->itmr);
 123         return 0;
 124 }
 125 
 126 static int txx9tmr_tick_resume(struct clock_event_device *evt)
 127 {
 128         struct txx9_clock_event_device *txx9_cd =
 129                 container_of(evt, struct txx9_clock_event_device, cd);
 130         struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
 131 
 132         txx9tmr_stop_and_clear(tmrptr);
 133         __raw_writel(TIMER_CCD, &tmrptr->ccdr);
 134         __raw_writel(0, &tmrptr->itmr);
 135         return 0;
 136 }
 137 
 138 static int txx9tmr_set_next_event(unsigned long delta,
 139                                   struct clock_event_device *evt)
 140 {
 141         struct txx9_clock_event_device *txx9_cd =
 142                 container_of(evt, struct txx9_clock_event_device, cd);
 143         struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
 144 
 145         txx9tmr_stop_and_clear(tmrptr);
 146         /* start timer */
 147         __raw_writel(delta, &tmrptr->cpra);
 148         __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
 149         return 0;
 150 }
 151 
 152 static struct txx9_clock_event_device txx9_clock_event_device = {
 153         .cd = {
 154                 .name                   = "TXx9",
 155                 .features               = CLOCK_EVT_FEAT_PERIODIC |
 156                                           CLOCK_EVT_FEAT_ONESHOT,
 157                 .rating                 = 200,
 158                 .set_state_shutdown     = txx9tmr_set_state_shutdown,
 159                 .set_state_periodic     = txx9tmr_set_state_periodic,
 160                 .set_state_oneshot      = txx9tmr_set_state_oneshot,
 161                 .tick_resume            = txx9tmr_tick_resume,
 162                 .set_next_event         = txx9tmr_set_next_event,
 163         },
 164 };
 165 
 166 static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id)
 167 {
 168         struct txx9_clock_event_device *txx9_cd = dev_id;
 169         struct clock_event_device *cd = &txx9_cd->cd;
 170         struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
 171 
 172         __raw_writel(0, &tmrptr->tisr); /* ack interrupt */
 173         cd->event_handler(cd);
 174         return IRQ_HANDLED;
 175 }
 176 
 177 static struct irqaction txx9tmr_irq = {
 178         .handler        = txx9tmr_interrupt,
 179         .flags          = IRQF_PERCPU | IRQF_TIMER,
 180         .name           = "txx9tmr",
 181         .dev_id         = &txx9_clock_event_device,
 182 };
 183 
 184 void __init txx9_clockevent_init(unsigned long baseaddr, int irq,
 185                                  unsigned int imbusclk)
 186 {
 187         struct clock_event_device *cd = &txx9_clock_event_device.cd;
 188         struct txx9_tmr_reg __iomem *tmrptr;
 189 
 190         tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
 191         txx9tmr_stop_and_clear(tmrptr);
 192         __raw_writel(TIMER_CCD, &tmrptr->ccdr);
 193         __raw_writel(0, &tmrptr->itmr);
 194         txx9_clock_event_device.tmrptr = tmrptr;
 195 
 196         clockevent_set_clock(cd, TIMER_CLK(imbusclk));
 197         cd->max_delta_ns =
 198                 clockevent_delta2ns(0xffffffff >> (32 - TXX9_TIMER_BITS), cd);
 199         cd->max_delta_ticks = 0xffffffff >> (32 - TXX9_TIMER_BITS);
 200         cd->min_delta_ns = clockevent_delta2ns(0xf, cd);
 201         cd->min_delta_ticks = 0xf;
 202         cd->irq = irq;
 203         cd->cpumask = cpumask_of(0),
 204         clockevents_register_device(cd);
 205         setup_irq(irq, &txx9tmr_irq);
 206         printk(KERN_INFO "TXx9: clockevent device at 0x%lx, irq %d\n",
 207                baseaddr, irq);
 208 }
 209 
 210 void __init txx9_tmr_init(unsigned long baseaddr)
 211 {
 212         struct txx9_tmr_reg __iomem *tmrptr;
 213 
 214         tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
 215         /* Start once to make CounterResetEnable effective */
 216         __raw_writel(TXx9_TMTCR_CRE | TXx9_TMTCR_TCE, &tmrptr->tcr);
 217         /* Stop and reset the counter */
 218         __raw_writel(TXx9_TMTCR_CRE, &tmrptr->tcr);
 219         __raw_writel(0, &tmrptr->tisr);
 220         __raw_writel(0xffffffff, &tmrptr->cpra);
 221         __raw_writel(0, &tmrptr->itmr);
 222         __raw_writel(0, &tmrptr->ccdr);
 223         __raw_writel(0, &tmrptr->pgmr);
 224         iounmap(tmrptr);
 225 }

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