| 1 | |
| 2 | |
| 3 | * SuperH Timer Support - CMT
|
| 4 | *
|
| 5 | * Copyright (C) 2008 Magnus Damm
|
| 6 |
|
| 7 |
|
| 8 | #include <linux/clk.h>
|
| 9 | #include <linux/clockchips.h>
|
| 10 | #include <linux/clocksource.h>
|
| 11 | #include <linux/delay.h>
|
| 12 | #include <linux/err.h>
|
| 13 | #include <linux/init.h>
|
| 14 | #include <linux/interrupt.h>
|
| 15 | #include <linux/io.h>
|
| 16 | #include <linux/iopoll.h>
|
| 17 | #include <linux/ioport.h>
|
| 18 | #include <linux/irq.h>
|
| 19 | #include <linux/module.h>
|
| 20 | #include <linux/of.h>
|
| 21 | #include <linux/platform_device.h>
|
| 22 | #include <linux/pm_domain.h>
|
| 23 | #include <linux/pm_runtime.h>
|
| 24 | #include <linux/sh_timer.h>
|
| 25 | #include <linux/slab.h>
|
| 26 | #include <linux/spinlock.h>
|
| 27 |
|
| 28 | #ifdef CONFIG_SUPERH
|
| 29 | #include <asm/platform_early.h>
|
| 30 | #endif
|
| 31 |
|
| 32 | struct sh_cmt_device;
|
| 33 |
|
| 34 | |
| 35 | * The CMT comes in 5 different identified flavours, depending not only on the
|
| 36 | * SoC but also on the particular instance. The following table lists the main
|
| 37 | * characteristics of those flavours.
|
| 38 | *
|
| 39 | * 16B 32B 32B-F 48B R-Car Gen2
|
| 40 | * -----------------------------------------------------------------------------
|
| 41 | * Channels 2 1/4 1 6 2/8
|
| 42 | * Control Width 16 16 16 16 32
|
| 43 | * Counter Width 16 32 32 32/48 32/48
|
| 44 | * Shared Start/Stop Y Y Y Y N
|
| 45 | *
|
| 46 | * The r8a73a4 / R-Car Gen2 version has a per-channel start/stop register
|
| 47 | * located in the channel registers block. All other versions have a shared
|
| 48 | * start/stop register located in the global space.
|
| 49 | *
|
| 50 | * Channels are indexed from 0 to N-1 in the documentation. The channel index
|
| 51 | * infers the start/stop bit position in the control register and the channel
|
| 52 | * registers block address. Some CMT instances have a subset of channels
|
| 53 | * available, in which case the index in the documentation doesn't match the
|
| 54 | * "real" index as implemented in hardware. This is for instance the case with
|
| 55 | * CMT0 on r8a7740, which is a 32-bit variant with a single channel numbered 0
|
| 56 | * in the documentation but using start/stop bit 5 and having its registers
|
| 57 | * block at 0x60.
|
| 58 | *
|
| 59 | * Similarly CMT0 on r8a73a4, r8a7790 and r8a7791, while implementing 32-bit
|
| 60 | * channels only, is a 48-bit gen2 CMT with the 48-bit channels unavailable.
|
| 61 |
|
| 62 |
|
| 63 | enum sh_cmt_model {
|
| 64 | SH_CMT_16BIT,
|
| 65 | SH_CMT_32BIT,
|
| 66 | SH_CMT_48BIT,
|
| 67 | SH_CMT0_RCAR_GEN2,
|
| 68 | SH_CMT1_RCAR_GEN2,
|
| 69 | };
|
| 70 |
|
| 71 | struct sh_cmt_info {
|
| 72 | enum sh_cmt_model model;
|
| 73 |
|
| 74 | unsigned int channels_mask;
|
| 75 |
|
| 76 | unsigned long width;
|
| 77 | u32 overflow_bit;
|
| 78 | u32 clear_bits;
|
| 79 |
|
| 80 |
|
| 81 | u32 (*read_control)(void __iomem *base, unsigned long offs);
|
| 82 | void (*write_control)(void __iomem *base, unsigned long offs,
|
| 83 | u32 value);
|
| 84 |
|
| 85 |
|
| 86 | u32 (*read_count)(void __iomem *base, unsigned long offs);
|
| 87 | void (*write_count)(void __iomem *base, unsigned long offs, u32 value);
|
| 88 | };
|
| 89 |
|
| 90 | struct sh_cmt_channel {
|
| 91 | struct sh_cmt_device *cmt;
|
| 92 |
|
| 93 | unsigned int index;
|
| 94 | unsigned int hwidx;
|
| 95 |
|
| 96 | void __iomem *iostart;
|
| 97 | void __iomem *ioctrl;
|
| 98 |
|
| 99 | unsigned int timer_bit;
|
| 100 | unsigned long flags;
|
| 101 | u32 match_value;
|
| 102 | u32 next_match_value;
|
| 103 | u32 max_match_value;
|
| 104 | raw_spinlock_t lock;
|
| 105 | struct clock_event_device ced;
|
| 106 | struct clocksource cs;
|
| 107 | u64 total_cycles;
|
| 108 | bool cs_enabled;
|
| 109 | };
|
| 110 |
|
| 111 | struct sh_cmt_device {
|
| 112 | struct platform_device *pdev;
|
| 113 |
|
| 114 | const struct sh_cmt_info *info;
|
| 115 |
|
| 116 | void __iomem *mapbase;
|
| 117 | struct clk *clk;
|
| 118 | unsigned long rate;
|
| 119 | unsigned int reg_delay;
|
| 120 |
|
| 121 | raw_spinlock_t lock;
|
| 122 |
|
| 123 | struct sh_cmt_channel *channels;
|
| 124 | unsigned int num_channels;
|
| 125 | unsigned int hw_channels;
|
| 126 |
|
| 127 | bool has_clockevent;
|
| 128 | bool has_clocksource;
|
| 129 | };
|
| 130 |
|
| 131 | #define SH_CMT16_CMCSR_CMF (1 << 7)
|
| 132 | #define SH_CMT16_CMCSR_CMIE (1 << 6)
|
| 133 | #define SH_CMT16_CMCSR_CKS8 (0 << 0)
|
| 134 | #define SH_CMT16_CMCSR_CKS32 (1 << 0)
|
| 135 | #define SH_CMT16_CMCSR_CKS128 (2 << 0)
|
| 136 | #define SH_CMT16_CMCSR_CKS512 (3 << 0)
|
| 137 | #define SH_CMT16_CMCSR_CKS_MASK (3 << 0)
|
| 138 |
|
| 139 | #define SH_CMT32_CMCSR_CMF (1 << 15)
|
| 140 | #define SH_CMT32_CMCSR_OVF (1 << 14)
|
| 141 | #define SH_CMT32_CMCSR_WRFLG (1 << 13)
|
| 142 | #define SH_CMT32_CMCSR_STTF (1 << 12)
|
| 143 | #define SH_CMT32_CMCSR_STPF (1 << 11)
|
| 144 | #define SH_CMT32_CMCSR_SSIE (1 << 10)
|
| 145 | #define SH_CMT32_CMCSR_CMS (1 << 9)
|
| 146 | #define SH_CMT32_CMCSR_CMM (1 << 8)
|
| 147 | #define SH_CMT32_CMCSR_CMTOUT_IE (1 << 7)
|
| 148 | #define SH_CMT32_CMCSR_CMR_NONE (0 << 4)
|
| 149 | #define SH_CMT32_CMCSR_CMR_DMA (1 << 4)
|
| 150 | #define SH_CMT32_CMCSR_CMR_IRQ (2 << 4)
|
| 151 | #define SH_CMT32_CMCSR_CMR_MASK (3 << 4)
|
| 152 | #define SH_CMT32_CMCSR_DBGIVD (1 << 3)
|
| 153 | #define SH_CMT32_CMCSR_CKS_RCLK8 (4 << 0)
|
| 154 | #define SH_CMT32_CMCSR_CKS_RCLK32 (5 << 0)
|
| 155 | #define SH_CMT32_CMCSR_CKS_RCLK128 (6 << 0)
|
| 156 | #define SH_CMT32_CMCSR_CKS_RCLK1 (7 << 0)
|
| 157 | #define SH_CMT32_CMCSR_CKS_MASK (7 << 0)
|
| 158 |
|
| 159 | static u32 sh_cmt_read16(void __iomem *base, unsigned long offs)
|
| 160 | {
|
| 161 | return ioread16(base + (offs << 1));
|
| 162 | }
|
| 163 |
|
| 164 | static u32 sh_cmt_read32(void __iomem *base, unsigned long offs)
|
| 165 | {
|
| 166 | return ioread32(base + (offs << 2));
|
| 167 | }
|
| 168 |
|
| 169 | static void sh_cmt_write16(void __iomem *base, unsigned long offs, u32 value)
|
| 170 | {
|
| 171 | iowrite16(value, base + (offs << 1));
|
| 172 | }
|
| 173 |
|
| 174 | static void sh_cmt_write32(void __iomem *base, unsigned long offs, u32 value)
|
| 175 | {
|
| 176 | iowrite32(value, base + (offs << 2));
|
| 177 | }
|
| 178 |
|
| 179 | static const struct sh_cmt_info sh_cmt_info[] = {
|
| 180 | [SH_CMT_16BIT] = {
|
| 181 | .model = SH_CMT_16BIT,
|
| 182 | .width = 16,
|
| 183 | .overflow_bit = SH_CMT16_CMCSR_CMF,
|
| 184 | .clear_bits = ~SH_CMT16_CMCSR_CMF,
|
| 185 | .read_control = sh_cmt_read16,
|
| 186 | .write_control = sh_cmt_write16,
|
| 187 | .read_count = sh_cmt_read16,
|
| 188 | .write_count = sh_cmt_write16,
|
| 189 | },
|
| 190 | [SH_CMT_32BIT] = {
|
| 191 | .model = SH_CMT_32BIT,
|
| 192 | .width = 32,
|
| 193 | .overflow_bit = SH_CMT32_CMCSR_CMF,
|
| 194 | .clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
|
| 195 | .read_control = sh_cmt_read16,
|
| 196 | .write_control = sh_cmt_write16,
|
| 197 | .read_count = sh_cmt_read32,
|
| 198 | .write_count = sh_cmt_write32,
|
| 199 | },
|
| 200 | [SH_CMT_48BIT] = {
|
| 201 | .model = SH_CMT_48BIT,
|
| 202 | .channels_mask = 0x3f,
|
| 203 | .width = 32,
|
| 204 | .overflow_bit = SH_CMT32_CMCSR_CMF,
|
| 205 | .clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
|
| 206 | .read_control = sh_cmt_read32,
|
| 207 | .write_control = sh_cmt_write32,
|
| 208 | .read_count = sh_cmt_read32,
|
| 209 | .write_count = sh_cmt_write32,
|
| 210 | },
|
| 211 | [SH_CMT0_RCAR_GEN2] = {
|
| 212 | .model = SH_CMT0_RCAR_GEN2,
|
| 213 | .channels_mask = 0x60,
|
| 214 | .width = 32,
|
| 215 | .overflow_bit = SH_CMT32_CMCSR_CMF,
|
| 216 | .clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
|
| 217 | .read_control = sh_cmt_read32,
|
| 218 | .write_control = sh_cmt_write32,
|
| 219 | .read_count = sh_cmt_read32,
|
| 220 | .write_count = sh_cmt_write32,
|
| 221 | },
|
| 222 | [SH_CMT1_RCAR_GEN2] = {
|
| 223 | .model = SH_CMT1_RCAR_GEN2,
|
| 224 | .channels_mask = 0xff,
|
| 225 | .width = 32,
|
| 226 | .overflow_bit = SH_CMT32_CMCSR_CMF,
|
| 227 | .clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF),
|
| 228 | .read_control = sh_cmt_read32,
|
| 229 | .write_control = sh_cmt_write32,
|
| 230 | .read_count = sh_cmt_read32,
|
| 231 | .write_count = sh_cmt_write32,
|
| 232 | },
|
| 233 | };
|
| 234 |
|
| 235 | #define CMCSR 0
|
| 236 | #define CMCNT 1
|
| 237 | #define CMCOR 2
|
| 238 |
|
| 239 | #define CMCLKE 0x1000
|
| 240 |
|
| 241 | static inline u32 sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
|
| 242 | {
|
| 243 | if (ch->iostart)
|
| 244 | return ch->cmt->info->read_control(ch->iostart, 0);
|
| 245 | else
|
| 246 | return ch->cmt->info->read_control(ch->cmt->mapbase, 0);
|
| 247 | }
|
| 248 |
|
| 249 | static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch, u32 value)
|
| 250 | {
|
| 251 | u32 old_value = sh_cmt_read_cmstr(ch);
|
| 252 |
|
| 253 | if (value != old_value) {
|
| 254 | if (ch->iostart) {
|
| 255 | ch->cmt->info->write_control(ch->iostart, 0, value);
|
| 256 | udelay(ch->cmt->reg_delay);
|
| 257 | } else {
|
| 258 | ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
|
| 259 | udelay(ch->cmt->reg_delay);
|
| 260 | }
|
| 261 | }
|
| 262 | }
|
| 263 |
|
| 264 | static inline u32 sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
|
| 265 | {
|
| 266 | return ch->cmt->info->read_control(ch->ioctrl, CMCSR);
|
| 267 | }
|
| 268 |
|
| 269 | static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch, u32 value)
|
| 270 | {
|
| 271 | u32 old_value = sh_cmt_read_cmcsr(ch);
|
| 272 |
|
| 273 | if (value != old_value) {
|
| 274 | ch->cmt->info->write_control(ch->ioctrl, CMCSR, value);
|
| 275 | udelay(ch->cmt->reg_delay);
|
| 276 | }
|
| 277 | }
|
| 278 |
|
| 279 | static inline u32 sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
|
| 280 | {
|
| 281 | return ch->cmt->info->read_count(ch->ioctrl, CMCNT);
|
| 282 | }
|
| 283 |
|
| 284 | static inline int sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, u32 value)
|
| 285 | {
|
| 286 |
|
| 287 | unsigned int cmcnt_delay = DIV_ROUND_UP(3 * ch->cmt->reg_delay, 2);
|
| 288 | u32 reg;
|
| 289 |
|
| 290 | if (ch->cmt->info->model > SH_CMT_16BIT) {
|
| 291 | int ret = read_poll_timeout_atomic(sh_cmt_read_cmcsr, reg,
|
| 292 | !(reg & SH_CMT32_CMCSR_WRFLG),
|
| 293 | 1, cmcnt_delay, false, ch);
|
| 294 | if (ret < 0)
|
| 295 | return ret;
|
| 296 | }
|
| 297 |
|
| 298 | ch->cmt->info->write_count(ch->ioctrl, CMCNT, value);
|
| 299 | udelay(cmcnt_delay);
|
| 300 | return 0;
|
| 301 | }
|
| 302 |
|
| 303 | static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch, u32 value)
|
| 304 | {
|
| 305 | u32 old_value = ch->cmt->info->read_count(ch->ioctrl, CMCOR);
|
| 306 |
|
| 307 | if (value != old_value) {
|
| 308 | ch->cmt->info->write_count(ch->ioctrl, CMCOR, value);
|
| 309 | udelay(ch->cmt->reg_delay);
|
| 310 | }
|
| 311 | }
|
| 312 |
|
| 313 | static u32 sh_cmt_get_counter(struct sh_cmt_channel *ch, u32 *has_wrapped)
|
| 314 | {
|
| 315 | u32 v1, v2, v3;
|
| 316 | u32 o1, o2;
|
| 317 |
|
| 318 | o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit;
|
| 319 |
|
| 320 |
|
| 321 | do {
|
| 322 | o2 = o1;
|
| 323 | v1 = sh_cmt_read_cmcnt(ch);
|
| 324 | v2 = sh_cmt_read_cmcnt(ch);
|
| 325 | v3 = sh_cmt_read_cmcnt(ch);
|
| 326 | o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit;
|
| 327 | } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
|
| 328 | || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
|
| 329 |
|
| 330 | *has_wrapped = o1;
|
| 331 | return v2;
|
| 332 | }
|
| 333 |
|
| 334 | static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
|
| 335 | {
|
| 336 | unsigned long flags;
|
| 337 | u32 value;
|
| 338 |
|
| 339 |
|
| 340 | raw_spin_lock_irqsave(&ch->cmt->lock, flags);
|
| 341 | value = sh_cmt_read_cmstr(ch);
|
| 342 |
|
| 343 | if (start)
|
| 344 | value |= 1 << ch->timer_bit;
|
| 345 | else
|
| 346 | value &= ~(1 << ch->timer_bit);
|
| 347 |
|
| 348 | sh_cmt_write_cmstr(ch, value);
|
| 349 | raw_spin_unlock_irqrestore(&ch->cmt->lock, flags);
|
| 350 | }
|
| 351 |
|
| 352 | static int sh_cmt_enable(struct sh_cmt_channel *ch)
|
| 353 | {
|
| 354 | int ret;
|
| 355 |
|
| 356 | dev_pm_syscore_device(&ch->cmt->pdev->dev, true);
|
| 357 |
|
| 358 |
|
| 359 | sh_cmt_start_stop_ch(ch, 0);
|
| 360 |
|
| 361 |
|
| 362 | if (ch->cmt->info->width == 16) {
|
| 363 | sh_cmt_write_cmcsr(ch, SH_CMT16_CMCSR_CMIE |
|
| 364 | SH_CMT16_CMCSR_CKS512);
|
| 365 | } else {
|
| 366 | u32 cmtout = ch->cmt->info->model <= SH_CMT_48BIT ?
|
| 367 | SH_CMT32_CMCSR_CMTOUT_IE : 0;
|
| 368 | sh_cmt_write_cmcsr(ch, cmtout | SH_CMT32_CMCSR_CMM |
|
| 369 | SH_CMT32_CMCSR_CMR_IRQ |
|
| 370 | SH_CMT32_CMCSR_CKS_RCLK8);
|
| 371 | }
|
| 372 |
|
| 373 | sh_cmt_write_cmcor(ch, 0xffffffff);
|
| 374 | ret = sh_cmt_write_cmcnt(ch, 0);
|
| 375 |
|
| 376 | if (ret || sh_cmt_read_cmcnt(ch)) {
|
| 377 | dev_err(&ch->cmt->pdev->dev, "ch%u: cannot clear CMCNT\n",
|
| 378 | ch->index);
|
| 379 | return -ETIMEDOUT;
|
| 380 | }
|
| 381 |
|
| 382 |
|
| 383 | sh_cmt_start_stop_ch(ch, 1);
|
| 384 | return 0;
|
| 385 | }
|
| 386 |
|
| 387 | static void sh_cmt_disable(struct sh_cmt_channel *ch)
|
| 388 | {
|
| 389 |
|
| 390 | sh_cmt_start_stop_ch(ch, 0);
|
| 391 |
|
| 392 |
|
| 393 | sh_cmt_write_cmcsr(ch, 0);
|
| 394 |
|
| 395 | dev_pm_syscore_device(&ch->cmt->pdev->dev, false);
|
| 396 | }
|
| 397 |
|
| 398 |
|
| 399 | #define FLAG_CLOCKEVENT (1 << 0)
|
| 400 | #define FLAG_CLOCKSOURCE (1 << 1)
|
| 401 | #define FLAG_REPROGRAM (1 << 2)
|
| 402 | #define FLAG_SKIPEVENT (1 << 3)
|
| 403 | #define FLAG_IRQCONTEXT (1 << 4)
|
| 404 |
|
| 405 | static void sh_cmt_clock_event_program_verify(struct sh_cmt_channel *ch,
|
| 406 | int absolute)
|
| 407 | {
|
| 408 | u32 value = ch->next_match_value;
|
| 409 | u32 new_match;
|
| 410 | u32 delay = 0;
|
| 411 | u32 now = 0;
|
| 412 | u32 has_wrapped;
|
| 413 |
|
| 414 | now = sh_cmt_get_counter(ch, &has_wrapped);
|
| 415 | ch->flags |= FLAG_REPROGRAM;
|
| 416 |
|
| 417 | if (has_wrapped) {
|
| 418 | |
| 419 | * -> let the interrupt handler reprogram the timer.
|
| 420 | * -> interrupt number two handles the event.
|
| 421 |
|
| 422 | ch->flags |= FLAG_SKIPEVENT;
|
| 423 | return;
|
| 424 | }
|
| 425 |
|
| 426 | if (absolute)
|
| 427 | now = 0;
|
| 428 |
|
| 429 | do {
|
| 430 | |
| 431 | * but don't save the new match value yet.
|
| 432 |
|
| 433 | new_match = now + value + delay;
|
| 434 | if (new_match > ch->max_match_value)
|
| 435 | new_match = ch->max_match_value;
|
| 436 |
|
| 437 | sh_cmt_write_cmcor(ch, new_match);
|
| 438 |
|
| 439 | now = sh_cmt_get_counter(ch, &has_wrapped);
|
| 440 | if (has_wrapped && (new_match > ch->match_value)) {
|
| 441 | |
| 442 | * so this wrap must be caused by the counter
|
| 443 | * matching the old value.
|
| 444 | * -> first interrupt reprograms the timer.
|
| 445 | * -> interrupt number two handles the event.
|
| 446 |
|
| 447 | ch->flags |= FLAG_SKIPEVENT;
|
| 448 | break;
|
| 449 | }
|
| 450 |
|
| 451 | if (has_wrapped) {
|
| 452 | |
| 453 | * so the wrap must be caused by the counter
|
| 454 | * matching the new value.
|
| 455 | * -> save programmed match value.
|
| 456 | * -> let isr handle the event.
|
| 457 |
|
| 458 | ch->match_value = new_match;
|
| 459 | break;
|
| 460 | }
|
| 461 |
|
| 462 |
|
| 463 | if (now < new_match) {
|
| 464 | |
| 465 | * this makes sure we won't miss any match events.
|
| 466 | * -> save programmed match value.
|
| 467 | * -> let isr handle the event.
|
| 468 |
|
| 469 | ch->match_value = new_match;
|
| 470 | break;
|
| 471 | }
|
| 472 |
|
| 473 | |
| 474 | * than our new match value. and since the
|
| 475 | * has_wrapped flag isn't set we must have
|
| 476 | * programmed a too close event.
|
| 477 | * -> increase delay and retry.
|
| 478 |
|
| 479 | if (delay)
|
| 480 | delay <<= 1;
|
| 481 | else
|
| 482 | delay = 1;
|
| 483 |
|
| 484 | if (!delay)
|
| 485 | dev_warn(&ch->cmt->pdev->dev, "ch%u: too long delay\n",
|
| 486 | ch->index);
|
| 487 |
|
| 488 | } while (delay);
|
| 489 | }
|
| 490 |
|
| 491 | static void __sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
|
| 492 | {
|
| 493 | if (delta > ch->max_match_value)
|
| 494 | dev_warn(&ch->cmt->pdev->dev, "ch%u: delta out of range\n",
|
| 495 | ch->index);
|
| 496 |
|
| 497 | ch->next_match_value = delta;
|
| 498 | sh_cmt_clock_event_program_verify(ch, 0);
|
| 499 | }
|
| 500 |
|
| 501 | static void sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
|
| 502 | {
|
| 503 | unsigned long flags;
|
| 504 |
|
| 505 | raw_spin_lock_irqsave(&ch->lock, flags);
|
| 506 | __sh_cmt_set_next(ch, delta);
|
| 507 | raw_spin_unlock_irqrestore(&ch->lock, flags);
|
| 508 | }
|
| 509 |
|
| 510 | static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
|
| 511 | {
|
| 512 | struct sh_cmt_channel *ch = dev_id;
|
| 513 | unsigned long flags;
|
| 514 |
|
| 515 |
|
| 516 | sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) &
|
| 517 | ch->cmt->info->clear_bits);
|
| 518 |
|
| 519 | |
| 520 | * the wrap flag should be cleared by the timer specific
|
| 521 | * isr before we end up here.
|
| 522 |
|
| 523 | if (ch->flags & FLAG_CLOCKSOURCE)
|
| 524 | ch->total_cycles += ch->match_value + 1;
|
| 525 |
|
| 526 | if (!(ch->flags & FLAG_REPROGRAM))
|
| 527 | ch->next_match_value = ch->max_match_value;
|
| 528 |
|
| 529 | ch->flags |= FLAG_IRQCONTEXT;
|
| 530 |
|
| 531 | if (ch->flags & FLAG_CLOCKEVENT) {
|
| 532 | if (!(ch->flags & FLAG_SKIPEVENT)) {
|
| 533 | if (clockevent_state_oneshot(&ch->ced)) {
|
| 534 | ch->next_match_value = ch->max_match_value;
|
| 535 | ch->flags |= FLAG_REPROGRAM;
|
| 536 | }
|
| 537 |
|
| 538 | ch->ced.event_handler(&ch->ced);
|
| 539 | }
|
| 540 | }
|
| 541 |
|
| 542 | ch->flags &= ~FLAG_SKIPEVENT;
|
| 543 |
|
| 544 | raw_spin_lock_irqsave(&ch->lock, flags);
|
| 545 |
|
| 546 | if (ch->flags & FLAG_REPROGRAM) {
|
| 547 | ch->flags &= ~FLAG_REPROGRAM;
|
| 548 | sh_cmt_clock_event_program_verify(ch, 1);
|
| 549 |
|
| 550 | if (ch->flags & FLAG_CLOCKEVENT)
|
| 551 | if ((clockevent_state_shutdown(&ch->ced))
|
| 552 | || (ch->match_value == ch->next_match_value))
|
| 553 | ch->flags &= ~FLAG_REPROGRAM;
|
| 554 | }
|
| 555 |
|
| 556 | ch->flags &= ~FLAG_IRQCONTEXT;
|
| 557 |
|
| 558 | raw_spin_unlock_irqrestore(&ch->lock, flags);
|
| 559 |
|
| 560 | return IRQ_HANDLED;
|
| 561 | }
|
| 562 |
|
| 563 | static int sh_cmt_start_clocksource(struct sh_cmt_channel *ch)
|
| 564 | {
|
| 565 | int ret = 0;
|
| 566 | unsigned long flags;
|
| 567 |
|
| 568 | raw_spin_lock_irqsave(&ch->lock, flags);
|
| 569 |
|
| 570 | if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
|
| 571 | ret = sh_cmt_enable(ch);
|
| 572 |
|
| 573 | if (ret)
|
| 574 | goto out;
|
| 575 |
|
| 576 | ch->flags |= FLAG_CLOCKSOURCE;
|
| 577 |
|
| 578 |
|
| 579 | if (ch->cmt->num_channels == 1 && !(ch->flags & FLAG_CLOCKEVENT))
|
| 580 | __sh_cmt_set_next(ch, ch->max_match_value);
|
| 581 | out:
|
| 582 | raw_spin_unlock_irqrestore(&ch->lock, flags);
|
| 583 |
|
| 584 | return ret;
|
| 585 | }
|
| 586 |
|
| 587 | static void sh_cmt_stop_clocksource(struct sh_cmt_channel *ch)
|
| 588 | {
|
| 589 | unsigned long flags;
|
| 590 | unsigned long f;
|
| 591 |
|
| 592 | raw_spin_lock_irqsave(&ch->lock, flags);
|
| 593 |
|
| 594 | f = ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
|
| 595 |
|
| 596 | ch->flags &= ~FLAG_CLOCKSOURCE;
|
| 597 |
|
| 598 | if (f && !(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
|
| 599 | sh_cmt_disable(ch);
|
| 600 |
|
| 601 | raw_spin_unlock_irqrestore(&ch->lock, flags);
|
| 602 | }
|
| 603 |
|
| 604 | static int sh_cmt_start_clockevent(struct sh_cmt_channel *ch)
|
| 605 | {
|
| 606 | int ret = 0;
|
| 607 | unsigned long flags;
|
| 608 |
|
| 609 | raw_spin_lock_irqsave(&ch->lock, flags);
|
| 610 |
|
| 611 | if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
|
| 612 | ret = sh_cmt_enable(ch);
|
| 613 |
|
| 614 | if (ret)
|
| 615 | goto out;
|
| 616 |
|
| 617 | ch->flags |= FLAG_CLOCKEVENT;
|
| 618 | out:
|
| 619 | raw_spin_unlock_irqrestore(&ch->lock, flags);
|
| 620 |
|
| 621 | return ret;
|
| 622 | }
|
| 623 |
|
| 624 | static void sh_cmt_stop_clockevent(struct sh_cmt_channel *ch)
|
| 625 | {
|
| 626 | unsigned long flags;
|
| 627 | unsigned long f;
|
| 628 |
|
| 629 | raw_spin_lock_irqsave(&ch->lock, flags);
|
| 630 |
|
| 631 | f = ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
|
| 632 |
|
| 633 | ch->flags &= ~FLAG_CLOCKEVENT;
|
| 634 |
|
| 635 | if (f && !(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
|
| 636 | sh_cmt_disable(ch);
|
| 637 |
|
| 638 |
|
| 639 | if (ch->flags & FLAG_CLOCKSOURCE)
|
| 640 | __sh_cmt_set_next(ch, ch->max_match_value);
|
| 641 |
|
| 642 | raw_spin_unlock_irqrestore(&ch->lock, flags);
|
| 643 | }
|
| 644 |
|
| 645 | static struct sh_cmt_channel *cs_to_sh_cmt(struct clocksource *cs)
|
| 646 | {
|
| 647 | return container_of(cs, struct sh_cmt_channel, cs);
|
| 648 | }
|
| 649 |
|
| 650 | static u64 sh_cmt_clocksource_read(struct clocksource *cs)
|
| 651 | {
|
| 652 | struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
|
| 653 | u32 has_wrapped;
|
| 654 |
|
| 655 | if (ch->cmt->num_channels == 1) {
|
| 656 | unsigned long flags;
|
| 657 | u64 value;
|
| 658 | u32 raw;
|
| 659 |
|
| 660 | raw_spin_lock_irqsave(&ch->lock, flags);
|
| 661 | value = ch->total_cycles;
|
| 662 | raw = sh_cmt_get_counter(ch, &has_wrapped);
|
| 663 |
|
| 664 | if (unlikely(has_wrapped))
|
| 665 | raw += ch->match_value + 1;
|
| 666 | raw_spin_unlock_irqrestore(&ch->lock, flags);
|
| 667 |
|
| 668 | return value + raw;
|
| 669 | }
|
| 670 |
|
| 671 | return sh_cmt_get_counter(ch, &has_wrapped);
|
| 672 | }
|
| 673 |
|
| 674 | static int sh_cmt_clocksource_enable(struct clocksource *cs)
|
| 675 | {
|
| 676 | int ret;
|
| 677 | struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
|
| 678 |
|
| 679 | WARN_ON(ch->cs_enabled);
|
| 680 |
|
| 681 | ch->total_cycles = 0;
|
| 682 |
|
| 683 | ret = sh_cmt_start_clocksource(ch);
|
| 684 | if (!ret)
|
| 685 | ch->cs_enabled = true;
|
| 686 |
|
| 687 | return ret;
|
| 688 | }
|
| 689 |
|
| 690 | static void sh_cmt_clocksource_disable(struct clocksource *cs)
|
| 691 | {
|
| 692 | struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
|
| 693 |
|
| 694 | WARN_ON(!ch->cs_enabled);
|
| 695 |
|
| 696 | sh_cmt_stop_clocksource(ch);
|
| 697 | ch->cs_enabled = false;
|
| 698 | }
|
| 699 |
|
| 700 | static void sh_cmt_clocksource_suspend(struct clocksource *cs)
|
| 701 | {
|
| 702 | struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
|
| 703 |
|
| 704 | if (!ch->cs_enabled)
|
| 705 | return;
|
| 706 |
|
| 707 | sh_cmt_stop_clocksource(ch);
|
| 708 | dev_pm_genpd_suspend(&ch->cmt->pdev->dev);
|
| 709 | }
|
| 710 |
|
| 711 | static void sh_cmt_clocksource_resume(struct clocksource *cs)
|
| 712 | {
|
| 713 | struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
|
| 714 |
|
| 715 | if (!ch->cs_enabled)
|
| 716 | return;
|
| 717 |
|
| 718 | dev_pm_genpd_resume(&ch->cmt->pdev->dev);
|
| 719 | sh_cmt_start_clocksource(ch);
|
| 720 | }
|
| 721 |
|
| 722 | static int sh_cmt_register_clocksource(struct sh_cmt_channel *ch,
|
| 723 | const char *name)
|
| 724 | {
|
| 725 | struct clocksource *cs = &ch->cs;
|
| 726 |
|
| 727 | cs->name = name;
|
| 728 | cs->rating = 125;
|
| 729 | cs->read = sh_cmt_clocksource_read;
|
| 730 | cs->enable = sh_cmt_clocksource_enable;
|
| 731 | cs->disable = sh_cmt_clocksource_disable;
|
| 732 | cs->suspend = sh_cmt_clocksource_suspend;
|
| 733 | cs->resume = sh_cmt_clocksource_resume;
|
| 734 | cs->mask = CLOCKSOURCE_MASK(ch->cmt->info->width);
|
| 735 | cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
|
| 736 |
|
| 737 | dev_info(&ch->cmt->pdev->dev, "ch%u: used as clock source\n",
|
| 738 | ch->index);
|
| 739 |
|
| 740 | clocksource_register_hz(cs, ch->cmt->rate);
|
| 741 | return 0;
|
| 742 | }
|
| 743 |
|
| 744 | static struct sh_cmt_channel *ced_to_sh_cmt(struct clock_event_device *ced)
|
| 745 | {
|
| 746 | return container_of(ced, struct sh_cmt_channel, ced);
|
| 747 | }
|
| 748 |
|
| 749 | static void sh_cmt_clock_event_start(struct sh_cmt_channel *ch, int periodic)
|
| 750 | {
|
| 751 | sh_cmt_start_clockevent(ch);
|
| 752 |
|
| 753 | if (periodic)
|
| 754 | sh_cmt_set_next(ch, ((ch->cmt->rate + HZ/2) / HZ) - 1);
|
| 755 | else
|
| 756 | sh_cmt_set_next(ch, ch->max_match_value);
|
| 757 | }
|
| 758 |
|
| 759 | static int sh_cmt_clock_event_shutdown(struct clock_event_device *ced)
|
| 760 | {
|
| 761 | struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
|
| 762 |
|
| 763 | sh_cmt_stop_clockevent(ch);
|
| 764 | return 0;
|
| 765 | }
|
| 766 |
|
| 767 | static int sh_cmt_clock_event_set_state(struct clock_event_device *ced,
|
| 768 | int periodic)
|
| 769 | {
|
| 770 | struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
|
| 771 |
|
| 772 |
|
| 773 | if (clockevent_state_oneshot(ced) || clockevent_state_periodic(ced))
|
| 774 | sh_cmt_stop_clockevent(ch);
|
| 775 |
|
| 776 | dev_info(&ch->cmt->pdev->dev, "ch%u: used for %s clock events\n",
|
| 777 | ch->index, periodic ? "periodic" : "oneshot");
|
| 778 | sh_cmt_clock_event_start(ch, periodic);
|
| 779 | return 0;
|
| 780 | }
|
| 781 |
|
| 782 | static int sh_cmt_clock_event_set_oneshot(struct clock_event_device *ced)
|
| 783 | {
|
| 784 | return sh_cmt_clock_event_set_state(ced, 0);
|
| 785 | }
|
| 786 |
|
| 787 | static int sh_cmt_clock_event_set_periodic(struct clock_event_device *ced)
|
| 788 | {
|
| 789 | return sh_cmt_clock_event_set_state(ced, 1);
|
| 790 | }
|
| 791 |
|
| 792 | static int sh_cmt_clock_event_next(unsigned long delta,
|
| 793 | struct clock_event_device *ced)
|
| 794 | {
|
| 795 | struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
|
| 796 | unsigned long flags;
|
| 797 |
|
| 798 | BUG_ON(!clockevent_state_oneshot(ced));
|
| 799 |
|
| 800 | raw_spin_lock_irqsave(&ch->lock, flags);
|
| 801 |
|
| 802 | if (likely(ch->flags & FLAG_IRQCONTEXT))
|
| 803 | ch->next_match_value = delta - 1;
|
| 804 | else
|
| 805 | __sh_cmt_set_next(ch, delta - 1);
|
| 806 |
|
| 807 | raw_spin_unlock_irqrestore(&ch->lock, flags);
|
| 808 |
|
| 809 | return 0;
|
| 810 | }
|
| 811 |
|
| 812 | static void sh_cmt_clock_event_suspend(struct clock_event_device *ced)
|
| 813 | {
|
| 814 | struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
|
| 815 |
|
| 816 | dev_pm_genpd_suspend(&ch->cmt->pdev->dev);
|
| 817 | clk_unprepare(ch->cmt->clk);
|
| 818 | }
|
| 819 |
|
| 820 | static void sh_cmt_clock_event_resume(struct clock_event_device *ced)
|
| 821 | {
|
| 822 | struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
|
| 823 |
|
| 824 | clk_prepare(ch->cmt->clk);
|
| 825 | dev_pm_genpd_resume(&ch->cmt->pdev->dev);
|
| 826 | }
|
| 827 |
|
| 828 | static int sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
|
| 829 | const char *name)
|
| 830 | {
|
| 831 | struct clock_event_device *ced = &ch->ced;
|
| 832 | int irq;
|
| 833 | int ret;
|
| 834 |
|
| 835 | irq = platform_get_irq(ch->cmt->pdev, ch->index);
|
| 836 | if (irq < 0)
|
| 837 | return irq;
|
| 838 |
|
| 839 | ret = request_irq(irq, sh_cmt_interrupt,
|
| 840 | IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
|
| 841 | dev_name(&ch->cmt->pdev->dev), ch);
|
| 842 | if (ret) {
|
| 843 | dev_err(&ch->cmt->pdev->dev, "ch%u: failed to request irq %d\n",
|
| 844 | ch->index, irq);
|
| 845 | return ret;
|
| 846 | }
|
| 847 |
|
| 848 | ced->name = name;
|
| 849 | ced->features = CLOCK_EVT_FEAT_PERIODIC;
|
| 850 | ced->features |= CLOCK_EVT_FEAT_ONESHOT;
|
| 851 | ced->rating = 125;
|
| 852 | ced->cpumask = cpu_possible_mask;
|
| 853 | ced->set_next_event = sh_cmt_clock_event_next;
|
| 854 | ced->set_state_shutdown = sh_cmt_clock_event_shutdown;
|
| 855 | ced->set_state_periodic = sh_cmt_clock_event_set_periodic;
|
| 856 | ced->set_state_oneshot = sh_cmt_clock_event_set_oneshot;
|
| 857 | ced->suspend = sh_cmt_clock_event_suspend;
|
| 858 | ced->resume = sh_cmt_clock_event_resume;
|
| 859 |
|
| 860 |
|
| 861 | ced->shift = 32;
|
| 862 | ced->mult = div_sc(ch->cmt->rate, NSEC_PER_SEC, ced->shift);
|
| 863 | ced->max_delta_ns = clockevent_delta2ns(ch->max_match_value, ced);
|
| 864 | ced->max_delta_ticks = ch->max_match_value;
|
| 865 | ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
|
| 866 | ced->min_delta_ticks = 0x1f;
|
| 867 |
|
| 868 | dev_info(&ch->cmt->pdev->dev, "ch%u: used for clock events\n",
|
| 869 | ch->index);
|
| 870 | clockevents_register_device(ced);
|
| 871 |
|
| 872 | return 0;
|
| 873 | }
|
| 874 |
|
| 875 | static int sh_cmt_register(struct sh_cmt_channel *ch, const char *name,
|
| 876 | bool clockevent, bool clocksource)
|
| 877 | {
|
| 878 | int ret;
|
| 879 |
|
| 880 | if (clockevent) {
|
| 881 | ch->cmt->has_clockevent = true;
|
| 882 | ret = sh_cmt_register_clockevent(ch, name);
|
| 883 | if (ret < 0)
|
| 884 | return ret;
|
| 885 | }
|
| 886 |
|
| 887 | if (clocksource) {
|
| 888 | ch->cmt->has_clocksource = true;
|
| 889 | sh_cmt_register_clocksource(ch, name);
|
| 890 | }
|
| 891 |
|
| 892 | return 0;
|
| 893 | }
|
| 894 |
|
| 895 | static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
|
| 896 | unsigned int hwidx, bool clockevent,
|
| 897 | bool clocksource, struct sh_cmt_device *cmt)
|
| 898 | {
|
| 899 | u32 value;
|
| 900 | int ret;
|
| 901 |
|
| 902 |
|
| 903 | if (!clockevent && !clocksource)
|
| 904 | return 0;
|
| 905 |
|
| 906 | ch->cmt = cmt;
|
| 907 | ch->index = index;
|
| 908 | ch->hwidx = hwidx;
|
| 909 | ch->timer_bit = hwidx;
|
| 910 |
|
| 911 | |
| 912 | * Compute the address of the channel control register block. For the
|
| 913 | * timers with a per-channel start/stop register, compute its address
|
| 914 | * as well.
|
| 915 |
|
| 916 | switch (cmt->info->model) {
|
| 917 | case SH_CMT_16BIT:
|
| 918 | ch->ioctrl = cmt->mapbase + 2 + ch->hwidx * 6;
|
| 919 | break;
|
| 920 | case SH_CMT_32BIT:
|
| 921 | case SH_CMT_48BIT:
|
| 922 | ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10;
|
| 923 | break;
|
| 924 | case SH_CMT0_RCAR_GEN2:
|
| 925 | case SH_CMT1_RCAR_GEN2:
|
| 926 | ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
|
| 927 | ch->ioctrl = ch->iostart + 0x10;
|
| 928 | ch->timer_bit = 0;
|
| 929 |
|
| 930 |
|
| 931 | value = ioread32(cmt->mapbase + CMCLKE);
|
| 932 | value |= BIT(hwidx);
|
| 933 | iowrite32(value, cmt->mapbase + CMCLKE);
|
| 934 | break;
|
| 935 | }
|
| 936 |
|
| 937 | if (cmt->info->width == (sizeof(ch->max_match_value) * 8))
|
| 938 | ch->max_match_value = ~0;
|
| 939 | else
|
| 940 | ch->max_match_value = (1 << cmt->info->width) - 1;
|
| 941 |
|
| 942 | ch->match_value = ch->max_match_value;
|
| 943 | raw_spin_lock_init(&ch->lock);
|
| 944 |
|
| 945 | ret = sh_cmt_register(ch, dev_name(&cmt->pdev->dev),
|
| 946 | clockevent, clocksource);
|
| 947 | if (ret) {
|
| 948 | dev_err(&cmt->pdev->dev, "ch%u: registration failed\n",
|
| 949 | ch->index);
|
| 950 | return ret;
|
| 951 | }
|
| 952 | ch->cs_enabled = false;
|
| 953 |
|
| 954 | return 0;
|
| 955 | }
|
| 956 |
|
| 957 | static int sh_cmt_map_memory(struct sh_cmt_device *cmt)
|
| 958 | {
|
| 959 | struct resource *mem;
|
| 960 |
|
| 961 | mem = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
|
| 962 | if (!mem) {
|
| 963 | dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
|
| 964 | return -ENXIO;
|
| 965 | }
|
| 966 |
|
| 967 | cmt->mapbase = ioremap(mem->start, resource_size(mem));
|
| 968 | if (cmt->mapbase == NULL) {
|
| 969 | dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
|
| 970 | return -ENXIO;
|
| 971 | }
|
| 972 |
|
| 973 | return 0;
|
| 974 | }
|
| 975 |
|
| 976 | static const struct platform_device_id sh_cmt_id_table[] = {
|
| 977 | { .name = "sh-cmt-16", .driver_data = (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
|
| 978 | { .name = "sh-cmt-32", .driver_data = (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
|
| 979 | { }
|
| 980 | };
|
| 981 | MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
|
| 982 |
|
| 983 | static const struct of_device_id sh_cmt_of_table[] __maybe_unused = {
|
| 984 | {
|
| 985 |
|
| 986 | .compatible = "renesas,cmt-48",
|
| 987 | .data = &sh_cmt_info[SH_CMT_48BIT]
|
| 988 | },
|
| 989 | {
|
| 990 |
|
| 991 | .compatible = "renesas,cmt-48-gen2",
|
| 992 | .data = &sh_cmt_info[SH_CMT0_RCAR_GEN2]
|
| 993 | },
|
| 994 | {
|
| 995 | .compatible = "renesas,r8a7740-cmt1",
|
| 996 | .data = &sh_cmt_info[SH_CMT_48BIT]
|
| 997 | },
|
| 998 | {
|
| 999 | .compatible = "renesas,sh73a0-cmt1",
|
| 1000 | .data = &sh_cmt_info[SH_CMT_48BIT]
|
| 1001 | },
|
| 1002 | {
|
| 1003 | .compatible = "renesas,rcar-gen2-cmt0",
|
| 1004 | .data = &sh_cmt_info[SH_CMT0_RCAR_GEN2]
|
| 1005 | },
|
| 1006 | {
|
| 1007 | .compatible = "renesas,rcar-gen2-cmt1",
|
| 1008 | .data = &sh_cmt_info[SH_CMT1_RCAR_GEN2]
|
| 1009 | },
|
| 1010 | {
|
| 1011 | .compatible = "renesas,rcar-gen3-cmt0",
|
| 1012 | .data = &sh_cmt_info[SH_CMT0_RCAR_GEN2]
|
| 1013 | },
|
| 1014 | {
|
| 1015 | .compatible = "renesas,rcar-gen3-cmt1",
|
| 1016 | .data = &sh_cmt_info[SH_CMT1_RCAR_GEN2]
|
| 1017 | },
|
| 1018 | {
|
| 1019 | .compatible = "renesas,rcar-gen4-cmt0",
|
| 1020 | .data = &sh_cmt_info[SH_CMT0_RCAR_GEN2]
|
| 1021 | },
|
| 1022 | {
|
| 1023 | .compatible = "renesas,rcar-gen4-cmt1",
|
| 1024 | .data = &sh_cmt_info[SH_CMT1_RCAR_GEN2]
|
| 1025 | },
|
| 1026 | { }
|
| 1027 | };
|
| 1028 | MODULE_DEVICE_TABLE(of, sh_cmt_of_table);
|
| 1029 |
|
| 1030 | static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
|
| 1031 | {
|
| 1032 | unsigned int mask, i;
|
| 1033 | unsigned long rate;
|
| 1034 | int ret;
|
| 1035 |
|
| 1036 | cmt->pdev = pdev;
|
| 1037 | raw_spin_lock_init(&cmt->lock);
|
| 1038 |
|
| 1039 | if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
|
| 1040 | cmt->info = of_device_get_match_data(&pdev->dev);
|
| 1041 | cmt->hw_channels = cmt->info->channels_mask;
|
| 1042 | } else if (pdev->dev.platform_data) {
|
| 1043 | struct sh_timer_config *cfg = pdev->dev.platform_data;
|
| 1044 | const struct platform_device_id *id = pdev->id_entry;
|
| 1045 |
|
| 1046 | cmt->info = (const struct sh_cmt_info *)id->driver_data;
|
| 1047 | cmt->hw_channels = cfg->channels_mask;
|
| 1048 | } else {
|
| 1049 | dev_err(&cmt->pdev->dev, "missing platform data\n");
|
| 1050 | return -ENXIO;
|
| 1051 | }
|
| 1052 |
|
| 1053 |
|
| 1054 | cmt->clk = clk_get(&cmt->pdev->dev, "fck");
|
| 1055 | if (IS_ERR(cmt->clk)) {
|
| 1056 | dev_err(&cmt->pdev->dev, "cannot get clock\n");
|
| 1057 | return PTR_ERR(cmt->clk);
|
| 1058 | }
|
| 1059 |
|
| 1060 | ret = clk_prepare(cmt->clk);
|
| 1061 | if (ret < 0)
|
| 1062 | goto err_clk_put;
|
| 1063 |
|
| 1064 |
|
| 1065 | ret = clk_enable(cmt->clk);
|
| 1066 | if (ret < 0)
|
| 1067 | goto err_clk_unprepare;
|
| 1068 |
|
| 1069 | rate = clk_get_rate(cmt->clk);
|
| 1070 | if (!rate) {
|
| 1071 | ret = -EINVAL;
|
| 1072 | goto err_clk_disable;
|
| 1073 | }
|
| 1074 |
|
| 1075 |
|
| 1076 | if (cmt->info->model >= SH_CMT_48BIT)
|
| 1077 | cmt->reg_delay = DIV_ROUND_UP(2UL * USEC_PER_SEC, rate);
|
| 1078 | cmt->rate = rate / (cmt->info->width == 16 ? 512 : 8);
|
| 1079 |
|
| 1080 |
|
| 1081 | ret = sh_cmt_map_memory(cmt);
|
| 1082 | if (ret < 0)
|
| 1083 | goto err_clk_disable;
|
| 1084 |
|
| 1085 |
|
| 1086 | cmt->num_channels = hweight8(cmt->hw_channels);
|
| 1087 | cmt->channels = kzalloc_objs(*cmt->channels, cmt->num_channels);
|
| 1088 | if (cmt->channels == NULL) {
|
| 1089 | ret = -ENOMEM;
|
| 1090 | goto err_unmap;
|
| 1091 | }
|
| 1092 |
|
| 1093 | |
| 1094 | * Use the first channel as a clock event device and the second channel
|
| 1095 | * as a clock source. If only one channel is available use it for both.
|
| 1096 |
|
| 1097 | for (i = 0, mask = cmt->hw_channels; i < cmt->num_channels; ++i) {
|
| 1098 | unsigned int hwidx = ffs(mask) - 1;
|
| 1099 | bool clocksource = i == 1 || cmt->num_channels == 1;
|
| 1100 | bool clockevent = i == 0;
|
| 1101 |
|
| 1102 | ret = sh_cmt_setup_channel(&cmt->channels[i], i, hwidx,
|
| 1103 | clockevent, clocksource, cmt);
|
| 1104 | if (ret < 0)
|
| 1105 | goto err_unmap;
|
| 1106 |
|
| 1107 | mask &= ~(1 << hwidx);
|
| 1108 | }
|
| 1109 |
|
| 1110 | platform_set_drvdata(pdev, cmt);
|
| 1111 |
|
| 1112 | return 0;
|
| 1113 |
|
| 1114 | err_unmap:
|
| 1115 | kfree(cmt->channels);
|
| 1116 | iounmap(cmt->mapbase);
|
| 1117 | err_clk_disable:
|
| 1118 | clk_disable(cmt->clk);
|
| 1119 | err_clk_unprepare:
|
| 1120 | clk_unprepare(cmt->clk);
|
| 1121 | err_clk_put:
|
| 1122 | clk_put(cmt->clk);
|
| 1123 | return ret;
|
| 1124 | }
|
| 1125 |
|
| 1126 | static int sh_cmt_probe(struct platform_device *pdev)
|
| 1127 | {
|
| 1128 | struct sh_cmt_device *cmt = platform_get_drvdata(pdev);
|
| 1129 | int ret;
|
| 1130 |
|
| 1131 | if (!is_sh_early_platform_device(pdev)) {
|
| 1132 | pm_runtime_set_active(&pdev->dev);
|
| 1133 | pm_runtime_enable(&pdev->dev);
|
| 1134 | }
|
| 1135 |
|
| 1136 | if (cmt) {
|
| 1137 | dev_info(&pdev->dev, "kept as earlytimer\n");
|
| 1138 | goto out;
|
| 1139 | }
|
| 1140 |
|
| 1141 | cmt = kzalloc_obj(*cmt);
|
| 1142 | if (cmt == NULL)
|
| 1143 | return -ENOMEM;
|
| 1144 |
|
| 1145 | ret = sh_cmt_setup(cmt, pdev);
|
| 1146 | if (ret) {
|
| 1147 | kfree(cmt);
|
| 1148 | pm_runtime_idle(&pdev->dev);
|
| 1149 | return ret;
|
| 1150 | }
|
| 1151 | if (is_sh_early_platform_device(pdev))
|
| 1152 | return 0;
|
| 1153 |
|
| 1154 | out:
|
| 1155 | if (cmt->has_clockevent || cmt->has_clocksource)
|
| 1156 | pm_runtime_irq_safe(&pdev->dev);
|
| 1157 |
|
| 1158 | return 0;
|
| 1159 | }
|
| 1160 |
|
| 1161 | static struct platform_driver sh_cmt_device_driver = {
|
| 1162 | .probe = sh_cmt_probe,
|
| 1163 | .driver = {
|
| 1164 | .name = "sh_cmt",
|
| 1165 | .of_match_table = of_match_ptr(sh_cmt_of_table),
|
| 1166 | .suppress_bind_attrs = true,
|
| 1167 | },
|
| 1168 | .id_table = sh_cmt_id_table,
|
| 1169 | };
|
| 1170 |
|
| 1171 | static int __init sh_cmt_init(void)
|
| 1172 | {
|
| 1173 | return platform_driver_register(&sh_cmt_device_driver);
|
| 1174 | }
|
| 1175 |
|
| 1176 | static void __exit sh_cmt_exit(void)
|
| 1177 | {
|
| 1178 | platform_driver_unregister(&sh_cmt_device_driver);
|
| 1179 | }
|
| 1180 |
|
| 1181 | #ifdef CONFIG_SUPERH
|
| 1182 | sh_early_platform_init("earlytimer", &sh_cmt_device_driver);
|
| 1183 | #endif
|
| 1184 |
|
| 1185 | subsys_initcall(sh_cmt_init);
|
| 1186 | module_exit(sh_cmt_exit);
|
| 1187 |
|
| 1188 | MODULE_AUTHOR("Magnus Damm");
|
| 1189 | MODULE_DESCRIPTION("SuperH CMT Timer Driver");
|