ptp_ocp.c (71d7e0850476918b2932ac1dca5a135a5584f742) ptp_ocp.c (a62a56d04e63cf0ececb5dd339811f0a14b7e77c)
1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright (c) 2020 Facebook */
3
4#include <linux/err.h>
5#include <linux/kernel.h>
6#include <linux/module.h>
7#include <linux/debugfs.h>
8#include <linux/init.h>

--- 177 unchanged lines hidden (view full) ---

186 unsigned long fixed_rate;
187 size_t data_size;
188 void *data;
189};
190
191struct ptp_ocp_ext_info {
192 int index;
193 irqreturn_t (*irq_fcn)(int irq, void *priv);
1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright (c) 2020 Facebook */
3
4#include <linux/err.h>
5#include <linux/kernel.h>
6#include <linux/module.h>
7#include <linux/debugfs.h>
8#include <linux/init.h>

--- 177 unchanged lines hidden (view full) ---

186 unsigned long fixed_rate;
187 size_t data_size;
188 void *data;
189};
190
191struct ptp_ocp_ext_info {
192 int index;
193 irqreturn_t (*irq_fcn)(int irq, void *priv);
194 int (*enable)(void *priv, bool enable);
194 int (*enable)(void *priv, u32 req, bool enable);
195};
196
197struct ptp_ocp_ext_src {
198 void __iomem *mem;
199 struct ptp_ocp *bp;
200 struct ptp_ocp_ext_info *info;
201 int irq_vec;
202};

--- 29 unchanged lines hidden (view full) ---

232 int id;
233 int n_irqs;
234 int gnss_port;
235 int gnss2_port;
236 int mac_port; /* miniature atomic clock */
237 int nmea_port;
238 u8 serial[6];
239 bool has_serial;
195};
196
197struct ptp_ocp_ext_src {
198 void __iomem *mem;
199 struct ptp_ocp *bp;
200 struct ptp_ocp_ext_info *info;
201 int irq_vec;
202};

--- 29 unchanged lines hidden (view full) ---

232 int id;
233 int n_irqs;
234 int gnss_port;
235 int gnss2_port;
236 int mac_port; /* miniature atomic clock */
237 int nmea_port;
238 u8 serial[6];
239 bool has_serial;
240 u32 pps_req_map;
240 int flash_start;
241 u32 utc_tai_offset;
242};
243
241 int flash_start;
242 u32 utc_tai_offset;
243};
244
245#define OCP_REQ_TIMESTAMP BIT(0)
246#define OCP_REQ_PPS BIT(1)
247
244struct ocp_resource {
245 unsigned long offset;
246 int size;
247 int irq_vec;
248 int (*setup)(struct ptp_ocp *bp, struct ocp_resource *r);
249 void *extra;
250 unsigned long bp_offset;
251 const char * const name;
252};
253
254static int ptp_ocp_register_mem(struct ptp_ocp *bp, struct ocp_resource *r);
255static int ptp_ocp_register_i2c(struct ptp_ocp *bp, struct ocp_resource *r);
256static int ptp_ocp_register_spi(struct ptp_ocp *bp, struct ocp_resource *r);
257static int ptp_ocp_register_serial(struct ptp_ocp *bp, struct ocp_resource *r);
258static int ptp_ocp_register_ext(struct ptp_ocp *bp, struct ocp_resource *r);
259static int ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r);
260static irqreturn_t ptp_ocp_ts_irq(int irq, void *priv);
248struct ocp_resource {
249 unsigned long offset;
250 int size;
251 int irq_vec;
252 int (*setup)(struct ptp_ocp *bp, struct ocp_resource *r);
253 void *extra;
254 unsigned long bp_offset;
255 const char * const name;
256};
257
258static int ptp_ocp_register_mem(struct ptp_ocp *bp, struct ocp_resource *r);
259static int ptp_ocp_register_i2c(struct ptp_ocp *bp, struct ocp_resource *r);
260static int ptp_ocp_register_spi(struct ptp_ocp *bp, struct ocp_resource *r);
261static int ptp_ocp_register_serial(struct ptp_ocp *bp, struct ocp_resource *r);
262static int ptp_ocp_register_ext(struct ptp_ocp *bp, struct ocp_resource *r);
263static int ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r);
264static irqreturn_t ptp_ocp_ts_irq(int irq, void *priv);
261static int ptp_ocp_ts_enable(void *priv, bool enable);
265static int ptp_ocp_ts_enable(void *priv, u32 req, bool enable);
262
263#define bp_assign_entry(bp, res, val) ({ \
264 uintptr_t addr = (uintptr_t)(bp) + (res)->bp_offset; \
265 *(typeof(val) *)addr = val; \
266})
267
268#define OCP_RES_LOCATION(member) \
269 .name = #member, .bp_offset = offsetof(struct ptp_ocp, member)

--- 9 unchanged lines hidden (view full) ---

279
280#define OCP_SPI_RESOURCE(member) \
281 OCP_RES_LOCATION(member), .setup = ptp_ocp_register_spi
282
283#define OCP_EXT_RESOURCE(member) \
284 OCP_RES_LOCATION(member), .setup = ptp_ocp_register_ext
285
286/* This is the MSI vector mapping used.
266
267#define bp_assign_entry(bp, res, val) ({ \
268 uintptr_t addr = (uintptr_t)(bp) + (res)->bp_offset; \
269 *(typeof(val) *)addr = val; \
270})
271
272#define OCP_RES_LOCATION(member) \
273 .name = #member, .bp_offset = offsetof(struct ptp_ocp, member)

--- 9 unchanged lines hidden (view full) ---

283
284#define OCP_SPI_RESOURCE(member) \
285 OCP_RES_LOCATION(member), .setup = ptp_ocp_register_spi
286
287#define OCP_EXT_RESOURCE(member) \
288 OCP_RES_LOCATION(member), .setup = ptp_ocp_register_ext
289
290/* This is the MSI vector mapping used.
287 * 0: N/C
291 * 0: TS3 (and PPS)
288 * 1: TS0
289 * 2: TS1
290 * 3: GNSS
291 * 4: GNSS2
292 * 5: MAC
293 * 6: TS2
294 * 7: I2C controller
295 * 8: HWICAP (notused)

--- 29 unchanged lines hidden (view full) ---

325 .offset = 0x01060000, .size = 0x10000, .irq_vec = 6,
326 .extra = &(struct ptp_ocp_ext_info) {
327 .index = 2,
328 .irq_fcn = ptp_ocp_ts_irq,
329 .enable = ptp_ocp_ts_enable,
330 },
331 },
332 {
292 * 1: TS0
293 * 2: TS1
294 * 3: GNSS
295 * 4: GNSS2
296 * 5: MAC
297 * 6: TS2
298 * 7: I2C controller
299 * 8: HWICAP (notused)

--- 29 unchanged lines hidden (view full) ---

329 .offset = 0x01060000, .size = 0x10000, .irq_vec = 6,
330 .extra = &(struct ptp_ocp_ext_info) {
331 .index = 2,
332 .irq_fcn = ptp_ocp_ts_irq,
333 .enable = ptp_ocp_ts_enable,
334 },
335 },
336 {
337 OCP_EXT_RESOURCE(pps),
338 .offset = 0x010C0000, .size = 0x10000, .irq_vec = 0,
339 .extra = &(struct ptp_ocp_ext_info) {
340 .index = 3,
341 .irq_fcn = ptp_ocp_ts_irq,
342 .enable = ptp_ocp_ts_enable,
343 },
344 },
345 {
333 OCP_MEM_RESOURCE(pps_to_ext),
334 .offset = 0x01030000, .size = 0x10000,
335 },
336 {
337 OCP_MEM_RESOURCE(pps_to_clk),
338 .offset = 0x01040000, .size = 0x10000,
339 },
340 {

--- 288 unchanged lines hidden (view full) ---

629}
630
631static int
632ptp_ocp_enable(struct ptp_clock_info *ptp_info, struct ptp_clock_request *rq,
633 int on)
634{
635 struct ptp_ocp *bp = container_of(ptp_info, struct ptp_ocp, ptp_info);
636 struct ptp_ocp_ext_src *ext = NULL;
346 OCP_MEM_RESOURCE(pps_to_ext),
347 .offset = 0x01030000, .size = 0x10000,
348 },
349 {
350 OCP_MEM_RESOURCE(pps_to_clk),
351 .offset = 0x01040000, .size = 0x10000,
352 },
353 {

--- 288 unchanged lines hidden (view full) ---

642}
643
644static int
645ptp_ocp_enable(struct ptp_clock_info *ptp_info, struct ptp_clock_request *rq,
646 int on)
647{
648 struct ptp_ocp *bp = container_of(ptp_info, struct ptp_ocp, ptp_info);
649 struct ptp_ocp_ext_src *ext = NULL;
650 u32 req;
637 int err;
638
639 switch (rq->type) {
640 case PTP_CLK_REQ_EXTTS:
651 int err;
652
653 switch (rq->type) {
654 case PTP_CLK_REQ_EXTTS:
655 req = OCP_REQ_TIMESTAMP;
641 switch (rq->extts.index) {
642 case 0:
643 ext = bp->ts0;
644 break;
645 case 1:
646 ext = bp->ts1;
647 break;
648 case 2:
649 ext = bp->ts2;
650 break;
656 switch (rq->extts.index) {
657 case 0:
658 ext = bp->ts0;
659 break;
660 case 1:
661 ext = bp->ts1;
662 break;
663 case 2:
664 ext = bp->ts2;
665 break;
666 case 3:
667 ext = bp->pps;
668 break;
651 }
652 break;
653 case PTP_CLK_REQ_PPS:
669 }
670 break;
671 case PTP_CLK_REQ_PPS:
672 req = OCP_REQ_PPS;
654 ext = bp->pps;
655 break;
673 ext = bp->pps;
674 break;
675 case PTP_CLK_REQ_PEROUT:
676 if (on &&
677 (rq->perout.period.sec != 1 || rq->perout.period.nsec != 0))
678 return -EINVAL;
679 /* This is a request for 1PPS on an output SMA.
680 * Allow, but assume manual configuration.
681 */
682 return 0;
656 default:
657 return -EOPNOTSUPP;
658 }
659
660 err = -ENXIO;
661 if (ext)
683 default:
684 return -EOPNOTSUPP;
685 }
686
687 err = -ENXIO;
688 if (ext)
662 err = ext->info->enable(ext, on);
689 err = ext->info->enable(ext, req, on);
663
664 return err;
665}
666
667static const struct ptp_clock_info ptp_ocp_clock_info = {
668 .owner = THIS_MODULE,
669 .name = KBUILD_MODNAME,
670 .max_adj = 100000000,
671 .gettimex64 = ptp_ocp_gettimex,
672 .settime64 = ptp_ocp_settime,
673 .adjtime = ptp_ocp_adjtime,
674 .adjfine = ptp_ocp_null_adjfine,
675 .adjphase = ptp_ocp_adjphase,
676 .enable = ptp_ocp_enable,
677 .pps = true,
690
691 return err;
692}
693
694static const struct ptp_clock_info ptp_ocp_clock_info = {
695 .owner = THIS_MODULE,
696 .name = KBUILD_MODNAME,
697 .max_adj = 100000000,
698 .gettimex64 = ptp_ocp_gettimex,
699 .settime64 = ptp_ocp_settime,
700 .adjtime = ptp_ocp_adjtime,
701 .adjfine = ptp_ocp_null_adjfine,
702 .adjphase = ptp_ocp_adjphase,
703 .enable = ptp_ocp_enable,
704 .pps = true,
678 .n_ext_ts = 3,
705 .n_ext_ts = 4,
706 .n_per_out = 1,
679};
680
681static void
682__ptp_ocp_clear_drift_locked(struct ptp_ocp *bp)
683{
684 u32 ctrl, select;
685
686 select = ioread32(&bp->reg->select);

--- 471 unchanged lines hidden (view full) ---

1158static irqreturn_t
1159ptp_ocp_ts_irq(int irq, void *priv)
1160{
1161 struct ptp_ocp_ext_src *ext = priv;
1162 struct ts_reg __iomem *reg = ext->mem;
1163 struct ptp_clock_event ev;
1164 u32 sec, nsec;
1165
707};
708
709static void
710__ptp_ocp_clear_drift_locked(struct ptp_ocp *bp)
711{
712 u32 ctrl, select;
713
714 select = ioread32(&bp->reg->select);

--- 471 unchanged lines hidden (view full) ---

1186static irqreturn_t
1187ptp_ocp_ts_irq(int irq, void *priv)
1188{
1189 struct ptp_ocp_ext_src *ext = priv;
1190 struct ts_reg __iomem *reg = ext->mem;
1191 struct ptp_clock_event ev;
1192 u32 sec, nsec;
1193
1194 if (ext == ext->bp->pps) {
1195 if (ext->bp->pps_req_map & OCP_REQ_PPS) {
1196 ev.type = PTP_CLOCK_PPS;
1197 ptp_clock_event(ext->bp->ptp, &ev);
1198 }
1199
1200 if ((ext->bp->pps_req_map & ~OCP_REQ_PPS) == 0)
1201 goto out;
1202 }
1203
1166 /* XXX should fix API - this converts s/ns -> ts -> s/ns */
1167 sec = ioread32(&reg->time_sec);
1168 nsec = ioread32(&reg->time_ns);
1169
1170 ev.type = PTP_CLOCK_EXTTS;
1171 ev.index = ext->info->index;
1172 ev.timestamp = sec * 1000000000ULL + nsec;
1173
1174 ptp_clock_event(ext->bp->ptp, &ev);
1175
1204 /* XXX should fix API - this converts s/ns -> ts -> s/ns */
1205 sec = ioread32(&reg->time_sec);
1206 nsec = ioread32(&reg->time_ns);
1207
1208 ev.type = PTP_CLOCK_EXTTS;
1209 ev.index = ext->info->index;
1210 ev.timestamp = sec * 1000000000ULL + nsec;
1211
1212 ptp_clock_event(ext->bp->ptp, &ev);
1213
1214out:
1176 iowrite32(1, &reg->intr); /* write 1 to ack */
1177
1178 return IRQ_HANDLED;
1179}
1180
1181static int
1215 iowrite32(1, &reg->intr); /* write 1 to ack */
1216
1217 return IRQ_HANDLED;
1218}
1219
1220static int
1182ptp_ocp_ts_enable(void *priv, bool enable)
1221ptp_ocp_ts_enable(void *priv, u32 req, bool enable)
1183{
1184 struct ptp_ocp_ext_src *ext = priv;
1185 struct ts_reg __iomem *reg = ext->mem;
1222{
1223 struct ptp_ocp_ext_src *ext = priv;
1224 struct ts_reg __iomem *reg = ext->mem;
1225 struct ptp_ocp *bp = ext->bp;
1186
1226
1227 if (ext == bp->pps) {
1228 u32 old_map = bp->pps_req_map;
1229
1230 if (enable)
1231 bp->pps_req_map |= req;
1232 else
1233 bp->pps_req_map &= ~req;
1234
1235 /* if no state change, just return */
1236 if ((!!old_map ^ !!bp->pps_req_map) == 0)
1237 return 0;
1238 }
1239
1187 if (enable) {
1188 iowrite32(1, &reg->enable);
1189 iowrite32(1, &reg->intr_mask);
1190 iowrite32(1, &reg->intr);
1191 } else {
1192 iowrite32(0, &reg->intr_mask);
1193 iowrite32(0, &reg->enable);
1194 }
1195
1196 return 0;
1197}
1198
1199static void
1200ptp_ocp_unregister_ext(struct ptp_ocp_ext_src *ext)
1201{
1240 if (enable) {
1241 iowrite32(1, &reg->enable);
1242 iowrite32(1, &reg->intr_mask);
1243 iowrite32(1, &reg->intr);
1244 } else {
1245 iowrite32(0, &reg->intr_mask);
1246 iowrite32(0, &reg->enable);
1247 }
1248
1249 return 0;
1250}
1251
1252static void
1253ptp_ocp_unregister_ext(struct ptp_ocp_ext_src *ext)
1254{
1202 ext->info->enable(ext, false);
1255 ext->info->enable(ext, ~0, false);
1203 pci_free_irq(ext->bp->pdev, ext->irq_vec, ext);
1204 kfree(ext);
1205}
1206
1207static int
1208ptp_ocp_register_ext(struct ptp_ocp *bp, struct ocp_resource *r)
1209{
1210 struct pci_dev *pdev = bp->pdev;

--- 673 unchanged lines hidden (view full) ---

1884{
1885 struct device *dev = s->private;
1886 struct ptp_system_timestamp sts;
1887 u32 sma_in, sma_out, ctrl, val;
1888 struct ts_reg __iomem *ts_reg;
1889 struct timespec64 ts;
1890 struct ptp_ocp *bp;
1891 const char *src;
1256 pci_free_irq(ext->bp->pdev, ext->irq_vec, ext);
1257 kfree(ext);
1258}
1259
1260static int
1261ptp_ocp_register_ext(struct ptp_ocp *bp, struct ocp_resource *r)
1262{
1263 struct pci_dev *pdev = bp->pdev;

--- 673 unchanged lines hidden (view full) ---

1937{
1938 struct device *dev = s->private;
1939 struct ptp_system_timestamp sts;
1940 u32 sma_in, sma_out, ctrl, val;
1941 struct ts_reg __iomem *ts_reg;
1942 struct timespec64 ts;
1943 struct ptp_ocp *bp;
1944 const char *src;
1945 bool on, map;
1892 char *buf;
1946 char *buf;
1893 bool on;
1894
1895 buf = (char *)__get_free_page(GFP_KERNEL);
1896 if (!buf)
1897 return -ENOMEM;
1898
1899 bp = dev_get_drvdata(dev);
1900 sma_in = ioread32(&bp->sma->gpio1);
1901 sma_out = ioread32(&bp->sma->gpio2);

--- 31 unchanged lines hidden (view full) ---

1933 if (bp->ts2) {
1934 ts_reg = bp->ts2->mem;
1935 on = ioread32(&ts_reg->enable);
1936 src = gpio_map(sma_in, 3, "sma1", "sma2", "----");
1937 seq_printf(s, "%7s: %s, src: %s\n", "TS2",
1938 on ? " ON" : "OFF", src);
1939 }
1940
1947
1948 buf = (char *)__get_free_page(GFP_KERNEL);
1949 if (!buf)
1950 return -ENOMEM;
1951
1952 bp = dev_get_drvdata(dev);
1953 sma_in = ioread32(&bp->sma->gpio1);
1954 sma_out = ioread32(&bp->sma->gpio2);

--- 31 unchanged lines hidden (view full) ---

1986 if (bp->ts2) {
1987 ts_reg = bp->ts2->mem;
1988 on = ioread32(&ts_reg->enable);
1989 src = gpio_map(sma_in, 3, "sma1", "sma2", "----");
1990 seq_printf(s, "%7s: %s, src: %s\n", "TS2",
1991 on ? " ON" : "OFF", src);
1992 }
1993
1994 if (bp->pps) {
1995 ts_reg = bp->pps->mem;
1996 src = "PHC";
1997 on = ioread32(&ts_reg->enable);
1998 map = !!(bp->pps_req_map & OCP_REQ_TIMESTAMP);
1999 seq_printf(s, "%7s: %s, src: %s\n", "TS3",
2000 on & map ? " ON" : "OFF", src);
2001
2002 map = !!(bp->pps_req_map & OCP_REQ_PPS);
2003 seq_printf(s, "%7s: %s, src: %s\n", "PPS",
2004 on & map ? " ON" : "OFF", src);
2005 }
2006
1941 if (bp->irig_out) {
1942 ctrl = ioread32(&bp->irig_out->ctrl);
1943 on = ctrl & IRIG_M_CTRL_ENABLE;
1944 val = ioread32(&bp->irig_out->status);
1945 gpio_multi_map(buf, sma_out, 4, "sma3", "sma4", "----");
1946 seq_printf(s, "%7s: %s, error: %d, mode %d, out: %s\n", "IRIG",
1947 on ? " ON" : "OFF", val, (ctrl >> 16), buf);
1948 }

--- 549 unchanged lines hidden ---
2007 if (bp->irig_out) {
2008 ctrl = ioread32(&bp->irig_out->ctrl);
2009 on = ctrl & IRIG_M_CTRL_ENABLE;
2010 val = ioread32(&bp->irig_out->status);
2011 gpio_multi_map(buf, sma_out, 4, "sma3", "sma4", "----");
2012 seq_printf(s, "%7s: %s, error: %d, mode %d, out: %s\n", "IRIG",
2013 on ? " ON" : "OFF", val, (ctrl >> 16), buf);
2014 }

--- 549 unchanged lines hidden ---