0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/init.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/irq.h>
0017 #include <linux/sched_clock.h>
0018 #include <asm/time.h>
0019 #include <asm/txx9tmr.h>
0020
0021 #define TCR_BASE (TXx9_TMTCR_CCDE | TXx9_TMTCR_CRE | TXx9_TMTCR_TMODE_ITVL)
0022 #define TIMER_CCD 0
0023 #define TIMER_CLK(imclk) ((imclk) / (2 << TIMER_CCD))
0024
0025 struct txx9_clocksource {
0026 struct clocksource cs;
0027 struct txx9_tmr_reg __iomem *tmrptr;
0028 };
0029
0030 static u64 txx9_cs_read(struct clocksource *cs)
0031 {
0032 struct txx9_clocksource *txx9_cs =
0033 container_of(cs, struct txx9_clocksource, cs);
0034 return __raw_readl(&txx9_cs->tmrptr->trr);
0035 }
0036
0037
0038 #define TXX9_CLOCKSOURCE_BITS (TXX9_TIMER_BITS - 1)
0039
0040 static struct txx9_clocksource txx9_clocksource = {
0041 .cs = {
0042 .name = "TXx9",
0043 .rating = 200,
0044 .read = txx9_cs_read,
0045 .mask = CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS),
0046 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
0047 },
0048 };
0049
0050 static u64 notrace txx9_read_sched_clock(void)
0051 {
0052 return __raw_readl(&txx9_clocksource.tmrptr->trr);
0053 }
0054
0055 void __init txx9_clocksource_init(unsigned long baseaddr,
0056 unsigned int imbusclk)
0057 {
0058 struct txx9_tmr_reg __iomem *tmrptr;
0059
0060 clocksource_register_hz(&txx9_clocksource.cs, TIMER_CLK(imbusclk));
0061
0062 tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
0063 __raw_writel(TCR_BASE, &tmrptr->tcr);
0064 __raw_writel(0, &tmrptr->tisr);
0065 __raw_writel(TIMER_CCD, &tmrptr->ccdr);
0066 __raw_writel(TXx9_TMITMR_TZCE, &tmrptr->itmr);
0067 __raw_writel(1 << TXX9_CLOCKSOURCE_BITS, &tmrptr->cpra);
0068 __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
0069 txx9_clocksource.tmrptr = tmrptr;
0070
0071 sched_clock_register(txx9_read_sched_clock, TXX9_CLOCKSOURCE_BITS,
0072 TIMER_CLK(imbusclk));
0073 }
0074
0075 struct txx9_clock_event_device {
0076 struct clock_event_device cd;
0077 struct txx9_tmr_reg __iomem *tmrptr;
0078 };
0079
0080 static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr)
0081 {
0082
0083 __raw_writel(TCR_BASE, &tmrptr->tcr);
0084
0085 __raw_writel(0, &tmrptr->tisr);
0086 }
0087
0088 static int txx9tmr_set_state_periodic(struct clock_event_device *evt)
0089 {
0090 struct txx9_clock_event_device *txx9_cd =
0091 container_of(evt, struct txx9_clock_event_device, cd);
0092 struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
0093
0094 txx9tmr_stop_and_clear(tmrptr);
0095
0096 __raw_writel(TXx9_TMITMR_TIIE | TXx9_TMITMR_TZCE, &tmrptr->itmr);
0097
0098 __raw_writel(((u64)(NSEC_PER_SEC / HZ) * evt->mult) >> evt->shift,
0099 &tmrptr->cpra);
0100 __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
0101 return 0;
0102 }
0103
0104 static int txx9tmr_set_state_oneshot(struct clock_event_device *evt)
0105 {
0106 struct txx9_clock_event_device *txx9_cd =
0107 container_of(evt, struct txx9_clock_event_device, cd);
0108 struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
0109
0110 txx9tmr_stop_and_clear(tmrptr);
0111 __raw_writel(TXx9_TMITMR_TIIE, &tmrptr->itmr);
0112 return 0;
0113 }
0114
0115 static int txx9tmr_set_state_shutdown(struct clock_event_device *evt)
0116 {
0117 struct txx9_clock_event_device *txx9_cd =
0118 container_of(evt, struct txx9_clock_event_device, cd);
0119 struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
0120
0121 txx9tmr_stop_and_clear(tmrptr);
0122 __raw_writel(0, &tmrptr->itmr);
0123 return 0;
0124 }
0125
0126 static int txx9tmr_tick_resume(struct clock_event_device *evt)
0127 {
0128 struct txx9_clock_event_device *txx9_cd =
0129 container_of(evt, struct txx9_clock_event_device, cd);
0130 struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
0131
0132 txx9tmr_stop_and_clear(tmrptr);
0133 __raw_writel(TIMER_CCD, &tmrptr->ccdr);
0134 __raw_writel(0, &tmrptr->itmr);
0135 return 0;
0136 }
0137
0138 static int txx9tmr_set_next_event(unsigned long delta,
0139 struct clock_event_device *evt)
0140 {
0141 struct txx9_clock_event_device *txx9_cd =
0142 container_of(evt, struct txx9_clock_event_device, cd);
0143 struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
0144
0145 txx9tmr_stop_and_clear(tmrptr);
0146
0147 __raw_writel(delta, &tmrptr->cpra);
0148 __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
0149 return 0;
0150 }
0151
0152 static struct txx9_clock_event_device txx9_clock_event_device = {
0153 .cd = {
0154 .name = "TXx9",
0155 .features = CLOCK_EVT_FEAT_PERIODIC |
0156 CLOCK_EVT_FEAT_ONESHOT,
0157 .rating = 200,
0158 .set_state_shutdown = txx9tmr_set_state_shutdown,
0159 .set_state_periodic = txx9tmr_set_state_periodic,
0160 .set_state_oneshot = txx9tmr_set_state_oneshot,
0161 .tick_resume = txx9tmr_tick_resume,
0162 .set_next_event = txx9tmr_set_next_event,
0163 },
0164 };
0165
0166 static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id)
0167 {
0168 struct txx9_clock_event_device *txx9_cd = dev_id;
0169 struct clock_event_device *cd = &txx9_cd->cd;
0170 struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
0171
0172 __raw_writel(0, &tmrptr->tisr);
0173 cd->event_handler(cd);
0174 return IRQ_HANDLED;
0175 }
0176
0177 void __init txx9_clockevent_init(unsigned long baseaddr, int irq,
0178 unsigned int imbusclk)
0179 {
0180 struct clock_event_device *cd = &txx9_clock_event_device.cd;
0181 struct txx9_tmr_reg __iomem *tmrptr;
0182
0183 tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
0184 txx9tmr_stop_and_clear(tmrptr);
0185 __raw_writel(TIMER_CCD, &tmrptr->ccdr);
0186 __raw_writel(0, &tmrptr->itmr);
0187 txx9_clock_event_device.tmrptr = tmrptr;
0188
0189 clockevent_set_clock(cd, TIMER_CLK(imbusclk));
0190 cd->max_delta_ns =
0191 clockevent_delta2ns(0xffffffff >> (32 - TXX9_TIMER_BITS), cd);
0192 cd->max_delta_ticks = 0xffffffff >> (32 - TXX9_TIMER_BITS);
0193 cd->min_delta_ns = clockevent_delta2ns(0xf, cd);
0194 cd->min_delta_ticks = 0xf;
0195 cd->irq = irq;
0196 cd->cpumask = cpumask_of(0);
0197 clockevents_register_device(cd);
0198 if (request_irq(irq, txx9tmr_interrupt, IRQF_PERCPU | IRQF_TIMER,
0199 "txx9tmr", &txx9_clock_event_device))
0200 pr_err("Failed to request irq %d (txx9tmr)\n", irq);
0201 printk(KERN_INFO "TXx9: clockevent device at 0x%lx, irq %d\n",
0202 baseaddr, irq);
0203 }
0204
0205 void __init txx9_tmr_init(unsigned long baseaddr)
0206 {
0207 struct txx9_tmr_reg __iomem *tmrptr;
0208
0209 tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
0210
0211 __raw_writel(TXx9_TMTCR_CRE | TXx9_TMTCR_TCE, &tmrptr->tcr);
0212
0213 __raw_writel(TXx9_TMTCR_CRE, &tmrptr->tcr);
0214 __raw_writel(0, &tmrptr->tisr);
0215 __raw_writel(0xffffffff, &tmrptr->cpra);
0216 __raw_writel(0, &tmrptr->itmr);
0217 __raw_writel(0, &tmrptr->ccdr);
0218 __raw_writel(0, &tmrptr->pgmr);
0219 iounmap(tmrptr);
0220 }