1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * An RTC driver for Allwinner A10/A20 4 * 5 * Copyright (c) 2013, Carlo Caione <carlo.caione@gmail.com> 6 */ 7 8 #include <linux/delay.h> 9 #include <linux/err.h> 10 #include <linux/fs.h> 11 #include <linux/init.h> 12 #include <linux/interrupt.h> 13 #include <linux/io.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/platform_device.h> 18 #include <linux/rtc.h> 19 #include <linux/types.h> 20 21 #define SUNXI_LOSC_CTRL 0x0000 22 #define SUNXI_LOSC_CTRL_RTC_HMS_ACC BIT(8) 23 #define SUNXI_LOSC_CTRL_RTC_YMD_ACC BIT(7) 24 25 #define SUNXI_RTC_YMD 0x0004 26 27 #define SUNXI_RTC_HMS 0x0008 28 29 #define SUNXI_ALRM_DHMS 0x000c 30 31 #define SUNXI_ALRM_EN 0x0014 32 #define SUNXI_ALRM_EN_CNT_EN BIT(8) 33 34 #define SUNXI_ALRM_IRQ_EN 0x0018 35 #define SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN BIT(0) 36 37 #define SUNXI_ALRM_IRQ_STA 0x001c 38 #define SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND BIT(0) 39 40 #define SUNXI_MASK_DH 0x0000001f 41 #define SUNXI_MASK_SM 0x0000003f 42 #define SUNXI_MASK_M 0x0000000f 43 #define SUNXI_MASK_LY 0x00000001 44 #define SUNXI_MASK_D 0x00000ffe 45 #define SUNXI_MASK_M 0x0000000f 46 47 #define SUNXI_GET(x, mask, shift) (((x) & ((mask) << (shift))) \ 48 >> (shift)) 49 50 #define SUNXI_SET(x, mask, shift) (((x) & (mask)) << (shift)) 51 52 /* 53 * Get date values 54 */ 55 #define SUNXI_DATE_GET_DAY_VALUE(x) SUNXI_GET(x, SUNXI_MASK_DH, 0) 56 #define SUNXI_DATE_GET_MON_VALUE(x) SUNXI_GET(x, SUNXI_MASK_M, 8) 57 #define SUNXI_DATE_GET_YEAR_VALUE(x, mask) SUNXI_GET(x, mask, 16) 58 59 /* 60 * Get time values 61 */ 62 #define SUNXI_TIME_GET_SEC_VALUE(x) SUNXI_GET(x, SUNXI_MASK_SM, 0) 63 #define SUNXI_TIME_GET_MIN_VALUE(x) SUNXI_GET(x, SUNXI_MASK_SM, 8) 64 #define SUNXI_TIME_GET_HOUR_VALUE(x) SUNXI_GET(x, SUNXI_MASK_DH, 16) 65 66 /* 67 * Get alarm values 68 */ 69 #define SUNXI_ALRM_GET_SEC_VALUE(x) SUNXI_GET(x, SUNXI_MASK_SM, 0) 70 #define SUNXI_ALRM_GET_MIN_VALUE(x) SUNXI_GET(x, SUNXI_MASK_SM, 8) 71 #define SUNXI_ALRM_GET_HOUR_VALUE(x) SUNXI_GET(x, SUNXI_MASK_DH, 16) 72 73 /* 74 * Set date values 75 */ 76 #define SUNXI_DATE_SET_DAY_VALUE(x) SUNXI_DATE_GET_DAY_VALUE(x) 77 #define SUNXI_DATE_SET_MON_VALUE(x) SUNXI_SET(x, SUNXI_MASK_M, 8) 78 #define SUNXI_DATE_SET_YEAR_VALUE(x, mask) SUNXI_SET(x, mask, 16) 79 #define SUNXI_LEAP_SET_VALUE(x, shift) SUNXI_SET(x, SUNXI_MASK_LY, shift) 80 81 /* 82 * Set time values 83 */ 84 #define SUNXI_TIME_SET_SEC_VALUE(x) SUNXI_TIME_GET_SEC_VALUE(x) 85 #define SUNXI_TIME_SET_MIN_VALUE(x) SUNXI_SET(x, SUNXI_MASK_SM, 8) 86 #define SUNXI_TIME_SET_HOUR_VALUE(x) SUNXI_SET(x, SUNXI_MASK_DH, 16) 87 88 /* 89 * Set alarm values 90 */ 91 #define SUNXI_ALRM_SET_SEC_VALUE(x) SUNXI_ALRM_GET_SEC_VALUE(x) 92 #define SUNXI_ALRM_SET_MIN_VALUE(x) SUNXI_SET(x, SUNXI_MASK_SM, 8) 93 #define SUNXI_ALRM_SET_HOUR_VALUE(x) SUNXI_SET(x, SUNXI_MASK_DH, 16) 94 #define SUNXI_ALRM_SET_DAY_VALUE(x) SUNXI_SET(x, SUNXI_MASK_D, 21) 95 96 /* 97 * Time unit conversions 98 */ 99 #define SEC_IN_MIN 60 100 #define SEC_IN_HOUR (60 * SEC_IN_MIN) 101 #define SEC_IN_DAY (24 * SEC_IN_HOUR) 102 103 /* 104 * The year parameter passed to the driver is usually an offset relative to 105 * the year 1900. This macro is used to convert this offset to another one 106 * relative to the minimum year allowed by the hardware. 107 */ 108 #define SUNXI_YEAR_OFF(x) ((x)->min - 1900) 109 110 /* 111 * min and max year are arbitrary set considering the limited range of the 112 * hardware register field 113 */ 114 struct sunxi_rtc_data_year { 115 unsigned int min; /* min year allowed */ 116 unsigned int max; /* max year allowed */ 117 unsigned int mask; /* mask for the year field */ 118 unsigned char leap_shift; /* bit shift to get the leap year */ 119 }; 120 121 static const struct sunxi_rtc_data_year data_year_param[] = { 122 [0] = { 123 .min = 2010, 124 .max = 2073, 125 .mask = 0x3f, 126 .leap_shift = 22, 127 }, 128 [1] = { 129 .min = 1970, 130 .max = 2225, 131 .mask = 0xff, 132 .leap_shift = 24, 133 }, 134 }; 135 136 struct sunxi_rtc_dev { 137 struct rtc_device *rtc; 138 struct device *dev; 139 const struct sunxi_rtc_data_year *data_year; 140 void __iomem *base; 141 int irq; 142 }; 143 144 static irqreturn_t sunxi_rtc_alarmirq(int irq, void *id) 145 { 146 struct sunxi_rtc_dev *chip = (struct sunxi_rtc_dev *) id; 147 u32 val; 148 149 val = readl(chip->base + SUNXI_ALRM_IRQ_STA); 150 151 if (val & SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND) { 152 val |= SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND; 153 writel(val, chip->base + SUNXI_ALRM_IRQ_STA); 154 155 rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF); 156 157 return IRQ_HANDLED; 158 } 159 160 return IRQ_NONE; 161 } 162 163 static void sunxi_rtc_setaie(unsigned int to, struct sunxi_rtc_dev *chip) 164 { 165 u32 alrm_val = 0; 166 u32 alrm_irq_val = 0; 167 168 if (to) { 169 alrm_val = readl(chip->base + SUNXI_ALRM_EN); 170 alrm_val |= SUNXI_ALRM_EN_CNT_EN; 171 172 alrm_irq_val = readl(chip->base + SUNXI_ALRM_IRQ_EN); 173 alrm_irq_val |= SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN; 174 } else { 175 writel(SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND, 176 chip->base + SUNXI_ALRM_IRQ_STA); 177 } 178 179 writel(alrm_val, chip->base + SUNXI_ALRM_EN); 180 writel(alrm_irq_val, chip->base + SUNXI_ALRM_IRQ_EN); 181 } 182 183 static int sunxi_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm) 184 { 185 struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); 186 struct rtc_time *alrm_tm = &wkalrm->time; 187 u32 alrm; 188 u32 alrm_en; 189 u32 date; 190 191 alrm = readl(chip->base + SUNXI_ALRM_DHMS); 192 date = readl(chip->base + SUNXI_RTC_YMD); 193 194 alrm_tm->tm_sec = SUNXI_ALRM_GET_SEC_VALUE(alrm); 195 alrm_tm->tm_min = SUNXI_ALRM_GET_MIN_VALUE(alrm); 196 alrm_tm->tm_hour = SUNXI_ALRM_GET_HOUR_VALUE(alrm); 197 198 alrm_tm->tm_mday = SUNXI_DATE_GET_DAY_VALUE(date); 199 alrm_tm->tm_mon = SUNXI_DATE_GET_MON_VALUE(date); 200 alrm_tm->tm_year = SUNXI_DATE_GET_YEAR_VALUE(date, 201 chip->data_year->mask); 202 203 alrm_tm->tm_mon -= 1; 204 205 /* 206 * switch from (data_year->min)-relative offset to 207 * a (1900)-relative one 208 */ 209 alrm_tm->tm_year += SUNXI_YEAR_OFF(chip->data_year); 210 211 alrm_en = readl(chip->base + SUNXI_ALRM_IRQ_EN); 212 if (alrm_en & SUNXI_ALRM_EN_CNT_EN) 213 wkalrm->enabled = 1; 214 215 return 0; 216 } 217 218 static int sunxi_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) 219 { 220 struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); 221 u32 date, time; 222 223 /* 224 * read again in case it changes 225 */ 226 do { 227 date = readl(chip->base + SUNXI_RTC_YMD); 228 time = readl(chip->base + SUNXI_RTC_HMS); 229 } while ((date != readl(chip->base + SUNXI_RTC_YMD)) || 230 (time != readl(chip->base + SUNXI_RTC_HMS))); 231 232 rtc_tm->tm_sec = SUNXI_TIME_GET_SEC_VALUE(time); 233 rtc_tm->tm_min = SUNXI_TIME_GET_MIN_VALUE(time); 234 rtc_tm->tm_hour = SUNXI_TIME_GET_HOUR_VALUE(time); 235 236 rtc_tm->tm_mday = SUNXI_DATE_GET_DAY_VALUE(date); 237 rtc_tm->tm_mon = SUNXI_DATE_GET_MON_VALUE(date); 238 rtc_tm->tm_year = SUNXI_DATE_GET_YEAR_VALUE(date, 239 chip->data_year->mask); 240 241 rtc_tm->tm_mon -= 1; 242 243 /* 244 * switch from (data_year->min)-relative offset to 245 * a (1900)-relative one 246 */ 247 rtc_tm->tm_year += SUNXI_YEAR_OFF(chip->data_year); 248 249 return 0; 250 } 251 252 static int sunxi_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm) 253 { 254 struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); 255 struct rtc_time *alrm_tm = &wkalrm->time; 256 struct rtc_time tm_now; 257 u32 alrm; 258 time64_t diff; 259 unsigned long time_gap; 260 unsigned long time_gap_day; 261 unsigned long time_gap_hour; 262 unsigned long time_gap_min; 263 int ret; 264 265 ret = sunxi_rtc_gettime(dev, &tm_now); 266 if (ret < 0) { 267 dev_err(dev, "Error in getting time\n"); 268 return -EINVAL; 269 } 270 271 diff = rtc_tm_sub(alrm_tm, &tm_now); 272 if (diff <= 0) { 273 dev_err(dev, "Date to set in the past\n"); 274 return -EINVAL; 275 } 276 277 if (diff > 255 * SEC_IN_DAY) { 278 dev_err(dev, "Day must be in the range 0 - 255\n"); 279 return -EINVAL; 280 } 281 282 time_gap = diff; 283 time_gap_day = time_gap / SEC_IN_DAY; 284 time_gap -= time_gap_day * SEC_IN_DAY; 285 time_gap_hour = time_gap / SEC_IN_HOUR; 286 time_gap -= time_gap_hour * SEC_IN_HOUR; 287 time_gap_min = time_gap / SEC_IN_MIN; 288 time_gap -= time_gap_min * SEC_IN_MIN; 289 290 sunxi_rtc_setaie(0, chip); 291 writel(0, chip->base + SUNXI_ALRM_DHMS); 292 usleep_range(100, 300); 293 294 alrm = SUNXI_ALRM_SET_SEC_VALUE(time_gap) | 295 SUNXI_ALRM_SET_MIN_VALUE(time_gap_min) | 296 SUNXI_ALRM_SET_HOUR_VALUE(time_gap_hour) | 297 SUNXI_ALRM_SET_DAY_VALUE(time_gap_day); 298 writel(alrm, chip->base + SUNXI_ALRM_DHMS); 299 300 writel(0, chip->base + SUNXI_ALRM_IRQ_EN); 301 writel(SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN, chip->base + SUNXI_ALRM_IRQ_EN); 302 303 sunxi_rtc_setaie(wkalrm->enabled, chip); 304 305 return 0; 306 } 307 308 static int sunxi_rtc_wait(struct sunxi_rtc_dev *chip, int offset, 309 unsigned int mask, unsigned int ms_timeout) 310 { 311 const unsigned long timeout = jiffies + msecs_to_jiffies(ms_timeout); 312 u32 reg; 313 314 do { 315 reg = readl(chip->base + offset); 316 reg &= mask; 317 318 if (reg == mask) 319 return 0; 320 321 } while (time_before(jiffies, timeout)); 322 323 return -ETIMEDOUT; 324 } 325 326 static int sunxi_rtc_settime(struct device *dev, struct rtc_time *rtc_tm) 327 { 328 struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); 329 u32 date = 0; 330 u32 time = 0; 331 unsigned int year; 332 333 /* 334 * the input rtc_tm->tm_year is the offset relative to 1900. We use 335 * the SUNXI_YEAR_OFF macro to rebase it with respect to the min year 336 * allowed by the hardware 337 */ 338 339 year = rtc_tm->tm_year + 1900; 340 if (year < chip->data_year->min || year > chip->data_year->max) { 341 dev_err(dev, "rtc only supports year in range %u - %u\n", 342 chip->data_year->min, chip->data_year->max); 343 return -EINVAL; 344 } 345 346 rtc_tm->tm_year -= SUNXI_YEAR_OFF(chip->data_year); 347 rtc_tm->tm_mon += 1; 348 349 date = SUNXI_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) | 350 SUNXI_DATE_SET_MON_VALUE(rtc_tm->tm_mon) | 351 SUNXI_DATE_SET_YEAR_VALUE(rtc_tm->tm_year, 352 chip->data_year->mask); 353 354 if (is_leap_year(year)) 355 date |= SUNXI_LEAP_SET_VALUE(1, chip->data_year->leap_shift); 356 357 time = SUNXI_TIME_SET_SEC_VALUE(rtc_tm->tm_sec) | 358 SUNXI_TIME_SET_MIN_VALUE(rtc_tm->tm_min) | 359 SUNXI_TIME_SET_HOUR_VALUE(rtc_tm->tm_hour); 360 361 writel(0, chip->base + SUNXI_RTC_HMS); 362 writel(0, chip->base + SUNXI_RTC_YMD); 363 364 writel(time, chip->base + SUNXI_RTC_HMS); 365 366 /* 367 * After writing the RTC HH-MM-SS register, the 368 * SUNXI_LOSC_CTRL_RTC_HMS_ACC bit is set and it will not 369 * be cleared until the real writing operation is finished 370 */ 371 372 if (sunxi_rtc_wait(chip, SUNXI_LOSC_CTRL, 373 SUNXI_LOSC_CTRL_RTC_HMS_ACC, 50)) { 374 dev_err(dev, "Failed to set rtc time.\n"); 375 return -1; 376 } 377 378 writel(date, chip->base + SUNXI_RTC_YMD); 379 380 /* 381 * After writing the RTC YY-MM-DD register, the 382 * SUNXI_LOSC_CTRL_RTC_YMD_ACC bit is set and it will not 383 * be cleared until the real writing operation is finished 384 */ 385 386 if (sunxi_rtc_wait(chip, SUNXI_LOSC_CTRL, 387 SUNXI_LOSC_CTRL_RTC_YMD_ACC, 50)) { 388 dev_err(dev, "Failed to set rtc time.\n"); 389 return -1; 390 } 391 392 return 0; 393 } 394 395 static int sunxi_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) 396 { 397 struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); 398 399 if (!enabled) 400 sunxi_rtc_setaie(enabled, chip); 401 402 return 0; 403 } 404 405 static const struct rtc_class_ops sunxi_rtc_ops = { 406 .read_time = sunxi_rtc_gettime, 407 .set_time = sunxi_rtc_settime, 408 .read_alarm = sunxi_rtc_getalarm, 409 .set_alarm = sunxi_rtc_setalarm, 410 .alarm_irq_enable = sunxi_rtc_alarm_irq_enable 411 }; 412 413 static const struct of_device_id sunxi_rtc_dt_ids[] = { 414 { .compatible = "allwinner,sun4i-a10-rtc", .data = &data_year_param[0] }, 415 { .compatible = "allwinner,sun7i-a20-rtc", .data = &data_year_param[1] }, 416 { /* sentinel */ }, 417 }; 418 MODULE_DEVICE_TABLE(of, sunxi_rtc_dt_ids); 419 420 static int sunxi_rtc_probe(struct platform_device *pdev) 421 { 422 struct sunxi_rtc_dev *chip; 423 int ret; 424 425 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); 426 if (!chip) 427 return -ENOMEM; 428 429 platform_set_drvdata(pdev, chip); 430 chip->dev = &pdev->dev; 431 432 chip->rtc = devm_rtc_allocate_device(&pdev->dev); 433 if (IS_ERR(chip->rtc)) 434 return PTR_ERR(chip->rtc); 435 436 chip->base = devm_platform_ioremap_resource(pdev, 0); 437 if (IS_ERR(chip->base)) 438 return PTR_ERR(chip->base); 439 440 chip->irq = platform_get_irq(pdev, 0); 441 if (chip->irq < 0) 442 return chip->irq; 443 ret = devm_request_irq(&pdev->dev, chip->irq, sunxi_rtc_alarmirq, 444 0, dev_name(&pdev->dev), chip); 445 if (ret) { 446 dev_err(&pdev->dev, "Could not request IRQ\n"); 447 return ret; 448 } 449 450 chip->data_year = of_device_get_match_data(&pdev->dev); 451 if (!chip->data_year) { 452 dev_err(&pdev->dev, "Unable to setup RTC data\n"); 453 return -ENODEV; 454 } 455 456 /* clear the alarm count value */ 457 writel(0, chip->base + SUNXI_ALRM_DHMS); 458 459 /* disable alarm, not generate irq pending */ 460 writel(0, chip->base + SUNXI_ALRM_EN); 461 462 /* disable alarm week/cnt irq, unset to cpu */ 463 writel(0, chip->base + SUNXI_ALRM_IRQ_EN); 464 465 /* clear alarm week/cnt irq pending */ 466 writel(SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND, chip->base + 467 SUNXI_ALRM_IRQ_STA); 468 469 chip->rtc->ops = &sunxi_rtc_ops; 470 471 return devm_rtc_register_device(chip->rtc); 472 } 473 474 static struct platform_driver sunxi_rtc_driver = { 475 .probe = sunxi_rtc_probe, 476 .driver = { 477 .name = "sunxi-rtc", 478 .of_match_table = sunxi_rtc_dt_ids, 479 }, 480 }; 481 482 module_platform_driver(sunxi_rtc_driver); 483 484 MODULE_DESCRIPTION("sunxi RTC driver"); 485 MODULE_AUTHOR("Carlo Caione <carlo.caione@gmail.com>"); 486 MODULE_LICENSE("GPL"); 487