timer-imx-gpt.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. // SPDX-License-Identifier: GPL-2.0+
  2. //
  3. // Copyright (C) 2000-2001 Deep Blue Solutions
  4. // Copyright (C) 2002 Shane Nay (shane@minirl.com)
  5. // Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
  6. // Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
  7. #include <linux/interrupt.h>
  8. #include <linux/irq.h>
  9. #include <linux/clockchips.h>
  10. #include <linux/clk.h>
  11. #include <linux/delay.h>
  12. #include <linux/err.h>
  13. #include <linux/sched_clock.h>
  14. #include <linux/slab.h>
  15. #include <linux/of.h>
  16. #include <linux/of_address.h>
  17. #include <linux/of_irq.h>
  18. #include <soc/imx/timer.h>
  19. /*
  20. * There are 4 versions of the timer hardware on Freescale MXC hardware.
  21. * - MX1/MXL
  22. * - MX21, MX27.
  23. * - MX25, MX31, MX35, MX37, MX51, MX6Q(rev1.0)
  24. * - MX6DL, MX6SX, MX6Q(rev1.1+)
  25. */
  26. /* defines common for all i.MX */
  27. #define MXC_TCTL 0x00
  28. #define MXC_TCTL_TEN (1 << 0) /* Enable module */
  29. #define MXC_TPRER 0x04
  30. /* MX1, MX21, MX27 */
  31. #define MX1_2_TCTL_CLK_PCLK1 (1 << 1)
  32. #define MX1_2_TCTL_IRQEN (1 << 4)
  33. #define MX1_2_TCTL_FRR (1 << 8)
  34. #define MX1_2_TCMP 0x08
  35. #define MX1_2_TCN 0x10
  36. #define MX1_2_TSTAT 0x14
  37. /* MX21, MX27 */
  38. #define MX2_TSTAT_CAPT (1 << 1)
  39. #define MX2_TSTAT_COMP (1 << 0)
  40. /* MX31, MX35, MX25, MX5, MX6 */
  41. #define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */
  42. #define V2_TCTL_CLK_IPG (1 << 6)
  43. #define V2_TCTL_CLK_PER (2 << 6)
  44. #define V2_TCTL_CLK_OSC_DIV8 (5 << 6)
  45. #define V2_TCTL_FRR (1 << 9)
  46. #define V2_TCTL_24MEN (1 << 10)
  47. #define V2_TPRER_PRE24M 12
  48. #define V2_IR 0x0c
  49. #define V2_TSTAT 0x08
  50. #define V2_TSTAT_OF1 (1 << 0)
  51. #define V2_TCN 0x24
  52. #define V2_TCMP 0x10
  53. #define V2_TIMER_RATE_OSC_DIV8 3000000
  54. struct imx_timer {
  55. enum imx_gpt_type type;
  56. void __iomem *base;
  57. int irq;
  58. struct clk *clk_per;
  59. struct clk *clk_ipg;
  60. const struct imx_gpt_data *gpt;
  61. struct clock_event_device ced;
  62. };
  63. struct imx_gpt_data {
  64. int reg_tstat;
  65. int reg_tcn;
  66. int reg_tcmp;
  67. void (*gpt_setup_tctl)(struct imx_timer *imxtm);
  68. void (*gpt_irq_enable)(struct imx_timer *imxtm);
  69. void (*gpt_irq_disable)(struct imx_timer *imxtm);
  70. void (*gpt_irq_acknowledge)(struct imx_timer *imxtm);
  71. int (*set_next_event)(unsigned long evt,
  72. struct clock_event_device *ced);
  73. };
  74. static inline struct imx_timer *to_imx_timer(struct clock_event_device *ced)
  75. {
  76. return container_of(ced, struct imx_timer, ced);
  77. }
  78. static void imx1_gpt_irq_disable(struct imx_timer *imxtm)
  79. {
  80. unsigned int tmp;
  81. tmp = readl_relaxed(imxtm->base + MXC_TCTL);
  82. writel_relaxed(tmp & ~MX1_2_TCTL_IRQEN, imxtm->base + MXC_TCTL);
  83. }
  84. #define imx21_gpt_irq_disable imx1_gpt_irq_disable
  85. static void imx31_gpt_irq_disable(struct imx_timer *imxtm)
  86. {
  87. writel_relaxed(0, imxtm->base + V2_IR);
  88. }
  89. #define imx6dl_gpt_irq_disable imx31_gpt_irq_disable
  90. static void imx1_gpt_irq_enable(struct imx_timer *imxtm)
  91. {
  92. unsigned int tmp;
  93. tmp = readl_relaxed(imxtm->base + MXC_TCTL);
  94. writel_relaxed(tmp | MX1_2_TCTL_IRQEN, imxtm->base + MXC_TCTL);
  95. }
  96. #define imx21_gpt_irq_enable imx1_gpt_irq_enable
  97. static void imx31_gpt_irq_enable(struct imx_timer *imxtm)
  98. {
  99. writel_relaxed(1<<0, imxtm->base + V2_IR);
  100. }
  101. #define imx6dl_gpt_irq_enable imx31_gpt_irq_enable
  102. static void imx1_gpt_irq_acknowledge(struct imx_timer *imxtm)
  103. {
  104. writel_relaxed(0, imxtm->base + MX1_2_TSTAT);
  105. }
  106. static void imx21_gpt_irq_acknowledge(struct imx_timer *imxtm)
  107. {
  108. writel_relaxed(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
  109. imxtm->base + MX1_2_TSTAT);
  110. }
  111. static void imx31_gpt_irq_acknowledge(struct imx_timer *imxtm)
  112. {
  113. writel_relaxed(V2_TSTAT_OF1, imxtm->base + V2_TSTAT);
  114. }
  115. #define imx6dl_gpt_irq_acknowledge imx31_gpt_irq_acknowledge
  116. static void __iomem *sched_clock_reg;
  117. static u64 notrace mxc_read_sched_clock(void)
  118. {
  119. return sched_clock_reg ? readl_relaxed(sched_clock_reg) : 0;
  120. }
  121. #if defined(CONFIG_ARM)
  122. static struct delay_timer imx_delay_timer;
  123. static unsigned long imx_read_current_timer(void)
  124. {
  125. return readl_relaxed(sched_clock_reg);
  126. }
  127. #endif
  128. static int __init mxc_clocksource_init(struct imx_timer *imxtm)
  129. {
  130. unsigned int c = clk_get_rate(imxtm->clk_per);
  131. void __iomem *reg = imxtm->base + imxtm->gpt->reg_tcn;
  132. #if defined(CONFIG_ARM)
  133. imx_delay_timer.read_current_timer = &imx_read_current_timer;
  134. imx_delay_timer.freq = c;
  135. register_current_timer_delay(&imx_delay_timer);
  136. #endif
  137. sched_clock_reg = reg;
  138. sched_clock_register(mxc_read_sched_clock, 32, c);
  139. return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32,
  140. clocksource_mmio_readl_up);
  141. }
  142. /* clock event */
  143. static int mx1_2_set_next_event(unsigned long evt,
  144. struct clock_event_device *ced)
  145. {
  146. struct imx_timer *imxtm = to_imx_timer(ced);
  147. unsigned long tcmp;
  148. tcmp = readl_relaxed(imxtm->base + MX1_2_TCN) + evt;
  149. writel_relaxed(tcmp, imxtm->base + MX1_2_TCMP);
  150. return (int)(tcmp - readl_relaxed(imxtm->base + MX1_2_TCN)) < 0 ?
  151. -ETIME : 0;
  152. }
  153. static int v2_set_next_event(unsigned long evt,
  154. struct clock_event_device *ced)
  155. {
  156. struct imx_timer *imxtm = to_imx_timer(ced);
  157. unsigned long tcmp;
  158. tcmp = readl_relaxed(imxtm->base + V2_TCN) + evt;
  159. writel_relaxed(tcmp, imxtm->base + V2_TCMP);
  160. return evt < 0x7fffffff &&
  161. (int)(tcmp - readl_relaxed(imxtm->base + V2_TCN)) < 0 ?
  162. -ETIME : 0;
  163. }
  164. static int mxc_shutdown(struct clock_event_device *ced)
  165. {
  166. struct imx_timer *imxtm = to_imx_timer(ced);
  167. u32 tcn;
  168. /* Disable interrupt in GPT module */
  169. imxtm->gpt->gpt_irq_disable(imxtm);
  170. tcn = readl_relaxed(imxtm->base + imxtm->gpt->reg_tcn);
  171. /* Set event time into far-far future */
  172. writel_relaxed(tcn - 3, imxtm->base + imxtm->gpt->reg_tcmp);
  173. /* Clear pending interrupt */
  174. imxtm->gpt->gpt_irq_acknowledge(imxtm);
  175. #ifdef DEBUG
  176. printk(KERN_INFO "%s: changing mode\n", __func__);
  177. #endif /* DEBUG */
  178. return 0;
  179. }
  180. static int mxc_set_oneshot(struct clock_event_device *ced)
  181. {
  182. struct imx_timer *imxtm = to_imx_timer(ced);
  183. /* Disable interrupt in GPT module */
  184. imxtm->gpt->gpt_irq_disable(imxtm);
  185. if (!clockevent_state_oneshot(ced)) {
  186. u32 tcn = readl_relaxed(imxtm->base + imxtm->gpt->reg_tcn);
  187. /* Set event time into far-far future */
  188. writel_relaxed(tcn - 3, imxtm->base + imxtm->gpt->reg_tcmp);
  189. /* Clear pending interrupt */
  190. imxtm->gpt->gpt_irq_acknowledge(imxtm);
  191. }
  192. #ifdef DEBUG
  193. printk(KERN_INFO "%s: changing mode\n", __func__);
  194. #endif /* DEBUG */
  195. /*
  196. * Do not put overhead of interrupt enable/disable into
  197. * mxc_set_next_event(), the core has about 4 minutes
  198. * to call mxc_set_next_event() or shutdown clock after
  199. * mode switching
  200. */
  201. imxtm->gpt->gpt_irq_enable(imxtm);
  202. return 0;
  203. }
  204. /*
  205. * IRQ handler for the timer
  206. */
  207. static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
  208. {
  209. struct clock_event_device *ced = dev_id;
  210. struct imx_timer *imxtm = to_imx_timer(ced);
  211. uint32_t tstat;
  212. tstat = readl_relaxed(imxtm->base + imxtm->gpt->reg_tstat);
  213. imxtm->gpt->gpt_irq_acknowledge(imxtm);
  214. ced->event_handler(ced);
  215. return IRQ_HANDLED;
  216. }
  217. static int __init mxc_clockevent_init(struct imx_timer *imxtm)
  218. {
  219. struct clock_event_device *ced = &imxtm->ced;
  220. ced->name = "mxc_timer1";
  221. ced->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ;
  222. ced->set_state_shutdown = mxc_shutdown;
  223. ced->set_state_oneshot = mxc_set_oneshot;
  224. ced->tick_resume = mxc_shutdown;
  225. ced->set_next_event = imxtm->gpt->set_next_event;
  226. ced->rating = 200;
  227. ced->cpumask = cpumask_of(0);
  228. ced->irq = imxtm->irq;
  229. clockevents_config_and_register(ced, clk_get_rate(imxtm->clk_per),
  230. 0xff, 0xfffffffe);
  231. return request_irq(imxtm->irq, mxc_timer_interrupt,
  232. IRQF_TIMER | IRQF_IRQPOLL, "i.MX Timer Tick", ced);
  233. }
  234. static void imx1_gpt_setup_tctl(struct imx_timer *imxtm)
  235. {
  236. u32 tctl_val;
  237. tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
  238. writel_relaxed(tctl_val, imxtm->base + MXC_TCTL);
  239. }
  240. #define imx21_gpt_setup_tctl imx1_gpt_setup_tctl
  241. static void imx31_gpt_setup_tctl(struct imx_timer *imxtm)
  242. {
  243. u32 tctl_val;
  244. tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
  245. if (clk_get_rate(imxtm->clk_per) == V2_TIMER_RATE_OSC_DIV8)
  246. tctl_val |= V2_TCTL_CLK_OSC_DIV8;
  247. else
  248. tctl_val |= V2_TCTL_CLK_PER;
  249. writel_relaxed(tctl_val, imxtm->base + MXC_TCTL);
  250. }
  251. static void imx6dl_gpt_setup_tctl(struct imx_timer *imxtm)
  252. {
  253. u32 tctl_val;
  254. tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
  255. if (clk_get_rate(imxtm->clk_per) == V2_TIMER_RATE_OSC_DIV8) {
  256. tctl_val |= V2_TCTL_CLK_OSC_DIV8;
  257. /* 24 / 8 = 3 MHz */
  258. writel_relaxed(7 << V2_TPRER_PRE24M, imxtm->base + MXC_TPRER);
  259. tctl_val |= V2_TCTL_24MEN;
  260. } else {
  261. tctl_val |= V2_TCTL_CLK_PER;
  262. }
  263. writel_relaxed(tctl_val, imxtm->base + MXC_TCTL);
  264. }
  265. static const struct imx_gpt_data imx1_gpt_data = {
  266. .reg_tstat = MX1_2_TSTAT,
  267. .reg_tcn = MX1_2_TCN,
  268. .reg_tcmp = MX1_2_TCMP,
  269. .gpt_irq_enable = imx1_gpt_irq_enable,
  270. .gpt_irq_disable = imx1_gpt_irq_disable,
  271. .gpt_irq_acknowledge = imx1_gpt_irq_acknowledge,
  272. .gpt_setup_tctl = imx1_gpt_setup_tctl,
  273. .set_next_event = mx1_2_set_next_event,
  274. };
  275. static const struct imx_gpt_data imx21_gpt_data = {
  276. .reg_tstat = MX1_2_TSTAT,
  277. .reg_tcn = MX1_2_TCN,
  278. .reg_tcmp = MX1_2_TCMP,
  279. .gpt_irq_enable = imx21_gpt_irq_enable,
  280. .gpt_irq_disable = imx21_gpt_irq_disable,
  281. .gpt_irq_acknowledge = imx21_gpt_irq_acknowledge,
  282. .gpt_setup_tctl = imx21_gpt_setup_tctl,
  283. .set_next_event = mx1_2_set_next_event,
  284. };
  285. static const struct imx_gpt_data imx31_gpt_data = {
  286. .reg_tstat = V2_TSTAT,
  287. .reg_tcn = V2_TCN,
  288. .reg_tcmp = V2_TCMP,
  289. .gpt_irq_enable = imx31_gpt_irq_enable,
  290. .gpt_irq_disable = imx31_gpt_irq_disable,
  291. .gpt_irq_acknowledge = imx31_gpt_irq_acknowledge,
  292. .gpt_setup_tctl = imx31_gpt_setup_tctl,
  293. .set_next_event = v2_set_next_event,
  294. };
  295. static const struct imx_gpt_data imx6dl_gpt_data = {
  296. .reg_tstat = V2_TSTAT,
  297. .reg_tcn = V2_TCN,
  298. .reg_tcmp = V2_TCMP,
  299. .gpt_irq_enable = imx6dl_gpt_irq_enable,
  300. .gpt_irq_disable = imx6dl_gpt_irq_disable,
  301. .gpt_irq_acknowledge = imx6dl_gpt_irq_acknowledge,
  302. .gpt_setup_tctl = imx6dl_gpt_setup_tctl,
  303. .set_next_event = v2_set_next_event,
  304. };
  305. static int __init _mxc_timer_init(struct imx_timer *imxtm)
  306. {
  307. int ret;
  308. switch (imxtm->type) {
  309. case GPT_TYPE_IMX1:
  310. imxtm->gpt = &imx1_gpt_data;
  311. break;
  312. case GPT_TYPE_IMX21:
  313. imxtm->gpt = &imx21_gpt_data;
  314. break;
  315. case GPT_TYPE_IMX31:
  316. imxtm->gpt = &imx31_gpt_data;
  317. break;
  318. case GPT_TYPE_IMX6DL:
  319. imxtm->gpt = &imx6dl_gpt_data;
  320. break;
  321. default:
  322. return -EINVAL;
  323. }
  324. if (IS_ERR(imxtm->clk_per)) {
  325. pr_err("i.MX timer: unable to get clk\n");
  326. return PTR_ERR(imxtm->clk_per);
  327. }
  328. if (!IS_ERR(imxtm->clk_ipg))
  329. clk_prepare_enable(imxtm->clk_ipg);
  330. clk_prepare_enable(imxtm->clk_per);
  331. /*
  332. * Initialise to a known state (all timers off, and timing reset)
  333. */
  334. writel_relaxed(0, imxtm->base + MXC_TCTL);
  335. writel_relaxed(0, imxtm->base + MXC_TPRER); /* see datasheet note */
  336. imxtm->gpt->gpt_setup_tctl(imxtm);
  337. /* init and register the timer to the framework */
  338. ret = mxc_clocksource_init(imxtm);
  339. if (ret)
  340. return ret;
  341. return mxc_clockevent_init(imxtm);
  342. }
  343. void __init mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type)
  344. {
  345. struct imx_timer *imxtm;
  346. imxtm = kzalloc(sizeof(*imxtm), GFP_KERNEL);
  347. BUG_ON(!imxtm);
  348. imxtm->clk_per = clk_get_sys("imx-gpt.0", "per");
  349. imxtm->clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
  350. imxtm->base = ioremap(pbase, SZ_4K);
  351. BUG_ON(!imxtm->base);
  352. imxtm->type = type;
  353. imxtm->irq = irq;
  354. _mxc_timer_init(imxtm);
  355. }
  356. static int __init mxc_timer_init_dt(struct device_node *np, enum imx_gpt_type type)
  357. {
  358. struct imx_timer *imxtm;
  359. static int initialized;
  360. int ret;
  361. /* Support one instance only */
  362. if (initialized)
  363. return 0;
  364. imxtm = kzalloc(sizeof(*imxtm), GFP_KERNEL);
  365. if (!imxtm)
  366. return -ENOMEM;
  367. imxtm->base = of_iomap(np, 0);
  368. if (!imxtm->base)
  369. return -ENXIO;
  370. imxtm->irq = irq_of_parse_and_map(np, 0);
  371. if (imxtm->irq <= 0)
  372. return -EINVAL;
  373. imxtm->clk_ipg = of_clk_get_by_name(np, "ipg");
  374. /* Try osc_per first, and fall back to per otherwise */
  375. imxtm->clk_per = of_clk_get_by_name(np, "osc_per");
  376. if (IS_ERR(imxtm->clk_per))
  377. imxtm->clk_per = of_clk_get_by_name(np, "per");
  378. imxtm->type = type;
  379. ret = _mxc_timer_init(imxtm);
  380. if (ret)
  381. return ret;
  382. initialized = 1;
  383. return 0;
  384. }
  385. static int __init imx1_timer_init_dt(struct device_node *np)
  386. {
  387. return mxc_timer_init_dt(np, GPT_TYPE_IMX1);
  388. }
  389. static int __init imx21_timer_init_dt(struct device_node *np)
  390. {
  391. return mxc_timer_init_dt(np, GPT_TYPE_IMX21);
  392. }
  393. static int __init imx31_timer_init_dt(struct device_node *np)
  394. {
  395. enum imx_gpt_type type = GPT_TYPE_IMX31;
  396. /*
  397. * We were using the same compatible string for i.MX6Q/D and i.MX6DL/S
  398. * GPT device, while they actually have different programming model.
  399. * This is a workaround to keep the existing i.MX6DL/S DTBs continue
  400. * working with the new kernel.
  401. */
  402. if (of_machine_is_compatible("fsl,imx6dl"))
  403. type = GPT_TYPE_IMX6DL;
  404. return mxc_timer_init_dt(np, type);
  405. }
  406. static int __init imx6dl_timer_init_dt(struct device_node *np)
  407. {
  408. return mxc_timer_init_dt(np, GPT_TYPE_IMX6DL);
  409. }
  410. TIMER_OF_DECLARE(imx1_timer, "fsl,imx1-gpt", imx1_timer_init_dt);
  411. TIMER_OF_DECLARE(imx21_timer, "fsl,imx21-gpt", imx21_timer_init_dt);
  412. TIMER_OF_DECLARE(imx27_timer, "fsl,imx27-gpt", imx21_timer_init_dt);
  413. TIMER_OF_DECLARE(imx31_timer, "fsl,imx31-gpt", imx31_timer_init_dt);
  414. TIMER_OF_DECLARE(imx25_timer, "fsl,imx25-gpt", imx31_timer_init_dt);
  415. TIMER_OF_DECLARE(imx50_timer, "fsl,imx50-gpt", imx31_timer_init_dt);
  416. TIMER_OF_DECLARE(imx51_timer, "fsl,imx51-gpt", imx31_timer_init_dt);
  417. TIMER_OF_DECLARE(imx53_timer, "fsl,imx53-gpt", imx31_timer_init_dt);
  418. TIMER_OF_DECLARE(imx6q_timer, "fsl,imx6q-gpt", imx31_timer_init_dt);
  419. TIMER_OF_DECLARE(imx6dl_timer, "fsl,imx6dl-gpt", imx6dl_timer_init_dt);
  420. TIMER_OF_DECLARE(imx6sl_timer, "fsl,imx6sl-gpt", imx6dl_timer_init_dt);
  421. TIMER_OF_DECLARE(imx6sx_timer, "fsl,imx6sx-gpt", imx6dl_timer_init_dt);