| .. | .. |
|---|
| 13 | 13 | #include <linux/init.h> |
|---|
| 14 | 14 | #include <linux/interrupt.h> |
|---|
| 15 | 15 | #include <linux/io.h> |
|---|
| 16 | +#include <linux/iopoll.h> |
|---|
| 16 | 17 | #include <linux/ioport.h> |
|---|
| 17 | 18 | #include <linux/irq.h> |
|---|
| 18 | 19 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 116 | 117 | void __iomem *mapbase; |
|---|
| 117 | 118 | struct clk *clk; |
|---|
| 118 | 119 | unsigned long rate; |
|---|
| 120 | + unsigned int reg_delay; |
|---|
| 119 | 121 | |
|---|
| 120 | 122 | raw_spinlock_t lock; /* Protect the shared start/stop register */ |
|---|
| 121 | 123 | |
|---|
| .. | .. |
|---|
| 235 | 237 | #define CMCNT 1 /* channel register */ |
|---|
| 236 | 238 | #define CMCOR 2 /* channel register */ |
|---|
| 237 | 239 | |
|---|
| 240 | +#define CMCLKE 0x1000 /* CLK Enable Register (R-Car Gen2) */ |
|---|
| 241 | + |
|---|
| 238 | 242 | static inline u32 sh_cmt_read_cmstr(struct sh_cmt_channel *ch) |
|---|
| 239 | 243 | { |
|---|
| 240 | 244 | if (ch->iostart) |
|---|
| .. | .. |
|---|
| 245 | 249 | |
|---|
| 246 | 250 | static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch, u32 value) |
|---|
| 247 | 251 | { |
|---|
| 248 | | - if (ch->iostart) |
|---|
| 249 | | - ch->cmt->info->write_control(ch->iostart, 0, value); |
|---|
| 250 | | - else |
|---|
| 251 | | - ch->cmt->info->write_control(ch->cmt->mapbase, 0, value); |
|---|
| 252 | + u32 old_value = sh_cmt_read_cmstr(ch); |
|---|
| 253 | + |
|---|
| 254 | + if (value != old_value) { |
|---|
| 255 | + if (ch->iostart) { |
|---|
| 256 | + ch->cmt->info->write_control(ch->iostart, 0, value); |
|---|
| 257 | + udelay(ch->cmt->reg_delay); |
|---|
| 258 | + } else { |
|---|
| 259 | + ch->cmt->info->write_control(ch->cmt->mapbase, 0, value); |
|---|
| 260 | + udelay(ch->cmt->reg_delay); |
|---|
| 261 | + } |
|---|
| 262 | + } |
|---|
| 252 | 263 | } |
|---|
| 253 | 264 | |
|---|
| 254 | 265 | static inline u32 sh_cmt_read_cmcsr(struct sh_cmt_channel *ch) |
|---|
| .. | .. |
|---|
| 258 | 269 | |
|---|
| 259 | 270 | static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch, u32 value) |
|---|
| 260 | 271 | { |
|---|
| 261 | | - ch->cmt->info->write_control(ch->ioctrl, CMCSR, value); |
|---|
| 272 | + u32 old_value = sh_cmt_read_cmcsr(ch); |
|---|
| 273 | + |
|---|
| 274 | + if (value != old_value) { |
|---|
| 275 | + ch->cmt->info->write_control(ch->ioctrl, CMCSR, value); |
|---|
| 276 | + udelay(ch->cmt->reg_delay); |
|---|
| 277 | + } |
|---|
| 262 | 278 | } |
|---|
| 263 | 279 | |
|---|
| 264 | 280 | static inline u32 sh_cmt_read_cmcnt(struct sh_cmt_channel *ch) |
|---|
| .. | .. |
|---|
| 266 | 282 | return ch->cmt->info->read_count(ch->ioctrl, CMCNT); |
|---|
| 267 | 283 | } |
|---|
| 268 | 284 | |
|---|
| 269 | | -static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, u32 value) |
|---|
| 285 | +static inline int sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, u32 value) |
|---|
| 270 | 286 | { |
|---|
| 287 | + /* Tests showed that we need to wait 3 clocks here */ |
|---|
| 288 | + unsigned int cmcnt_delay = DIV_ROUND_UP(3 * ch->cmt->reg_delay, 2); |
|---|
| 289 | + u32 reg; |
|---|
| 290 | + |
|---|
| 291 | + if (ch->cmt->info->model > SH_CMT_16BIT) { |
|---|
| 292 | + int ret = read_poll_timeout_atomic(sh_cmt_read_cmcsr, reg, |
|---|
| 293 | + !(reg & SH_CMT32_CMCSR_WRFLG), |
|---|
| 294 | + 1, cmcnt_delay, false, ch); |
|---|
| 295 | + if (ret < 0) |
|---|
| 296 | + return ret; |
|---|
| 297 | + } |
|---|
| 298 | + |
|---|
| 271 | 299 | ch->cmt->info->write_count(ch->ioctrl, CMCNT, value); |
|---|
| 300 | + udelay(cmcnt_delay); |
|---|
| 301 | + return 0; |
|---|
| 272 | 302 | } |
|---|
| 273 | 303 | |
|---|
| 274 | 304 | static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch, u32 value) |
|---|
| 275 | 305 | { |
|---|
| 276 | | - ch->cmt->info->write_count(ch->ioctrl, CMCOR, value); |
|---|
| 306 | + u32 old_value = ch->cmt->info->read_count(ch->ioctrl, CMCOR); |
|---|
| 307 | + |
|---|
| 308 | + if (value != old_value) { |
|---|
| 309 | + ch->cmt->info->write_count(ch->ioctrl, CMCOR, value); |
|---|
| 310 | + udelay(ch->cmt->reg_delay); |
|---|
| 311 | + } |
|---|
| 277 | 312 | } |
|---|
| 278 | 313 | |
|---|
| 279 | 314 | static u32 sh_cmt_get_counter(struct sh_cmt_channel *ch, u32 *has_wrapped) |
|---|
| .. | .. |
|---|
| 317 | 352 | |
|---|
| 318 | 353 | static int sh_cmt_enable(struct sh_cmt_channel *ch) |
|---|
| 319 | 354 | { |
|---|
| 320 | | - int k, ret; |
|---|
| 355 | + int ret; |
|---|
| 321 | 356 | |
|---|
| 322 | 357 | pm_runtime_get_sync(&ch->cmt->pdev->dev); |
|---|
| 323 | 358 | dev_pm_syscore_device(&ch->cmt->pdev->dev, true); |
|---|
| .. | .. |
|---|
| 345 | 380 | } |
|---|
| 346 | 381 | |
|---|
| 347 | 382 | sh_cmt_write_cmcor(ch, 0xffffffff); |
|---|
| 348 | | - sh_cmt_write_cmcnt(ch, 0); |
|---|
| 383 | + ret = sh_cmt_write_cmcnt(ch, 0); |
|---|
| 349 | 384 | |
|---|
| 350 | | - /* |
|---|
| 351 | | - * According to the sh73a0 user's manual, as CMCNT can be operated |
|---|
| 352 | | - * only by the RCLK (Pseudo 32 kHz), there's one restriction on |
|---|
| 353 | | - * modifying CMCNT register; two RCLK cycles are necessary before |
|---|
| 354 | | - * this register is either read or any modification of the value |
|---|
| 355 | | - * it holds is reflected in the LSI's actual operation. |
|---|
| 356 | | - * |
|---|
| 357 | | - * While at it, we're supposed to clear out the CMCNT as of this |
|---|
| 358 | | - * moment, so make sure it's processed properly here. This will |
|---|
| 359 | | - * take RCLKx2 at maximum. |
|---|
| 360 | | - */ |
|---|
| 361 | | - for (k = 0; k < 100; k++) { |
|---|
| 362 | | - if (!sh_cmt_read_cmcnt(ch)) |
|---|
| 363 | | - break; |
|---|
| 364 | | - udelay(1); |
|---|
| 365 | | - } |
|---|
| 366 | | - |
|---|
| 367 | | - if (sh_cmt_read_cmcnt(ch)) { |
|---|
| 385 | + if (ret || sh_cmt_read_cmcnt(ch)) { |
|---|
| 368 | 386 | dev_err(&ch->cmt->pdev->dev, "ch%u: cannot clear CMCNT\n", |
|---|
| 369 | 387 | ch->index); |
|---|
| 370 | 388 | ret = -ETIMEDOUT; |
|---|
| .. | .. |
|---|
| 849 | 867 | unsigned int hwidx, bool clockevent, |
|---|
| 850 | 868 | bool clocksource, struct sh_cmt_device *cmt) |
|---|
| 851 | 869 | { |
|---|
| 870 | + u32 value; |
|---|
| 852 | 871 | int ret; |
|---|
| 853 | 872 | |
|---|
| 854 | 873 | /* Skip unused channels. */ |
|---|
| .. | .. |
|---|
| 878 | 897 | ch->iostart = cmt->mapbase + ch->hwidx * 0x100; |
|---|
| 879 | 898 | ch->ioctrl = ch->iostart + 0x10; |
|---|
| 880 | 899 | ch->timer_bit = 0; |
|---|
| 900 | + |
|---|
| 901 | + /* Enable the clock supply to the channel */ |
|---|
| 902 | + value = ioread32(cmt->mapbase + CMCLKE); |
|---|
| 903 | + value |= BIT(hwidx); |
|---|
| 904 | + iowrite32(value, cmt->mapbase + CMCLKE); |
|---|
| 881 | 905 | break; |
|---|
| 882 | 906 | } |
|---|
| 883 | 907 | |
|---|
| .. | .. |
|---|
| 968 | 992 | |
|---|
| 969 | 993 | static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev) |
|---|
| 970 | 994 | { |
|---|
| 971 | | - unsigned int mask; |
|---|
| 972 | | - unsigned int i; |
|---|
| 995 | + unsigned int mask, i; |
|---|
| 996 | + unsigned long rate; |
|---|
| 973 | 997 | int ret; |
|---|
| 974 | 998 | |
|---|
| 975 | 999 | cmt->pdev = pdev; |
|---|
| .. | .. |
|---|
| 1005 | 1029 | if (ret < 0) |
|---|
| 1006 | 1030 | goto err_clk_unprepare; |
|---|
| 1007 | 1031 | |
|---|
| 1008 | | - if (cmt->info->width == 16) |
|---|
| 1009 | | - cmt->rate = clk_get_rate(cmt->clk) / 512; |
|---|
| 1010 | | - else |
|---|
| 1011 | | - cmt->rate = clk_get_rate(cmt->clk) / 8; |
|---|
| 1032 | + rate = clk_get_rate(cmt->clk); |
|---|
| 1033 | + if (!rate) { |
|---|
| 1034 | + ret = -EINVAL; |
|---|
| 1035 | + goto err_clk_disable; |
|---|
| 1036 | + } |
|---|
| 1012 | 1037 | |
|---|
| 1013 | | - clk_disable(cmt->clk); |
|---|
| 1038 | + /* We shall wait 2 input clks after register writes */ |
|---|
| 1039 | + if (cmt->info->model >= SH_CMT_48BIT) |
|---|
| 1040 | + cmt->reg_delay = DIV_ROUND_UP(2UL * USEC_PER_SEC, rate); |
|---|
| 1041 | + cmt->rate = rate / (cmt->info->width == 16 ? 512 : 8); |
|---|
| 1014 | 1042 | |
|---|
| 1015 | 1043 | /* Map the memory resource(s). */ |
|---|
| 1016 | 1044 | ret = sh_cmt_map_memory(cmt); |
|---|
| 1017 | 1045 | if (ret < 0) |
|---|
| 1018 | | - goto err_clk_unprepare; |
|---|
| 1046 | + goto err_clk_disable; |
|---|
| 1019 | 1047 | |
|---|
| 1020 | 1048 | /* Allocate and setup the channels. */ |
|---|
| 1021 | 1049 | cmt->num_channels = hweight8(cmt->hw_channels); |
|---|
| .. | .. |
|---|
| 1043 | 1071 | mask &= ~(1 << hwidx); |
|---|
| 1044 | 1072 | } |
|---|
| 1045 | 1073 | |
|---|
| 1074 | + clk_disable(cmt->clk); |
|---|
| 1075 | + |
|---|
| 1046 | 1076 | platform_set_drvdata(pdev, cmt); |
|---|
| 1047 | 1077 | |
|---|
| 1048 | 1078 | return 0; |
|---|
| .. | .. |
|---|
| 1050 | 1080 | err_unmap: |
|---|
| 1051 | 1081 | kfree(cmt->channels); |
|---|
| 1052 | 1082 | iounmap(cmt->mapbase); |
|---|
| 1083 | +err_clk_disable: |
|---|
| 1084 | + clk_disable(cmt->clk); |
|---|
| 1053 | 1085 | err_clk_unprepare: |
|---|
| 1054 | 1086 | clk_unprepare(cmt->clk); |
|---|
| 1055 | 1087 | err_clk_put: |
|---|