Skip to content

Commit e3516bb

Browse files
jlemondavem330
authored andcommitted
ptp: ocp: Add NMEA output
The timecard can provide a NMEA-1083 ZDA (time and date) output string on a serial port, which can be used to drive other devices. Add the NMEA resources, and the serial port as a sysfs attribute. Signed-off-by: Jonathan Lemon <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f67bf66 commit e3516bb

File tree

1 file changed

+55
-2
lines changed

1 file changed

+55
-2
lines changed

drivers/ptp/ptp_ocp.c

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ struct ptp_ocp {
215215
struct irig_slave_reg __iomem *irig_in;
216216
struct dcf_master_reg __iomem *dcf_out;
217217
struct dcf_slave_reg __iomem *dcf_in;
218+
struct tod_reg __iomem *nmea_out;
218219
struct ptp_ocp_ext_src *pps;
219220
struct ptp_ocp_ext_src *ts0;
220221
struct ptp_ocp_ext_src *ts1;
@@ -232,6 +233,7 @@ struct ptp_ocp {
232233
int n_irqs;
233234
int gnss_port;
234235
int mac_port; /* miniature atomic clock */
236+
int nmea_port;
235237
u8 serial[6];
236238
bool has_serial;
237239
int flash_start;
@@ -289,8 +291,9 @@ static int ptp_ocp_ts_enable(void *priv, bool enable);
289291
* 5: MAC
290292
* 6: TS2
291293
* 7: I2C controller
292-
* 8: HWICAP
294+
* 8: HWICAP (notused)
293295
* 9: SPI Flash
296+
* 10: NMEA
294297
*/
295298

296299
static struct ocp_resource ocp_fb_resource[] = {
@@ -353,6 +356,10 @@ static struct ocp_resource ocp_fb_resource[] = {
353356
OCP_MEM_RESOURCE(dcf_out),
354357
.offset = 0x010A0000, .size = 0x10000,
355358
},
359+
{
360+
OCP_MEM_RESOURCE(nmea_out),
361+
.offset = 0x010B0000, .size = 0x10000,
362+
},
356363
{
357364
OCP_MEM_RESOURCE(image),
358365
.offset = 0x00020000, .size = 0x1000,
@@ -381,6 +388,10 @@ static struct ocp_resource ocp_fb_resource[] = {
381388
OCP_SERIAL_RESOURCE(mac_port),
382389
.offset = 0x00180000 + 0x1000, .irq_vec = 5,
383390
},
391+
{
392+
OCP_SERIAL_RESOURCE(nmea_port),
393+
.offset = 0x00190000 + 0x1000, .irq_vec = 10,
394+
},
384395
{
385396
OCP_SPI_RESOURCE(spi_flash),
386397
.offset = 0x00310000, .size = 0x10000, .irq_vec = 9,
@@ -761,6 +772,8 @@ ptp_ocp_utc_distribute(struct ptp_ocp *bp, u32 val)
761772
iowrite32(val, &bp->irig_out->adj_sec);
762773
if (bp->dcf_out)
763774
iowrite32(val, &bp->dcf_out->adj_sec);
775+
if (bp->nmea_out)
776+
iowrite32(val, &bp->nmea_out->adj_sec);
764777

765778
spin_unlock_irqrestore(&bp->lock, flags);
766779
}
@@ -1272,13 +1285,25 @@ ptp_ocp_register_mem(struct ptp_ocp *bp, struct ocp_resource *r)
12721285
return 0;
12731286
}
12741287

1288+
static void
1289+
ptp_ocp_nmea_out_init(struct ptp_ocp *bp)
1290+
{
1291+
if (!bp->nmea_out)
1292+
return;
1293+
1294+
iowrite32(0, &bp->nmea_out->ctrl); /* disable */
1295+
iowrite32(7, &bp->nmea_out->uart_baud); /* 115200 */
1296+
iowrite32(1, &bp->nmea_out->ctrl); /* enable */
1297+
}
1298+
12751299
/* FB specific board initializers; last "resource" registered. */
12761300
static int
12771301
ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r)
12781302
{
12791303
bp->flash_start = 1024 * 4096;
12801304

12811305
ptp_ocp_tod_init(bp);
1306+
ptp_ocp_nmea_out_init(bp);
12821307

12831308
return ptp_ocp_init_clock(bp);
12841309
}
@@ -1941,6 +1966,13 @@ ptp_ocp_summary_show(struct seq_file *s, void *data)
19411966
on ? " ON" : "OFF", val, src);
19421967
}
19431968

1969+
if (bp->nmea_out) {
1970+
on = ioread32(&bp->nmea_out->ctrl) & 1;
1971+
val = ioread32(&bp->nmea_out->status);
1972+
seq_printf(s, "%7s: %s, error: %d\n", "NMEA",
1973+
on ? " ON" : "OFF", val);
1974+
}
1975+
19441976
/* compute src for PPS1, used below. */
19451977
if (bp->pps_select) {
19461978
val = ioread32(&bp->pps_select->gpio1);
@@ -2069,6 +2101,7 @@ ptp_ocp_device_init(struct ptp_ocp *bp, struct pci_dev *pdev)
20692101
spin_lock_init(&bp->lock);
20702102
bp->gnss_port = -1;
20712103
bp->mac_port = -1;
2104+
bp->nmea_port = -1;
20722105
bp->pdev = pdev;
20732106

20742107
device_initialize(&bp->dev);
@@ -2134,6 +2167,10 @@ ptp_ocp_complete(struct ptp_ocp *bp)
21342167
sprintf(buf, "ttyS%d", bp->mac_port);
21352168
ptp_ocp_link_child(bp, buf, "ttyMAC");
21362169
}
2170+
if (bp->nmea_port != -1) {
2171+
sprintf(buf, "ttyS%d", bp->nmea_port);
2172+
ptp_ocp_link_child(bp, buf, "ttyNMEA");
2173+
}
21372174
sprintf(buf, "ptp%d", ptp_clock_index(bp->ptp));
21382175
ptp_ocp_link_child(bp, buf, "ptp");
21392176

@@ -2180,7 +2217,13 @@ ptp_ocp_serial_info(struct device *dev, const char *name, int port, int baud)
21802217
static void
21812218
ptp_ocp_info(struct ptp_ocp *bp)
21822219
{
2220+
static int nmea_baud[] = {
2221+
1200, 2400, 4800, 9600, 19200, 38400,
2222+
57600, 115200, 230400, 460800, 921600,
2223+
1000000, 2000000
2224+
};
21832225
struct device *dev = &bp->pdev->dev;
2226+
u32 reg;
21842227

21852228
ptp_ocp_phc_info(bp);
21862229
if (bp->tod)
@@ -2199,6 +2242,14 @@ ptp_ocp_info(struct ptp_ocp *bp)
21992242
}
22002243
ptp_ocp_serial_info(dev, "GNSS", bp->gnss_port, 115200);
22012244
ptp_ocp_serial_info(dev, "MAC", bp->mac_port, 57600);
2245+
if (bp->nmea_out && bp->nmea_port != -1) {
2246+
int baud = -1;
2247+
2248+
reg = ioread32(&bp->nmea_out->uart_baud);
2249+
if (reg < ARRAY_SIZE(nmea_baud))
2250+
baud = nmea_baud[reg];
2251+
ptp_ocp_serial_info(dev, "NMEA", bp->nmea_port, baud);
2252+
}
22022253
}
22032254

22042255
static void
@@ -2232,6 +2283,8 @@ ptp_ocp_detach(struct ptp_ocp *bp)
22322283
serial8250_unregister_port(bp->gnss_port);
22332284
if (bp->mac_port != -1)
22342285
serial8250_unregister_port(bp->mac_port);
2286+
if (bp->nmea_port != -1)
2287+
serial8250_unregister_port(bp->nmea_port);
22352288
if (bp->spi_flash)
22362289
platform_device_unregister(bp->spi_flash);
22372290
if (bp->i2c_ctrl)
@@ -2278,7 +2331,7 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
22782331
* allow this - if not all of the IRQ's are returned, skip the
22792332
* extra devices and just register the clock.
22802333
*/
2281-
err = pci_alloc_irq_vectors(pdev, 1, 10, PCI_IRQ_MSI | PCI_IRQ_MSIX);
2334+
err = pci_alloc_irq_vectors(pdev, 1, 11, PCI_IRQ_MSI | PCI_IRQ_MSIX);
22822335
if (err < 0) {
22832336
dev_err(&pdev->dev, "alloc_irq_vectors err: %d\n", err);
22842337
goto out;

0 commit comments

Comments
 (0)