This patch is to support DPAA (Data Path Acceleration Architecture)
1588 timer by adding "fsl,fman-ptp-timer" compatible, sharing
interrupt with FMan, adding FSL_DPAA_ETH dependency, and fixing
up register offset.

Signed-off-by: Yangbo Lu <yangbo...@nxp.com>
Acked-by: Richard Cochran <richardcoch...@gmail.com>
Acked-by: Madalin Bucur <madalin.bu...@nxp.com>
---
Changes for v2:
        - None.
Changes for v3:
        - None.
Changes for v4:
        - Added ACKs.
---
 drivers/ptp/Kconfig           |    2 +-
 drivers/ptp/ptp_qoriq.c       |  104 ++++++++++++++++++++++++++---------------
 include/linux/fsl/ptp_qoriq.h |   38 ++++++++++++---
 3 files changed, 98 insertions(+), 46 deletions(-)

diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index 474c988..d137c48 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -43,7 +43,7 @@ config PTP_1588_CLOCK_DTE
 
 config PTP_1588_CLOCK_QORIQ
        tristate "Freescale QorIQ 1588 timer as PTP clock"
-       depends on GIANFAR
+       depends on GIANFAR || FSL_DPAA_ETH
        depends on PTP_1588_CLOCK
        default y
        help
diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index e8652c1..a14c317 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -39,11 +39,12 @@
 /* Caller must hold qoriq_ptp->lock. */
 static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp)
 {
+       struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
        u64 ns;
        u32 lo, hi;
 
-       lo = qoriq_read(&qoriq_ptp->regs->tmr_cnt_l);
-       hi = qoriq_read(&qoriq_ptp->regs->tmr_cnt_h);
+       lo = qoriq_read(&regs->ctrl_regs->tmr_cnt_l);
+       hi = qoriq_read(&regs->ctrl_regs->tmr_cnt_h);
        ns = ((u64) hi) << 32;
        ns |= lo;
        return ns;
@@ -52,16 +53,18 @@ static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp)
 /* Caller must hold qoriq_ptp->lock. */
 static void tmr_cnt_write(struct qoriq_ptp *qoriq_ptp, u64 ns)
 {
+       struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
        u32 hi = ns >> 32;
        u32 lo = ns & 0xffffffff;
 
-       qoriq_write(&qoriq_ptp->regs->tmr_cnt_l, lo);
-       qoriq_write(&qoriq_ptp->regs->tmr_cnt_h, hi);
+       qoriq_write(&regs->ctrl_regs->tmr_cnt_l, lo);
+       qoriq_write(&regs->ctrl_regs->tmr_cnt_h, hi);
 }
 
 /* Caller must hold qoriq_ptp->lock. */
 static void set_alarm(struct qoriq_ptp *qoriq_ptp)
 {
+       struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
        u64 ns;
        u32 lo, hi;
 
@@ -70,16 +73,18 @@ static void set_alarm(struct qoriq_ptp *qoriq_ptp)
        ns -= qoriq_ptp->tclk_period;
        hi = ns >> 32;
        lo = ns & 0xffffffff;
-       qoriq_write(&qoriq_ptp->regs->tmr_alarm1_l, lo);
-       qoriq_write(&qoriq_ptp->regs->tmr_alarm1_h, hi);
+       qoriq_write(&regs->alarm_regs->tmr_alarm1_l, lo);
+       qoriq_write(&regs->alarm_regs->tmr_alarm1_h, hi);
 }
 
 /* Caller must hold qoriq_ptp->lock. */
 static void set_fipers(struct qoriq_ptp *qoriq_ptp)
 {
+       struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+
        set_alarm(qoriq_ptp);
-       qoriq_write(&qoriq_ptp->regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
-       qoriq_write(&qoriq_ptp->regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
+       qoriq_write(&regs->fiper_regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
+       qoriq_write(&regs->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
 }
 
 /*
@@ -89,16 +94,17 @@ static void set_fipers(struct qoriq_ptp *qoriq_ptp)
 static irqreturn_t isr(int irq, void *priv)
 {
        struct qoriq_ptp *qoriq_ptp = priv;
+       struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
        struct ptp_clock_event event;
        u64 ns;
        u32 ack = 0, lo, hi, mask, val;
 
-       val = qoriq_read(&qoriq_ptp->regs->tmr_tevent);
+       val = qoriq_read(&regs->ctrl_regs->tmr_tevent);
 
        if (val & ETS1) {
                ack |= ETS1;
-               hi = qoriq_read(&qoriq_ptp->regs->tmr_etts1_h);
-               lo = qoriq_read(&qoriq_ptp->regs->tmr_etts1_l);
+               hi = qoriq_read(&regs->etts_regs->tmr_etts1_h);
+               lo = qoriq_read(&regs->etts_regs->tmr_etts1_l);
                event.type = PTP_CLOCK_EXTTS;
                event.index = 0;
                event.timestamp = ((u64) hi) << 32;
@@ -108,8 +114,8 @@ static irqreturn_t isr(int irq, void *priv)
 
        if (val & ETS2) {
                ack |= ETS2;
-               hi = qoriq_read(&qoriq_ptp->regs->tmr_etts2_h);
-               lo = qoriq_read(&qoriq_ptp->regs->tmr_etts2_l);
+               hi = qoriq_read(&regs->etts_regs->tmr_etts2_h);
+               lo = qoriq_read(&regs->etts_regs->tmr_etts2_l);
                event.type = PTP_CLOCK_EXTTS;
                event.index = 1;
                event.timestamp = ((u64) hi) << 32;
@@ -130,16 +136,16 @@ static irqreturn_t isr(int irq, void *priv)
                        hi = ns >> 32;
                        lo = ns & 0xffffffff;
                        spin_lock(&qoriq_ptp->lock);
-                       qoriq_write(&qoriq_ptp->regs->tmr_alarm2_l, lo);
-                       qoriq_write(&qoriq_ptp->regs->tmr_alarm2_h, hi);
+                       qoriq_write(&regs->alarm_regs->tmr_alarm2_l, lo);
+                       qoriq_write(&regs->alarm_regs->tmr_alarm2_h, hi);
                        spin_unlock(&qoriq_ptp->lock);
                        qoriq_ptp->alarm_value = ns;
                } else {
-                       qoriq_write(&qoriq_ptp->regs->tmr_tevent, ALM2);
+                       qoriq_write(&regs->ctrl_regs->tmr_tevent, ALM2);
                        spin_lock(&qoriq_ptp->lock);
-                       mask = qoriq_read(&qoriq_ptp->regs->tmr_temask);
+                       mask = qoriq_read(&regs->ctrl_regs->tmr_temask);
                        mask &= ~ALM2EN;
-                       qoriq_write(&qoriq_ptp->regs->tmr_temask, mask);
+                       qoriq_write(&regs->ctrl_regs->tmr_temask, mask);
                        spin_unlock(&qoriq_ptp->lock);
                        qoriq_ptp->alarm_value = 0;
                        qoriq_ptp->alarm_interval = 0;
@@ -153,7 +159,7 @@ static irqreturn_t isr(int irq, void *priv)
        }
 
        if (ack) {
-               qoriq_write(&qoriq_ptp->regs->tmr_tevent, ack);
+               qoriq_write(&regs->ctrl_regs->tmr_tevent, ack);
                return IRQ_HANDLED;
        } else
                return IRQ_NONE;
@@ -169,6 +175,7 @@ static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, 
long scaled_ppm)
        u32 tmr_add;
        int neg_adj = 0;
        struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
+       struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
 
        if (scaled_ppm < 0) {
                neg_adj = 1;
@@ -186,7 +193,7 @@ static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, 
long scaled_ppm)
 
        tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
 
-       qoriq_write(&qoriq_ptp->regs->tmr_add, tmr_add);
+       qoriq_write(&regs->ctrl_regs->tmr_add, tmr_add);
 
        return 0;
 }
@@ -250,6 +257,7 @@ static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
                              struct ptp_clock_request *rq, int on)
 {
        struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
+       struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
        unsigned long flags;
        u32 bit, mask;
 
@@ -266,23 +274,23 @@ static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
                        return -EINVAL;
                }
                spin_lock_irqsave(&qoriq_ptp->lock, flags);
-               mask = qoriq_read(&qoriq_ptp->regs->tmr_temask);
+               mask = qoriq_read(&regs->ctrl_regs->tmr_temask);
                if (on)
                        mask |= bit;
                else
                        mask &= ~bit;
-               qoriq_write(&qoriq_ptp->regs->tmr_temask, mask);
+               qoriq_write(&regs->ctrl_regs->tmr_temask, mask);
                spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
                return 0;
 
        case PTP_CLK_REQ_PPS:
                spin_lock_irqsave(&qoriq_ptp->lock, flags);
-               mask = qoriq_read(&qoriq_ptp->regs->tmr_temask);
+               mask = qoriq_read(&regs->ctrl_regs->tmr_temask);
                if (on)
                        mask |= PP1EN;
                else
                        mask &= ~PP1EN;
-               qoriq_write(&qoriq_ptp->regs->tmr_temask, mask);
+               qoriq_write(&regs->ctrl_regs->tmr_temask, mask);
                spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
                return 0;
 
@@ -313,10 +321,12 @@ static int qoriq_ptp_probe(struct platform_device *dev)
 {
        struct device_node *node = dev->dev.of_node;
        struct qoriq_ptp *qoriq_ptp;
+       struct qoriq_ptp_registers *regs;
        struct timespec64 now;
        int err = -ENOMEM;
        u32 tmr_ctrl;
        unsigned long flags;
+       void __iomem *base;
 
        qoriq_ptp = kzalloc(sizeof(*qoriq_ptp), GFP_KERNEL);
        if (!qoriq_ptp)
@@ -351,7 +361,7 @@ static int qoriq_ptp_probe(struct platform_device *dev)
                pr_err("irq not in device tree\n");
                goto no_node;
        }
-       if (request_irq(qoriq_ptp->irq, isr, 0, DRIVER, qoriq_ptp)) {
+       if (request_irq(qoriq_ptp->irq, isr, IRQF_SHARED, DRIVER, qoriq_ptp)) {
                pr_err("request_irq failed\n");
                goto no_node;
        }
@@ -368,12 +378,27 @@ static int qoriq_ptp_probe(struct platform_device *dev)
 
        spin_lock_init(&qoriq_ptp->lock);
 
-       qoriq_ptp->regs = ioremap(qoriq_ptp->rsrc->start,
-                               resource_size(qoriq_ptp->rsrc));
-       if (!qoriq_ptp->regs) {
+       base = ioremap(qoriq_ptp->rsrc->start,
+                      resource_size(qoriq_ptp->rsrc));
+       if (!base) {
                pr_err("ioremap ptp registers failed\n");
                goto no_ioremap;
        }
+
+       qoriq_ptp->base = base;
+
+       if (of_device_is_compatible(node, "fsl,fman-ptp-timer")) {
+               qoriq_ptp->regs.ctrl_regs = base + FMAN_CTRL_REGS_OFFSET;
+               qoriq_ptp->regs.alarm_regs = base + FMAN_ALARM_REGS_OFFSET;
+               qoriq_ptp->regs.fiper_regs = base + FMAN_FIPER_REGS_OFFSET;
+               qoriq_ptp->regs.etts_regs = base + FMAN_ETTS_REGS_OFFSET;
+       } else {
+               qoriq_ptp->regs.ctrl_regs = base + CTRL_REGS_OFFSET;
+               qoriq_ptp->regs.alarm_regs = base + ALARM_REGS_OFFSET;
+               qoriq_ptp->regs.fiper_regs = base + FIPER_REGS_OFFSET;
+               qoriq_ptp->regs.etts_regs = base + ETTS_REGS_OFFSET;
+       }
+
        ktime_get_real_ts64(&now);
        ptp_qoriq_settime(&qoriq_ptp->caps, &now);
 
@@ -383,13 +408,14 @@ static int qoriq_ptp_probe(struct platform_device *dev)
 
        spin_lock_irqsave(&qoriq_ptp->lock, flags);
 
-       qoriq_write(&qoriq_ptp->regs->tmr_ctrl,   tmr_ctrl);
-       qoriq_write(&qoriq_ptp->regs->tmr_add,    qoriq_ptp->tmr_add);
-       qoriq_write(&qoriq_ptp->regs->tmr_prsc,   qoriq_ptp->tmr_prsc);
-       qoriq_write(&qoriq_ptp->regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
-       qoriq_write(&qoriq_ptp->regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
+       regs = &qoriq_ptp->regs;
+       qoriq_write(&regs->ctrl_regs->tmr_ctrl,   tmr_ctrl);
+       qoriq_write(&regs->ctrl_regs->tmr_add,    qoriq_ptp->tmr_add);
+       qoriq_write(&regs->ctrl_regs->tmr_prsc,   qoriq_ptp->tmr_prsc);
+       qoriq_write(&regs->fiper_regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
+       qoriq_write(&regs->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
        set_alarm(qoriq_ptp);
-       qoriq_write(&qoriq_ptp->regs->tmr_ctrl,   tmr_ctrl|FIPERST|RTPE|TE|FRD);
+       qoriq_write(&regs->ctrl_regs->tmr_ctrl,   tmr_ctrl|FIPERST|RTPE|TE|FRD);
 
        spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
 
@@ -405,7 +431,7 @@ static int qoriq_ptp_probe(struct platform_device *dev)
        return 0;
 
 no_clock:
-       iounmap(qoriq_ptp->regs);
+       iounmap(qoriq_ptp->base);
 no_ioremap:
        release_resource(qoriq_ptp->rsrc);
 no_resource:
@@ -419,12 +445,13 @@ static int qoriq_ptp_probe(struct platform_device *dev)
 static int qoriq_ptp_remove(struct platform_device *dev)
 {
        struct qoriq_ptp *qoriq_ptp = platform_get_drvdata(dev);
+       struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
 
-       qoriq_write(&qoriq_ptp->regs->tmr_temask, 0);
-       qoriq_write(&qoriq_ptp->regs->tmr_ctrl,   0);
+       qoriq_write(&regs->ctrl_regs->tmr_temask, 0);
+       qoriq_write(&regs->ctrl_regs->tmr_ctrl,   0);
 
        ptp_clock_unregister(qoriq_ptp->clock);
-       iounmap(qoriq_ptp->regs);
+       iounmap(qoriq_ptp->base);
        release_resource(qoriq_ptp->rsrc);
        free_irq(qoriq_ptp->irq, qoriq_ptp);
        kfree(qoriq_ptp);
@@ -434,6 +461,7 @@ static int qoriq_ptp_remove(struct platform_device *dev)
 
 static const struct of_device_id match_table[] = {
        { .compatible = "fsl,etsec-ptp" },
+       { .compatible = "fsl,fman-ptp-timer" },
        {},
 };
 MODULE_DEVICE_TABLE(of, match_table);
diff --git a/include/linux/fsl/ptp_qoriq.h b/include/linux/fsl/ptp_qoriq.h
index b462d9e..dc3dac4 100644
--- a/include/linux/fsl/ptp_qoriq.h
+++ b/include/linux/fsl/ptp_qoriq.h
@@ -11,9 +11,8 @@
 
 /*
  * qoriq ptp registers
- * Generated by regen.tcl on Thu May 13 01:38:57 PM CEST 2010
  */
-struct qoriq_ptp_registers {
+struct ctrl_regs {
        u32 tmr_ctrl;     /* Timer control register */
        u32 tmr_tevent;   /* Timestamp event register */
        u32 tmr_temask;   /* Timer event mask register */
@@ -28,22 +27,47 @@ struct qoriq_ptp_registers {
        u8  res1[4];
        u32 tmroff_h;     /* Timer offset high */
        u32 tmroff_l;     /* Timer offset low */
-       u8  res2[8];
+};
+
+struct alarm_regs {
        u32 tmr_alarm1_h; /* Timer alarm 1 high register */
        u32 tmr_alarm1_l; /* Timer alarm 1 high register */
        u32 tmr_alarm2_h; /* Timer alarm 2 high register */
        u32 tmr_alarm2_l; /* Timer alarm 2 high register */
-       u8  res3[48];
+};
+
+struct fiper_regs {
        u32 tmr_fiper1;   /* Timer fixed period interval */
        u32 tmr_fiper2;   /* Timer fixed period interval */
        u32 tmr_fiper3;   /* Timer fixed period interval */
-       u8  res4[20];
+};
+
+struct etts_regs {
        u32 tmr_etts1_h;  /* Timestamp of general purpose external trigger */
        u32 tmr_etts1_l;  /* Timestamp of general purpose external trigger */
        u32 tmr_etts2_h;  /* Timestamp of general purpose external trigger */
        u32 tmr_etts2_l;  /* Timestamp of general purpose external trigger */
 };
 
+struct qoriq_ptp_registers {
+       struct ctrl_regs __iomem *ctrl_regs;
+       struct alarm_regs __iomem *alarm_regs;
+       struct fiper_regs __iomem *fiper_regs;
+       struct etts_regs __iomem *etts_regs;
+};
+
+/* Offset definitions for the four register groups */
+#define CTRL_REGS_OFFSET       0x0
+#define ALARM_REGS_OFFSET      0x40
+#define FIPER_REGS_OFFSET      0x80
+#define ETTS_REGS_OFFSET       0xa0
+
+#define FMAN_CTRL_REGS_OFFSET  0x80
+#define FMAN_ALARM_REGS_OFFSET 0xb8
+#define FMAN_FIPER_REGS_OFFSET 0xd0
+#define FMAN_ETTS_REGS_OFFSET  0xe0
+
+
 /* Bit definitions for the TMR_CTRL register */
 #define ALM1P                 (1<<31) /* Alarm1 output polarity */
 #define ALM2P                 (1<<30) /* Alarm2 output polarity */
@@ -105,10 +129,10 @@ struct qoriq_ptp_registers {
 #define DRIVER         "ptp_qoriq"
 #define DEFAULT_CKSEL  1
 #define N_EXT_TS       2
-#define REG_SIZE       sizeof(struct qoriq_ptp_registers)
 
 struct qoriq_ptp {
-       struct qoriq_ptp_registers __iomem *regs;
+       void __iomem *base;
+       struct qoriq_ptp_registers regs;
        spinlock_t lock; /* protects regs */
        struct ptp_clock *clock;
        struct ptp_clock_info caps;
-- 
1.7.1

Reply via email to