linux/drivers/rtc/rtc-tegra.c
<<
>>
Prefs
   1/*
   2 * An RTC driver for the NVIDIA Tegra 200 series internal RTC.
   3 *
   4 * Copyright (c) 2010, NVIDIA Corporation.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful, but WITHOUT
  12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  14 * more details.
  15 *
  16 * You should have received a copy of the GNU General Public License along
  17 * with this program; if not, write to the Free Software Foundation, Inc.,
  18 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  19 */
  20
  21#include <linux/clk.h>
  22#include <linux/delay.h>
  23#include <linux/init.h>
  24#include <linux/io.h>
  25#include <linux/irq.h>
  26#include <linux/kernel.h>
  27#include <linux/module.h>
  28#include <linux/platform_device.h>
  29#include <linux/pm.h>
  30#include <linux/rtc.h>
  31#include <linux/slab.h>
  32
  33/* set to 1 = busy every eight 32kHz clocks during copy of sec+msec to AHB */
  34#define TEGRA_RTC_REG_BUSY                      0x004
  35#define TEGRA_RTC_REG_SECONDS                   0x008
  36/* when msec is read, the seconds are buffered into shadow seconds. */
  37#define TEGRA_RTC_REG_SHADOW_SECONDS            0x00c
  38#define TEGRA_RTC_REG_MILLI_SECONDS             0x010
  39#define TEGRA_RTC_REG_SECONDS_ALARM0            0x014
  40#define TEGRA_RTC_REG_SECONDS_ALARM1            0x018
  41#define TEGRA_RTC_REG_MILLI_SECONDS_ALARM0      0x01c
  42#define TEGRA_RTC_REG_INTR_MASK                 0x028
  43/* write 1 bits to clear status bits */
  44#define TEGRA_RTC_REG_INTR_STATUS               0x02c
  45
  46/* bits in INTR_MASK */
  47#define TEGRA_RTC_INTR_MASK_MSEC_CDN_ALARM      (1<<4)
  48#define TEGRA_RTC_INTR_MASK_SEC_CDN_ALARM       (1<<3)
  49#define TEGRA_RTC_INTR_MASK_MSEC_ALARM          (1<<2)
  50#define TEGRA_RTC_INTR_MASK_SEC_ALARM1          (1<<1)
  51#define TEGRA_RTC_INTR_MASK_SEC_ALARM0          (1<<0)
  52
  53/* bits in INTR_STATUS */
  54#define TEGRA_RTC_INTR_STATUS_MSEC_CDN_ALARM    (1<<4)
  55#define TEGRA_RTC_INTR_STATUS_SEC_CDN_ALARM     (1<<3)
  56#define TEGRA_RTC_INTR_STATUS_MSEC_ALARM        (1<<2)
  57#define TEGRA_RTC_INTR_STATUS_SEC_ALARM1        (1<<1)
  58#define TEGRA_RTC_INTR_STATUS_SEC_ALARM0        (1<<0)
  59
  60struct tegra_rtc_info {
  61        struct platform_device  *pdev;
  62        struct rtc_device       *rtc_dev;
  63        void __iomem            *rtc_base; /* NULL if not initialized. */
  64        struct clk              *clk;
  65        int                     tegra_rtc_irq; /* alarm and periodic irq */
  66        spinlock_t              tegra_rtc_lock;
  67};
  68
  69/* RTC hardware is busy when it is updating its values over AHB once
  70 * every eight 32kHz clocks (~250uS).
  71 * outside of these updates the CPU is free to write.
  72 * CPU is always free to read.
  73 */
  74static inline u32 tegra_rtc_check_busy(struct tegra_rtc_info *info)
  75{
  76        return readl(info->rtc_base + TEGRA_RTC_REG_BUSY) & 1;
  77}
  78
  79/* Wait for hardware to be ready for writing.
  80 * This function tries to maximize the amount of time before the next update.
  81 * It does this by waiting for the RTC to become busy with its periodic update,
  82 * then returning once the RTC first becomes not busy.
  83 * This periodic update (where the seconds and milliseconds are copied to the
  84 * AHB side) occurs every eight 32kHz clocks (~250uS).
  85 * The behavior of this function allows us to make some assumptions without
  86 * introducing a race, because 250uS is plenty of time to read/write a value.
  87 */
  88static int tegra_rtc_wait_while_busy(struct device *dev)
  89{
  90        struct tegra_rtc_info *info = dev_get_drvdata(dev);
  91
  92        int retries = 500; /* ~490 us is the worst case, ~250 us is best. */
  93
  94        /* first wait for the RTC to become busy. this is when it
  95         * posts its updated seconds+msec registers to AHB side. */
  96        while (tegra_rtc_check_busy(info)) {
  97                if (!retries--)
  98                        goto retry_failed;
  99                udelay(1);
 100        }
 101
 102        /* now we have about 250 us to manipulate registers */
 103        return 0;
 104
 105retry_failed:
 106        dev_err(dev, "write failed:retry count exceeded.\n");
 107        return -ETIMEDOUT;
 108}
 109
 110static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm)
 111{
 112        struct tegra_rtc_info *info = dev_get_drvdata(dev);
 113        unsigned long sec, msec;
 114        unsigned long sl_irq_flags;
 115
 116        /* RTC hardware copies seconds to shadow seconds when a read
 117         * of milliseconds occurs. use a lock to keep other threads out. */
 118        spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags);
 119
 120        msec = readl(info->rtc_base + TEGRA_RTC_REG_MILLI_SECONDS);
 121        sec = readl(info->rtc_base + TEGRA_RTC_REG_SHADOW_SECONDS);
 122
 123        spin_unlock_irqrestore(&info->tegra_rtc_lock, sl_irq_flags);
 124
 125        rtc_time_to_tm(sec, tm);
 126
 127        dev_vdbg(dev, "time read as %lu. %d/%d/%d %d:%02u:%02u\n",
 128                sec,
 129                tm->tm_mon + 1,
 130                tm->tm_mday,
 131                tm->tm_year + 1900,
 132                tm->tm_hour,
 133                tm->tm_min,
 134                tm->tm_sec
 135        );
 136
 137        return 0;
 138}
 139
 140static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm)
 141{
 142        struct tegra_rtc_info *info = dev_get_drvdata(dev);
 143        unsigned long sec;
 144        int ret;
 145
 146        /* convert tm to seconds. */
 147        rtc_tm_to_time(tm, &sec);
 148
 149        dev_vdbg(dev, "time set to %lu. %d/%d/%d %d:%02u:%02u\n",
 150                sec,
 151                tm->tm_mon+1,
 152                tm->tm_mday,
 153                tm->tm_year+1900,
 154                tm->tm_hour,
 155                tm->tm_min,
 156                tm->tm_sec
 157        );
 158
 159        /* seconds only written if wait succeeded. */
 160        ret = tegra_rtc_wait_while_busy(dev);
 161        if (!ret)
 162                writel(sec, info->rtc_base + TEGRA_RTC_REG_SECONDS);
 163
 164        dev_vdbg(dev, "time read back as %d\n",
 165                readl(info->rtc_base + TEGRA_RTC_REG_SECONDS));
 166
 167        return ret;
 168}
 169
 170static int tegra_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 171{
 172        struct tegra_rtc_info *info = dev_get_drvdata(dev);
 173        unsigned long sec;
 174        unsigned tmp;
 175
 176        sec = readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0);
 177
 178        if (sec == 0) {
 179                /* alarm is disabled. */
 180                alarm->enabled = 0;
 181        } else {
 182                /* alarm is enabled. */
 183                alarm->enabled = 1;
 184                rtc_time_to_tm(sec, &alarm->time);
 185        }
 186
 187        tmp = readl(info->rtc_base + TEGRA_RTC_REG_INTR_STATUS);
 188        alarm->pending = (tmp & TEGRA_RTC_INTR_STATUS_SEC_ALARM0) != 0;
 189
 190        return 0;
 191}
 192
 193static int tegra_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 194{
 195        struct tegra_rtc_info *info = dev_get_drvdata(dev);
 196        unsigned status;
 197        unsigned long sl_irq_flags;
 198
 199        tegra_rtc_wait_while_busy(dev);
 200        spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags);
 201
 202        /* read the original value, and OR in the flag. */
 203        status = readl(info->rtc_base + TEGRA_RTC_REG_INTR_MASK);
 204        if (enabled)
 205                status |= TEGRA_RTC_INTR_MASK_SEC_ALARM0; /* set it */
 206        else
 207                status &= ~TEGRA_RTC_INTR_MASK_SEC_ALARM0; /* clear it */
 208
 209        writel(status, info->rtc_base + TEGRA_RTC_REG_INTR_MASK);
 210
 211        spin_unlock_irqrestore(&info->tegra_rtc_lock, sl_irq_flags);
 212
 213        return 0;
 214}
 215
 216static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 217{
 218        struct tegra_rtc_info *info = dev_get_drvdata(dev);
 219        unsigned long sec;
 220
 221        if (alarm->enabled)
 222                rtc_tm_to_time(&alarm->time, &sec);
 223        else
 224                sec = 0;
 225
 226        tegra_rtc_wait_while_busy(dev);
 227        writel(sec, info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0);
 228        dev_vdbg(dev, "alarm read back as %d\n",
 229                readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0));
 230
 231        /* if successfully written and alarm is enabled ... */
 232        if (sec) {
 233                tegra_rtc_alarm_irq_enable(dev, 1);
 234
 235                dev_vdbg(dev, "alarm set as %lu. %d/%d/%d %d:%02u:%02u\n",
 236                        sec,
 237                        alarm->time.tm_mon+1,
 238                        alarm->time.tm_mday,
 239                        alarm->time.tm_year+1900,
 240                        alarm->time.tm_hour,
 241                        alarm->time.tm_min,
 242                        alarm->time.tm_sec);
 243        } else {
 244                /* disable alarm if 0 or write error. */
 245                dev_vdbg(dev, "alarm disabled\n");
 246                tegra_rtc_alarm_irq_enable(dev, 0);
 247        }
 248
 249        return 0;
 250}
 251
 252static int tegra_rtc_proc(struct device *dev, struct seq_file *seq)
 253{
 254        if (!dev || !dev->driver)
 255                return 0;
 256
 257        seq_printf(seq, "name\t\t: %s\n", dev_name(dev));
 258
 259        return 0;
 260}
 261
 262static irqreturn_t tegra_rtc_irq_handler(int irq, void *data)
 263{
 264        struct device *dev = data;
 265        struct tegra_rtc_info *info = dev_get_drvdata(dev);
 266        unsigned long events = 0;
 267        unsigned status;
 268        unsigned long sl_irq_flags;
 269
 270        status = readl(info->rtc_base + TEGRA_RTC_REG_INTR_STATUS);
 271        if (status) {
 272                /* clear the interrupt masks and status on any irq. */
 273                tegra_rtc_wait_while_busy(dev);
 274                spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags);
 275                writel(0, info->rtc_base + TEGRA_RTC_REG_INTR_MASK);
 276                writel(status, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS);
 277                spin_unlock_irqrestore(&info->tegra_rtc_lock, sl_irq_flags);
 278        }
 279
 280        /* check if Alarm */
 281        if ((status & TEGRA_RTC_INTR_STATUS_SEC_ALARM0))
 282                events |= RTC_IRQF | RTC_AF;
 283
 284        /* check if Periodic */
 285        if ((status & TEGRA_RTC_INTR_STATUS_SEC_CDN_ALARM))
 286                events |= RTC_IRQF | RTC_PF;
 287
 288        rtc_update_irq(info->rtc_dev, 1, events);
 289
 290        return IRQ_HANDLED;
 291}
 292
 293static const struct rtc_class_ops tegra_rtc_ops = {
 294        .read_time      = tegra_rtc_read_time,
 295        .set_time       = tegra_rtc_set_time,
 296        .read_alarm     = tegra_rtc_read_alarm,
 297        .set_alarm      = tegra_rtc_set_alarm,
 298        .proc           = tegra_rtc_proc,
 299        .alarm_irq_enable = tegra_rtc_alarm_irq_enable,
 300};
 301
 302static const struct of_device_id tegra_rtc_dt_match[] = {
 303        { .compatible = "nvidia,tegra20-rtc", },
 304        {}
 305};
 306MODULE_DEVICE_TABLE(of, tegra_rtc_dt_match);
 307
 308static int __init tegra_rtc_probe(struct platform_device *pdev)
 309{
 310        struct tegra_rtc_info *info;
 311        struct resource *res;
 312        int ret;
 313
 314        info = devm_kzalloc(&pdev->dev, sizeof(struct tegra_rtc_info),
 315                GFP_KERNEL);
 316        if (!info)
 317                return -ENOMEM;
 318
 319        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 320        info->rtc_base = devm_ioremap_resource(&pdev->dev, res);
 321        if (IS_ERR(info->rtc_base))
 322                return PTR_ERR(info->rtc_base);
 323
 324        info->tegra_rtc_irq = platform_get_irq(pdev, 0);
 325        if (info->tegra_rtc_irq <= 0)
 326                return -EBUSY;
 327
 328        info->clk = devm_clk_get(&pdev->dev, NULL);
 329        if (IS_ERR(info->clk))
 330                return PTR_ERR(info->clk);
 331
 332        ret = clk_prepare_enable(info->clk);
 333        if (ret < 0)
 334                return ret;
 335
 336        /* set context info. */
 337        info->pdev = pdev;
 338        spin_lock_init(&info->tegra_rtc_lock);
 339
 340        platform_set_drvdata(pdev, info);
 341
 342        /* clear out the hardware. */
 343        writel(0, info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0);
 344        writel(0xffffffff, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS);
 345        writel(0, info->rtc_base + TEGRA_RTC_REG_INTR_MASK);
 346
 347        device_init_wakeup(&pdev->dev, 1);
 348
 349        info->rtc_dev = devm_rtc_device_register(&pdev->dev,
 350                                dev_name(&pdev->dev), &tegra_rtc_ops,
 351                                THIS_MODULE);
 352        if (IS_ERR(info->rtc_dev)) {
 353                ret = PTR_ERR(info->rtc_dev);
 354                dev_err(&pdev->dev, "Unable to register device (err=%d).\n",
 355                        ret);
 356                goto disable_clk;
 357        }
 358
 359        ret = devm_request_irq(&pdev->dev, info->tegra_rtc_irq,
 360                        tegra_rtc_irq_handler, IRQF_TRIGGER_HIGH,
 361                        dev_name(&pdev->dev), &pdev->dev);
 362        if (ret) {
 363                dev_err(&pdev->dev,
 364                        "Unable to request interrupt for device (err=%d).\n",
 365                        ret);
 366                goto disable_clk;
 367        }
 368
 369        dev_notice(&pdev->dev, "Tegra internal Real Time Clock\n");
 370
 371        return 0;
 372
 373disable_clk:
 374        clk_disable_unprepare(info->clk);
 375        return ret;
 376}
 377
 378static int tegra_rtc_remove(struct platform_device *pdev)
 379{
 380        struct tegra_rtc_info *info = platform_get_drvdata(pdev);
 381
 382        clk_disable_unprepare(info->clk);
 383
 384        return 0;
 385}
 386
 387#ifdef CONFIG_PM_SLEEP
 388static int tegra_rtc_suspend(struct device *dev)
 389{
 390        struct tegra_rtc_info *info = dev_get_drvdata(dev);
 391
 392        tegra_rtc_wait_while_busy(dev);
 393
 394        /* only use ALARM0 as a wake source. */
 395        writel(0xffffffff, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS);
 396        writel(TEGRA_RTC_INTR_STATUS_SEC_ALARM0,
 397                info->rtc_base + TEGRA_RTC_REG_INTR_MASK);
 398
 399        dev_vdbg(dev, "alarm sec = %d\n",
 400                readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0));
 401
 402        dev_vdbg(dev, "Suspend (device_may_wakeup=%d) irq:%d\n",
 403                device_may_wakeup(dev), info->tegra_rtc_irq);
 404
 405        /* leave the alarms on as a wake source. */
 406        if (device_may_wakeup(dev))
 407                enable_irq_wake(info->tegra_rtc_irq);
 408
 409        return 0;
 410}
 411
 412static int tegra_rtc_resume(struct device *dev)
 413{
 414        struct tegra_rtc_info *info = dev_get_drvdata(dev);
 415
 416        dev_vdbg(dev, "Resume (device_may_wakeup=%d)\n",
 417                device_may_wakeup(dev));
 418        /* alarms were left on as a wake source, turn them off. */
 419        if (device_may_wakeup(dev))
 420                disable_irq_wake(info->tegra_rtc_irq);
 421
 422        return 0;
 423}
 424#endif
 425
 426static SIMPLE_DEV_PM_OPS(tegra_rtc_pm_ops, tegra_rtc_suspend, tegra_rtc_resume);
 427
 428static void tegra_rtc_shutdown(struct platform_device *pdev)
 429{
 430        dev_vdbg(&pdev->dev, "disabling interrupts.\n");
 431        tegra_rtc_alarm_irq_enable(&pdev->dev, 0);
 432}
 433
 434MODULE_ALIAS("platform:tegra_rtc");
 435static struct platform_driver tegra_rtc_driver = {
 436        .remove         = tegra_rtc_remove,
 437        .shutdown       = tegra_rtc_shutdown,
 438        .driver         = {
 439                .name   = "tegra_rtc",
 440                .of_match_table = tegra_rtc_dt_match,
 441                .pm     = &tegra_rtc_pm_ops,
 442        },
 443};
 444
 445module_platform_driver_probe(tegra_rtc_driver, tegra_rtc_probe);
 446
 447MODULE_AUTHOR("Jon Mayo <jmayo@nvidia.com>");
 448MODULE_DESCRIPTION("driver for Tegra internal RTC");
 449MODULE_LICENSE("GPL");
 450