Lines Matching +full:silicon +full:- +full:id

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * drivers/rtc/rtc-pl031.c
12 * Copyright 2010 (c) ST-Ericsson AB
55 #define RTC_SEC_MASK (0x3F << RTC_SEC_SHIFT) /* Second [0-59] */
57 #define RTC_MIN_MASK (0x3F << RTC_MIN_SHIFT) /* Minute [0-59] */
59 #define RTC_HOUR_MASK (0x1F << RTC_HOUR_SHIFT) /* Hour [0-23] */
61 #define RTC_WDAY_MASK (0x7 << RTC_WDAY_SHIFT) /* Day of Week [1-7] 1=Sunday */
63 #define RTC_MDAY_MASK (0x1F << RTC_MDAY_SHIFT) /* Day of Month [1-31] */
65 #define RTC_MON_MASK (0xF << RTC_MON_SHIFT) /* Month [1-12] 1=January */
70 * struct pl031_vendor_data - per-vendor variations
71 * @ops: the vendor-specific operations used on this silicon version
72 * @clockwatch: if this is an ST Microelectronics silicon version with a
74 * @st_weekday: if this is an ST Microelectronics silicon version that need
100 writel(RTC_BIT_AI, ldata->base + RTC_ICR); in pl031_alarm_irq_enable()
102 imsc = readl(ldata->base + RTC_IMSC); in pl031_alarm_irq_enable()
105 writel(imsc | RTC_BIT_AI, ldata->base + RTC_IMSC); in pl031_alarm_irq_enable()
107 writel(imsc & ~RTC_BIT_AI, ldata->base + RTC_IMSC); in pl031_alarm_irq_enable()
119 int year = tm->tm_year + 1900; in pl031_stv2_tm_to_time()
120 int wday = tm->tm_wday; in pl031_stv2_tm_to_time()
123 if (wday < -1 || wday > 6) { in pl031_stv2_tm_to_time()
124 dev_err(dev, "invalid wday value %d\n", tm->tm_wday); in pl031_stv2_tm_to_time()
125 return -EINVAL; in pl031_stv2_tm_to_time()
126 } else if (wday == -1) { in pl031_stv2_tm_to_time()
136 *st_time = ((tm->tm_mon + 1) << RTC_MON_SHIFT) in pl031_stv2_tm_to_time()
137 | (tm->tm_mday << RTC_MDAY_SHIFT) in pl031_stv2_tm_to_time()
139 | (tm->tm_hour << RTC_HOUR_SHIFT) in pl031_stv2_tm_to_time()
140 | (tm->tm_min << RTC_MIN_SHIFT) in pl031_stv2_tm_to_time()
141 | (tm->tm_sec << RTC_SEC_SHIFT); in pl031_stv2_tm_to_time()
152 tm->tm_year = bcd2bin(bcd_year) + (bcd2bin(bcd_year >> 8) * 100); in pl031_stv2_time_to_tm()
153 tm->tm_mon = ((st_time & RTC_MON_MASK) >> RTC_MON_SHIFT) - 1; in pl031_stv2_time_to_tm()
154 tm->tm_mday = ((st_time & RTC_MDAY_MASK) >> RTC_MDAY_SHIFT); in pl031_stv2_time_to_tm()
155 tm->tm_wday = ((st_time & RTC_WDAY_MASK) >> RTC_WDAY_SHIFT) - 1; in pl031_stv2_time_to_tm()
156 tm->tm_hour = ((st_time & RTC_HOUR_MASK) >> RTC_HOUR_SHIFT); in pl031_stv2_time_to_tm()
157 tm->tm_min = ((st_time & RTC_MIN_MASK) >> RTC_MIN_SHIFT); in pl031_stv2_time_to_tm()
158 tm->tm_sec = ((st_time & RTC_SEC_MASK) >> RTC_SEC_SHIFT); in pl031_stv2_time_to_tm()
160 tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); in pl031_stv2_time_to_tm()
161 tm->tm_year -= 1900; in pl031_stv2_time_to_tm()
170 pl031_stv2_time_to_tm(readl(ldata->base + RTC_DR), in pl031_stv2_read_time()
171 readl(ldata->base + RTC_YDR), tm); in pl031_stv2_read_time()
185 writel(bcd_year, ldata->base + RTC_YLR); in pl031_stv2_set_time()
186 writel(time, ldata->base + RTC_LR); in pl031_stv2_set_time()
197 ret = pl031_stv2_time_to_tm(readl(ldata->base + RTC_MR), in pl031_stv2_read_alarm()
198 readl(ldata->base + RTC_YMR), &alarm->time); in pl031_stv2_read_alarm()
200 alarm->pending = readl(ldata->base + RTC_RIS) & RTC_BIT_AI; in pl031_stv2_read_alarm()
201 alarm->enabled = readl(ldata->base + RTC_IMSC) & RTC_BIT_AI; in pl031_stv2_read_alarm()
213 ret = pl031_stv2_tm_to_time(dev, &alarm->time, in pl031_stv2_set_alarm()
216 writel(bcd_year, ldata->base + RTC_YMR); in pl031_stv2_set_alarm()
217 writel(time, ldata->base + RTC_MR); in pl031_stv2_set_alarm()
219 pl031_alarm_irq_enable(dev, alarm->enabled); in pl031_stv2_set_alarm()
231 rtcmis = readl(ldata->base + RTC_MIS); in pl031_interrupt()
233 writel(RTC_BIT_AI, ldata->base + RTC_ICR); in pl031_interrupt()
235 rtc_update_irq(ldata->rtc, 1, events); in pl031_interrupt()
247 rtc_time64_to_tm(readl(ldata->base + RTC_DR), tm); in pl031_read_time()
256 writel(rtc_tm_to_time64(tm), ldata->base + RTC_LR); in pl031_set_time()
265 rtc_time64_to_tm(readl(ldata->base + RTC_MR), &alarm->time); in pl031_read_alarm()
267 alarm->pending = readl(ldata->base + RTC_RIS) & RTC_BIT_AI; in pl031_read_alarm()
268 alarm->enabled = readl(ldata->base + RTC_IMSC) & RTC_BIT_AI; in pl031_read_alarm()
277 writel(rtc_tm_to_time64(&alarm->time), ldata->base + RTC_MR); in pl031_set_alarm()
278 pl031_alarm_irq_enable(dev, alarm->enabled); in pl031_set_alarm()
285 struct pl031_local *ldata = dev_get_drvdata(&adev->dev); in pl031_remove()
287 dev_pm_clear_wake_irq(&adev->dev); in pl031_remove()
288 device_init_wakeup(&adev->dev, false); in pl031_remove()
289 if (adev->irq[0]) in pl031_remove()
290 free_irq(adev->irq[0], ldata); in pl031_remove()
294 static int pl031_probe(struct amba_device *adev, const struct amba_id *id) in pl031_probe() argument
298 struct pl031_vendor_data *vendor = id->data; in pl031_probe()
306 ldata = devm_kzalloc(&adev->dev, sizeof(struct pl031_local), in pl031_probe()
308 ops = devm_kmemdup(&adev->dev, &vendor->ops, sizeof(vendor->ops), in pl031_probe()
311 ret = -ENOMEM; in pl031_probe()
315 ldata->vendor = vendor; in pl031_probe()
316 ldata->base = devm_ioremap(&adev->dev, adev->res.start, in pl031_probe()
317 resource_size(&adev->res)); in pl031_probe()
318 if (!ldata->base) { in pl031_probe()
319 ret = -ENOMEM; in pl031_probe()
325 dev_dbg(&adev->dev, "designer ID = 0x%02x\n", amba_manf(adev)); in pl031_probe()
326 dev_dbg(&adev->dev, "revision = 0x%01x\n", amba_rev(adev)); in pl031_probe()
328 data = readl(ldata->base + RTC_CR); in pl031_probe()
330 if (vendor->clockwatch) in pl031_probe()
334 writel(data, ldata->base + RTC_CR); in pl031_probe()
338 * weekday for 2000-01-01. Correct the erroneous sunday to saturday. in pl031_probe()
340 if (vendor->st_weekday) { in pl031_probe()
341 if (readl(ldata->base + RTC_YDR) == 0x2000) { in pl031_probe()
342 time = readl(ldata->base + RTC_DR); in pl031_probe()
347 writel(0x2000, ldata->base + RTC_YLR); in pl031_probe()
348 writel(time, ldata->base + RTC_LR); in pl031_probe()
353 device_init_wakeup(&adev->dev, true); in pl031_probe()
354 ldata->rtc = devm_rtc_allocate_device(&adev->dev); in pl031_probe()
355 if (IS_ERR(ldata->rtc)) { in pl031_probe()
356 ret = PTR_ERR(ldata->rtc); in pl031_probe()
360 if (!adev->irq[0]) in pl031_probe()
361 clear_bit(RTC_FEATURE_ALARM, ldata->rtc->features); in pl031_probe()
363 ldata->rtc->ops = ops; in pl031_probe()
364 ldata->rtc->range_min = vendor->range_min; in pl031_probe()
365 ldata->rtc->range_max = vendor->range_max; in pl031_probe()
367 ret = devm_rtc_register_device(ldata->rtc); in pl031_probe()
371 if (adev->irq[0]) { in pl031_probe()
372 ret = request_irq(adev->irq[0], pl031_interrupt, in pl031_probe()
373 vendor->irqflags, "rtc-pl031", ldata); in pl031_probe()
376 dev_pm_set_wake_irq(&adev->dev, adev->irq[0]); in pl031_probe()
437 .id = 0x00041031,
443 .id = 0x00180031,
448 .id = 0x00280031,
459 .name = "rtc-pl031",