Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 /*
0004  * Copyright 2019 Cadence
0005  *
0006  * Authors:
0007  *  Jan Kotas <jank@cadence.com>
0008  */
0009 
0010 #include <linux/module.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/of.h>
0013 #include <linux/io.h>
0014 #include <linux/rtc.h>
0015 #include <linux/clk.h>
0016 #include <linux/bcd.h>
0017 #include <linux/bitfield.h>
0018 #include <linux/interrupt.h>
0019 #include <linux/pm_wakeirq.h>
0020 
0021 /* Registers */
0022 #define CDNS_RTC_CTLR       0x00
0023 #define CDNS_RTC_HMR        0x04
0024 #define CDNS_RTC_TIMR       0x08
0025 #define CDNS_RTC_CALR       0x0C
0026 #define CDNS_RTC_TIMAR      0x10
0027 #define CDNS_RTC_CALAR      0x14
0028 #define CDNS_RTC_AENR       0x18
0029 #define CDNS_RTC_EFLR       0x1C
0030 #define CDNS_RTC_IENR       0x20
0031 #define CDNS_RTC_IDISR      0x24
0032 #define CDNS_RTC_IMSKR      0x28
0033 #define CDNS_RTC_STSR       0x2C
0034 #define CDNS_RTC_KRTCR      0x30
0035 
0036 /* Control */
0037 #define CDNS_RTC_CTLR_TIME  BIT(0)
0038 #define CDNS_RTC_CTLR_CAL   BIT(1)
0039 #define CDNS_RTC_CTLR_TIME_CAL  (CDNS_RTC_CTLR_TIME | CDNS_RTC_CTLR_CAL)
0040 
0041 /* Status */
0042 #define CDNS_RTC_STSR_VT    BIT(0)
0043 #define CDNS_RTC_STSR_VC    BIT(1)
0044 #define CDNS_RTC_STSR_VTA   BIT(2)
0045 #define CDNS_RTC_STSR_VCA   BIT(3)
0046 #define CDNS_RTC_STSR_VT_VC (CDNS_RTC_STSR_VT | CDNS_RTC_STSR_VC)
0047 #define CDNS_RTC_STSR_VTA_VCA   (CDNS_RTC_STSR_VTA | CDNS_RTC_STSR_VCA)
0048 
0049 /* Keep RTC */
0050 #define CDNS_RTC_KRTCR_KRTC BIT(0)
0051 
0052 /* Alarm, Event, Interrupt */
0053 #define CDNS_RTC_AEI_HOS    BIT(0)
0054 #define CDNS_RTC_AEI_SEC    BIT(1)
0055 #define CDNS_RTC_AEI_MIN    BIT(2)
0056 #define CDNS_RTC_AEI_HOUR   BIT(3)
0057 #define CDNS_RTC_AEI_DATE   BIT(4)
0058 #define CDNS_RTC_AEI_MNTH   BIT(5)
0059 #define CDNS_RTC_AEI_ALRM   BIT(6)
0060 
0061 /* Time */
0062 #define CDNS_RTC_TIME_H     GENMASK(7, 0)
0063 #define CDNS_RTC_TIME_S     GENMASK(14, 8)
0064 #define CDNS_RTC_TIME_M     GENMASK(22, 16)
0065 #define CDNS_RTC_TIME_HR    GENMASK(29, 24)
0066 #define CDNS_RTC_TIME_PM    BIT(30)
0067 #define CDNS_RTC_TIME_CH    BIT(31)
0068 
0069 /* Calendar */
0070 #define CDNS_RTC_CAL_DAY    GENMASK(2, 0)
0071 #define CDNS_RTC_CAL_M      GENMASK(7, 3)
0072 #define CDNS_RTC_CAL_D      GENMASK(13, 8)
0073 #define CDNS_RTC_CAL_Y      GENMASK(23, 16)
0074 #define CDNS_RTC_CAL_C      GENMASK(29, 24)
0075 #define CDNS_RTC_CAL_CH     BIT(31)
0076 
0077 #define CDNS_RTC_MAX_REGS_TRIES 3
0078 
0079 struct cdns_rtc {
0080     struct rtc_device *rtc_dev;
0081     struct clk *pclk;
0082     struct clk *ref_clk;
0083     void __iomem *regs;
0084     int irq;
0085 };
0086 
0087 static void cdns_rtc_set_enabled(struct cdns_rtc *crtc, bool enabled)
0088 {
0089     u32 reg = enabled ? 0x0 : CDNS_RTC_CTLR_TIME_CAL;
0090 
0091     writel(reg, crtc->regs + CDNS_RTC_CTLR);
0092 }
0093 
0094 static bool cdns_rtc_get_enabled(struct cdns_rtc *crtc)
0095 {
0096     return !(readl(crtc->regs + CDNS_RTC_CTLR) & CDNS_RTC_CTLR_TIME_CAL);
0097 }
0098 
0099 static irqreturn_t cdns_rtc_irq_handler(int irq, void *id)
0100 {
0101     struct device *dev = id;
0102     struct cdns_rtc *crtc = dev_get_drvdata(dev);
0103 
0104     /* Reading the register clears it */
0105     if (!(readl(crtc->regs + CDNS_RTC_EFLR) & CDNS_RTC_AEI_ALRM))
0106         return IRQ_NONE;
0107 
0108     rtc_update_irq(crtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
0109     return IRQ_HANDLED;
0110 }
0111 
0112 static u32 cdns_rtc_time2reg(struct rtc_time *tm)
0113 {
0114     return FIELD_PREP(CDNS_RTC_TIME_S,  bin2bcd(tm->tm_sec))
0115          | FIELD_PREP(CDNS_RTC_TIME_M,  bin2bcd(tm->tm_min))
0116          | FIELD_PREP(CDNS_RTC_TIME_HR, bin2bcd(tm->tm_hour));
0117 }
0118 
0119 static void cdns_rtc_reg2time(u32 reg, struct rtc_time *tm)
0120 {
0121     tm->tm_sec  = bcd2bin(FIELD_GET(CDNS_RTC_TIME_S, reg));
0122     tm->tm_min  = bcd2bin(FIELD_GET(CDNS_RTC_TIME_M, reg));
0123     tm->tm_hour = bcd2bin(FIELD_GET(CDNS_RTC_TIME_HR, reg));
0124 }
0125 
0126 static int cdns_rtc_read_time(struct device *dev, struct rtc_time *tm)
0127 {
0128     struct cdns_rtc *crtc = dev_get_drvdata(dev);
0129     u32 reg;
0130 
0131     /* If the RTC is disabled, assume the values are invalid */
0132     if (!cdns_rtc_get_enabled(crtc))
0133         return -EINVAL;
0134 
0135     cdns_rtc_set_enabled(crtc, false);
0136 
0137     reg = readl(crtc->regs + CDNS_RTC_TIMR);
0138     cdns_rtc_reg2time(reg, tm);
0139 
0140     reg = readl(crtc->regs + CDNS_RTC_CALR);
0141     tm->tm_mday = bcd2bin(FIELD_GET(CDNS_RTC_CAL_D, reg));
0142     tm->tm_mon  = bcd2bin(FIELD_GET(CDNS_RTC_CAL_M, reg)) - 1;
0143     tm->tm_year = bcd2bin(FIELD_GET(CDNS_RTC_CAL_Y, reg))
0144             + bcd2bin(FIELD_GET(CDNS_RTC_CAL_C, reg)) * 100 - 1900;
0145     tm->tm_wday = bcd2bin(FIELD_GET(CDNS_RTC_CAL_DAY, reg)) - 1;
0146 
0147     cdns_rtc_set_enabled(crtc, true);
0148     return 0;
0149 }
0150 
0151 static int cdns_rtc_set_time(struct device *dev, struct rtc_time *tm)
0152 {
0153     struct cdns_rtc *crtc = dev_get_drvdata(dev);
0154     u32 timr, calr, stsr;
0155     int ret = -EIO;
0156     int year = tm->tm_year + 1900;
0157     int tries;
0158 
0159     cdns_rtc_set_enabled(crtc, false);
0160 
0161     timr = cdns_rtc_time2reg(tm);
0162 
0163     calr = FIELD_PREP(CDNS_RTC_CAL_D, bin2bcd(tm->tm_mday))
0164          | FIELD_PREP(CDNS_RTC_CAL_M, bin2bcd(tm->tm_mon + 1))
0165          | FIELD_PREP(CDNS_RTC_CAL_Y, bin2bcd(year % 100))
0166          | FIELD_PREP(CDNS_RTC_CAL_C, bin2bcd(year / 100))
0167          | FIELD_PREP(CDNS_RTC_CAL_DAY, tm->tm_wday + 1);
0168 
0169     /* Update registers, check valid flags */
0170     for (tries = 0; tries < CDNS_RTC_MAX_REGS_TRIES; tries++) {
0171         writel(timr, crtc->regs + CDNS_RTC_TIMR);
0172         writel(calr, crtc->regs + CDNS_RTC_CALR);
0173         stsr = readl(crtc->regs + CDNS_RTC_STSR);
0174 
0175         if ((stsr & CDNS_RTC_STSR_VT_VC) == CDNS_RTC_STSR_VT_VC) {
0176             ret = 0;
0177             break;
0178         }
0179     }
0180 
0181     cdns_rtc_set_enabled(crtc, true);
0182     return ret;
0183 }
0184 
0185 static int cdns_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
0186 {
0187     struct cdns_rtc *crtc = dev_get_drvdata(dev);
0188 
0189     if (enabled) {
0190         writel((CDNS_RTC_AEI_SEC | CDNS_RTC_AEI_MIN | CDNS_RTC_AEI_HOUR
0191             | CDNS_RTC_AEI_DATE | CDNS_RTC_AEI_MNTH),
0192                crtc->regs + CDNS_RTC_AENR);
0193         writel(CDNS_RTC_AEI_ALRM, crtc->regs + CDNS_RTC_IENR);
0194     } else {
0195         writel(0, crtc->regs + CDNS_RTC_AENR);
0196         writel(CDNS_RTC_AEI_ALRM, crtc->regs + CDNS_RTC_IDISR);
0197     }
0198 
0199     return 0;
0200 }
0201 
0202 static int cdns_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
0203 {
0204     struct cdns_rtc *crtc = dev_get_drvdata(dev);
0205     u32 reg;
0206 
0207     reg = readl(crtc->regs + CDNS_RTC_TIMAR);
0208     cdns_rtc_reg2time(reg, &alarm->time);
0209 
0210     reg = readl(crtc->regs + CDNS_RTC_CALAR);
0211     alarm->time.tm_mday = bcd2bin(FIELD_GET(CDNS_RTC_CAL_D, reg));
0212     alarm->time.tm_mon  = bcd2bin(FIELD_GET(CDNS_RTC_CAL_M, reg)) - 1;
0213 
0214     return 0;
0215 }
0216 
0217 static int cdns_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
0218 {
0219     struct cdns_rtc *crtc = dev_get_drvdata(dev);
0220     int ret = -EIO;
0221     int tries;
0222     u32 timar, calar, stsr;
0223 
0224     cdns_rtc_alarm_irq_enable(dev, 0);
0225 
0226     timar = cdns_rtc_time2reg(&alarm->time);
0227     calar = FIELD_PREP(CDNS_RTC_CAL_D, bin2bcd(alarm->time.tm_mday))
0228           | FIELD_PREP(CDNS_RTC_CAL_M, bin2bcd(alarm->time.tm_mon + 1));
0229 
0230     /* Update registers, check valid alarm flags */
0231     for (tries = 0; tries < CDNS_RTC_MAX_REGS_TRIES; tries++) {
0232         writel(timar, crtc->regs + CDNS_RTC_TIMAR);
0233         writel(calar, crtc->regs + CDNS_RTC_CALAR);
0234         stsr = readl(crtc->regs + CDNS_RTC_STSR);
0235 
0236         if ((stsr & CDNS_RTC_STSR_VTA_VCA) == CDNS_RTC_STSR_VTA_VCA) {
0237             ret = 0;
0238             break;
0239         }
0240     }
0241 
0242     if (!ret)
0243         cdns_rtc_alarm_irq_enable(dev, alarm->enabled);
0244     return ret;
0245 }
0246 
0247 static const struct rtc_class_ops cdns_rtc_ops = {
0248     .read_time  = cdns_rtc_read_time,
0249     .set_time   = cdns_rtc_set_time,
0250     .read_alarm = cdns_rtc_read_alarm,
0251     .set_alarm  = cdns_rtc_set_alarm,
0252     .alarm_irq_enable = cdns_rtc_alarm_irq_enable,
0253 };
0254 
0255 static int cdns_rtc_probe(struct platform_device *pdev)
0256 {
0257     struct cdns_rtc *crtc;
0258     int ret;
0259     unsigned long ref_clk_freq;
0260 
0261     crtc = devm_kzalloc(&pdev->dev, sizeof(*crtc), GFP_KERNEL);
0262     if (!crtc)
0263         return -ENOMEM;
0264 
0265     crtc->regs = devm_platform_ioremap_resource(pdev, 0);
0266     if (IS_ERR(crtc->regs))
0267         return PTR_ERR(crtc->regs);
0268 
0269     crtc->irq = platform_get_irq(pdev, 0);
0270     if (crtc->irq < 0)
0271         return -EINVAL;
0272 
0273     crtc->pclk = devm_clk_get(&pdev->dev, "pclk");
0274     if (IS_ERR(crtc->pclk)) {
0275         ret = PTR_ERR(crtc->pclk);
0276         dev_err(&pdev->dev,
0277             "Failed to retrieve the peripheral clock, %d\n", ret);
0278         return ret;
0279     }
0280 
0281     crtc->ref_clk = devm_clk_get(&pdev->dev, "ref_clk");
0282     if (IS_ERR(crtc->ref_clk)) {
0283         ret = PTR_ERR(crtc->ref_clk);
0284         dev_err(&pdev->dev,
0285             "Failed to retrieve the reference clock, %d\n", ret);
0286         return ret;
0287     }
0288 
0289     crtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
0290     if (IS_ERR(crtc->rtc_dev))
0291         return PTR_ERR(crtc->rtc_dev);
0292 
0293     platform_set_drvdata(pdev, crtc);
0294 
0295     ret = clk_prepare_enable(crtc->pclk);
0296     if (ret) {
0297         dev_err(&pdev->dev,
0298             "Failed to enable the peripheral clock, %d\n", ret);
0299         return ret;
0300     }
0301 
0302     ret = clk_prepare_enable(crtc->ref_clk);
0303     if (ret) {
0304         dev_err(&pdev->dev,
0305             "Failed to enable the reference clock, %d\n", ret);
0306         goto err_disable_pclk;
0307     }
0308 
0309     ref_clk_freq = clk_get_rate(crtc->ref_clk);
0310     if ((ref_clk_freq != 1) && (ref_clk_freq != 100)) {
0311         dev_err(&pdev->dev,
0312             "Invalid reference clock frequency %lu Hz.\n",
0313             ref_clk_freq);
0314         ret = -EINVAL;
0315         goto err_disable_ref_clk;
0316     }
0317 
0318     ret = devm_request_irq(&pdev->dev, crtc->irq,
0319                    cdns_rtc_irq_handler, 0,
0320                    dev_name(&pdev->dev), &pdev->dev);
0321     if (ret) {
0322         dev_err(&pdev->dev,
0323             "Failed to request interrupt for the device, %d\n",
0324             ret);
0325         goto err_disable_ref_clk;
0326     }
0327 
0328     /* The RTC supports 01.01.1900 - 31.12.2999 */
0329     crtc->rtc_dev->range_min = mktime64(1900,  1,  1,  0,  0,  0);
0330     crtc->rtc_dev->range_max = mktime64(2999, 12, 31, 23, 59, 59);
0331 
0332     crtc->rtc_dev->ops = &cdns_rtc_ops;
0333     device_init_wakeup(&pdev->dev, true);
0334 
0335     /* Always use 24-hour mode and keep the RTC values */
0336     writel(0, crtc->regs + CDNS_RTC_HMR);
0337     writel(CDNS_RTC_KRTCR_KRTC, crtc->regs + CDNS_RTC_KRTCR);
0338 
0339     ret = devm_rtc_register_device(crtc->rtc_dev);
0340     if (ret)
0341         goto err_disable_wakeup;
0342 
0343     return 0;
0344 
0345 err_disable_wakeup:
0346     device_init_wakeup(&pdev->dev, false);
0347 
0348 err_disable_ref_clk:
0349     clk_disable_unprepare(crtc->ref_clk);
0350 
0351 err_disable_pclk:
0352     clk_disable_unprepare(crtc->pclk);
0353 
0354     return ret;
0355 }
0356 
0357 static int cdns_rtc_remove(struct platform_device *pdev)
0358 {
0359     struct cdns_rtc *crtc = platform_get_drvdata(pdev);
0360 
0361     cdns_rtc_alarm_irq_enable(&pdev->dev, 0);
0362     device_init_wakeup(&pdev->dev, 0);
0363 
0364     clk_disable_unprepare(crtc->pclk);
0365     clk_disable_unprepare(crtc->ref_clk);
0366 
0367     return 0;
0368 }
0369 
0370 #ifdef CONFIG_PM_SLEEP
0371 static int cdns_rtc_suspend(struct device *dev)
0372 {
0373     struct cdns_rtc *crtc = dev_get_drvdata(dev);
0374 
0375     if (device_may_wakeup(dev))
0376         enable_irq_wake(crtc->irq);
0377 
0378     return 0;
0379 }
0380 
0381 static int cdns_rtc_resume(struct device *dev)
0382 {
0383     struct cdns_rtc *crtc = dev_get_drvdata(dev);
0384 
0385     if (device_may_wakeup(dev))
0386         disable_irq_wake(crtc->irq);
0387 
0388     return 0;
0389 }
0390 #endif
0391 
0392 static SIMPLE_DEV_PM_OPS(cdns_rtc_pm_ops, cdns_rtc_suspend, cdns_rtc_resume);
0393 
0394 static const struct of_device_id cdns_rtc_of_match[] = {
0395     { .compatible = "cdns,rtc-r109v3" },
0396     { },
0397 };
0398 MODULE_DEVICE_TABLE(of, cdns_rtc_of_match);
0399 
0400 static struct platform_driver cdns_rtc_driver = {
0401     .driver = {
0402         .name = "cdns-rtc",
0403         .of_match_table = cdns_rtc_of_match,
0404         .pm = &cdns_rtc_pm_ops,
0405     },
0406     .probe = cdns_rtc_probe,
0407     .remove = cdns_rtc_remove,
0408 };
0409 module_platform_driver(cdns_rtc_driver);
0410 
0411 MODULE_AUTHOR("Jan Kotas <jank@cadence.com>");
0412 MODULE_DESCRIPTION("Cadence RTC driver");
0413 MODULE_LICENSE("GPL v2");
0414 MODULE_ALIAS("platform:cdns-rtc");