linux/drivers/ptp/ptp_qoriq.c
<<
>>
Prefs
   1/*
   2 * PTP 1588 clock for Freescale QorIQ 1588 timer
   3 *
   4 * Copyright (C) 2010 OMICRON electronics GmbH
   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,
  12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *  GNU General Public License for more details.
  15 *
  16 *  You should have received a copy of the GNU General Public License
  17 *  along with this program; if not, write to the Free Software
  18 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 */
  20
  21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  22
  23#include <linux/device.h>
  24#include <linux/hrtimer.h>
  25#include <linux/interrupt.h>
  26#include <linux/kernel.h>
  27#include <linux/module.h>
  28#include <linux/of.h>
  29#include <linux/of_platform.h>
  30#include <linux/timex.h>
  31#include <linux/slab.h>
  32#include <linux/clk.h>
  33
  34#include <linux/fsl/ptp_qoriq.h>
  35
  36/*
  37 * Register access functions
  38 */
  39
  40/* Caller must hold qoriq_ptp->lock. */
  41static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp)
  42{
  43        struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
  44        u64 ns;
  45        u32 lo, hi;
  46
  47        lo = qoriq_read(&regs->ctrl_regs->tmr_cnt_l);
  48        hi = qoriq_read(&regs->ctrl_regs->tmr_cnt_h);
  49        ns = ((u64) hi) << 32;
  50        ns |= lo;
  51        return ns;
  52}
  53
  54/* Caller must hold qoriq_ptp->lock. */
  55static void tmr_cnt_write(struct qoriq_ptp *qoriq_ptp, u64 ns)
  56{
  57        struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
  58        u32 hi = ns >> 32;
  59        u32 lo = ns & 0xffffffff;
  60
  61        qoriq_write(&regs->ctrl_regs->tmr_cnt_l, lo);
  62        qoriq_write(&regs->ctrl_regs->tmr_cnt_h, hi);
  63}
  64
  65/* Caller must hold qoriq_ptp->lock. */
  66static void set_alarm(struct qoriq_ptp *qoriq_ptp)
  67{
  68        struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
  69        u64 ns;
  70        u32 lo, hi;
  71
  72        ns = tmr_cnt_read(qoriq_ptp) + 1500000000ULL;
  73        ns = div_u64(ns, 1000000000UL) * 1000000000ULL;
  74        ns -= qoriq_ptp->tclk_period;
  75        hi = ns >> 32;
  76        lo = ns & 0xffffffff;
  77        qoriq_write(&regs->alarm_regs->tmr_alarm1_l, lo);
  78        qoriq_write(&regs->alarm_regs->tmr_alarm1_h, hi);
  79}
  80
  81/* Caller must hold qoriq_ptp->lock. */
  82static void set_fipers(struct qoriq_ptp *qoriq_ptp)
  83{
  84        struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
  85
  86        set_alarm(qoriq_ptp);
  87        qoriq_write(&regs->fiper_regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
  88        qoriq_write(&regs->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
  89}
  90
  91/*
  92 * Interrupt service routine
  93 */
  94
  95static irqreturn_t isr(int irq, void *priv)
  96{
  97        struct qoriq_ptp *qoriq_ptp = priv;
  98        struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
  99        struct ptp_clock_event event;
 100        u64 ns;
 101        u32 ack = 0, lo, hi, mask, val;
 102
 103        val = qoriq_read(&regs->ctrl_regs->tmr_tevent);
 104
 105        if (val & ETS1) {
 106                ack |= ETS1;
 107                hi = qoriq_read(&regs->etts_regs->tmr_etts1_h);
 108                lo = qoriq_read(&regs->etts_regs->tmr_etts1_l);
 109                event.type = PTP_CLOCK_EXTTS;
 110                event.index = 0;
 111                event.timestamp = ((u64) hi) << 32;
 112                event.timestamp |= lo;
 113                ptp_clock_event(qoriq_ptp->clock, &event);
 114        }
 115
 116        if (val & ETS2) {
 117                ack |= ETS2;
 118                hi = qoriq_read(&regs->etts_regs->tmr_etts2_h);
 119                lo = qoriq_read(&regs->etts_regs->tmr_etts2_l);
 120                event.type = PTP_CLOCK_EXTTS;
 121                event.index = 1;
 122                event.timestamp = ((u64) hi) << 32;
 123                event.timestamp |= lo;
 124                ptp_clock_event(qoriq_ptp->clock, &event);
 125        }
 126
 127        if (val & ALM2) {
 128                ack |= ALM2;
 129                if (qoriq_ptp->alarm_value) {
 130                        event.type = PTP_CLOCK_ALARM;
 131                        event.index = 0;
 132                        event.timestamp = qoriq_ptp->alarm_value;
 133                        ptp_clock_event(qoriq_ptp->clock, &event);
 134                }
 135                if (qoriq_ptp->alarm_interval) {
 136                        ns = qoriq_ptp->alarm_value + qoriq_ptp->alarm_interval;
 137                        hi = ns >> 32;
 138                        lo = ns & 0xffffffff;
 139                        spin_lock(&qoriq_ptp->lock);
 140                        qoriq_write(&regs->alarm_regs->tmr_alarm2_l, lo);
 141                        qoriq_write(&regs->alarm_regs->tmr_alarm2_h, hi);
 142                        spin_unlock(&qoriq_ptp->lock);
 143                        qoriq_ptp->alarm_value = ns;
 144                } else {
 145                        qoriq_write(&regs->ctrl_regs->tmr_tevent, ALM2);
 146                        spin_lock(&qoriq_ptp->lock);
 147                        mask = qoriq_read(&regs->ctrl_regs->tmr_temask);
 148                        mask &= ~ALM2EN;
 149                        qoriq_write(&regs->ctrl_regs->tmr_temask, mask);
 150                        spin_unlock(&qoriq_ptp->lock);
 151                        qoriq_ptp->alarm_value = 0;
 152                        qoriq_ptp->alarm_interval = 0;
 153                }
 154        }
 155
 156        if (val & PP1) {
 157                ack |= PP1;
 158                event.type = PTP_CLOCK_PPS;
 159                ptp_clock_event(qoriq_ptp->clock, &event);
 160        }
 161
 162        if (ack) {
 163                qoriq_write(&regs->ctrl_regs->tmr_tevent, ack);
 164                return IRQ_HANDLED;
 165        } else
 166                return IRQ_NONE;
 167}
 168
 169/*
 170 * PTP clock operations
 171 */
 172
 173static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
 174{
 175        u64 adj, diff;
 176        u32 tmr_add;
 177        int neg_adj = 0;
 178        struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
 179        struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
 180
 181        if (scaled_ppm < 0) {
 182                neg_adj = 1;
 183                scaled_ppm = -scaled_ppm;
 184        }
 185        tmr_add = qoriq_ptp->tmr_add;
 186        adj = tmr_add;
 187
 188        /* calculate diff as adj*(scaled_ppm/65536)/1000000
 189         * and round() to the nearest integer
 190         */
 191        adj *= scaled_ppm;
 192        diff = div_u64(adj, 8000000);
 193        diff = (diff >> 13) + ((diff >> 12) & 1);
 194
 195        tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
 196
 197        qoriq_write(&regs->ctrl_regs->tmr_add, tmr_add);
 198
 199        return 0;
 200}
 201
 202static int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta)
 203{
 204        s64 now;
 205        unsigned long flags;
 206        struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
 207
 208        spin_lock_irqsave(&qoriq_ptp->lock, flags);
 209
 210        now = tmr_cnt_read(qoriq_ptp);
 211        now += delta;
 212        tmr_cnt_write(qoriq_ptp, now);
 213        set_fipers(qoriq_ptp);
 214
 215        spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
 216
 217        return 0;
 218}
 219
 220static int ptp_qoriq_gettime(struct ptp_clock_info *ptp,
 221                               struct timespec64 *ts)
 222{
 223        u64 ns;
 224        unsigned long flags;
 225        struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
 226
 227        spin_lock_irqsave(&qoriq_ptp->lock, flags);
 228
 229        ns = tmr_cnt_read(qoriq_ptp);
 230
 231        spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
 232
 233        *ts = ns_to_timespec64(ns);
 234
 235        return 0;
 236}
 237
 238static int ptp_qoriq_settime(struct ptp_clock_info *ptp,
 239                               const struct timespec64 *ts)
 240{
 241        u64 ns;
 242        unsigned long flags;
 243        struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
 244
 245        ns = timespec64_to_ns(ts);
 246
 247        spin_lock_irqsave(&qoriq_ptp->lock, flags);
 248
 249        tmr_cnt_write(qoriq_ptp, ns);
 250        set_fipers(qoriq_ptp);
 251
 252        spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
 253
 254        return 0;
 255}
 256
 257static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
 258                              struct ptp_clock_request *rq, int on)
 259{
 260        struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
 261        struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
 262        unsigned long flags;
 263        u32 bit, mask;
 264
 265        switch (rq->type) {
 266        case PTP_CLK_REQ_EXTTS:
 267                switch (rq->extts.index) {
 268                case 0:
 269                        bit = ETS1EN;
 270                        break;
 271                case 1:
 272                        bit = ETS2EN;
 273                        break;
 274                default:
 275                        return -EINVAL;
 276                }
 277                spin_lock_irqsave(&qoriq_ptp->lock, flags);
 278                mask = qoriq_read(&regs->ctrl_regs->tmr_temask);
 279                if (on)
 280                        mask |= bit;
 281                else
 282                        mask &= ~bit;
 283                qoriq_write(&regs->ctrl_regs->tmr_temask, mask);
 284                spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
 285                return 0;
 286
 287        case PTP_CLK_REQ_PPS:
 288                spin_lock_irqsave(&qoriq_ptp->lock, flags);
 289                mask = qoriq_read(&regs->ctrl_regs->tmr_temask);
 290                if (on)
 291                        mask |= PP1EN;
 292                else
 293                        mask &= ~PP1EN;
 294                qoriq_write(&regs->ctrl_regs->tmr_temask, mask);
 295                spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
 296                return 0;
 297
 298        default:
 299                break;
 300        }
 301
 302        return -EOPNOTSUPP;
 303}
 304
 305static const struct ptp_clock_info ptp_qoriq_caps = {
 306        .owner          = THIS_MODULE,
 307        .name           = "qoriq ptp clock",
 308        .max_adj        = 512000,
 309        .n_alarm        = 0,
 310        .n_ext_ts       = N_EXT_TS,
 311        .n_per_out      = 0,
 312        .n_pins         = 0,
 313        .pps            = 1,
 314        .adjfine        = ptp_qoriq_adjfine,
 315        .adjtime        = ptp_qoriq_adjtime,
 316        .gettime64      = ptp_qoriq_gettime,
 317        .settime64      = ptp_qoriq_settime,
 318        .enable         = ptp_qoriq_enable,
 319};
 320
 321/**
 322 * qoriq_ptp_nominal_freq - calculate nominal frequency according to
 323 *                          reference clock frequency
 324 *
 325 * @clk_src: reference clock frequency
 326 *
 327 * The nominal frequency is the desired clock frequency.
 328 * It should be less than the reference clock frequency.
 329 * It should be a factor of 1000MHz.
 330 *
 331 * Return the nominal frequency
 332 */
 333static u32 qoriq_ptp_nominal_freq(u32 clk_src)
 334{
 335        u32 remainder = 0;
 336
 337        clk_src /= 1000000;
 338        remainder = clk_src % 100;
 339        if (remainder) {
 340                clk_src -= remainder;
 341                clk_src += 100;
 342        }
 343
 344        do {
 345                clk_src -= 100;
 346
 347        } while (1000 % clk_src);
 348
 349        return clk_src * 1000000;
 350}
 351
 352/**
 353 * qoriq_ptp_auto_config - calculate a set of default configurations
 354 *
 355 * @qoriq_ptp: pointer to qoriq_ptp
 356 * @node: pointer to device_node
 357 *
 358 * If below dts properties are not provided, this function will be
 359 * called to calculate a set of default configurations for them.
 360 *   "fsl,tclk-period"
 361 *   "fsl,tmr-prsc"
 362 *   "fsl,tmr-add"
 363 *   "fsl,tmr-fiper1"
 364 *   "fsl,tmr-fiper2"
 365 *   "fsl,max-adj"
 366 *
 367 * Return 0 if success
 368 */
 369static int qoriq_ptp_auto_config(struct qoriq_ptp *qoriq_ptp,
 370                                 struct device_node *node)
 371{
 372        struct clk *clk;
 373        u64 freq_comp;
 374        u64 max_adj;
 375        u32 nominal_freq;
 376        u32 remainder = 0;
 377        u32 clk_src = 0;
 378
 379        qoriq_ptp->cksel = DEFAULT_CKSEL;
 380
 381        clk = of_clk_get(node, 0);
 382        if (!IS_ERR(clk)) {
 383                clk_src = clk_get_rate(clk);
 384                clk_put(clk);
 385        }
 386
 387        if (clk_src <= 100000000UL) {
 388                pr_err("error reference clock value, or lower than 100MHz\n");
 389                return -EINVAL;
 390        }
 391
 392        nominal_freq = qoriq_ptp_nominal_freq(clk_src);
 393        if (!nominal_freq)
 394                return -EINVAL;
 395
 396        qoriq_ptp->tclk_period = 1000000000UL / nominal_freq;
 397        qoriq_ptp->tmr_prsc = DEFAULT_TMR_PRSC;
 398
 399        /* Calculate initial frequency compensation value for TMR_ADD register.
 400         * freq_comp = ceil(2^32 / freq_ratio)
 401         * freq_ratio = reference_clock_freq / nominal_freq
 402         */
 403        freq_comp = ((u64)1 << 32) * nominal_freq;
 404        freq_comp = div_u64_rem(freq_comp, clk_src, &remainder);
 405        if (remainder)
 406                freq_comp++;
 407
 408        qoriq_ptp->tmr_add = freq_comp;
 409        qoriq_ptp->tmr_fiper1 = DEFAULT_FIPER1_PERIOD - qoriq_ptp->tclk_period;
 410        qoriq_ptp->tmr_fiper2 = DEFAULT_FIPER2_PERIOD - qoriq_ptp->tclk_period;
 411
 412        /* max_adj = 1000000000 * (freq_ratio - 1.0) - 1
 413         * freq_ratio = reference_clock_freq / nominal_freq
 414         */
 415        max_adj = 1000000000ULL * (clk_src - nominal_freq);
 416        max_adj = div_u64(max_adj, nominal_freq) - 1;
 417        qoriq_ptp->caps.max_adj = max_adj;
 418
 419        return 0;
 420}
 421
 422static int qoriq_ptp_probe(struct platform_device *dev)
 423{
 424        struct device_node *node = dev->dev.of_node;
 425        struct qoriq_ptp *qoriq_ptp;
 426        struct qoriq_ptp_registers *regs;
 427        struct timespec64 now;
 428        int err = -ENOMEM;
 429        u32 tmr_ctrl;
 430        unsigned long flags;
 431        void __iomem *base;
 432
 433        qoriq_ptp = kzalloc(sizeof(*qoriq_ptp), GFP_KERNEL);
 434        if (!qoriq_ptp)
 435                goto no_memory;
 436
 437        err = -EINVAL;
 438
 439        qoriq_ptp->caps = ptp_qoriq_caps;
 440
 441        if (of_property_read_u32(node, "fsl,cksel", &qoriq_ptp->cksel))
 442                qoriq_ptp->cksel = DEFAULT_CKSEL;
 443
 444        if (of_property_read_u32(node,
 445                                 "fsl,tclk-period", &qoriq_ptp->tclk_period) ||
 446            of_property_read_u32(node,
 447                                 "fsl,tmr-prsc", &qoriq_ptp->tmr_prsc) ||
 448            of_property_read_u32(node,
 449                                 "fsl,tmr-add", &qoriq_ptp->tmr_add) ||
 450            of_property_read_u32(node,
 451                                 "fsl,tmr-fiper1", &qoriq_ptp->tmr_fiper1) ||
 452            of_property_read_u32(node,
 453                                 "fsl,tmr-fiper2", &qoriq_ptp->tmr_fiper2) ||
 454            of_property_read_u32(node,
 455                                 "fsl,max-adj", &qoriq_ptp->caps.max_adj)) {
 456                pr_warn("device tree node missing required elements, try automatic configuration\n");
 457
 458                if (qoriq_ptp_auto_config(qoriq_ptp, node))
 459                        goto no_config;
 460        }
 461
 462        err = -ENODEV;
 463
 464        qoriq_ptp->irq = platform_get_irq(dev, 0);
 465
 466        if (qoriq_ptp->irq < 0) {
 467                pr_err("irq not in device tree\n");
 468                goto no_node;
 469        }
 470        if (request_irq(qoriq_ptp->irq, isr, IRQF_SHARED, DRIVER, qoriq_ptp)) {
 471                pr_err("request_irq failed\n");
 472                goto no_node;
 473        }
 474
 475        qoriq_ptp->rsrc = platform_get_resource(dev, IORESOURCE_MEM, 0);
 476        if (!qoriq_ptp->rsrc) {
 477                pr_err("no resource\n");
 478                goto no_resource;
 479        }
 480        if (request_resource(&iomem_resource, qoriq_ptp->rsrc)) {
 481                pr_err("resource busy\n");
 482                goto no_resource;
 483        }
 484
 485        spin_lock_init(&qoriq_ptp->lock);
 486
 487        base = ioremap(qoriq_ptp->rsrc->start,
 488                       resource_size(qoriq_ptp->rsrc));
 489        if (!base) {
 490                pr_err("ioremap ptp registers failed\n");
 491                goto no_ioremap;
 492        }
 493
 494        qoriq_ptp->base = base;
 495
 496        if (of_device_is_compatible(node, "fsl,fman-ptp-timer")) {
 497                qoriq_ptp->regs.ctrl_regs = base + FMAN_CTRL_REGS_OFFSET;
 498                qoriq_ptp->regs.alarm_regs = base + FMAN_ALARM_REGS_OFFSET;
 499                qoriq_ptp->regs.fiper_regs = base + FMAN_FIPER_REGS_OFFSET;
 500                qoriq_ptp->regs.etts_regs = base + FMAN_ETTS_REGS_OFFSET;
 501        } else {
 502                qoriq_ptp->regs.ctrl_regs = base + CTRL_REGS_OFFSET;
 503                qoriq_ptp->regs.alarm_regs = base + ALARM_REGS_OFFSET;
 504                qoriq_ptp->regs.fiper_regs = base + FIPER_REGS_OFFSET;
 505                qoriq_ptp->regs.etts_regs = base + ETTS_REGS_OFFSET;
 506        }
 507
 508        ktime_get_real_ts64(&now);
 509        ptp_qoriq_settime(&qoriq_ptp->caps, &now);
 510
 511        tmr_ctrl =
 512          (qoriq_ptp->tclk_period & TCLK_PERIOD_MASK) << TCLK_PERIOD_SHIFT |
 513          (qoriq_ptp->cksel & CKSEL_MASK) << CKSEL_SHIFT;
 514
 515        spin_lock_irqsave(&qoriq_ptp->lock, flags);
 516
 517        regs = &qoriq_ptp->regs;
 518        qoriq_write(&regs->ctrl_regs->tmr_ctrl,   tmr_ctrl);
 519        qoriq_write(&regs->ctrl_regs->tmr_add,    qoriq_ptp->tmr_add);
 520        qoriq_write(&regs->ctrl_regs->tmr_prsc,   qoriq_ptp->tmr_prsc);
 521        qoriq_write(&regs->fiper_regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
 522        qoriq_write(&regs->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
 523        set_alarm(qoriq_ptp);
 524        qoriq_write(&regs->ctrl_regs->tmr_ctrl,   tmr_ctrl|FIPERST|RTPE|TE|FRD);
 525
 526        spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
 527
 528        qoriq_ptp->clock = ptp_clock_register(&qoriq_ptp->caps, &dev->dev);
 529        if (IS_ERR(qoriq_ptp->clock)) {
 530                err = PTR_ERR(qoriq_ptp->clock);
 531                goto no_clock;
 532        }
 533        qoriq_ptp->phc_index = ptp_clock_index(qoriq_ptp->clock);
 534
 535        platform_set_drvdata(dev, qoriq_ptp);
 536
 537        return 0;
 538
 539no_clock:
 540        iounmap(qoriq_ptp->base);
 541no_ioremap:
 542        release_resource(qoriq_ptp->rsrc);
 543no_resource:
 544        free_irq(qoriq_ptp->irq, qoriq_ptp);
 545no_config:
 546no_node:
 547        kfree(qoriq_ptp);
 548no_memory:
 549        return err;
 550}
 551
 552static int qoriq_ptp_remove(struct platform_device *dev)
 553{
 554        struct qoriq_ptp *qoriq_ptp = platform_get_drvdata(dev);
 555        struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
 556
 557        qoriq_write(&regs->ctrl_regs->tmr_temask, 0);
 558        qoriq_write(&regs->ctrl_regs->tmr_ctrl,   0);
 559
 560        ptp_clock_unregister(qoriq_ptp->clock);
 561        iounmap(qoriq_ptp->base);
 562        release_resource(qoriq_ptp->rsrc);
 563        free_irq(qoriq_ptp->irq, qoriq_ptp);
 564        kfree(qoriq_ptp);
 565
 566        return 0;
 567}
 568
 569static const struct of_device_id match_table[] = {
 570        { .compatible = "fsl,etsec-ptp" },
 571        { .compatible = "fsl,fman-ptp-timer" },
 572        {},
 573};
 574MODULE_DEVICE_TABLE(of, match_table);
 575
 576static struct platform_driver qoriq_ptp_driver = {
 577        .driver = {
 578                .name           = "ptp_qoriq",
 579                .of_match_table = match_table,
 580        },
 581        .probe       = qoriq_ptp_probe,
 582        .remove      = qoriq_ptp_remove,
 583};
 584
 585module_platform_driver(qoriq_ptp_driver);
 586
 587MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.com>");
 588MODULE_DESCRIPTION("PTP clock for Freescale QorIQ 1588 timer");
 589MODULE_LICENSE("GPL");
 590