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(®->time_sec); 1168 nsec = ioread32(®->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(®->time_sec); 1206 nsec = ioread32(®->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, ®->intr); /* write 1 to ack */ 1177 1178 return IRQ_HANDLED; 1179} 1180 1181static int | 1215 iowrite32(1, ®->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, ®->enable); 1189 iowrite32(1, ®->intr_mask); 1190 iowrite32(1, ®->intr); 1191 } else { 1192 iowrite32(0, ®->intr_mask); 1193 iowrite32(0, ®->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, ®->enable); 1242 iowrite32(1, ®->intr_mask); 1243 iowrite32(1, ®->intr); 1244 } else { 1245 iowrite32(0, ®->intr_mask); 1246 iowrite32(0, ®->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 --- |