0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define pr_fmt(fmt) "AT91: PIT: " fmt
0011
0012 #include <linux/clk.h>
0013 #include <linux/clockchips.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/irq.h>
0016 #include <linux/kernel.h>
0017 #include <linux/of.h>
0018 #include <linux/of_address.h>
0019 #include <linux/of_irq.h>
0020 #include <linux/slab.h>
0021
0022 #define AT91_PIT_MR 0x00
0023 #define AT91_PIT_PITIEN BIT(25)
0024 #define AT91_PIT_PITEN BIT(24)
0025 #define AT91_PIT_PIV GENMASK(19, 0)
0026
0027 #define AT91_PIT_SR 0x04
0028 #define AT91_PIT_PITS BIT(0)
0029
0030 #define AT91_PIT_PIVR 0x08
0031 #define AT91_PIT_PIIR 0x0c
0032 #define AT91_PIT_PICNT GENMASK(31, 20)
0033 #define AT91_PIT_CPIV GENMASK(19, 0)
0034
0035 #define PIT_CPIV(x) ((x) & AT91_PIT_CPIV)
0036 #define PIT_PICNT(x) (((x) & AT91_PIT_PICNT) >> 20)
0037
0038 struct pit_data {
0039 struct clock_event_device clkevt;
0040 struct clocksource clksrc;
0041
0042 void __iomem *base;
0043 u32 cycle;
0044 u32 cnt;
0045 unsigned int irq;
0046 struct clk *mck;
0047 };
0048
0049 static inline struct pit_data *clksrc_to_pit_data(struct clocksource *clksrc)
0050 {
0051 return container_of(clksrc, struct pit_data, clksrc);
0052 }
0053
0054 static inline struct pit_data *clkevt_to_pit_data(struct clock_event_device *clkevt)
0055 {
0056 return container_of(clkevt, struct pit_data, clkevt);
0057 }
0058
0059 static inline unsigned int pit_read(void __iomem *base, unsigned int reg_offset)
0060 {
0061 return readl_relaxed(base + reg_offset);
0062 }
0063
0064 static inline void pit_write(void __iomem *base, unsigned int reg_offset, unsigned long value)
0065 {
0066 writel_relaxed(value, base + reg_offset);
0067 }
0068
0069
0070
0071
0072
0073 static u64 read_pit_clk(struct clocksource *cs)
0074 {
0075 struct pit_data *data = clksrc_to_pit_data(cs);
0076 unsigned long flags;
0077 u32 elapsed;
0078 u32 t;
0079
0080 raw_local_irq_save(flags);
0081 elapsed = data->cnt;
0082 t = pit_read(data->base, AT91_PIT_PIIR);
0083 raw_local_irq_restore(flags);
0084
0085 elapsed += PIT_PICNT(t) * data->cycle;
0086 elapsed += PIT_CPIV(t);
0087 return elapsed;
0088 }
0089
0090 static int pit_clkevt_shutdown(struct clock_event_device *dev)
0091 {
0092 struct pit_data *data = clkevt_to_pit_data(dev);
0093
0094
0095 pit_write(data->base, AT91_PIT_MR, (data->cycle - 1) | AT91_PIT_PITEN);
0096 return 0;
0097 }
0098
0099
0100
0101
0102 static int pit_clkevt_set_periodic(struct clock_event_device *dev)
0103 {
0104 struct pit_data *data = clkevt_to_pit_data(dev);
0105
0106
0107 data->cnt += data->cycle * PIT_PICNT(pit_read(data->base, AT91_PIT_PIVR));
0108 pit_write(data->base, AT91_PIT_MR,
0109 (data->cycle - 1) | AT91_PIT_PITEN | AT91_PIT_PITIEN);
0110 return 0;
0111 }
0112
0113 static void at91sam926x_pit_suspend(struct clock_event_device *cedev)
0114 {
0115 struct pit_data *data = clkevt_to_pit_data(cedev);
0116
0117
0118 pit_write(data->base, AT91_PIT_MR, 0);
0119 }
0120
0121 static void at91sam926x_pit_reset(struct pit_data *data)
0122 {
0123
0124 pit_write(data->base, AT91_PIT_MR, 0);
0125
0126
0127 while (PIT_CPIV(pit_read(data->base, AT91_PIT_PIVR)) != 0)
0128 cpu_relax();
0129
0130
0131 pit_write(data->base, AT91_PIT_MR,
0132 (data->cycle - 1) | AT91_PIT_PITEN);
0133 }
0134
0135 static void at91sam926x_pit_resume(struct clock_event_device *cedev)
0136 {
0137 struct pit_data *data = clkevt_to_pit_data(cedev);
0138
0139 at91sam926x_pit_reset(data);
0140 }
0141
0142
0143
0144
0145 static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id)
0146 {
0147 struct pit_data *data = dev_id;
0148
0149
0150 if (clockevent_state_periodic(&data->clkevt) &&
0151 (pit_read(data->base, AT91_PIT_SR) & AT91_PIT_PITS)) {
0152
0153 data->cnt += data->cycle * PIT_PICNT(pit_read(data->base,
0154 AT91_PIT_PIVR));
0155 data->clkevt.event_handler(&data->clkevt);
0156
0157 return IRQ_HANDLED;
0158 }
0159
0160 return IRQ_NONE;
0161 }
0162
0163
0164
0165
0166 static int __init at91sam926x_pit_dt_init(struct device_node *node)
0167 {
0168 unsigned long pit_rate;
0169 unsigned bits;
0170 int ret;
0171 struct pit_data *data;
0172
0173 data = kzalloc(sizeof(*data), GFP_KERNEL);
0174 if (!data)
0175 return -ENOMEM;
0176
0177 data->base = of_iomap(node, 0);
0178 if (!data->base) {
0179 pr_err("Could not map PIT address\n");
0180 ret = -ENXIO;
0181 goto exit;
0182 }
0183
0184 data->mck = of_clk_get(node, 0);
0185 if (IS_ERR(data->mck)) {
0186 pr_err("Unable to get mck clk\n");
0187 ret = PTR_ERR(data->mck);
0188 goto exit;
0189 }
0190
0191 ret = clk_prepare_enable(data->mck);
0192 if (ret) {
0193 pr_err("Unable to enable mck\n");
0194 goto exit;
0195 }
0196
0197
0198 data->irq = irq_of_parse_and_map(node, 0);
0199 if (!data->irq) {
0200 pr_err("Unable to get IRQ from DT\n");
0201 ret = -EINVAL;
0202 goto exit;
0203 }
0204
0205
0206
0207
0208
0209 pit_rate = clk_get_rate(data->mck) / 16;
0210 data->cycle = DIV_ROUND_CLOSEST(pit_rate, HZ);
0211 WARN_ON(((data->cycle - 1) & ~AT91_PIT_PIV) != 0);
0212
0213
0214 at91sam926x_pit_reset(data);
0215
0216
0217
0218
0219
0220 bits = 12 + ilog2(data->cycle) ;
0221 data->clksrc.mask = CLOCKSOURCE_MASK(bits);
0222 data->clksrc.name = "pit";
0223 data->clksrc.rating = 175;
0224 data->clksrc.read = read_pit_clk;
0225 data->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
0226
0227 ret = clocksource_register_hz(&data->clksrc, pit_rate);
0228 if (ret) {
0229 pr_err("Failed to register clocksource\n");
0230 goto exit;
0231 }
0232
0233
0234 ret = request_irq(data->irq, at91sam926x_pit_interrupt,
0235 IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL,
0236 "at91_tick", data);
0237 if (ret) {
0238 pr_err("Unable to setup IRQ\n");
0239 clocksource_unregister(&data->clksrc);
0240 goto exit;
0241 }
0242
0243
0244 data->clkevt.name = "pit";
0245 data->clkevt.features = CLOCK_EVT_FEAT_PERIODIC;
0246 data->clkevt.shift = 32;
0247 data->clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, data->clkevt.shift);
0248 data->clkevt.rating = 100;
0249 data->clkevt.cpumask = cpumask_of(0);
0250
0251 data->clkevt.set_state_shutdown = pit_clkevt_shutdown;
0252 data->clkevt.set_state_periodic = pit_clkevt_set_periodic;
0253 data->clkevt.resume = at91sam926x_pit_resume;
0254 data->clkevt.suspend = at91sam926x_pit_suspend;
0255 clockevents_register_device(&data->clkevt);
0256
0257 return 0;
0258
0259 exit:
0260 kfree(data);
0261 return ret;
0262 }
0263 TIMER_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit",
0264 at91sam926x_pit_dt_init);