Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * drivers/rtc/rtc-pl031.c
0004  *
0005  * Real Time Clock interface for ARM AMBA PrimeCell 031 RTC
0006  *
0007  * Author: Deepak Saxena <dsaxena@plexity.net>
0008  *
0009  * Copyright 2006 (c) MontaVista Software, Inc.
0010  *
0011  * Author: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
0012  * Copyright 2010 (c) ST-Ericsson AB
0013  */
0014 #include <linux/module.h>
0015 #include <linux/rtc.h>
0016 #include <linux/init.h>
0017 #include <linux/interrupt.h>
0018 #include <linux/amba/bus.h>
0019 #include <linux/io.h>
0020 #include <linux/bcd.h>
0021 #include <linux/delay.h>
0022 #include <linux/pm_wakeirq.h>
0023 #include <linux/slab.h>
0024 
0025 /*
0026  * Register definitions
0027  */
0028 #define RTC_DR      0x00    /* Data read register */
0029 #define RTC_MR      0x04    /* Match register */
0030 #define RTC_LR      0x08    /* Data load register */
0031 #define RTC_CR      0x0c    /* Control register */
0032 #define RTC_IMSC    0x10    /* Interrupt mask and set register */
0033 #define RTC_RIS     0x14    /* Raw interrupt status register */
0034 #define RTC_MIS     0x18    /* Masked interrupt status register */
0035 #define RTC_ICR     0x1c    /* Interrupt clear register */
0036 /* ST variants have additional timer functionality */
0037 #define RTC_TDR     0x20    /* Timer data read register */
0038 #define RTC_TLR     0x24    /* Timer data load register */
0039 #define RTC_TCR     0x28    /* Timer control register */
0040 #define RTC_YDR     0x30    /* Year data read register */
0041 #define RTC_YMR     0x34    /* Year match register */
0042 #define RTC_YLR     0x38    /* Year data load register */
0043 
0044 #define RTC_CR_EN   (1 << 0)    /* counter enable bit */
0045 #define RTC_CR_CWEN (1 << 26)   /* Clockwatch enable bit */
0046 
0047 #define RTC_TCR_EN  (1 << 1) /* Periodic timer enable bit */
0048 
0049 /* Common bit definitions for Interrupt status and control registers */
0050 #define RTC_BIT_AI  (1 << 0) /* Alarm interrupt bit */
0051 #define RTC_BIT_PI  (1 << 1) /* Periodic interrupt bit. ST variants only. */
0052 
0053 /* Common bit definations for ST v2 for reading/writing time */
0054 #define RTC_SEC_SHIFT 0
0055 #define RTC_SEC_MASK (0x3F << RTC_SEC_SHIFT) /* Second [0-59] */
0056 #define RTC_MIN_SHIFT 6
0057 #define RTC_MIN_MASK (0x3F << RTC_MIN_SHIFT) /* Minute [0-59] */
0058 #define RTC_HOUR_SHIFT 12
0059 #define RTC_HOUR_MASK (0x1F << RTC_HOUR_SHIFT) /* Hour [0-23] */
0060 #define RTC_WDAY_SHIFT 17
0061 #define RTC_WDAY_MASK (0x7 << RTC_WDAY_SHIFT) /* Day of Week [1-7] 1=Sunday */
0062 #define RTC_MDAY_SHIFT 20
0063 #define RTC_MDAY_MASK (0x1F << RTC_MDAY_SHIFT) /* Day of Month [1-31] */
0064 #define RTC_MON_SHIFT 25
0065 #define RTC_MON_MASK (0xF << RTC_MON_SHIFT) /* Month [1-12] 1=January */
0066 
0067 #define RTC_TIMER_FREQ 32768
0068 
0069 /**
0070  * struct pl031_vendor_data - per-vendor variations
0071  * @ops: the vendor-specific operations used on this silicon version
0072  * @clockwatch: if this is an ST Microelectronics silicon version with a
0073  *  clockwatch function
0074  * @st_weekday: if this is an ST Microelectronics silicon version that need
0075  *  the weekday fix
0076  * @irqflags: special IRQ flags per variant
0077  */
0078 struct pl031_vendor_data {
0079     struct rtc_class_ops ops;
0080     bool clockwatch;
0081     bool st_weekday;
0082     unsigned long irqflags;
0083     time64_t range_min;
0084     timeu64_t range_max;
0085 };
0086 
0087 struct pl031_local {
0088     struct pl031_vendor_data *vendor;
0089     struct rtc_device *rtc;
0090     void __iomem *base;
0091 };
0092 
0093 static int pl031_alarm_irq_enable(struct device *dev,
0094     unsigned int enabled)
0095 {
0096     struct pl031_local *ldata = dev_get_drvdata(dev);
0097     unsigned long imsc;
0098 
0099     /* Clear any pending alarm interrupts. */
0100     writel(RTC_BIT_AI, ldata->base + RTC_ICR);
0101 
0102     imsc = readl(ldata->base + RTC_IMSC);
0103 
0104     if (enabled == 1)
0105         writel(imsc | RTC_BIT_AI, ldata->base + RTC_IMSC);
0106     else
0107         writel(imsc & ~RTC_BIT_AI, ldata->base + RTC_IMSC);
0108 
0109     return 0;
0110 }
0111 
0112 /*
0113  * Convert Gregorian date to ST v2 RTC format.
0114  */
0115 static int pl031_stv2_tm_to_time(struct device *dev,
0116                  struct rtc_time *tm, unsigned long *st_time,
0117     unsigned long *bcd_year)
0118 {
0119     int year = tm->tm_year + 1900;
0120     int wday = tm->tm_wday;
0121 
0122     /* wday masking is not working in hardware so wday must be valid */
0123     if (wday < -1 || wday > 6) {
0124         dev_err(dev, "invalid wday value %d\n", tm->tm_wday);
0125         return -EINVAL;
0126     } else if (wday == -1) {
0127         /* wday is not provided, calculate it here */
0128         struct rtc_time calc_tm;
0129 
0130         rtc_time64_to_tm(rtc_tm_to_time64(tm), &calc_tm);
0131         wday = calc_tm.tm_wday;
0132     }
0133 
0134     *bcd_year = (bin2bcd(year % 100) | bin2bcd(year / 100) << 8);
0135 
0136     *st_time = ((tm->tm_mon + 1) << RTC_MON_SHIFT)
0137             |   (tm->tm_mday << RTC_MDAY_SHIFT)
0138             |   ((wday + 1) << RTC_WDAY_SHIFT)
0139             |   (tm->tm_hour << RTC_HOUR_SHIFT)
0140             |   (tm->tm_min << RTC_MIN_SHIFT)
0141             |   (tm->tm_sec << RTC_SEC_SHIFT);
0142 
0143     return 0;
0144 }
0145 
0146 /*
0147  * Convert ST v2 RTC format to Gregorian date.
0148  */
0149 static int pl031_stv2_time_to_tm(unsigned long st_time, unsigned long bcd_year,
0150     struct rtc_time *tm)
0151 {
0152     tm->tm_year = bcd2bin(bcd_year) + (bcd2bin(bcd_year >> 8) * 100);
0153     tm->tm_mon  = ((st_time & RTC_MON_MASK) >> RTC_MON_SHIFT) - 1;
0154     tm->tm_mday = ((st_time & RTC_MDAY_MASK) >> RTC_MDAY_SHIFT);
0155     tm->tm_wday = ((st_time & RTC_WDAY_MASK) >> RTC_WDAY_SHIFT) - 1;
0156     tm->tm_hour = ((st_time & RTC_HOUR_MASK) >> RTC_HOUR_SHIFT);
0157     tm->tm_min  = ((st_time & RTC_MIN_MASK) >> RTC_MIN_SHIFT);
0158     tm->tm_sec  = ((st_time & RTC_SEC_MASK) >> RTC_SEC_SHIFT);
0159 
0160     tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
0161     tm->tm_year -= 1900;
0162 
0163     return 0;
0164 }
0165 
0166 static int pl031_stv2_read_time(struct device *dev, struct rtc_time *tm)
0167 {
0168     struct pl031_local *ldata = dev_get_drvdata(dev);
0169 
0170     pl031_stv2_time_to_tm(readl(ldata->base + RTC_DR),
0171             readl(ldata->base + RTC_YDR), tm);
0172 
0173     return 0;
0174 }
0175 
0176 static int pl031_stv2_set_time(struct device *dev, struct rtc_time *tm)
0177 {
0178     unsigned long time;
0179     unsigned long bcd_year;
0180     struct pl031_local *ldata = dev_get_drvdata(dev);
0181     int ret;
0182 
0183     ret = pl031_stv2_tm_to_time(dev, tm, &time, &bcd_year);
0184     if (ret == 0) {
0185         writel(bcd_year, ldata->base + RTC_YLR);
0186         writel(time, ldata->base + RTC_LR);
0187     }
0188 
0189     return ret;
0190 }
0191 
0192 static int pl031_stv2_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
0193 {
0194     struct pl031_local *ldata = dev_get_drvdata(dev);
0195     int ret;
0196 
0197     ret = pl031_stv2_time_to_tm(readl(ldata->base + RTC_MR),
0198             readl(ldata->base + RTC_YMR), &alarm->time);
0199 
0200     alarm->pending = readl(ldata->base + RTC_RIS) & RTC_BIT_AI;
0201     alarm->enabled = readl(ldata->base + RTC_IMSC) & RTC_BIT_AI;
0202 
0203     return ret;
0204 }
0205 
0206 static int pl031_stv2_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
0207 {
0208     struct pl031_local *ldata = dev_get_drvdata(dev);
0209     unsigned long time;
0210     unsigned long bcd_year;
0211     int ret;
0212 
0213     ret = pl031_stv2_tm_to_time(dev, &alarm->time,
0214                     &time, &bcd_year);
0215     if (ret == 0) {
0216         writel(bcd_year, ldata->base + RTC_YMR);
0217         writel(time, ldata->base + RTC_MR);
0218 
0219         pl031_alarm_irq_enable(dev, alarm->enabled);
0220     }
0221 
0222     return ret;
0223 }
0224 
0225 static irqreturn_t pl031_interrupt(int irq, void *dev_id)
0226 {
0227     struct pl031_local *ldata = dev_id;
0228     unsigned long rtcmis;
0229     unsigned long events = 0;
0230 
0231     rtcmis = readl(ldata->base + RTC_MIS);
0232     if (rtcmis & RTC_BIT_AI) {
0233         writel(RTC_BIT_AI, ldata->base + RTC_ICR);
0234         events |= (RTC_AF | RTC_IRQF);
0235         rtc_update_irq(ldata->rtc, 1, events);
0236 
0237         return IRQ_HANDLED;
0238     }
0239 
0240     return IRQ_NONE;
0241 }
0242 
0243 static int pl031_read_time(struct device *dev, struct rtc_time *tm)
0244 {
0245     struct pl031_local *ldata = dev_get_drvdata(dev);
0246 
0247     rtc_time64_to_tm(readl(ldata->base + RTC_DR), tm);
0248 
0249     return 0;
0250 }
0251 
0252 static int pl031_set_time(struct device *dev, struct rtc_time *tm)
0253 {
0254     struct pl031_local *ldata = dev_get_drvdata(dev);
0255 
0256     writel(rtc_tm_to_time64(tm), ldata->base + RTC_LR);
0257 
0258     return 0;
0259 }
0260 
0261 static int pl031_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
0262 {
0263     struct pl031_local *ldata = dev_get_drvdata(dev);
0264 
0265     rtc_time64_to_tm(readl(ldata->base + RTC_MR), &alarm->time);
0266 
0267     alarm->pending = readl(ldata->base + RTC_RIS) & RTC_BIT_AI;
0268     alarm->enabled = readl(ldata->base + RTC_IMSC) & RTC_BIT_AI;
0269 
0270     return 0;
0271 }
0272 
0273 static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
0274 {
0275     struct pl031_local *ldata = dev_get_drvdata(dev);
0276 
0277     writel(rtc_tm_to_time64(&alarm->time), ldata->base + RTC_MR);
0278     pl031_alarm_irq_enable(dev, alarm->enabled);
0279 
0280     return 0;
0281 }
0282 
0283 static void pl031_remove(struct amba_device *adev)
0284 {
0285     struct pl031_local *ldata = dev_get_drvdata(&adev->dev);
0286 
0287     dev_pm_clear_wake_irq(&adev->dev);
0288     device_init_wakeup(&adev->dev, false);
0289     if (adev->irq[0])
0290         free_irq(adev->irq[0], ldata);
0291     amba_release_regions(adev);
0292 }
0293 
0294 static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
0295 {
0296     int ret;
0297     struct pl031_local *ldata;
0298     struct pl031_vendor_data *vendor = id->data;
0299     struct rtc_class_ops *ops;
0300     unsigned long time, data;
0301 
0302     ret = amba_request_regions(adev, NULL);
0303     if (ret)
0304         goto err_req;
0305 
0306     ldata = devm_kzalloc(&adev->dev, sizeof(struct pl031_local),
0307                  GFP_KERNEL);
0308     ops = devm_kmemdup(&adev->dev, &vendor->ops, sizeof(vendor->ops),
0309                GFP_KERNEL);
0310     if (!ldata || !ops) {
0311         ret = -ENOMEM;
0312         goto out;
0313     }
0314 
0315     ldata->vendor = vendor;
0316     ldata->base = devm_ioremap(&adev->dev, adev->res.start,
0317                    resource_size(&adev->res));
0318     if (!ldata->base) {
0319         ret = -ENOMEM;
0320         goto out;
0321     }
0322 
0323     amba_set_drvdata(adev, ldata);
0324 
0325     dev_dbg(&adev->dev, "designer ID = 0x%02x\n", amba_manf(adev));
0326     dev_dbg(&adev->dev, "revision = 0x%01x\n", amba_rev(adev));
0327 
0328     data = readl(ldata->base + RTC_CR);
0329     /* Enable the clockwatch on ST Variants */
0330     if (vendor->clockwatch)
0331         data |= RTC_CR_CWEN;
0332     else
0333         data |= RTC_CR_EN;
0334     writel(data, ldata->base + RTC_CR);
0335 
0336     /*
0337      * On ST PL031 variants, the RTC reset value does not provide correct
0338      * weekday for 2000-01-01. Correct the erroneous sunday to saturday.
0339      */
0340     if (vendor->st_weekday) {
0341         if (readl(ldata->base + RTC_YDR) == 0x2000) {
0342             time = readl(ldata->base + RTC_DR);
0343             if ((time &
0344                  (RTC_MON_MASK | RTC_MDAY_MASK | RTC_WDAY_MASK))
0345                 == 0x02120000) {
0346                 time = time | (0x7 << RTC_WDAY_SHIFT);
0347                 writel(0x2000, ldata->base + RTC_YLR);
0348                 writel(time, ldata->base + RTC_LR);
0349             }
0350         }
0351     }
0352 
0353     device_init_wakeup(&adev->dev, true);
0354     ldata->rtc = devm_rtc_allocate_device(&adev->dev);
0355     if (IS_ERR(ldata->rtc)) {
0356         ret = PTR_ERR(ldata->rtc);
0357         goto out;
0358     }
0359 
0360     if (!adev->irq[0])
0361         clear_bit(RTC_FEATURE_ALARM, ldata->rtc->features);
0362 
0363     ldata->rtc->ops = ops;
0364     ldata->rtc->range_min = vendor->range_min;
0365     ldata->rtc->range_max = vendor->range_max;
0366 
0367     ret = devm_rtc_register_device(ldata->rtc);
0368     if (ret)
0369         goto out;
0370 
0371     if (adev->irq[0]) {
0372         ret = request_irq(adev->irq[0], pl031_interrupt,
0373                   vendor->irqflags, "rtc-pl031", ldata);
0374         if (ret)
0375             goto out;
0376         dev_pm_set_wake_irq(&adev->dev, adev->irq[0]);
0377     }
0378     return 0;
0379 
0380 out:
0381     amba_release_regions(adev);
0382 err_req:
0383 
0384     return ret;
0385 }
0386 
0387 /* Operations for the original ARM version */
0388 static struct pl031_vendor_data arm_pl031 = {
0389     .ops = {
0390         .read_time = pl031_read_time,
0391         .set_time = pl031_set_time,
0392         .read_alarm = pl031_read_alarm,
0393         .set_alarm = pl031_set_alarm,
0394         .alarm_irq_enable = pl031_alarm_irq_enable,
0395     },
0396     .range_max = U32_MAX,
0397 };
0398 
0399 /* The First ST derivative */
0400 static struct pl031_vendor_data stv1_pl031 = {
0401     .ops = {
0402         .read_time = pl031_read_time,
0403         .set_time = pl031_set_time,
0404         .read_alarm = pl031_read_alarm,
0405         .set_alarm = pl031_set_alarm,
0406         .alarm_irq_enable = pl031_alarm_irq_enable,
0407     },
0408     .clockwatch = true,
0409     .st_weekday = true,
0410     .range_max = U32_MAX,
0411 };
0412 
0413 /* And the second ST derivative */
0414 static struct pl031_vendor_data stv2_pl031 = {
0415     .ops = {
0416         .read_time = pl031_stv2_read_time,
0417         .set_time = pl031_stv2_set_time,
0418         .read_alarm = pl031_stv2_read_alarm,
0419         .set_alarm = pl031_stv2_set_alarm,
0420         .alarm_irq_enable = pl031_alarm_irq_enable,
0421     },
0422     .clockwatch = true,
0423     .st_weekday = true,
0424     /*
0425      * This variant shares the IRQ with another block and must not
0426      * suspend that IRQ line.
0427      * TODO check if it shares with IRQF_NO_SUSPEND user, else we can
0428      * remove IRQF_COND_SUSPEND
0429      */
0430     .irqflags = IRQF_SHARED | IRQF_COND_SUSPEND,
0431     .range_min = RTC_TIMESTAMP_BEGIN_0000,
0432     .range_max = RTC_TIMESTAMP_END_9999,
0433 };
0434 
0435 static const struct amba_id pl031_ids[] = {
0436     {
0437         .id = 0x00041031,
0438         .mask = 0x000fffff,
0439         .data = &arm_pl031,
0440     },
0441     /* ST Micro variants */
0442     {
0443         .id = 0x00180031,
0444         .mask = 0x00ffffff,
0445         .data = &stv1_pl031,
0446     },
0447     {
0448         .id = 0x00280031,
0449         .mask = 0x00ffffff,
0450         .data = &stv2_pl031,
0451     },
0452     {0, 0},
0453 };
0454 
0455 MODULE_DEVICE_TABLE(amba, pl031_ids);
0456 
0457 static struct amba_driver pl031_driver = {
0458     .drv = {
0459         .name = "rtc-pl031",
0460     },
0461     .id_table = pl031_ids,
0462     .probe = pl031_probe,
0463     .remove = pl031_remove,
0464 };
0465 
0466 module_amba_driver(pl031_driver);
0467 
0468 MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
0469 MODULE_DESCRIPTION("ARM AMBA PL031 RTC Driver");
0470 MODULE_LICENSE("GPL");