rtc-mt2712.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2019 MediaTek Inc.
  4. * Author: Ran Bi <ran.bi@mediatek.com>
  5. */
  6. #include <linux/delay.h>
  7. #include <linux/init.h>
  8. #include <linux/io.h>
  9. #include <linux/irqdomain.h>
  10. #include <linux/module.h>
  11. #include <linux/of_address.h>
  12. #include <linux/of_irq.h>
  13. #include <linux/platform_device.h>
  14. #include <linux/rtc.h>
  15. #define MT2712_BBPU 0x0000
  16. #define MT2712_BBPU_CLRPKY BIT(4)
  17. #define MT2712_BBPU_RELOAD BIT(5)
  18. #define MT2712_BBPU_CBUSY BIT(6)
  19. #define MT2712_BBPU_KEY (0x43 << 8)
  20. #define MT2712_IRQ_STA 0x0004
  21. #define MT2712_IRQ_STA_AL BIT(0)
  22. #define MT2712_IRQ_STA_TC BIT(1)
  23. #define MT2712_IRQ_EN 0x0008
  24. #define MT2712_IRQ_EN_AL BIT(0)
  25. #define MT2712_IRQ_EN_TC BIT(1)
  26. #define MT2712_IRQ_EN_ONESHOT BIT(2)
  27. #define MT2712_CII_EN 0x000c
  28. #define MT2712_AL_MASK 0x0010
  29. #define MT2712_AL_MASK_DOW BIT(4)
  30. #define MT2712_TC_SEC 0x0014
  31. #define MT2712_TC_MIN 0x0018
  32. #define MT2712_TC_HOU 0x001c
  33. #define MT2712_TC_DOM 0x0020
  34. #define MT2712_TC_DOW 0x0024
  35. #define MT2712_TC_MTH 0x0028
  36. #define MT2712_TC_YEA 0x002c
  37. #define MT2712_AL_SEC 0x0030
  38. #define MT2712_AL_MIN 0x0034
  39. #define MT2712_AL_HOU 0x0038
  40. #define MT2712_AL_DOM 0x003c
  41. #define MT2712_AL_DOW 0x0040
  42. #define MT2712_AL_MTH 0x0044
  43. #define MT2712_AL_YEA 0x0048
  44. #define MT2712_SEC_MASK 0x003f
  45. #define MT2712_MIN_MASK 0x003f
  46. #define MT2712_HOU_MASK 0x001f
  47. #define MT2712_DOM_MASK 0x001f
  48. #define MT2712_DOW_MASK 0x0007
  49. #define MT2712_MTH_MASK 0x000f
  50. #define MT2712_YEA_MASK 0x007f
  51. #define MT2712_POWERKEY1 0x004c
  52. #define MT2712_POWERKEY2 0x0050
  53. #define MT2712_POWERKEY1_KEY 0xa357
  54. #define MT2712_POWERKEY2_KEY 0x67d2
  55. #define MT2712_CON0 0x005c
  56. #define MT2712_CON1 0x0060
  57. #define MT2712_PROT 0x0070
  58. #define MT2712_PROT_UNLOCK1 0x9136
  59. #define MT2712_PROT_UNLOCK2 0x586a
  60. #define MT2712_WRTGR 0x0078
  61. #define MT2712_RTC_TIMESTAMP_END_2127 4985971199LL
  62. struct mt2712_rtc {
  63. struct rtc_device *rtc;
  64. void __iomem *base;
  65. int irq;
  66. u8 irq_wake_enabled;
  67. u8 powerlost;
  68. };
  69. static inline u32 mt2712_readl(struct mt2712_rtc *mt2712_rtc, u32 reg)
  70. {
  71. return readl(mt2712_rtc->base + reg);
  72. }
  73. static inline void mt2712_writel(struct mt2712_rtc *mt2712_rtc,
  74. u32 reg, u32 val)
  75. {
  76. writel(val, mt2712_rtc->base + reg);
  77. }
  78. static void mt2712_rtc_write_trigger(struct mt2712_rtc *mt2712_rtc)
  79. {
  80. unsigned long timeout = jiffies + HZ / 10;
  81. mt2712_writel(mt2712_rtc, MT2712_WRTGR, 1);
  82. while (1) {
  83. if (!(mt2712_readl(mt2712_rtc, MT2712_BBPU)
  84. & MT2712_BBPU_CBUSY))
  85. break;
  86. if (time_after(jiffies, timeout)) {
  87. dev_err(&mt2712_rtc->rtc->dev,
  88. "%s time out!\n", __func__);
  89. break;
  90. }
  91. cpu_relax();
  92. }
  93. }
  94. static void mt2712_rtc_writeif_unlock(struct mt2712_rtc *mt2712_rtc)
  95. {
  96. mt2712_writel(mt2712_rtc, MT2712_PROT, MT2712_PROT_UNLOCK1);
  97. mt2712_rtc_write_trigger(mt2712_rtc);
  98. mt2712_writel(mt2712_rtc, MT2712_PROT, MT2712_PROT_UNLOCK2);
  99. mt2712_rtc_write_trigger(mt2712_rtc);
  100. }
  101. static irqreturn_t rtc_irq_handler_thread(int irq, void *data)
  102. {
  103. struct mt2712_rtc *mt2712_rtc = data;
  104. u16 irqsta;
  105. /* Clear interrupt */
  106. irqsta = mt2712_readl(mt2712_rtc, MT2712_IRQ_STA);
  107. if (irqsta & MT2712_IRQ_STA_AL) {
  108. rtc_update_irq(mt2712_rtc->rtc, 1, RTC_IRQF | RTC_AF);
  109. return IRQ_HANDLED;
  110. }
  111. return IRQ_NONE;
  112. }
  113. static void __mt2712_rtc_read_time(struct mt2712_rtc *mt2712_rtc,
  114. struct rtc_time *tm, int *sec)
  115. {
  116. tm->tm_sec = mt2712_readl(mt2712_rtc, MT2712_TC_SEC)
  117. & MT2712_SEC_MASK;
  118. tm->tm_min = mt2712_readl(mt2712_rtc, MT2712_TC_MIN)
  119. & MT2712_MIN_MASK;
  120. tm->tm_hour = mt2712_readl(mt2712_rtc, MT2712_TC_HOU)
  121. & MT2712_HOU_MASK;
  122. tm->tm_mday = mt2712_readl(mt2712_rtc, MT2712_TC_DOM)
  123. & MT2712_DOM_MASK;
  124. tm->tm_mon = (mt2712_readl(mt2712_rtc, MT2712_TC_MTH) - 1)
  125. & MT2712_MTH_MASK;
  126. tm->tm_year = (mt2712_readl(mt2712_rtc, MT2712_TC_YEA) + 100)
  127. & MT2712_YEA_MASK;
  128. *sec = mt2712_readl(mt2712_rtc, MT2712_TC_SEC) & MT2712_SEC_MASK;
  129. }
  130. static int mt2712_rtc_read_time(struct device *dev, struct rtc_time *tm)
  131. {
  132. struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
  133. int sec;
  134. if (mt2712_rtc->powerlost)
  135. return -EINVAL;
  136. do {
  137. __mt2712_rtc_read_time(mt2712_rtc, tm, &sec);
  138. } while (sec < tm->tm_sec); /* SEC has carried */
  139. return 0;
  140. }
  141. static int mt2712_rtc_set_time(struct device *dev, struct rtc_time *tm)
  142. {
  143. struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
  144. mt2712_writel(mt2712_rtc, MT2712_TC_SEC, tm->tm_sec & MT2712_SEC_MASK);
  145. mt2712_writel(mt2712_rtc, MT2712_TC_MIN, tm->tm_min & MT2712_MIN_MASK);
  146. mt2712_writel(mt2712_rtc, MT2712_TC_HOU, tm->tm_hour & MT2712_HOU_MASK);
  147. mt2712_writel(mt2712_rtc, MT2712_TC_DOM, tm->tm_mday & MT2712_DOM_MASK);
  148. mt2712_writel(mt2712_rtc, MT2712_TC_MTH,
  149. (tm->tm_mon + 1) & MT2712_MTH_MASK);
  150. mt2712_writel(mt2712_rtc, MT2712_TC_YEA,
  151. (tm->tm_year - 100) & MT2712_YEA_MASK);
  152. mt2712_rtc_write_trigger(mt2712_rtc);
  153. if (mt2712_rtc->powerlost)
  154. mt2712_rtc->powerlost = false;
  155. return 0;
  156. }
  157. static int mt2712_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
  158. {
  159. struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
  160. struct rtc_time *tm = &alm->time;
  161. u16 irqen;
  162. irqen = mt2712_readl(mt2712_rtc, MT2712_IRQ_EN);
  163. alm->enabled = !!(irqen & MT2712_IRQ_EN_AL);
  164. tm->tm_sec = mt2712_readl(mt2712_rtc, MT2712_AL_SEC) & MT2712_SEC_MASK;
  165. tm->tm_min = mt2712_readl(mt2712_rtc, MT2712_AL_MIN) & MT2712_MIN_MASK;
  166. tm->tm_hour = mt2712_readl(mt2712_rtc, MT2712_AL_HOU) & MT2712_HOU_MASK;
  167. tm->tm_mday = mt2712_readl(mt2712_rtc, MT2712_AL_DOM) & MT2712_DOM_MASK;
  168. tm->tm_mon = (mt2712_readl(mt2712_rtc, MT2712_AL_MTH) - 1)
  169. & MT2712_MTH_MASK;
  170. tm->tm_year = (mt2712_readl(mt2712_rtc, MT2712_AL_YEA) + 100)
  171. & MT2712_YEA_MASK;
  172. return 0;
  173. }
  174. static int mt2712_rtc_alarm_irq_enable(struct device *dev,
  175. unsigned int enabled)
  176. {
  177. struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
  178. u16 irqen;
  179. irqen = mt2712_readl(mt2712_rtc, MT2712_IRQ_EN);
  180. if (enabled)
  181. irqen |= MT2712_IRQ_EN_AL;
  182. else
  183. irqen &= ~MT2712_IRQ_EN_AL;
  184. mt2712_writel(mt2712_rtc, MT2712_IRQ_EN, irqen);
  185. mt2712_rtc_write_trigger(mt2712_rtc);
  186. return 0;
  187. }
  188. static int mt2712_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
  189. {
  190. struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
  191. struct rtc_time *tm = &alm->time;
  192. dev_dbg(&mt2712_rtc->rtc->dev, "set al time: %ptR, alm en: %d\n",
  193. tm, alm->enabled);
  194. mt2712_writel(mt2712_rtc, MT2712_AL_SEC,
  195. (mt2712_readl(mt2712_rtc, MT2712_AL_SEC)
  196. & ~(MT2712_SEC_MASK)) | (tm->tm_sec & MT2712_SEC_MASK));
  197. mt2712_writel(mt2712_rtc, MT2712_AL_MIN,
  198. (mt2712_readl(mt2712_rtc, MT2712_AL_MIN)
  199. & ~(MT2712_MIN_MASK)) | (tm->tm_min & MT2712_MIN_MASK));
  200. mt2712_writel(mt2712_rtc, MT2712_AL_HOU,
  201. (mt2712_readl(mt2712_rtc, MT2712_AL_HOU)
  202. & ~(MT2712_HOU_MASK)) | (tm->tm_hour & MT2712_HOU_MASK));
  203. mt2712_writel(mt2712_rtc, MT2712_AL_DOM,
  204. (mt2712_readl(mt2712_rtc, MT2712_AL_DOM)
  205. & ~(MT2712_DOM_MASK)) | (tm->tm_mday & MT2712_DOM_MASK));
  206. mt2712_writel(mt2712_rtc, MT2712_AL_MTH,
  207. (mt2712_readl(mt2712_rtc, MT2712_AL_MTH)
  208. & ~(MT2712_MTH_MASK))
  209. | ((tm->tm_mon + 1) & MT2712_MTH_MASK));
  210. mt2712_writel(mt2712_rtc, MT2712_AL_YEA,
  211. (mt2712_readl(mt2712_rtc, MT2712_AL_YEA)
  212. & ~(MT2712_YEA_MASK))
  213. | ((tm->tm_year - 100) & MT2712_YEA_MASK));
  214. /* mask day of week */
  215. mt2712_writel(mt2712_rtc, MT2712_AL_MASK, MT2712_AL_MASK_DOW);
  216. mt2712_rtc_write_trigger(mt2712_rtc);
  217. mt2712_rtc_alarm_irq_enable(dev, alm->enabled);
  218. return 0;
  219. }
  220. /* Init RTC register */
  221. static void mt2712_rtc_hw_init(struct mt2712_rtc *mt2712_rtc)
  222. {
  223. u32 p1, p2;
  224. mt2712_writel(mt2712_rtc, MT2712_BBPU,
  225. MT2712_BBPU_KEY | MT2712_BBPU_RELOAD);
  226. mt2712_writel(mt2712_rtc, MT2712_CII_EN, 0);
  227. mt2712_writel(mt2712_rtc, MT2712_AL_MASK, 0);
  228. /* necessary before set MT2712_POWERKEY */
  229. mt2712_writel(mt2712_rtc, MT2712_CON0, 0x4848);
  230. mt2712_writel(mt2712_rtc, MT2712_CON1, 0x0048);
  231. mt2712_rtc_write_trigger(mt2712_rtc);
  232. p1 = mt2712_readl(mt2712_rtc, MT2712_POWERKEY1);
  233. p2 = mt2712_readl(mt2712_rtc, MT2712_POWERKEY2);
  234. if (p1 != MT2712_POWERKEY1_KEY || p2 != MT2712_POWERKEY2_KEY) {
  235. mt2712_rtc->powerlost = true;
  236. dev_dbg(&mt2712_rtc->rtc->dev,
  237. "powerkey not set (lost power)\n");
  238. } else {
  239. mt2712_rtc->powerlost = false;
  240. }
  241. /* RTC need POWERKEY1/2 match, then goto normal work mode */
  242. mt2712_writel(mt2712_rtc, MT2712_POWERKEY1, MT2712_POWERKEY1_KEY);
  243. mt2712_writel(mt2712_rtc, MT2712_POWERKEY2, MT2712_POWERKEY2_KEY);
  244. mt2712_rtc_write_trigger(mt2712_rtc);
  245. mt2712_rtc_writeif_unlock(mt2712_rtc);
  246. }
  247. static const struct rtc_class_ops mt2712_rtc_ops = {
  248. .read_time = mt2712_rtc_read_time,
  249. .set_time = mt2712_rtc_set_time,
  250. .read_alarm = mt2712_rtc_read_alarm,
  251. .set_alarm = mt2712_rtc_set_alarm,
  252. .alarm_irq_enable = mt2712_rtc_alarm_irq_enable,
  253. };
  254. static int mt2712_rtc_probe(struct platform_device *pdev)
  255. {
  256. struct mt2712_rtc *mt2712_rtc;
  257. int ret;
  258. mt2712_rtc = devm_kzalloc(&pdev->dev,
  259. sizeof(struct mt2712_rtc), GFP_KERNEL);
  260. if (!mt2712_rtc)
  261. return -ENOMEM;
  262. mt2712_rtc->base = devm_platform_ioremap_resource(pdev, 0);
  263. if (IS_ERR(mt2712_rtc->base))
  264. return PTR_ERR(mt2712_rtc->base);
  265. /* rtc hw init */
  266. mt2712_rtc_hw_init(mt2712_rtc);
  267. mt2712_rtc->irq = platform_get_irq(pdev, 0);
  268. if (mt2712_rtc->irq < 0)
  269. return mt2712_rtc->irq;
  270. platform_set_drvdata(pdev, mt2712_rtc);
  271. mt2712_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
  272. if (IS_ERR(mt2712_rtc->rtc))
  273. return PTR_ERR(mt2712_rtc->rtc);
  274. ret = devm_request_threaded_irq(&pdev->dev, mt2712_rtc->irq, NULL,
  275. rtc_irq_handler_thread,
  276. IRQF_ONESHOT | IRQF_TRIGGER_LOW,
  277. dev_name(&mt2712_rtc->rtc->dev),
  278. mt2712_rtc);
  279. if (ret) {
  280. dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
  281. mt2712_rtc->irq, ret);
  282. return ret;
  283. }
  284. device_init_wakeup(&pdev->dev, true);
  285. mt2712_rtc->rtc->ops = &mt2712_rtc_ops;
  286. mt2712_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
  287. mt2712_rtc->rtc->range_max = MT2712_RTC_TIMESTAMP_END_2127;
  288. return rtc_register_device(mt2712_rtc->rtc);
  289. }
  290. #ifdef CONFIG_PM_SLEEP
  291. static int mt2712_rtc_suspend(struct device *dev)
  292. {
  293. int wake_status = 0;
  294. struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
  295. if (device_may_wakeup(dev)) {
  296. wake_status = enable_irq_wake(mt2712_rtc->irq);
  297. if (!wake_status)
  298. mt2712_rtc->irq_wake_enabled = true;
  299. }
  300. return 0;
  301. }
  302. static int mt2712_rtc_resume(struct device *dev)
  303. {
  304. int wake_status = 0;
  305. struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
  306. if (device_may_wakeup(dev) && mt2712_rtc->irq_wake_enabled) {
  307. wake_status = disable_irq_wake(mt2712_rtc->irq);
  308. if (!wake_status)
  309. mt2712_rtc->irq_wake_enabled = false;
  310. }
  311. return 0;
  312. }
  313. static SIMPLE_DEV_PM_OPS(mt2712_pm_ops, mt2712_rtc_suspend,
  314. mt2712_rtc_resume);
  315. #endif
  316. static const struct of_device_id mt2712_rtc_of_match[] = {
  317. { .compatible = "mediatek,mt2712-rtc", },
  318. { },
  319. };
  320. MODULE_DEVICE_TABLE(of, mt2712_rtc_of_match);
  321. static struct platform_driver mt2712_rtc_driver = {
  322. .driver = {
  323. .name = "mt2712-rtc",
  324. .of_match_table = mt2712_rtc_of_match,
  325. #ifdef CONFIG_PM_SLEEP
  326. .pm = &mt2712_pm_ops,
  327. #endif
  328. },
  329. .probe = mt2712_rtc_probe,
  330. };
  331. module_platform_driver(mt2712_rtc_driver);
  332. MODULE_DESCRIPTION("MediaTek MT2712 SoC based RTC Driver");
  333. MODULE_AUTHOR("Ran Bi <ran.bi@mediatek.com>");
  334. MODULE_LICENSE("GPL");