0001
0002
0003
0004
0005 #include <linux/init.h>
0006 #include <linux/io.h>
0007 #include <linux/kernel.h>
0008 #include <linux/module.h>
0009 #include <linux/of.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/pm_wakeirq.h>
0012 #include <linux/rtc.h>
0013 #include <linux/clk.h>
0014 #include <linux/mfd/syscon.h>
0015 #include <linux/regmap.h>
0016
0017 #define SNVS_LPREGISTER_OFFSET 0x34
0018
0019
0020 #define SNVS_LPCR 0x04
0021 #define SNVS_LPSR 0x18
0022 #define SNVS_LPSRTCMR 0x1c
0023 #define SNVS_LPSRTCLR 0x20
0024 #define SNVS_LPTAR 0x24
0025 #define SNVS_LPPGDR 0x30
0026
0027 #define SNVS_LPCR_SRTC_ENV (1 << 0)
0028 #define SNVS_LPCR_LPTA_EN (1 << 1)
0029 #define SNVS_LPCR_LPWUI_EN (1 << 3)
0030 #define SNVS_LPSR_LPTA (1 << 0)
0031
0032 #define SNVS_LPPGDR_INIT 0x41736166
0033 #define CNTR_TO_SECS_SH 15
0034
0035 struct snvs_rtc_data {
0036 struct rtc_device *rtc;
0037 struct regmap *regmap;
0038 int offset;
0039 int irq;
0040 struct clk *clk;
0041 };
0042
0043
0044 static u64 rtc_read_lpsrt(struct snvs_rtc_data *data)
0045 {
0046 u32 msb, lsb;
0047
0048 regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &msb);
0049 regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &lsb);
0050 return (u64)msb << 32 | lsb;
0051 }
0052
0053
0054
0055
0056 static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
0057 {
0058 u64 read1, read2;
0059 unsigned int timeout = 100;
0060
0061
0062
0063
0064
0065 read1 = rtc_read_lpsrt(data);
0066 do {
0067 read2 = read1;
0068 read1 = rtc_read_lpsrt(data);
0069 } while (read1 != read2 && --timeout);
0070 if (!timeout)
0071 dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
0072
0073
0074 return (u32) (read1 >> CNTR_TO_SECS_SH);
0075 }
0076
0077
0078 static int rtc_read_lp_counter_lsb(struct snvs_rtc_data *data, u32 *lsb)
0079 {
0080 u32 count1, count2;
0081 unsigned int timeout = 100;
0082
0083 regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
0084 do {
0085 count2 = count1;
0086 regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
0087 } while (count1 != count2 && --timeout);
0088 if (!timeout) {
0089 dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
0090 return -ETIMEDOUT;
0091 }
0092
0093 *lsb = count1;
0094 return 0;
0095 }
0096
0097 static int rtc_write_sync_lp(struct snvs_rtc_data *data)
0098 {
0099 u32 count1, count2;
0100 u32 elapsed;
0101 unsigned int timeout = 1000;
0102 int ret;
0103
0104 ret = rtc_read_lp_counter_lsb(data, &count1);
0105 if (ret)
0106 return ret;
0107
0108
0109 do {
0110 ret = rtc_read_lp_counter_lsb(data, &count2);
0111 if (ret)
0112 return ret;
0113 elapsed = count2 - count1;
0114 } while (elapsed < 3 && --timeout);
0115 if (!timeout) {
0116 dev_err(&data->rtc->dev, "Timeout waiting for LPSRT Counter to change\n");
0117 return -ETIMEDOUT;
0118 }
0119 return 0;
0120 }
0121
0122 static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)
0123 {
0124 int timeout = 1000;
0125 u32 lpcr;
0126
0127 regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_SRTC_ENV,
0128 enable ? SNVS_LPCR_SRTC_ENV : 0);
0129
0130 while (--timeout) {
0131 regmap_read(data->regmap, data->offset + SNVS_LPCR, &lpcr);
0132
0133 if (enable) {
0134 if (lpcr & SNVS_LPCR_SRTC_ENV)
0135 break;
0136 } else {
0137 if (!(lpcr & SNVS_LPCR_SRTC_ENV))
0138 break;
0139 }
0140 }
0141
0142 if (!timeout)
0143 return -ETIMEDOUT;
0144
0145 return 0;
0146 }
0147
0148 static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm)
0149 {
0150 struct snvs_rtc_data *data = dev_get_drvdata(dev);
0151 unsigned long time;
0152 int ret;
0153
0154 ret = clk_enable(data->clk);
0155 if (ret)
0156 return ret;
0157
0158 time = rtc_read_lp_counter(data);
0159 rtc_time64_to_tm(time, tm);
0160
0161 clk_disable(data->clk);
0162
0163 return 0;
0164 }
0165
0166 static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
0167 {
0168 struct snvs_rtc_data *data = dev_get_drvdata(dev);
0169 unsigned long time = rtc_tm_to_time64(tm);
0170 int ret;
0171
0172 ret = clk_enable(data->clk);
0173 if (ret)
0174 return ret;
0175
0176
0177 ret = snvs_rtc_enable(data, false);
0178 if (ret)
0179 return ret;
0180
0181
0182 regmap_write(data->regmap, data->offset + SNVS_LPSRTCLR, time << CNTR_TO_SECS_SH);
0183 regmap_write(data->regmap, data->offset + SNVS_LPSRTCMR, time >> (32 - CNTR_TO_SECS_SH));
0184
0185
0186 ret = snvs_rtc_enable(data, true);
0187
0188 clk_disable(data->clk);
0189
0190 return ret;
0191 }
0192
0193 static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
0194 {
0195 struct snvs_rtc_data *data = dev_get_drvdata(dev);
0196 u32 lptar, lpsr;
0197 int ret;
0198
0199 ret = clk_enable(data->clk);
0200 if (ret)
0201 return ret;
0202
0203 regmap_read(data->regmap, data->offset + SNVS_LPTAR, &lptar);
0204 rtc_time64_to_tm(lptar, &alrm->time);
0205
0206 regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);
0207 alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0;
0208
0209 clk_disable(data->clk);
0210
0211 return 0;
0212 }
0213
0214 static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
0215 {
0216 struct snvs_rtc_data *data = dev_get_drvdata(dev);
0217 int ret;
0218
0219 ret = clk_enable(data->clk);
0220 if (ret)
0221 return ret;
0222
0223 regmap_update_bits(data->regmap, data->offset + SNVS_LPCR,
0224 (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN),
0225 enable ? (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN) : 0);
0226
0227 ret = rtc_write_sync_lp(data);
0228
0229 clk_disable(data->clk);
0230
0231 return ret;
0232 }
0233
0234 static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
0235 {
0236 struct snvs_rtc_data *data = dev_get_drvdata(dev);
0237 unsigned long time = rtc_tm_to_time64(&alrm->time);
0238 int ret;
0239
0240 ret = clk_enable(data->clk);
0241 if (ret)
0242 return ret;
0243
0244 regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0);
0245 ret = rtc_write_sync_lp(data);
0246 if (ret)
0247 return ret;
0248 regmap_write(data->regmap, data->offset + SNVS_LPTAR, time);
0249
0250
0251 regmap_write(data->regmap, data->offset + SNVS_LPSR, SNVS_LPSR_LPTA);
0252
0253 clk_disable(data->clk);
0254
0255 return snvs_rtc_alarm_irq_enable(dev, alrm->enabled);
0256 }
0257
0258 static const struct rtc_class_ops snvs_rtc_ops = {
0259 .read_time = snvs_rtc_read_time,
0260 .set_time = snvs_rtc_set_time,
0261 .read_alarm = snvs_rtc_read_alarm,
0262 .set_alarm = snvs_rtc_set_alarm,
0263 .alarm_irq_enable = snvs_rtc_alarm_irq_enable,
0264 };
0265
0266 static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)
0267 {
0268 struct device *dev = dev_id;
0269 struct snvs_rtc_data *data = dev_get_drvdata(dev);
0270 u32 lpsr;
0271 u32 events = 0;
0272
0273 clk_enable(data->clk);
0274
0275 regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);
0276
0277 if (lpsr & SNVS_LPSR_LPTA) {
0278 events |= (RTC_AF | RTC_IRQF);
0279
0280
0281 snvs_rtc_alarm_irq_enable(dev, 0);
0282
0283 rtc_update_irq(data->rtc, 1, events);
0284 }
0285
0286
0287 regmap_write(data->regmap, data->offset + SNVS_LPSR, lpsr);
0288
0289 clk_disable(data->clk);
0290
0291 return events ? IRQ_HANDLED : IRQ_NONE;
0292 }
0293
0294 static const struct regmap_config snvs_rtc_config = {
0295 .reg_bits = 32,
0296 .val_bits = 32,
0297 .reg_stride = 4,
0298 };
0299
0300 static void snvs_rtc_action(void *data)
0301 {
0302 clk_disable_unprepare(data);
0303 }
0304
0305 static int snvs_rtc_probe(struct platform_device *pdev)
0306 {
0307 struct snvs_rtc_data *data;
0308 int ret;
0309 void __iomem *mmio;
0310
0311 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
0312 if (!data)
0313 return -ENOMEM;
0314
0315 data->rtc = devm_rtc_allocate_device(&pdev->dev);
0316 if (IS_ERR(data->rtc))
0317 return PTR_ERR(data->rtc);
0318
0319 data->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "regmap");
0320
0321 if (IS_ERR(data->regmap)) {
0322 dev_warn(&pdev->dev, "snvs rtc: you use old dts file, please update it\n");
0323
0324 mmio = devm_platform_ioremap_resource(pdev, 0);
0325 if (IS_ERR(mmio))
0326 return PTR_ERR(mmio);
0327
0328 data->regmap = devm_regmap_init_mmio(&pdev->dev, mmio, &snvs_rtc_config);
0329 } else {
0330 data->offset = SNVS_LPREGISTER_OFFSET;
0331 of_property_read_u32(pdev->dev.of_node, "offset", &data->offset);
0332 }
0333
0334 if (IS_ERR(data->regmap)) {
0335 dev_err(&pdev->dev, "Can't find snvs syscon\n");
0336 return -ENODEV;
0337 }
0338
0339 data->irq = platform_get_irq(pdev, 0);
0340 if (data->irq < 0)
0341 return data->irq;
0342
0343 data->clk = devm_clk_get(&pdev->dev, "snvs-rtc");
0344 if (IS_ERR(data->clk)) {
0345 data->clk = NULL;
0346 } else {
0347 ret = clk_prepare_enable(data->clk);
0348 if (ret) {
0349 dev_err(&pdev->dev,
0350 "Could not prepare or enable the snvs clock\n");
0351 return ret;
0352 }
0353 }
0354
0355 ret = devm_add_action_or_reset(&pdev->dev, snvs_rtc_action, data->clk);
0356 if (ret)
0357 return ret;
0358
0359 platform_set_drvdata(pdev, data);
0360
0361
0362 regmap_write(data->regmap, data->offset + SNVS_LPPGDR, SNVS_LPPGDR_INIT);
0363
0364
0365 regmap_write(data->regmap, data->offset + SNVS_LPSR, 0xffffffff);
0366
0367
0368 ret = snvs_rtc_enable(data, true);
0369 if (ret) {
0370 dev_err(&pdev->dev, "failed to enable rtc %d\n", ret);
0371 return ret;
0372 }
0373
0374 device_init_wakeup(&pdev->dev, true);
0375 ret = dev_pm_set_wake_irq(&pdev->dev, data->irq);
0376 if (ret)
0377 dev_err(&pdev->dev, "failed to enable irq wake\n");
0378
0379 ret = devm_request_irq(&pdev->dev, data->irq, snvs_rtc_irq_handler,
0380 IRQF_SHARED, "rtc alarm", &pdev->dev);
0381 if (ret) {
0382 dev_err(&pdev->dev, "failed to request irq %d: %d\n",
0383 data->irq, ret);
0384 return ret;
0385 }
0386
0387 data->rtc->ops = &snvs_rtc_ops;
0388 data->rtc->range_max = U32_MAX;
0389
0390 return devm_rtc_register_device(data->rtc);
0391 }
0392
0393 static int __maybe_unused snvs_rtc_suspend_noirq(struct device *dev)
0394 {
0395 struct snvs_rtc_data *data = dev_get_drvdata(dev);
0396
0397 clk_disable(data->clk);
0398
0399 return 0;
0400 }
0401
0402 static int __maybe_unused snvs_rtc_resume_noirq(struct device *dev)
0403 {
0404 struct snvs_rtc_data *data = dev_get_drvdata(dev);
0405
0406 if (data->clk)
0407 return clk_enable(data->clk);
0408
0409 return 0;
0410 }
0411
0412 static const struct dev_pm_ops snvs_rtc_pm_ops = {
0413 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(snvs_rtc_suspend_noirq, snvs_rtc_resume_noirq)
0414 };
0415
0416 static const struct of_device_id snvs_dt_ids[] = {
0417 { .compatible = "fsl,sec-v4.0-mon-rtc-lp", },
0418 { }
0419 };
0420 MODULE_DEVICE_TABLE(of, snvs_dt_ids);
0421
0422 static struct platform_driver snvs_rtc_driver = {
0423 .driver = {
0424 .name = "snvs_rtc",
0425 .pm = &snvs_rtc_pm_ops,
0426 .of_match_table = snvs_dt_ids,
0427 },
0428 .probe = snvs_rtc_probe,
0429 };
0430 module_platform_driver(snvs_rtc_driver);
0431
0432 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
0433 MODULE_DESCRIPTION("Freescale SNVS RTC Driver");
0434 MODULE_LICENSE("GPL");