From patchwork Wed Sep 15 02:16:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495337 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6CB00C433EF for ; Wed, 15 Sep 2021 02:16:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4C78B608FB for ; Wed, 15 Sep 2021 02:16:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235369AbhIOCSD (ORCPT ); Tue, 14 Sep 2021 22:18:03 -0400 Received: from smtp7.emailarray.com ([65.39.216.66]:33233 "EHLO smtp7.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232666AbhIOCSB (ORCPT ); Tue, 14 Sep 2021 22:18:01 -0400 Received: (qmail 8681 invoked by uid 89); 15 Sep 2021 02:16:38 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp7.emailarray.com with SMTP; 15 Sep 2021 02:16:38 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 01/18] ptp: ocp: parameterize the i2c driver used Date: Tue, 14 Sep 2021 19:16:19 -0700 Message-Id: <20210915021636.153754-2-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Move the xilinx i2c driver parameters to the resource block instead of hardcoding things in the registration functions. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index caf9b37c5eb1..d37eac69150a 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -131,6 +131,13 @@ struct ptp_ocp_flash_info { void *data; }; +struct ptp_ocp_i2c_info { + const char *name; + unsigned long fixed_rate; + size_t data_size; + void *data; +}; + struct ptp_ocp_ext_info { const char *name; int index; @@ -269,6 +276,10 @@ static struct ocp_resource ocp_fb_resource[] = { { OCP_I2C_RESOURCE(i2c_ctrl), .offset = 0x00150000, .size = 0x10000, .irq_vec = 7, + .extra = &(struct ptp_ocp_i2c_info) { + .name = "xiic-i2c", + .fixed_rate = 50000000, + }, }, { OCP_SERIAL_RESOURCE(gnss_port), @@ -944,21 +955,25 @@ ptp_ocp_register_spi(struct ptp_ocp *bp, struct ocp_resource *r) static struct platform_device * ptp_ocp_i2c_bus(struct pci_dev *pdev, struct ocp_resource *r, int id) { + struct ptp_ocp_i2c_info *info; struct resource res[2]; unsigned long start; + info = r->extra; start = pci_resource_start(pdev, 0) + r->offset; ptp_ocp_set_mem_resource(&res[0], start, r->size); ptp_ocp_set_irq_resource(&res[1], pci_irq_vector(pdev, r->irq_vec)); - return platform_device_register_resndata(&pdev->dev, "xiic-i2c", - id, res, 2, NULL, 0); + return platform_device_register_resndata(&pdev->dev, info->name, + id, res, 2, + info->data, info->data_size); } static int ptp_ocp_register_i2c(struct ptp_ocp *bp, struct ocp_resource *r) { struct pci_dev *pdev = bp->pdev; + struct ptp_ocp_i2c_info *info; struct platform_device *p; struct clk_hw *clk; char buf[32]; @@ -970,15 +985,17 @@ ptp_ocp_register_i2c(struct ptp_ocp *bp, struct ocp_resource *r) return 0; } + info = r->extra; id = pci_dev_id(bp->pdev); sprintf(buf, "AXI.%d", id); - clk = clk_hw_register_fixed_rate(&pdev->dev, buf, NULL, 0, 50000000); + clk = clk_hw_register_fixed_rate(&pdev->dev, buf, NULL, 0, + info->fixed_rate); if (IS_ERR(clk)) return PTR_ERR(clk); bp->i2c_clk = clk; - sprintf(buf, "xiic-i2c.%d", id); + sprintf(buf, "%s.%d", info->name, id); devm_clk_hw_register_clkdev(&pdev->dev, clk, NULL, buf); p = ptp_ocp_i2c_bus(bp->pdev, r, id); if (IS_ERR(p)) From patchwork Wed Sep 15 02:16:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495333 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 08DBBC433EF for ; Wed, 15 Sep 2021 02:16:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DCBC2608FB for ; Wed, 15 Sep 2021 02:16:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230231AbhIOCSA (ORCPT ); Tue, 14 Sep 2021 22:18:00 -0400 Received: from smtp.emailarray.com ([69.28.212.198]:53779 "EHLO smtp2.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232666AbhIOCR7 (ORCPT ); Tue, 14 Sep 2021 22:17:59 -0400 Received: (qmail 33907 invoked by uid 89); 15 Sep 2021 02:16:39 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp2.emailarray.com with SMTP; 15 Sep 2021 02:16:39 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 02/18] ptp: ocp: Parameterize the TOD information display. Date: Tue, 14 Sep 2021 19:16:20 -0700 Message-Id: <20210915021636.153754-3-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Only display the TOD information if there is a corresponding TOD resource. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index d37eac69150a..2a6cc762c60e 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -743,7 +743,8 @@ ptp_ocp_info(struct ptp_ocp *bp) ptp_ocp_clock_name_from_val(select >> 16), ptp_clock_index(bp->ptp)); - ptp_ocp_tod_info(bp); + if (bp->tod) + ptp_ocp_tod_info(bp); } static struct device * From patchwork Wed Sep 15 02:16:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495335 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0533C433FE for ; Wed, 15 Sep 2021 02:16:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D0D2960EE0 for ; Wed, 15 Sep 2021 02:16:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230299AbhIOCSB (ORCPT ); Tue, 14 Sep 2021 22:18:01 -0400 Received: from smtp1.emailarray.com ([65.39.216.14]:48107 "EHLO smtp1.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234174AbhIOCR7 (ORCPT ); Tue, 14 Sep 2021 22:17:59 -0400 Received: (qmail 54672 invoked by uid 89); 15 Sep 2021 02:16:40 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp1.emailarray.com with SMTP; 15 Sep 2021 02:16:40 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 03/18] ptp: ocp: Skip I2C flash read when there is no controller. Date: Tue, 14 Sep 2021 19:16:21 -0700 Message-Id: <20210915021636.153754-4-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org If an I2C controller isn't present, don't try and read the I2C flash. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 2a6cc762c60e..196a457929f0 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -228,8 +228,8 @@ static int ptp_ocp_ts_enable(void *priv, bool enable); * 3: GPS * 4: GPS2 (n/c) * 5: MAC - * 6: SPI IMU (inertial measurement unit) - * 7: I2C oscillator + * 6: N/C + * 7: I2C controller * 8: HWICAP * 9: SPI Flash */ @@ -706,6 +706,9 @@ ptp_ocp_get_serial_number(struct ptp_ocp *bp) struct device *dev; int err; + if (!bp->i2c_ctrl) + return; + dev = device_find_child(&bp->i2c_ctrl->dev, NULL, ptp_ocp_firstchild); if (!dev) { dev_err(&bp->pdev->dev, "Can't find I2C adapter\n"); From patchwork Wed Sep 15 02:16:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495341 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E0411C4332F for ; Wed, 15 Sep 2021 02:16:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C74B8601FF for ; Wed, 15 Sep 2021 02:16:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234921AbhIOCSC (ORCPT ); Tue, 14 Sep 2021 22:18:02 -0400 Received: from smtp5.emailarray.com ([65.39.216.39]:44045 "EHLO smtp5.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230233AbhIOCSA (ORCPT ); Tue, 14 Sep 2021 22:18:00 -0400 Received: (qmail 83457 invoked by uid 89); 15 Sep 2021 02:16:41 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp5.emailarray.com with SMTP; 15 Sep 2021 02:16:41 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 04/18] ptp: ocp: Skip resources with out of range irqs Date: Tue, 14 Sep 2021 19:16:22 -0700 Message-Id: <20210915021636.153754-5-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The TimeCard exposes different resources, which may have their own irqs. Space for the irqs is allocated through a MSI or MSI-X interrupt vector. On some platforms, the interrupt allocation fails. Rather than making this fatal, just skip exposing those resources. The main timecard functionality (that of a PTP clock) will work without the additional resources. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 47 +++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 196a457929f0..ad8b794fa7e6 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -139,7 +139,6 @@ struct ptp_ocp_i2c_info { }; struct ptp_ocp_ext_info { - const char *name; int index; irqreturn_t (*irq_fcn)(int irq, void *priv); int (*enable)(void *priv, bool enable); @@ -187,6 +186,7 @@ struct ocp_resource { int (*setup)(struct ptp_ocp *bp, struct ocp_resource *r); void *extra; unsigned long bp_offset; + const char * const name; }; static int ptp_ocp_register_mem(struct ptp_ocp *bp, struct ocp_resource *r); @@ -204,7 +204,7 @@ static int ptp_ocp_ts_enable(void *priv, bool enable); }) #define OCP_RES_LOCATION(member) \ - .bp_offset = offsetof(struct ptp_ocp, member) + .name = #member, .bp_offset = offsetof(struct ptp_ocp, member) #define OCP_MEM_RESOURCE(member) \ OCP_RES_LOCATION(member), .setup = ptp_ocp_register_mem @@ -243,7 +243,7 @@ static struct ocp_resource ocp_fb_resource[] = { OCP_EXT_RESOURCE(ts0), .offset = 0x01010000, .size = 0x10000, .irq_vec = 1, .extra = &(struct ptp_ocp_ext_info) { - .name = "ts0", .index = 0, + .index = 0, .irq_fcn = ptp_ocp_ts_irq, .enable = ptp_ocp_ts_enable, }, @@ -252,7 +252,7 @@ static struct ocp_resource ocp_fb_resource[] = { OCP_EXT_RESOURCE(ts1), .offset = 0x01020000, .size = 0x10000, .irq_vec = 2, .extra = &(struct ptp_ocp_ext_info) { - .name = "ts1", .index = 1, + .index = 1, .irq_fcn = ptp_ocp_ts_irq, .enable = ptp_ocp_ts_enable, }, @@ -925,18 +925,6 @@ ptp_ocp_register_spi(struct ptp_ocp *bp, struct ocp_resource *r) unsigned long start; int id; - /* XXX hack to work around old FPGA */ - if (bp->n_irqs < 10) { - dev_err(&bp->pdev->dev, "FPGA does not have SPI devices\n"); - return 0; - } - - if (r->irq_vec > bp->n_irqs) { - dev_err(&bp->pdev->dev, "spi device irq %d out of range\n", - r->irq_vec); - return 0; - } - start = pci_resource_start(pdev, 0) + r->offset; ptp_ocp_set_mem_resource(&res[0], start, r->size); ptp_ocp_set_irq_resource(&res[1], pci_irq_vector(pdev, r->irq_vec)); @@ -983,12 +971,6 @@ ptp_ocp_register_i2c(struct ptp_ocp *bp, struct ocp_resource *r) char buf[32]; int id; - if (r->irq_vec > bp->n_irqs) { - dev_err(&bp->pdev->dev, "i2c device irq %d out of range\n", - r->irq_vec); - return 0; - } - info = r->extra; id = pci_dev_id(bp->pdev); @@ -1080,7 +1062,7 @@ ptp_ocp_register_ext(struct ptp_ocp *bp, struct ocp_resource *r) ext->irq_vec = r->irq_vec; err = pci_request_irq(pdev, r->irq_vec, ext->info->irq_fcn, NULL, - ext, "ocp%d.%s", bp->id, ext->info->name); + ext, "ocp%d.%s", bp->id, r->name); if (err) { dev_err(&pdev->dev, "Could not get irq %d\n", r->irq_vec); goto out; @@ -1122,12 +1104,6 @@ ptp_ocp_register_serial(struct ptp_ocp *bp, struct ocp_resource *r) { int port; - if (r->irq_vec > bp->n_irqs) { - dev_err(&bp->pdev->dev, "serial device irq %d out of range\n", - r->irq_vec); - return 0; - } - port = ptp_ocp_serial_line(bp, r); if (port < 0) return port; @@ -1160,6 +1136,17 @@ ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r) return ptp_ocp_init_clock(bp); } +static bool +ptp_ocp_allow_irq(struct ptp_ocp *bp, struct ocp_resource *r) +{ + bool allow = !r->irq_vec || r->irq_vec < bp->n_irqs; + + if (!allow) + dev_err(&bp->pdev->dev, "irq %d out of range, skipping %s\n", + r->irq_vec, r->name); + return allow; +} + static int ptp_ocp_register_resources(struct ptp_ocp *bp, kernel_ulong_t driver_data) { @@ -1168,6 +1155,8 @@ ptp_ocp_register_resources(struct ptp_ocp *bp, kernel_ulong_t driver_data) table = (struct ocp_resource *)driver_data; for (r = table; r->setup; r++) { + if (!ptp_ocp_allow_irq(bp, r)) + continue; err = r->setup(bp, r); if (err) break; From patchwork Wed Sep 15 02:16:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495339 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 79E56C433EF for ; Wed, 15 Sep 2021 02:16:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6712D601FF for ; Wed, 15 Sep 2021 02:16:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236063AbhIOCSH (ORCPT ); Tue, 14 Sep 2021 22:18:07 -0400 Received: from smtp.emailarray.com ([69.28.212.198]:53830 "EHLO smtp2.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230037AbhIOCSB (ORCPT ); Tue, 14 Sep 2021 22:18:01 -0400 Received: (qmail 33941 invoked by uid 89); 15 Sep 2021 02:16:43 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp2.emailarray.com with SMTP; 15 Sep 2021 02:16:43 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 05/18] ptp: ocp: Report error if resource registration fails. Date: Tue, 14 Sep 2021 19:16:23 -0700 Message-Id: <20210915021636.153754-6-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org If a resource could not be registered, report the name of the resource and the error code. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index ad8b794fa7e6..1f86e878ccba 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -1158,8 +1158,12 @@ ptp_ocp_register_resources(struct ptp_ocp *bp, kernel_ulong_t driver_data) if (!ptp_ocp_allow_irq(bp, r)) continue; err = r->setup(bp, r); - if (err) + if (err) { + dev_err(&bp->pdev->dev, + "Could not register %s: err %d\n", + r->name, err); break; + } } return err; } From patchwork Wed Sep 15 02:16:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495343 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DEE64C433FE for ; Wed, 15 Sep 2021 02:16:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C6EF560EE2 for ; Wed, 15 Sep 2021 02:16:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235103AbhIOCSI (ORCPT ); Tue, 14 Sep 2021 22:18:08 -0400 Received: from smtp8.emailarray.com ([65.39.216.67]:60807 "EHLO smtp8.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231706AbhIOCSD (ORCPT ); Tue, 14 Sep 2021 22:18:03 -0400 Received: (qmail 92083 invoked by uid 89); 15 Sep 2021 02:16:44 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp8.emailarray.com with SMTP; 15 Sep 2021 02:16:44 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 06/18] ptp: ocp: Add third timestamper Date: Tue, 14 Sep 2021 19:16:24 -0700 Message-Id: <20210915021636.153754-7-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The firmware may provide a third signal timestamper, so make it available for use. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 1f86e878ccba..23d5f20f43f8 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -162,6 +162,7 @@ struct ptp_ocp { struct ptp_ocp_ext_src *pps; struct ptp_ocp_ext_src *ts0; struct ptp_ocp_ext_src *ts1; + struct ptp_ocp_ext_src *ts2; struct img_reg __iomem *image; struct ptp_clock *ptp; struct ptp_clock_info ptp_info; @@ -228,7 +229,7 @@ static int ptp_ocp_ts_enable(void *priv, bool enable); * 3: GPS * 4: GPS2 (n/c) * 5: MAC - * 6: N/C + * 6: TS2 * 7: I2C controller * 8: HWICAP * 9: SPI Flash @@ -257,6 +258,15 @@ static struct ocp_resource ocp_fb_resource[] = { .enable = ptp_ocp_ts_enable, }, }, + { + OCP_EXT_RESOURCE(ts2), + .offset = 0x01060000, .size = 0x10000, .irq_vec = 6, + .extra = &(struct ptp_ocp_ext_info) { + .index = 2, + .irq_fcn = ptp_ocp_ts_irq, + .enable = ptp_ocp_ts_enable, + }, + }, { OCP_MEM_RESOURCE(pps_to_ext), .offset = 0x01030000, .size = 0x10000, @@ -497,6 +507,9 @@ ptp_ocp_enable(struct ptp_clock_info *ptp_info, struct ptp_clock_request *rq, case 1: ext = bp->ts1; break; + case 2: + ext = bp->ts2; + break; } break; case PTP_CLK_REQ_PPS: @@ -524,7 +537,7 @@ static const struct ptp_clock_info ptp_ocp_clock_info = { .adjphase = ptp_ocp_adjphase, .enable = ptp_ocp_enable, .pps = true, - .n_ext_ts = 2, + .n_ext_ts = 3, }; static void @@ -1407,6 +1420,8 @@ ptp_ocp_detach(struct ptp_ocp *bp) ptp_ocp_unregister_ext(bp->ts0); if (bp->ts1) ptp_ocp_unregister_ext(bp->ts1); + if (bp->ts2) + ptp_ocp_unregister_ext(bp->ts2); if (bp->pps) ptp_ocp_unregister_ext(bp->pps); if (bp->gnss_port != -1) From patchwork Wed Sep 15 02:16:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495345 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.9 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5DDB7C433F5 for ; Wed, 15 Sep 2021 02:16:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 407BF60FDA for ; Wed, 15 Sep 2021 02:16:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234763AbhIOCSL (ORCPT ); Tue, 14 Sep 2021 22:18:11 -0400 Received: from smtp8.emailarray.com ([65.39.216.67]:60851 "EHLO smtp8.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231715AbhIOCSE (ORCPT ); Tue, 14 Sep 2021 22:18:04 -0400 Received: (qmail 92111 invoked by uid 89); 15 Sep 2021 02:16:45 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp8.emailarray.com with SMTP; 15 Sep 2021 02:16:45 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 07/18] ptp: ocp: Add SMA selector and controls Date: Tue, 14 Sep 2021 19:16:25 -0700 Message-Id: <20210915021636.153754-8-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The latest firmware for the TimeCard adds selectable signals for the SMA input/outputs. Add support for SMA selectors, and the GPIO controls needed for steering signals. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 389 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 361 insertions(+), 28 deletions(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 23d5f20f43f8..7441dac4e9c5 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -124,6 +124,13 @@ struct img_reg { u32 version; }; +struct gpio_reg { + u32 gpio1; + u32 __pad0; + u32 gpio2; + u32 __pad1; +}; + struct ptp_ocp_flash_info { const char *name; int pci_offset; @@ -159,6 +166,7 @@ struct ptp_ocp { struct tod_reg __iomem *tod; struct pps_reg __iomem *pps_to_ext; struct pps_reg __iomem *pps_to_clk; + struct gpio_reg __iomem *sma; struct ptp_ocp_ext_src *pps; struct ptp_ocp_ext_src *ts0; struct ptp_ocp_ext_src *ts1; @@ -283,6 +291,10 @@ static struct ocp_resource ocp_fb_resource[] = { OCP_MEM_RESOURCE(image), .offset = 0x00020000, .size = 0x1000, }, + { + OCP_MEM_RESOURCE(sma), + .offset = 0x00140000, .size = 0x1000, + }, { OCP_I2C_RESOURCE(i2c_ctrl), .offset = 0x00150000, .size = 0x10000, .irq_vec = 7, @@ -330,10 +342,12 @@ MODULE_DEVICE_TABLE(pci, ptp_ocp_pcidev_id); static DEFINE_MUTEX(ptp_ocp_lock); static DEFINE_IDR(ptp_ocp_idr); -static struct { +struct ocp_selector { const char *name; int value; -} ptp_ocp_clock[] = { +}; + +static struct ocp_selector ptp_ocp_clock[] = { { .name = "NONE", .value = 0 }, { .name = "TOD", .value = 1 }, { .name = "IRIG", .value = 2 }, @@ -343,33 +357,67 @@ static struct { { .name = "DCF", .value = 6 }, { .name = "REGS", .value = 0xfe }, { .name = "EXT", .value = 0xff }, + { } +}; + +static struct ocp_selector ptp_ocp_sma_in[] = { + { .name = "10Mhz", .value = 0x00 }, + { .name = "PPS1", .value = 0x01 }, + { .name = "PPS2", .value = 0x02 }, + { .name = "TS1", .value = 0x04 }, + { .name = "TS2", .value = 0x08 }, + { } +}; + +static struct ocp_selector ptp_ocp_sma_out[] = { + { .name = "10Mhz", .value = 0x00 }, + { .name = "PHC", .value = 0x01 }, + { .name = "MAC", .value = 0x02 }, + { .name = "GNSS", .value = 0x04 }, + { .name = "GNSS2", .value = 0x08 }, + { } }; static const char * -ptp_ocp_clock_name_from_val(int val) +ptp_ocp_select_name_from_val(struct ocp_selector *tbl, int val) { int i; - for (i = 0; i < ARRAY_SIZE(ptp_ocp_clock); i++) - if (ptp_ocp_clock[i].value == val) - return ptp_ocp_clock[i].name; + for (i = 0; tbl[i].name; i++) + if (tbl[i].value == val) + return tbl[i].name; return NULL; } static int -ptp_ocp_clock_val_from_name(const char *name) +ptp_ocp_select_val_from_name(struct ocp_selector *tbl, const char *name) { - const char *clk; + const char *select; int i; - for (i = 0; i < ARRAY_SIZE(ptp_ocp_clock); i++) { - clk = ptp_ocp_clock[i].name; - if (!strncasecmp(name, clk, strlen(clk))) - return ptp_ocp_clock[i].value; + for (i = 0; tbl[i].name; i++) { + select = tbl[i].name; + if (!strncasecmp(name, select, strlen(select))) + return tbl[i].value; } return -EINVAL; } +static ssize_t +ptp_ocp_select_table_show(struct ocp_selector *tbl, char *buf) +{ + ssize_t count; + int i; + + count = 0; + for (i = 0; tbl[i].name; i++) + count += sysfs_emit_at(buf, count, "%s ", tbl[i].name); + if (count) + count--; + count += sysfs_emit_at(buf, count, "\n"); + return count; +} + static int __ptp_ocp_gettime_locked(struct ptp_ocp *bp, struct timespec64 *ts, struct ptp_system_timestamp *sts) @@ -756,7 +804,7 @@ ptp_ocp_info(struct ptp_ocp *bp) select = ioread32(&bp->reg->select); dev_info(&bp->pdev->dev, "Version %d.%d.%d, clock %s, device ptp%d\n", version >> 24, (version >> 16) & 0xff, version & 0xffff, - ptp_ocp_clock_name_from_val(select >> 16), + ptp_ocp_select_name_from_val(ptp_ocp_clock, select >> 16), ptp_clock_index(bp->ptp)); if (bp->tod) @@ -1181,6 +1229,297 @@ ptp_ocp_register_resources(struct ptp_ocp *bp, kernel_ulong_t driver_data) return err; } +/* + * ANT0 == gps (in) + * ANT1 == sma1 (in) + * ANT2 == sma2 (in) + * ANT3 == sma3 (out) + * ANT4 == sma4 (out) + */ + +enum ptp_ocp_sma_mode { + SMA_MODE_IN, + SMA_MODE_OUT, +}; + +static struct ptp_ocp_sma_connector { + enum ptp_ocp_sma_mode mode; + bool fixed_mode; + u16 default_out_idx; +} ptp_ocp_sma_map[4] = { + { + .mode = SMA_MODE_IN, + .fixed_mode = true, + }, + { + .mode = SMA_MODE_IN, + .fixed_mode = true, + }, + { + .mode = SMA_MODE_OUT, + .fixed_mode = true, + .default_out_idx = 0, /* 10Mhz */ + }, + { + .mode = SMA_MODE_OUT, + .fixed_mode = true, + .default_out_idx = 1, /* PHC */ + }, +}; + +static ssize_t +ptp_ocp_show_output(u32 val, char *buf, int default_idx) +{ + const char *name; + ssize_t count; + + count = sysfs_emit(buf, "OUT: "); + name = ptp_ocp_select_name_from_val(ptp_ocp_sma_out, val); + if (!name) + name = ptp_ocp_sma_out[default_idx].name; + count += sysfs_emit_at(buf, count, "%s\n", name); + return count; +} + +static ssize_t +ptp_ocp_show_inputs(u32 val, char *buf, const char *zero_in) +{ + const char *name; + ssize_t count; + int i; + + count = sysfs_emit(buf, "IN: "); + for (i = 0; i < ARRAY_SIZE(ptp_ocp_sma_in); i++) { + if (val & ptp_ocp_sma_in[i].value) { + name = ptp_ocp_sma_in[i].name; + count += sysfs_emit_at(buf, count, "%s ", name); + } + } + if (!val && zero_in) + count += sysfs_emit_at(buf, count, "%s ", zero_in); + if (count) + count--; + count += sysfs_emit_at(buf, count, "\n"); + return count; +} + +static int +sma_parse_inputs(const char *buf, enum ptp_ocp_sma_mode *mode) +{ + struct ocp_selector *tbl[] = { ptp_ocp_sma_in, ptp_ocp_sma_out }; + int idx, count, dir; + char **argv; + int ret; + + argv = argv_split(GFP_KERNEL, buf, &count); + if (!argv) + return -ENOMEM; + + ret = -EINVAL; + if (!count) + goto out; + + idx = 0; + dir = *mode == SMA_MODE_IN ? 0 : 1; + if (!strcasecmp("IN:", argv[idx])) { + dir = 0; + idx++; + } + if (!strcasecmp("OUT:", argv[0])) { + dir = 1; + idx++; + } + *mode = dir == 0 ? SMA_MODE_IN : SMA_MODE_OUT; + + ret = 0; + for (; idx < count; idx++) + ret |= ptp_ocp_select_val_from_name(tbl[dir], argv[idx]); + if (ret < 0) + ret = -EINVAL; + +out: + argv_free(argv); + return ret; +} + +static ssize_t +ptp_ocp_sma_show(struct ptp_ocp *bp, int sma_nr, u32 val, char *buf, + const char *zero_in) +{ + struct ptp_ocp_sma_connector *sma = &ptp_ocp_sma_map[sma_nr - 1]; + + if (sma->mode == SMA_MODE_IN) + return ptp_ocp_show_inputs(val, buf, zero_in); + + return ptp_ocp_show_output(val, buf, sma->default_out_idx); +} + +static ssize_t +sma1_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + u32 val; + + val = ioread32(&bp->sma->gpio1) & 0x3f; + return ptp_ocp_sma_show(bp, 1, val, buf, ptp_ocp_sma_in[0].name); +} + +static ssize_t +sma2_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + u32 val; + + val = (ioread32(&bp->sma->gpio1) >> 16) & 0x3f; + return ptp_ocp_sma_show(bp, 2, val, buf, NULL); +} + +static ssize_t +sma3_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + u32 val; + + val = ioread32(&bp->sma->gpio2) & 0x3f; + return ptp_ocp_sma_show(bp, 3, val, buf, NULL); +} + +static ssize_t +sma4_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + u32 val; + + val = (ioread32(&bp->sma->gpio2) >> 16) & 0x3f; + return ptp_ocp_sma_show(bp, 4, val, buf, NULL); +} + +static void +ptp_ocp_sma_store_output(struct ptp_ocp *bp, u32 val, u32 shift) +{ + unsigned long flags; + u32 gpio, mask; + + mask = 0xffff << (16 - shift); + + spin_lock_irqsave(&bp->lock, flags); + + gpio = ioread32(&bp->sma->gpio2); + gpio = (gpio & mask) | (val << shift); + iowrite32(gpio, &bp->sma->gpio2); + + spin_unlock_irqrestore(&bp->lock, flags); +} + +static void +ptp_ocp_sma_store_inputs(struct ptp_ocp *bp, u32 val, u32 shift) +{ + unsigned long flags; + u32 gpio, mask; + + mask = 0xffff << (16 - shift); + + spin_lock_irqsave(&bp->lock, flags); + + gpio = ioread32(&bp->sma->gpio1); + gpio = (gpio & mask) | (val << shift); + iowrite32(gpio, &bp->sma->gpio1); + + spin_unlock_irqrestore(&bp->lock, flags); +} + +static ssize_t +ptp_ocp_sma_store(struct ptp_ocp *bp, const char *buf, int sma_nr, u32 shift) +{ + struct ptp_ocp_sma_connector *sma = &ptp_ocp_sma_map[sma_nr - 1]; + enum ptp_ocp_sma_mode mode; + int val; + + mode = sma->mode; + val = sma_parse_inputs(buf, &mode); + if (val < 0) + return val; + + if (mode != sma->mode && sma->fixed_mode) + return -EOPNOTSUPP; + + if (mode != sma->mode) { + pr_err("Mode changes not supported yet.\n"); + return -EOPNOTSUPP; + } + + if (sma->mode == SMA_MODE_IN) + ptp_ocp_sma_store_inputs(bp, val, shift); + else + ptp_ocp_sma_store_output(bp, val, shift); + + return 0; +} + +static ssize_t +sma1_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + int err; + + err = ptp_ocp_sma_store(bp, buf, 1, 0); + return err ? err : count; +} + +static ssize_t +sma2_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + int err; + + err = ptp_ocp_sma_store(bp, buf, 2, 16); + return err ? err : count; +} + +static ssize_t +sma3_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + int err; + + err = ptp_ocp_sma_store(bp, buf, 3, 0); + return err ? err : count; +} + +static ssize_t +sma4_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + int err; + + err = ptp_ocp_sma_store(bp, buf, 4, 16); + return err ? err : count; +} +static DEVICE_ATTR_RW(sma1); +static DEVICE_ATTR_RW(sma2); +static DEVICE_ATTR_RW(sma3); +static DEVICE_ATTR_RW(sma4); + +static ssize_t +available_sma_inputs_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return ptp_ocp_select_table_show(ptp_ocp_sma_in, buf); +} +static DEVICE_ATTR_RO(available_sma_inputs); + +static ssize_t +available_sma_outputs_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return ptp_ocp_select_table_show(ptp_ocp_sma_out, buf); +} +static DEVICE_ATTR_RO(available_sma_outputs); + static ssize_t serialnum_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1216,7 +1555,7 @@ clock_source_show(struct device *dev, struct device_attribute *attr, char *buf) u32 select; select = ioread32(&bp->reg->select); - p = ptp_ocp_clock_name_from_val(select >> 16); + p = ptp_ocp_select_name_from_val(ptp_ocp_clock, select >> 16); return sysfs_emit(buf, "%s\n", p); } @@ -1229,7 +1568,7 @@ clock_source_store(struct device *dev, struct device_attribute *attr, unsigned long flags; int val; - val = ptp_ocp_clock_val_from_name(buf); + val = ptp_ocp_select_val_from_name(ptp_ocp_clock, buf); if (val < 0) return val; @@ -1245,19 +1584,7 @@ static ssize_t available_clock_sources_show(struct device *dev, struct device_attribute *attr, char *buf) { - const char *clk; - ssize_t count; - int i; - - count = 0; - for (i = 0; i < ARRAY_SIZE(ptp_ocp_clock); i++) { - clk = ptp_ocp_clock[i].name; - count += sysfs_emit_at(buf, count, "%s ", clk); - } - if (count) - count--; - count += sysfs_emit_at(buf, count, "\n"); - return count; + return ptp_ocp_select_table_show(ptp_ocp_clock, buf); } static DEVICE_ATTR_RO(available_clock_sources); @@ -1266,6 +1593,12 @@ static struct attribute *timecard_attrs[] = { &dev_attr_gnss_sync.attr, &dev_attr_clock_source.attr, &dev_attr_available_clock_sources.attr, + &dev_attr_sma1.attr, + &dev_attr_sma2.attr, + &dev_attr_sma3.attr, + &dev_attr_sma4.attr, + &dev_attr_available_sma_inputs.attr, + &dev_attr_available_sma_outputs.attr, NULL, }; ATTRIBUTE_GROUPS(timecard); From patchwork Wed Sep 15 02:16:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495349 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 933C0C433FE for ; Wed, 15 Sep 2021 02:16:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7796C60EE0 for ; Wed, 15 Sep 2021 02:16:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236037AbhIOCSN (ORCPT ); Tue, 14 Sep 2021 22:18:13 -0400 Received: from smtp5.emailarray.com ([65.39.216.39]:44112 "EHLO smtp5.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232666AbhIOCSF (ORCPT ); Tue, 14 Sep 2021 22:18:05 -0400 Received: (qmail 83522 invoked by uid 89); 15 Sep 2021 02:16:46 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp5.emailarray.com with SMTP; 15 Sep 2021 02:16:46 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 08/18] ptp: ocp: Add IRIG-B and DCF blocks Date: Tue, 14 Sep 2021 19:16:26 -0700 Message-Id: <20210915021636.153754-9-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org IRIG (Inter-range Instrumentation Group) timecode format on one of the SMA output channels is provided by the IRIG master FPGA block. Enable the master when the IRIG output format is selected on either one of the output channels. By default, the output is in B007 format. DCF output format is provided by the DCF master block. Also enable the IRIG and DCF slaves, which parse an incoming signal from the external SMA connectors, and may be used to adjust the PHC. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 129 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 7441dac4e9c5..1a210b77744c 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -131,6 +131,48 @@ struct gpio_reg { u32 __pad1; }; +struct irig_master_reg { + u32 ctrl; + u32 status; + u32 __pad0; + u32 version; + u32 adj_sec; + u32 mode_ctrl; +}; + +#define IRIG_M_CTRL_ENABLE BIT(0) + +struct irig_slave_reg { + u32 ctrl; + u32 status; + u32 __pad0; + u32 version; + u32 adj_sec; + u32 mode_ctrl; +}; + +#define IRIG_S_CTRL_ENABLE BIT(0) + +struct dcf_master_reg { + u32 ctrl; + u32 status; + u32 __pad0; + u32 version; + u32 adj_sec; +}; + +#define DCF_M_CTRL_ENABLE BIT(0) + +struct dcf_slave_reg { + u32 ctrl; + u32 status; + u32 __pad0; + u32 version; + u32 adj_sec; +}; + +#define DCF_S_CTRL_ENABLE BIT(0) + struct ptp_ocp_flash_info { const char *name; int pci_offset; @@ -167,6 +209,10 @@ struct ptp_ocp { struct pps_reg __iomem *pps_to_ext; struct pps_reg __iomem *pps_to_clk; struct gpio_reg __iomem *sma; + struct irig_master_reg __iomem *irig_out; + struct irig_slave_reg __iomem *irig_in; + struct dcf_master_reg __iomem *dcf_out; + struct dcf_slave_reg __iomem *dcf_in; struct ptp_ocp_ext_src *pps; struct ptp_ocp_ext_src *ts0; struct ptp_ocp_ext_src *ts1; @@ -287,6 +333,22 @@ static struct ocp_resource ocp_fb_resource[] = { OCP_MEM_RESOURCE(tod), .offset = 0x01050000, .size = 0x10000, }, + { + OCP_MEM_RESOURCE(irig_in), + .offset = 0x01070000, .size = 0x10000, + }, + { + OCP_MEM_RESOURCE(irig_out), + .offset = 0x01080000, .size = 0x10000, + }, + { + OCP_MEM_RESOURCE(dcf_in), + .offset = 0x01090000, .size = 0x10000, + }, + { + OCP_MEM_RESOURCE(dcf_out), + .offset = 0x010A0000, .size = 0x10000, + }, { OCP_MEM_RESOURCE(image), .offset = 0x00020000, .size = 0x1000, @@ -366,6 +428,8 @@ static struct ocp_selector ptp_ocp_sma_in[] = { { .name = "PPS2", .value = 0x02 }, { .name = "TS1", .value = 0x04 }, { .name = "TS2", .value = 0x08 }, + { .name = "IRIG", .value = 0x10 }, + { .name = "DCF", .value = 0x20 }, { } }; @@ -375,6 +439,8 @@ static struct ocp_selector ptp_ocp_sma_out[] = { { .name = "MAC", .value = 0x02 }, { .name = "GNSS", .value = 0x04 }, { .name = "GNSS2", .value = 0x08 }, + { .name = "IRIG", .value = 0x10 }, + { .name = "DCF", .value = 0x20 }, { } }; @@ -1229,6 +1295,63 @@ ptp_ocp_register_resources(struct ptp_ocp *bp, kernel_ulong_t driver_data) return err; } +static void +ptp_ocp_enable_fpga(u32 __iomem *reg, u32 bit, bool enable) +{ + u32 ctrl; + bool on; + + ctrl = ioread32(reg); + on = ctrl & bit; + if (on ^ enable) { + ctrl &= ~bit; + ctrl |= enable ? bit : 0; + iowrite32(ctrl, reg); + } +} + +static void +ptp_ocp_irig_out(struct ptp_ocp *bp, bool enable) +{ + return ptp_ocp_enable_fpga(&bp->irig_out->ctrl, + IRIG_M_CTRL_ENABLE, enable); +} + +static void +ptp_ocp_irig_in(struct ptp_ocp *bp, bool enable) +{ + return ptp_ocp_enable_fpga(&bp->irig_in->ctrl, + IRIG_S_CTRL_ENABLE, enable); +} + +static void +ptp_ocp_dcf_out(struct ptp_ocp *bp, bool enable) +{ + return ptp_ocp_enable_fpga(&bp->dcf_out->ctrl, + DCF_M_CTRL_ENABLE, enable); +} + +static void +ptp_ocp_dcf_in(struct ptp_ocp *bp, bool enable) +{ + return ptp_ocp_enable_fpga(&bp->dcf_in->ctrl, + DCF_S_CTRL_ENABLE, enable); +} + +static void +__handle_signal_outputs(struct ptp_ocp *bp, u32 val) +{ + ptp_ocp_irig_out(bp, val & 0x00100010); + ptp_ocp_dcf_out(bp, val & 0x00200020); +} + +static void +__handle_signal_inputs(struct ptp_ocp *bp, u32 val) +{ + ptp_ocp_irig_in(bp, val & 0x00100010); + ptp_ocp_dcf_in(bp, val & 0x00200020); +} + /* * ANT0 == gps (in) * ANT1 == sma1 (in) @@ -1406,6 +1529,9 @@ ptp_ocp_sma_store_output(struct ptp_ocp *bp, u32 val, u32 shift) gpio = ioread32(&bp->sma->gpio2); gpio = (gpio & mask) | (val << shift); + + __handle_signal_outputs(bp, gpio); + iowrite32(gpio, &bp->sma->gpio2); spin_unlock_irqrestore(&bp->lock, flags); @@ -1423,6 +1549,9 @@ ptp_ocp_sma_store_inputs(struct ptp_ocp *bp, u32 val, u32 shift) gpio = ioread32(&bp->sma->gpio1); gpio = (gpio & mask) | (val << shift); + + __handle_signal_inputs(bp, gpio); + iowrite32(gpio, &bp->sma->gpio1); spin_unlock_irqrestore(&bp->lock, flags); From patchwork Wed Sep 15 02:16:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495347 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 41E6EC433EF for ; Wed, 15 Sep 2021 02:16:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 29A46608FB for ; Wed, 15 Sep 2021 02:16:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233532AbhIOCSM (ORCPT ); Tue, 14 Sep 2021 22:18:12 -0400 Received: from smtp8.emailarray.com ([65.39.216.67]:60901 "EHLO smtp8.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235899AbhIOCSG (ORCPT ); Tue, 14 Sep 2021 22:18:06 -0400 Received: (qmail 92145 invoked by uid 89); 15 Sep 2021 02:16:47 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp8.emailarray.com with SMTP; 15 Sep 2021 02:16:47 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 09/18] ptp: ocp: Add IRIG-B output mode control Date: Tue, 14 Sep 2021 19:16:27 -0700 Message-Id: <20210915021636.153754-10-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org IRIG-B has several different output formats, the timecard defaults to using B007. Add a control which selects different output modes. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 1a210b77744c..2b3d4282d77a 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -1676,6 +1676,46 @@ gnss_sync_show(struct device *dev, struct device_attribute *attr, char *buf) } static DEVICE_ATTR_RO(gnss_sync); +static ssize_t +irig_b_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + u32 val; + + val = ioread32(&bp->irig_out->ctrl); + val = (val >> 16) & 0x07; + return sysfs_emit(buf, "%d\n", val); +} + +static ssize_t +irig_b_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + unsigned long flags; + int err; + u32 reg; + u8 val; + + err = kstrtou8(buf, 0, &val); + if (err) + return err; + if (val > 7) + return -EINVAL; + + reg = ((val & 0x7) << 16); + + spin_lock_irqsave(&bp->lock, flags); + iowrite32(0, &bp->irig_out->ctrl); /* disable */ + iowrite32(reg, &bp->irig_out->ctrl); /* change mode */ + iowrite32(reg | IRIG_M_CTRL_ENABLE, &bp->irig_out->ctrl); + spin_unlock_irqrestore(&bp->lock, flags); + + return count; +} +static DEVICE_ATTR_RW(irig_b_mode); + static ssize_t clock_source_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1728,6 +1768,7 @@ static struct attribute *timecard_attrs[] = { &dev_attr_sma4.attr, &dev_attr_available_sma_inputs.attr, &dev_attr_available_sma_outputs.attr, + &dev_attr_irig_b_mode.attr, NULL, }; ATTRIBUTE_GROUPS(timecard); From patchwork Wed Sep 15 02:16:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495351 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77D68C433F5 for ; Wed, 15 Sep 2021 02:16:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 63876601FF for ; Wed, 15 Sep 2021 02:16:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236143AbhIOCSO (ORCPT ); Tue, 14 Sep 2021 22:18:14 -0400 Received: from smtp5.emailarray.com ([65.39.216.39]:44170 "EHLO smtp5.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235548AbhIOCSH (ORCPT ); Tue, 14 Sep 2021 22:18:07 -0400 Received: (qmail 83593 invoked by uid 89); 15 Sep 2021 02:16:48 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp5.emailarray.com with SMTP; 15 Sep 2021 02:16:48 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 10/18] ptp: ocp: Add sysfs attribute utc_tai_offset Date: Tue, 14 Sep 2021 19:16:28 -0700 Message-Id: <20210915021636.153754-11-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org IRIG and DCF output time in UTC, but the timecard operates on TAI internally. Add an attribute node which allows adding an offset to these modes before output. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 49 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 2b3d4282d77a..2c3af3c9def7 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -230,8 +230,9 @@ struct ptp_ocp { int gnss_port; int mac_port; /* miniature atomic clock */ u8 serial[6]; - int flash_start; bool has_serial; + int flash_start; + u32 utc_tai_offset; }; struct ocp_resource { @@ -741,6 +742,23 @@ ptp_ocp_init_clock(struct ptp_ocp *bp) return 0; } +static void +ptp_ocp_utc_distribute(struct ptp_ocp *bp, u32 val) +{ + unsigned long flags; + + spin_lock_irqsave(&bp->lock, flags); + + bp->utc_tai_offset = val; + + if (bp->irig_out) + iowrite32(val, &bp->irig_out->adj_sec); + if (bp->dcf_out) + iowrite32(val, &bp->dcf_out->adj_sec); + + spin_unlock_irqrestore(&bp->lock, flags); +} + static void ptp_ocp_tod_info(struct ptp_ocp *bp) { @@ -1676,6 +1694,34 @@ gnss_sync_show(struct device *dev, struct device_attribute *attr, char *buf) } static DEVICE_ATTR_RO(gnss_sync); +static ssize_t +utc_tai_offset_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%d\n", bp->utc_tai_offset); +} + +static ssize_t +utc_tai_offset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + int err; + u32 val; + + err = kstrtou32(buf, 0, &val); + if (err) + return err; + + ptp_ocp_utc_distribute(bp, val); + + return count; +} +static DEVICE_ATTR_RW(utc_tai_offset); + static ssize_t irig_b_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1769,6 +1815,7 @@ static struct attribute *timecard_attrs[] = { &dev_attr_available_sma_inputs.attr, &dev_attr_available_sma_outputs.attr, &dev_attr_irig_b_mode.attr, + &dev_attr_utc_tai_offset.attr, NULL, }; ATTRIBUTE_GROUPS(timecard); From patchwork Wed Sep 15 02:16:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495353 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C80CFC433EF for ; Wed, 15 Sep 2021 02:16:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B22BC60EE0 for ; Wed, 15 Sep 2021 02:16:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236169AbhIOCSP (ORCPT ); Tue, 14 Sep 2021 22:18:15 -0400 Received: from smtp7.emailarray.com ([65.39.216.66]:33352 "EHLO smtp7.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236079AbhIOCSJ (ORCPT ); Tue, 14 Sep 2021 22:18:09 -0400 Received: (qmail 8889 invoked by uid 89); 15 Sep 2021 02:16:50 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp7.emailarray.com with SMTP; 15 Sep 2021 02:16:50 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 11/18] ptp: ocp: Separate the init and info logic Date: Tue, 14 Sep 2021 19:16:29 -0700 Message-Id: <20210915021636.153754-12-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org On startup, parts of the FPGA need to be initialized - break these out into their own functions, separate from the purely informational blocks. On startup, distrbute the UTC:TAI offset from the NMEA GNSS parser, if it is available. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 96 +++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 36 deletions(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 2c3af3c9def7..ea12f685edf6 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -72,7 +72,7 @@ struct tod_reg { u32 status; u32 uart_polarity; u32 version; - u32 correction_sec; + u32 adj_sec; u32 __pad0[3]; u32 uart_baud; u32 __pad1[3]; @@ -728,16 +728,15 @@ ptp_ocp_init_clock(struct ptp_ocp *bp) sync = ioread32(&bp->reg->status) & OCP_STATUS_IN_SYNC; if (!sync) { - ktime_get_real_ts64(&ts); + ktime_get_clocktai_ts64(&ts); ptp_ocp_settime(&bp->ptp_info, &ts); } - if (!ptp_ocp_gettimex(&bp->ptp_info, &ts, NULL)) - dev_info(&bp->pdev->dev, "Time: %lld.%ld, %s\n", - ts.tv_sec, ts.tv_nsec, - sync ? "in-sync" : "UNSYNCED"); - timer_setup(&bp->watchdog, ptp_ocp_watchdog, 0); - mod_timer(&bp->watchdog, jiffies + HZ); + /* If there is a clock supervisor, then enable the watchdog */ + if (bp->pps_to_clk) { + timer_setup(&bp->watchdog, ptp_ocp_watchdog, 0); + mod_timer(&bp->watchdog, jiffies + HZ); + } return 0; } @@ -759,6 +758,21 @@ ptp_ocp_utc_distribute(struct ptp_ocp *bp, u32 val) spin_unlock_irqrestore(&bp->lock, flags); } +static void +ptp_ocp_tod_init(struct ptp_ocp *bp) +{ + u32 ctrl, reg; + + ctrl = ioread32(&bp->tod->ctrl); + ctrl |= TOD_CTRL_PROTOCOL | TOD_CTRL_ENABLE; + ctrl &= ~(TOD_CTRL_DISABLE_FMT_A | TOD_CTRL_DISABLE_FMT_B); + iowrite32(ctrl, &bp->tod->ctrl); + + reg = ioread32(&bp->tod->utc_status); + if (reg & TOD_STATUS_UTC_VALID) + ptp_ocp_utc_distribute(bp, reg & TOD_STATUS_UTC_MASK); +} + static void ptp_ocp_tod_info(struct ptp_ocp *bp) { @@ -776,11 +790,6 @@ ptp_ocp_tod_info(struct ptp_ocp *bp) dev_info(&bp->pdev->dev, "TOD Version %d.%d.%d\n", version >> 24, (version >> 16) & 0xff, version & 0xffff); - ctrl = ioread32(&bp->tod->ctrl); - ctrl |= TOD_CTRL_PROTOCOL | TOD_CTRL_ENABLE; - ctrl &= ~(TOD_CTRL_DISABLE_FMT_A | TOD_CTRL_DISABLE_FMT_B); - iowrite32(ctrl, &bp->tod->ctrl); - ctrl = ioread32(&bp->tod->ctrl); idx = ctrl & TOD_CTRL_PROTOCOL ? 4 : 0; idx += (ctrl >> 16) & 3; @@ -795,7 +804,7 @@ ptp_ocp_tod_info(struct ptp_ocp *bp) reg = ioread32(&bp->tod->status); dev_info(&bp->pdev->dev, "status: %x\n", reg); - reg = ioread32(&bp->tod->correction_sec); + reg = ioread32(&bp->tod->adj_sec); dev_info(&bp->pdev->dev, "correction: %d\n", reg); reg = ioread32(&bp->tod->utc_status); @@ -879,22 +888,6 @@ ptp_ocp_get_serial_number(struct ptp_ocp *bp) put_device(dev); } -static void -ptp_ocp_info(struct ptp_ocp *bp) -{ - u32 version, select; - - version = ioread32(&bp->reg->version); - select = ioread32(&bp->reg->select); - dev_info(&bp->pdev->dev, "Version %d.%d.%d, clock %s, device ptp%d\n", - version >> 24, (version >> 16) & 0xff, version & 0xffff, - ptp_ocp_select_name_from_val(ptp_ocp_clock, select >> 16), - ptp_clock_index(bp->ptp)); - - if (bp->tod) - ptp_ocp_tod_info(bp); -} - static struct device * ptp_ocp_find_flash(struct ptp_ocp *bp) { @@ -1278,6 +1271,8 @@ ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r) { bp->flash_start = 1024 * 4096; + ptp_ocp_tod_init(bp); + return ptp_ocp_init_clock(bp); } @@ -1927,10 +1922,42 @@ ptp_ocp_complete(struct ptp_ocp *bp) } static void -ptp_ocp_resource_summary(struct ptp_ocp *bp) +ptp_ocp_phc_info(struct ptp_ocp *bp) +{ + struct timespec64 ts; + u32 version, select; + bool sync; + + version = ioread32(&bp->reg->version); + select = ioread32(&bp->reg->select); + dev_info(&bp->pdev->dev, "Version %d.%d.%d, clock %s, device ptp%d\n", + version >> 24, (version >> 16) & 0xff, version & 0xffff, + ptp_ocp_select_name_from_val(ptp_ocp_clock, select >> 16), + ptp_clock_index(bp->ptp)); + + sync = ioread32(&bp->reg->status) & OCP_STATUS_IN_SYNC; + if (!ptp_ocp_gettimex(&bp->ptp_info, &ts, NULL)) + dev_info(&bp->pdev->dev, "Time: %lld.%ld, %s\n", + ts.tv_sec, ts.tv_nsec, + sync ? "in-sync" : "UNSYNCED"); +} + +static void +ptp_ocp_serial_info(struct device *dev, const char *name, int port, int baud) +{ + if (port != -1) + dev_info(dev, "%5s: /dev/ttyS%-2d @ %6d\n", name, port, baud); +} + +static void +ptp_ocp_info(struct ptp_ocp *bp) { struct device *dev = &bp->pdev->dev; + ptp_ocp_phc_info(bp); + if (bp->tod) + ptp_ocp_tod_info(bp); + if (bp->image) { u32 ver = ioread32(&bp->image->version); @@ -1942,10 +1969,8 @@ ptp_ocp_resource_summary(struct ptp_ocp *bp) dev_info(dev, "golden image, version %d\n", ver >> 16); } - if (bp->gnss_port != -1) - dev_info(dev, "GNSS @ /dev/ttyS%d 115200\n", bp->gnss_port); - if (bp->mac_port != -1) - dev_info(dev, "MAC @ /dev/ttyS%d 57600\n", bp->mac_port); + ptp_ocp_serial_info(dev, "GNSS", bp->gnss_port, 115200); + ptp_ocp_serial_info(dev, "MAC", bp->mac_port, 57600); } static void @@ -2049,7 +2074,6 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto out; ptp_ocp_info(bp); - ptp_ocp_resource_summary(bp); return 0; From patchwork Wed Sep 15 02:16:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495355 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B759AC433EF for ; Wed, 15 Sep 2021 02:17:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A485C601FF for ; Wed, 15 Sep 2021 02:17:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235094AbhIOCSR (ORCPT ); Tue, 14 Sep 2021 22:18:17 -0400 Received: from smtp5.emailarray.com ([65.39.216.39]:44226 "EHLO smtp5.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235259AbhIOCSK (ORCPT ); Tue, 14 Sep 2021 22:18:10 -0400 Received: (qmail 83647 invoked by uid 89); 15 Sep 2021 02:16:51 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp5.emailarray.com with SMTP; 15 Sep 2021 02:16:51 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 12/18] ptp: ocp: Add debugfs entry for timecard Date: Tue, 14 Sep 2021 19:16:30 -0700 Message-Id: <20210915021636.153754-13-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Provide a view into the timecard internals for debugging. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 233 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index ea12f685edf6..36924423444e 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -208,6 +209,7 @@ struct ptp_ocp { struct tod_reg __iomem *tod; struct pps_reg __iomem *pps_to_ext; struct pps_reg __iomem *pps_to_clk; + struct gpio_reg __iomem *pps_select; struct gpio_reg __iomem *sma; struct irig_master_reg __iomem *irig_out; struct irig_slave_reg __iomem *irig_in; @@ -224,6 +226,7 @@ struct ptp_ocp { struct platform_device *spi_flash; struct clk_hw *i2c_clk; struct timer_list watchdog; + struct dentry *debug_root; time64_t gnss_lost; int id; int n_irqs; @@ -354,6 +357,10 @@ static struct ocp_resource ocp_fb_resource[] = { OCP_MEM_RESOURCE(image), .offset = 0x00020000, .size = 0x1000, }, + { + OCP_MEM_RESOURCE(pps_select), + .offset = 0x00130000, .size = 0x1000, + }, { OCP_MEM_RESOURCE(sma), .offset = 0x00140000, .size = 0x1000, @@ -1815,6 +1822,225 @@ static struct attribute *timecard_attrs[] = { }; ATTRIBUTE_GROUPS(timecard); +static const char * +gpio_map(u32 gpio, u32 bit, const char *pri, const char *sec, const char *def) +{ + const char *ans; + + if (gpio & (1 << bit)) + ans = pri; + else if (gpio & (1 << (bit + 16))) + ans = sec; + else + ans = def; + return ans; +} + +static void +gpio_multi_map(char *buf, u32 gpio, u32 bit, + const char *pri, const char *sec, const char *def) +{ + char *ans = buf; + + strcpy(ans, def); + if (gpio & (1 << bit)) + ans += sprintf(ans, "%s ", pri); + if (gpio & (1 << (bit + 16))) + ans += sprintf(ans, "%s ", sec); +} + +static int +ptp_ocp_summary_show(struct seq_file *s, void *data) +{ + struct device *dev = s->private; + struct ptp_system_timestamp sts; + u32 sma_in, sma_out, ctrl, val; + struct ts_reg __iomem *ts_reg; + struct timespec64 ts; + struct ptp_ocp *bp; + const char *src; + char *buf; + bool on; + + buf = (char *)__get_free_page(GFP_KERNEL); + if (!buf) + return -ENOMEM; + + bp = dev_get_drvdata(dev); + sma_in = ioread32(&bp->sma->gpio1); + sma_out = ioread32(&bp->sma->gpio2); + + seq_printf(s, "%7s: /dev/ptp%d\n", "PTP", ptp_clock_index(bp->ptp)); + + sma1_show(dev, NULL, buf); + seq_printf(s, " sma1: %s", buf); + + sma2_show(dev, NULL, buf); + seq_printf(s, " sma2: %s", buf); + + sma3_show(dev, NULL, buf); + seq_printf(s, " sma3: %s", buf); + + sma4_show(dev, NULL, buf); + seq_printf(s, " sma4: %s", buf); + + if (bp->ts0) { + ts_reg = bp->ts0->mem; + on = ioread32(&ts_reg->enable); + src = "GNSS"; + seq_printf(s, "%7s: %s, src: %s\n", "TS0", + on ? " ON" : "OFF", src); + } + + if (bp->ts1) { + ts_reg = bp->ts1->mem; + on = ioread32(&ts_reg->enable); + src = gpio_map(sma_in, 2, "sma1", "sma2", "----"); + seq_printf(s, "%7s: %s, src: %s\n", "TS1", + on ? " ON" : "OFF", src); + } + + if (bp->ts2) { + ts_reg = bp->ts2->mem; + on = ioread32(&ts_reg->enable); + src = gpio_map(sma_in, 3, "sma1", "sma2", "----"); + seq_printf(s, "%7s: %s, src: %s\n", "TS2", + on ? " ON" : "OFF", src); + } + + if (bp->irig_out) { + ctrl = ioread32(&bp->irig_out->ctrl); + on = ctrl & IRIG_M_CTRL_ENABLE; + val = ioread32(&bp->irig_out->status); + gpio_multi_map(buf, sma_out, 4, "sma3", "sma4", "----"); + seq_printf(s, "%7s: %s, error: %d, mode %d, out: %s\n", "IRIG", + on ? " ON" : "OFF", val, (ctrl >> 16), buf); + } + + if (bp->irig_in) { + on = ioread32(&bp->irig_in->ctrl) & IRIG_S_CTRL_ENABLE; + val = ioread32(&bp->irig_in->status); + src = gpio_map(sma_in, 4, "sma1", "sma2", "----"); + seq_printf(s, "%7s: %s, error: %d, src: %s\n", "IRIG in", + on ? " ON" : "OFF", val, src); + } + + if (bp->dcf_out) { + on = ioread32(&bp->dcf_out->ctrl) & DCF_M_CTRL_ENABLE; + val = ioread32(&bp->dcf_out->status); + gpio_multi_map(buf, sma_out, 5, "sma3", "sma4", "----"); + seq_printf(s, "%7s: %s, error: %d, out: %s\n", "DCF", + on ? " ON" : "OFF", val, buf); + } + + if (bp->dcf_in) { + on = ioread32(&bp->dcf_in->ctrl) & DCF_S_CTRL_ENABLE; + val = ioread32(&bp->dcf_in->status); + src = gpio_map(sma_in, 5, "sma1", "sma2", "----"); + seq_printf(s, "%7s: %s, error: %d, src: %s\n", "DCF in", + on ? " ON" : "OFF", val, src); + } + + /* compute src for PPS1, used below. */ + if (bp->pps_select) { + val = ioread32(&bp->pps_select->gpio1); + if (val & 0x01) + src = gpio_map(sma_in, 0, "sma1", "sma2", "----"); + else if (val & 0x02) + src = "MAC"; + else if (val & 0x04) + src = "GNSS"; + else + src = "----"; + } else { + src = "?"; + } + + /* assumes automatic switchover/selection */ + val = ioread32(&bp->reg->select); + switch (val >> 16) { + case 0: + sprintf(buf, "----"); + break; + case 2: + sprintf(buf, "IRIG"); + break; + case 3: + sprintf(buf, "%s via PPS1", src); + break; + case 6: + sprintf(buf, "DCF"); + break; + default: + strcpy(buf, "unknown"); + break; + } + val = ioread32(&bp->reg->status); + seq_printf(s, "%7s: %s, state: %s\n", "PHC src", buf, + val & OCP_STATUS_IN_SYNC ? "sync" : "unsynced"); + + /* reuses PPS1 src from earlier */ + seq_printf(s, "MAC PPS1 src: %s\n", src); + + src = gpio_map(sma_in, 1, "sma1", "sma2", "GNSS2"); + seq_printf(s, "MAC PPS2 src: %s\n", src); + + if (!ptp_ocp_gettimex(&bp->ptp_info, &ts, &sts)) { + struct timespec64 sys_ts; + s64 pre_ns, post_ns, ns; + + pre_ns = timespec64_to_ns(&sts.pre_ts); + post_ns = timespec64_to_ns(&sts.post_ts); + ns = (pre_ns + post_ns) / 2; + ns += (s64)bp->utc_tai_offset * NSEC_PER_SEC; + sys_ts = ns_to_timespec64(ns); + + seq_printf(s, "%7s: %lld.%ld == %ptT TAI\n", "PHC", + ts.tv_sec, ts.tv_nsec, &ts); + seq_printf(s, "%7s: %lld.%ld == %ptT UTC offset %d\n", "SYS", + sys_ts.tv_sec, sys_ts.tv_nsec, &sys_ts, + bp->utc_tai_offset); + seq_printf(s, "%7s: PHC:SYS offset: %lld window: %lld\n", "", + timespec64_to_ns(&ts) - ns, + post_ns - pre_ns); + } + + free_page((unsigned long)buf); + return 0; +} +DEFINE_SHOW_ATTRIBUTE(ptp_ocp_summary); + +static struct dentry *ptp_ocp_debugfs_root; + +static void +ptp_ocp_debugfs_add_device(struct ptp_ocp *bp) +{ + struct dentry *d; + + d = debugfs_create_dir(dev_name(&bp->dev), ptp_ocp_debugfs_root); + bp->debug_root = d; + debugfs_create_file("summary", 0444, bp->debug_root, + &bp->dev, &ptp_ocp_summary_fops); +} + +static void +ptp_ocp_debugfs_remove_device(struct ptp_ocp *bp) +{ + debugfs_remove_recursive(bp->debug_root); +} + +static void +ptp_ocp_debugfs_init(void) +{ + ptp_ocp_debugfs_root = debugfs_create_dir("timecard", NULL); +} + +static void +ptp_ocp_debugfs_fini(void) +{ + debugfs_remove_recursive(ptp_ocp_debugfs_root); +} + static void ptp_ocp_dev_release(struct device *dev) { @@ -1918,6 +2144,8 @@ ptp_ocp_complete(struct ptp_ocp *bp) if (device_add_groups(&bp->dev, timecard_groups)) pr_err("device add groups failed\n"); + ptp_ocp_debugfs_add_device(bp); + return 0; } @@ -1988,6 +2216,7 @@ ptp_ocp_detach_sysfs(struct ptp_ocp *bp) static void ptp_ocp_detach(struct ptp_ocp *bp) { + ptp_ocp_debugfs_remove_device(bp); ptp_ocp_detach_sysfs(bp); if (timer_pending(&bp->watchdog)) del_timer_sync(&bp->watchdog); @@ -2157,6 +2386,8 @@ ptp_ocp_init(void) const char *what; int err; + ptp_ocp_debugfs_init(); + what = "timecard class"; err = class_register(&timecard_class); if (err) @@ -2179,6 +2410,7 @@ ptp_ocp_init(void) out_notifier: class_unregister(&timecard_class); out: + ptp_ocp_debugfs_fini(); pr_err(KBUILD_MODNAME ": failed to register %s: %d\n", what, err); return err; } @@ -2189,6 +2421,7 @@ ptp_ocp_fini(void) bus_unregister_notifier(&i2c_bus_type, &ptp_ocp_i2c_notifier); pci_unregister_driver(&ptp_ocp_driver); class_unregister(&timecard_class); + ptp_ocp_debugfs_fini(); } module_init(ptp_ocp_init); From patchwork Wed Sep 15 02:16:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495357 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0D049C433F5 for ; Wed, 15 Sep 2021 02:17:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E83FC601FF for ; Wed, 15 Sep 2021 02:17:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236144AbhIOCST (ORCPT ); Tue, 14 Sep 2021 22:18:19 -0400 Received: from smtp5.emailarray.com ([65.39.216.39]:44261 "EHLO smtp5.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235649AbhIOCSL (ORCPT ); Tue, 14 Sep 2021 22:18:11 -0400 Received: (qmail 83667 invoked by uid 89); 15 Sep 2021 02:16:52 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp5.emailarray.com with SMTP; 15 Sep 2021 02:16:52 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 13/18] ptp: ocp: Add NMEA output Date: Tue, 14 Sep 2021 19:16:31 -0700 Message-Id: <20210915021636.153754-14-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org 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 --- drivers/ptp/ptp_ocp.c | 57 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 36924423444e..74b5561fbdae 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -215,6 +215,7 @@ struct ptp_ocp { struct irig_slave_reg __iomem *irig_in; struct dcf_master_reg __iomem *dcf_out; struct dcf_slave_reg __iomem *dcf_in; + struct tod_reg __iomem *nmea_out; struct ptp_ocp_ext_src *pps; struct ptp_ocp_ext_src *ts0; struct ptp_ocp_ext_src *ts1; @@ -232,6 +233,7 @@ struct ptp_ocp { int n_irqs; int gnss_port; int mac_port; /* miniature atomic clock */ + int nmea_port; u8 serial[6]; bool has_serial; int flash_start; @@ -289,8 +291,9 @@ static int ptp_ocp_ts_enable(void *priv, bool enable); * 5: MAC * 6: TS2 * 7: I2C controller - * 8: HWICAP + * 8: HWICAP (notused) * 9: SPI Flash + * 10: NMEA */ static struct ocp_resource ocp_fb_resource[] = { @@ -353,6 +356,10 @@ static struct ocp_resource ocp_fb_resource[] = { OCP_MEM_RESOURCE(dcf_out), .offset = 0x010A0000, .size = 0x10000, }, + { + OCP_MEM_RESOURCE(nmea_out), + .offset = 0x010B0000, .size = 0x10000, + }, { OCP_MEM_RESOURCE(image), .offset = 0x00020000, .size = 0x1000, @@ -381,6 +388,10 @@ static struct ocp_resource ocp_fb_resource[] = { OCP_SERIAL_RESOURCE(mac_port), .offset = 0x00180000 + 0x1000, .irq_vec = 5, }, + { + OCP_SERIAL_RESOURCE(nmea_port), + .offset = 0x00190000 + 0x1000, .irq_vec = 10, + }, { OCP_SPI_RESOURCE(spi_flash), .offset = 0x00310000, .size = 0x10000, .irq_vec = 9, @@ -761,6 +772,8 @@ ptp_ocp_utc_distribute(struct ptp_ocp *bp, u32 val) iowrite32(val, &bp->irig_out->adj_sec); if (bp->dcf_out) iowrite32(val, &bp->dcf_out->adj_sec); + if (bp->nmea_out) + iowrite32(val, &bp->nmea_out->adj_sec); spin_unlock_irqrestore(&bp->lock, flags); } @@ -1272,6 +1285,17 @@ ptp_ocp_register_mem(struct ptp_ocp *bp, struct ocp_resource *r) return 0; } +static void +ptp_ocp_nmea_out_init(struct ptp_ocp *bp) +{ + if (!bp->nmea_out) + return; + + iowrite32(0, &bp->nmea_out->ctrl); /* disable */ + iowrite32(7, &bp->nmea_out->uart_baud); /* 115200 */ + iowrite32(1, &bp->nmea_out->ctrl); /* enable */ +} + /* FB specific board initializers; last "resource" registered. */ static int ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r) @@ -1279,6 +1303,7 @@ ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r) bp->flash_start = 1024 * 4096; ptp_ocp_tod_init(bp); + ptp_ocp_nmea_out_init(bp); return ptp_ocp_init_clock(bp); } @@ -1941,6 +1966,13 @@ ptp_ocp_summary_show(struct seq_file *s, void *data) on ? " ON" : "OFF", val, src); } + if (bp->nmea_out) { + on = ioread32(&bp->nmea_out->ctrl) & 1; + val = ioread32(&bp->nmea_out->status); + seq_printf(s, "%7s: %s, error: %d\n", "NMEA", + on ? " ON" : "OFF", val); + } + /* compute src for PPS1, used below. */ if (bp->pps_select) { val = ioread32(&bp->pps_select->gpio1); @@ -2069,6 +2101,7 @@ ptp_ocp_device_init(struct ptp_ocp *bp, struct pci_dev *pdev) spin_lock_init(&bp->lock); bp->gnss_port = -1; bp->mac_port = -1; + bp->nmea_port = -1; bp->pdev = pdev; device_initialize(&bp->dev); @@ -2134,6 +2167,10 @@ ptp_ocp_complete(struct ptp_ocp *bp) sprintf(buf, "ttyS%d", bp->mac_port); ptp_ocp_link_child(bp, buf, "ttyMAC"); } + if (bp->nmea_port != -1) { + sprintf(buf, "ttyS%d", bp->nmea_port); + ptp_ocp_link_child(bp, buf, "ttyNMEA"); + } sprintf(buf, "ptp%d", ptp_clock_index(bp->ptp)); ptp_ocp_link_child(bp, buf, "ptp"); @@ -2180,7 +2217,13 @@ ptp_ocp_serial_info(struct device *dev, const char *name, int port, int baud) static void ptp_ocp_info(struct ptp_ocp *bp) { + static int nmea_baud[] = { + 1200, 2400, 4800, 9600, 19200, 38400, + 57600, 115200, 230400, 460800, 921600, + 1000000, 2000000 + }; struct device *dev = &bp->pdev->dev; + u32 reg; ptp_ocp_phc_info(bp); if (bp->tod) @@ -2199,6 +2242,14 @@ ptp_ocp_info(struct ptp_ocp *bp) } ptp_ocp_serial_info(dev, "GNSS", bp->gnss_port, 115200); ptp_ocp_serial_info(dev, "MAC", bp->mac_port, 57600); + if (bp->nmea_out && bp->nmea_port != -1) { + int baud = -1; + + reg = ioread32(&bp->nmea_out->uart_baud); + if (reg < ARRAY_SIZE(nmea_baud)) + baud = nmea_baud[reg]; + ptp_ocp_serial_info(dev, "NMEA", bp->nmea_port, baud); + } } static void @@ -2232,6 +2283,8 @@ ptp_ocp_detach(struct ptp_ocp *bp) serial8250_unregister_port(bp->gnss_port); if (bp->mac_port != -1) serial8250_unregister_port(bp->mac_port); + if (bp->nmea_port != -1) + serial8250_unregister_port(bp->nmea_port); if (bp->spi_flash) platform_device_unregister(bp->spi_flash); if (bp->i2c_ctrl) @@ -2278,7 +2331,7 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id) * allow this - if not all of the IRQ's are returned, skip the * extra devices and just register the clock. */ - err = pci_alloc_irq_vectors(pdev, 1, 10, PCI_IRQ_MSI | PCI_IRQ_MSIX); + err = pci_alloc_irq_vectors(pdev, 1, 11, PCI_IRQ_MSI | PCI_IRQ_MSIX); if (err < 0) { dev_err(&pdev->dev, "alloc_irq_vectors err: %d\n", err); goto out; From patchwork Wed Sep 15 02:16:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495359 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2EB8DC433FE for ; Wed, 15 Sep 2021 02:17:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 18A53601FF for ; Wed, 15 Sep 2021 02:17:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236237AbhIOCSU (ORCPT ); Tue, 14 Sep 2021 22:18:20 -0400 Received: from smtp5.emailarray.com ([65.39.216.39]:44300 "EHLO smtp5.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236078AbhIOCSM (ORCPT ); Tue, 14 Sep 2021 22:18:12 -0400 Received: (qmail 83692 invoked by uid 89); 15 Sep 2021 02:16:53 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp5.emailarray.com with SMTP; 15 Sep 2021 02:16:53 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 14/18] ptp: ocp: Add second GNSS device Date: Tue, 14 Sep 2021 19:16:32 -0700 Message-Id: <20210915021636.153754-15-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Upcoming boards may have a second GNSS receiver, getting information from a different constellation than the first receiver, which provides some measure of anti-spoofing. Expose the sysfs attribute for this device, if detected. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 74b5561fbdae..d0e3096f53f6 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -232,6 +232,7 @@ struct ptp_ocp { int id; int n_irqs; int gnss_port; + int gnss2_port; int mac_port; /* miniature atomic clock */ int nmea_port; u8 serial[6]; @@ -286,8 +287,8 @@ static int ptp_ocp_ts_enable(void *priv, bool enable); * 0: N/C * 1: TS0 * 2: TS1 - * 3: GPS - * 4: GPS2 (n/c) + * 3: GNSS + * 4: GNSS2 * 5: MAC * 6: TS2 * 7: I2C controller @@ -384,6 +385,10 @@ static struct ocp_resource ocp_fb_resource[] = { OCP_SERIAL_RESOURCE(gnss_port), .offset = 0x00160000 + 0x1000, .irq_vec = 3, }, + { + OCP_SERIAL_RESOURCE(gnss2_port), + .offset = 0x00170000 + 0x1000, .irq_vec = 4, + }, { OCP_SERIAL_RESOURCE(mac_port), .offset = 0x00180000 + 0x1000, .irq_vec = 5, @@ -2100,6 +2105,7 @@ ptp_ocp_device_init(struct ptp_ocp *bp, struct pci_dev *pdev) bp->ptp_info = ptp_ocp_clock_info; spin_lock_init(&bp->lock); bp->gnss_port = -1; + bp->gnss2_port = -1; bp->mac_port = -1; bp->nmea_port = -1; bp->pdev = pdev; @@ -2163,6 +2169,10 @@ ptp_ocp_complete(struct ptp_ocp *bp) sprintf(buf, "ttyS%d", bp->gnss_port); ptp_ocp_link_child(bp, buf, "ttyGNSS"); } + if (bp->gnss2_port != -1) { + sprintf(buf, "ttyS%d", bp->gnss2_port); + ptp_ocp_link_child(bp, buf, "ttyGNSS2"); + } if (bp->mac_port != -1) { sprintf(buf, "ttyS%d", bp->mac_port); ptp_ocp_link_child(bp, buf, "ttyMAC"); @@ -2241,6 +2251,7 @@ ptp_ocp_info(struct ptp_ocp *bp) ver >> 16); } ptp_ocp_serial_info(dev, "GNSS", bp->gnss_port, 115200); + ptp_ocp_serial_info(dev, "GNSS2", bp->gnss2_port, 115200); ptp_ocp_serial_info(dev, "MAC", bp->mac_port, 57600); if (bp->nmea_out && bp->nmea_port != -1) { int baud = -1; @@ -2281,6 +2292,8 @@ ptp_ocp_detach(struct ptp_ocp *bp) ptp_ocp_unregister_ext(bp->pps); if (bp->gnss_port != -1) serial8250_unregister_port(bp->gnss_port); + if (bp->gnss2_port != -1) + serial8250_unregister_port(bp->gnss2_port); if (bp->mac_port != -1) serial8250_unregister_port(bp->mac_port); if (bp->nmea_port != -1) From patchwork Wed Sep 15 02:16:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495361 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D126C433F5 for ; Wed, 15 Sep 2021 02:17:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3F7F160EE0 for ; Wed, 15 Sep 2021 02:17:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236258AbhIOCSV (ORCPT ); Tue, 14 Sep 2021 22:18:21 -0400 Received: from smtp3.emailarray.com ([65.39.216.17]:16941 "EHLO smtp3.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235950AbhIOCSN (ORCPT ); Tue, 14 Sep 2021 22:18:13 -0400 Received: (qmail 97137 invoked by uid 89); 15 Sep 2021 02:16:54 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp3.emailarray.com with SMTP; 15 Sep 2021 02:16:54 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 15/18] ptp: ocp: Enable 4th timestamper / PPS generator Date: Tue, 14 Sep 2021 19:16:33 -0700 Message-Id: <20210915021636.153754-16-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org A 4th timestamper is added which timestamps the output of the PHC. The clock nanosecond offset is not always zero, so when compared to other timestampers, this provides precise measurements. Also, the timestamper interrupt from the PHC can be used to generate a PPS signal for /dev/pps. Also allow PTP_CLK_REQ_PEROUT requests for a 1PPS output, but do not actually configure any output pins, this is done via sysfs. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 82 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index d0e3096f53f6..be8ab727a4ef 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -191,7 +191,7 @@ struct ptp_ocp_i2c_info { struct ptp_ocp_ext_info { int index; irqreturn_t (*irq_fcn)(int irq, void *priv); - int (*enable)(void *priv, bool enable); + int (*enable)(void *priv, u32 req, bool enable); }; struct ptp_ocp_ext_src { @@ -237,10 +237,14 @@ struct ptp_ocp { int nmea_port; u8 serial[6]; bool has_serial; + u32 pps_req_map; int flash_start; u32 utc_tai_offset; }; +#define OCP_REQ_TIMESTAMP BIT(0) +#define OCP_REQ_PPS BIT(1) + struct ocp_resource { unsigned long offset; int size; @@ -258,7 +262,7 @@ static int ptp_ocp_register_serial(struct ptp_ocp *bp, struct ocp_resource *r); static int ptp_ocp_register_ext(struct ptp_ocp *bp, struct ocp_resource *r); static int ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r); static irqreturn_t ptp_ocp_ts_irq(int irq, void *priv); -static int ptp_ocp_ts_enable(void *priv, bool enable); +static int ptp_ocp_ts_enable(void *priv, u32 req, bool enable); #define bp_assign_entry(bp, res, val) ({ \ uintptr_t addr = (uintptr_t)(bp) + (res)->bp_offset; \ @@ -284,7 +288,7 @@ static int ptp_ocp_ts_enable(void *priv, bool enable); OCP_RES_LOCATION(member), .setup = ptp_ocp_register_ext /* This is the MSI vector mapping used. - * 0: N/C + * 0: TS3 (and PPS) * 1: TS0 * 2: TS1 * 3: GNSS @@ -329,6 +333,15 @@ static struct ocp_resource ocp_fb_resource[] = { .enable = ptp_ocp_ts_enable, }, }, + { + OCP_EXT_RESOURCE(pps), + .offset = 0x010C0000, .size = 0x10000, .irq_vec = 0, + .extra = &(struct ptp_ocp_ext_info) { + .index = 3, + .irq_fcn = ptp_ocp_ts_irq, + .enable = ptp_ocp_ts_enable, + }, + }, { OCP_MEM_RESOURCE(pps_to_ext), .offset = 0x01030000, .size = 0x10000, @@ -634,10 +647,12 @@ ptp_ocp_enable(struct ptp_clock_info *ptp_info, struct ptp_clock_request *rq, { struct ptp_ocp *bp = container_of(ptp_info, struct ptp_ocp, ptp_info); struct ptp_ocp_ext_src *ext = NULL; + u32 req; int err; switch (rq->type) { case PTP_CLK_REQ_EXTTS: + req = OCP_REQ_TIMESTAMP; switch (rq->extts.index) { case 0: ext = bp->ts0; @@ -648,18 +663,30 @@ ptp_ocp_enable(struct ptp_clock_info *ptp_info, struct ptp_clock_request *rq, case 2: ext = bp->ts2; break; + case 3: + ext = bp->pps; + break; } break; case PTP_CLK_REQ_PPS: + req = OCP_REQ_PPS; ext = bp->pps; break; + case PTP_CLK_REQ_PEROUT: + if (on && + (rq->perout.period.sec != 1 || rq->perout.period.nsec != 0)) + return -EINVAL; + /* This is a request for 1PPS on an output SMA. + * Allow, but assume manual configuration. + */ + return 0; default: return -EOPNOTSUPP; } err = -ENXIO; if (ext) - err = ext->info->enable(ext, on); + err = ext->info->enable(ext, req, on); return err; } @@ -675,7 +702,8 @@ static const struct ptp_clock_info ptp_ocp_clock_info = { .adjphase = ptp_ocp_adjphase, .enable = ptp_ocp_enable, .pps = true, - .n_ext_ts = 3, + .n_ext_ts = 4, + .n_per_out = 1, }; static void @@ -1163,6 +1191,16 @@ ptp_ocp_ts_irq(int irq, void *priv) struct ptp_clock_event ev; u32 sec, nsec; + if (ext == ext->bp->pps) { + if (ext->bp->pps_req_map & OCP_REQ_PPS) { + ev.type = PTP_CLOCK_PPS; + ptp_clock_event(ext->bp->ptp, &ev); + } + + if ((ext->bp->pps_req_map & ~OCP_REQ_PPS) == 0) + goto out; + } + /* XXX should fix API - this converts s/ns -> ts -> s/ns */ sec = ioread32(®->time_sec); nsec = ioread32(®->time_ns); @@ -1173,16 +1211,31 @@ ptp_ocp_ts_irq(int irq, void *priv) ptp_clock_event(ext->bp->ptp, &ev); +out: iowrite32(1, ®->intr); /* write 1 to ack */ return IRQ_HANDLED; } static int -ptp_ocp_ts_enable(void *priv, bool enable) +ptp_ocp_ts_enable(void *priv, u32 req, bool enable) { struct ptp_ocp_ext_src *ext = priv; struct ts_reg __iomem *reg = ext->mem; + struct ptp_ocp *bp = ext->bp; + + if (ext == bp->pps) { + u32 old_map = bp->pps_req_map; + + if (enable) + bp->pps_req_map |= req; + else + bp->pps_req_map &= ~req; + + /* if no state change, just return */ + if ((!!old_map ^ !!bp->pps_req_map) == 0) + return 0; + } if (enable) { iowrite32(1, ®->enable); @@ -1199,7 +1252,7 @@ ptp_ocp_ts_enable(void *priv, bool enable) static void ptp_ocp_unregister_ext(struct ptp_ocp_ext_src *ext) { - ext->info->enable(ext, false); + ext->info->enable(ext, ~0, false); pci_free_irq(ext->bp->pdev, ext->irq_vec, ext); kfree(ext); } @@ -1889,8 +1942,8 @@ ptp_ocp_summary_show(struct seq_file *s, void *data) struct timespec64 ts; struct ptp_ocp *bp; const char *src; + bool on, map; char *buf; - bool on; buf = (char *)__get_free_page(GFP_KERNEL); if (!buf) @@ -1938,6 +1991,19 @@ ptp_ocp_summary_show(struct seq_file *s, void *data) on ? " ON" : "OFF", src); } + if (bp->pps) { + ts_reg = bp->pps->mem; + src = "PHC"; + on = ioread32(&ts_reg->enable); + map = !!(bp->pps_req_map & OCP_REQ_TIMESTAMP); + seq_printf(s, "%7s: %s, src: %s\n", "TS3", + on & map ? " ON" : "OFF", src); + + map = !!(bp->pps_req_map & OCP_REQ_PPS); + seq_printf(s, "%7s: %s, src: %s\n", "PPS", + on & map ? " ON" : "OFF", src); + } + if (bp->irig_out) { ctrl = ioread32(&bp->irig_out->ctrl); on = ctrl & IRIG_M_CTRL_ENABLE; From patchwork Wed Sep 15 02:16:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495363 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 18147C433EF for ; Wed, 15 Sep 2021 02:17:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 04BF360EFF for ; Wed, 15 Sep 2021 02:17:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236299AbhIOCS0 (ORCPT ); Tue, 14 Sep 2021 22:18:26 -0400 Received: from smtp6.emailarray.com ([65.39.216.46]:34565 "EHLO smtp6.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235899AbhIOCSP (ORCPT ); Tue, 14 Sep 2021 22:18:15 -0400 Received: (qmail 28574 invoked by uid 89); 15 Sep 2021 02:16:56 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp6.emailarray.com with SMTP; 15 Sep 2021 02:16:56 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 16/18] ptp: ocp: Have FPGA fold in ns adjustment for adjtime. Date: Tue, 14 Sep 2021 19:16:34 -0700 Message-Id: <20210915021636.153754-17-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The current implementation of adjtime uses gettime/settime to perform nanosecond adjustments. This introduces addtional phase errors due to delays. Instead, use the FPGA's ability to just apply the nanosecond adjustment to the clock directly. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index be8ab727a4ef..e6779a712bbb 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -594,9 +594,6 @@ ptp_ocp_settime(struct ptp_clock_info *ptp_info, const struct timespec64 *ts) struct ptp_ocp *bp = container_of(ptp_info, struct ptp_ocp, ptp_info); unsigned long flags; - if (ioread32(&bp->reg->status) & OCP_STATUS_IN_SYNC) - return 0; - spin_lock_irqsave(&bp->lock, flags); __ptp_ocp_settime_locked(bp, ts); spin_unlock_irqrestore(&bp->lock, flags); @@ -604,26 +601,39 @@ ptp_ocp_settime(struct ptp_clock_info *ptp_info, const struct timespec64 *ts) return 0; } +static void +__ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u64 adj_val) +{ + u32 select, ctrl; + + select = ioread32(&bp->reg->select); + iowrite32(OCP_SELECT_CLK_REG, &bp->reg->select); + + iowrite32(adj_val, &bp->reg->offset_ns); + iowrite32(adj_val & 0x7f, &bp->reg->offset_window_ns); + + ctrl = OCP_CTRL_ADJUST_OFFSET | OCP_CTRL_ENABLE; + iowrite32(ctrl, &bp->reg->ctrl); + + /* restore clock selection */ + iowrite32(select >> 16, &bp->reg->select); +} + static int ptp_ocp_adjtime(struct ptp_clock_info *ptp_info, s64 delta_ns) { struct ptp_ocp *bp = container_of(ptp_info, struct ptp_ocp, ptp_info); - struct timespec64 ts; unsigned long flags; - int err; + u32 adj_ns, sign; - if (ioread32(&bp->reg->status) & OCP_STATUS_IN_SYNC) - return 0; + sign = delta_ns < 0 ? BIT(31) : 0; + adj_ns = sign ? -delta_ns : delta_ns; spin_lock_irqsave(&bp->lock, flags); - err = __ptp_ocp_gettime_locked(bp, &ts, NULL); - if (likely(!err)) { - timespec64_add_ns(&ts, delta_ns); - __ptp_ocp_settime_locked(bp, &ts); - } + __ptp_ocp_adjtime_locked(bp, sign | adj_ns); spin_unlock_irqrestore(&bp->lock, flags); - return err; + return 0; } static int @@ -636,7 +646,7 @@ ptp_ocp_null_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm) } static int -ptp_ocp_adjphase(struct ptp_clock_info *ptp_info, s32 phase_ns) +ptp_ocp_null_adjphase(struct ptp_clock_info *ptp_info, s32 phase_ns) { return -EOPNOTSUPP; } @@ -699,7 +709,7 @@ static const struct ptp_clock_info ptp_ocp_clock_info = { .settime64 = ptp_ocp_settime, .adjtime = ptp_ocp_adjtime, .adjfine = ptp_ocp_null_adjfine, - .adjphase = ptp_ocp_adjphase, + .adjphase = ptp_ocp_null_adjphase, .enable = ptp_ocp_enable, .pps = true, .n_ext_ts = 4, From patchwork Wed Sep 15 02:16:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495365 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2FFEBC433EF for ; Wed, 15 Sep 2021 02:17:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0F69960FDA for ; Wed, 15 Sep 2021 02:17:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236181AbhIOCSc (ORCPT ); Tue, 14 Sep 2021 22:18:32 -0400 Received: from smtp6.emailarray.com ([65.39.216.46]:34595 "EHLO smtp6.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236133AbhIOCSQ (ORCPT ); Tue, 14 Sep 2021 22:18:16 -0400 Received: (qmail 28592 invoked by uid 89); 15 Sep 2021 02:16:57 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp6.emailarray.com with SMTP; 15 Sep 2021 02:16:57 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 17/18] ptp: ocp: Add timestamp window adjustment Date: Tue, 14 Sep 2021 19:16:35 -0700 Message-Id: <20210915021636.153754-18-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The following process is used to read the PHC clock and correlate the reading with the "correct" system time. - get starting timestamp - issue PCI write command - issue PCI read command - get ending timestamp - read latched sec/nsec registers The write command is posted to PCI bus and returns. When the write arrives at the FPGA, the PHC time is latched into the sec/nsec registers, and a flag is set indicating the registers are valid. The read command returns this flag, and the time retrieval proceeds. Below is a non-scaled picture of the timing diagram involved. The PHC time corresponds to some SYS time between [start, end]. Userspace usually uses the midpoint between [start, end] to estimate the PCI delay and match this with the PHC time. [start] | | write |-------+ | | \ | read |----+ +----->| | \ * PHC time latched into register | \ | midpoint | +------->| | | | | | +----| | / | |<--------+ | [end] | | As the diagram indicates, the PHC time is latched before the midpoint, so the system clock time is slightly off the real PHC time. This shows up as a phase error with an oscilliscope. The workaround here is to provide a tunable which reduces (shrinks) the end time in the above diagram. This in turn moves the calculated midpoint so the system time and PHC time are in agreemment. Currently, the adjustment reduces the end time by 3/16th of the entire window. E.g.: [start, end] ==> [start, (end - (3/16 * end)], which produces reasonably good results. Also reduce delays by just writing to the clock control register instead of performing a read/modify/write sequence, as the contents of the control register are known. Signed-off-by: Jonathan Lemon --- drivers/ptp/ptp_ocp.c | 77 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 11 deletions(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index e6779a712bbb..844b1401cc5d 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -240,6 +240,7 @@ struct ptp_ocp { u32 pps_req_map; int flash_start; u32 utc_tai_offset; + u32 ts_window_adjust; }; #define OCP_REQ_TIMESTAMP BIT(0) @@ -528,10 +529,9 @@ __ptp_ocp_gettime_locked(struct ptp_ocp *bp, struct timespec64 *ts, u32 ctrl, time_sec, time_ns; int i; - ctrl = ioread32(&bp->reg->ctrl); - ctrl |= OCP_CTRL_READ_TIME_REQ; - ptp_read_system_prets(sts); + + ctrl = OCP_CTRL_READ_TIME_REQ | OCP_CTRL_ENABLE; iowrite32(ctrl, &bp->reg->ctrl); for (i = 0; i < 100; i++) { @@ -541,6 +541,12 @@ __ptp_ocp_gettime_locked(struct ptp_ocp *bp, struct timespec64 *ts, } ptp_read_system_postts(sts); + if (sts && bp->ts_window_adjust) { + s64 ns = timespec64_to_ns(&sts->post_ts); + + sts->post_ts = ns_to_timespec64(ns - bp->ts_window_adjust); + } + time_ns = ioread32(&bp->reg->time_ns); time_sec = ioread32(&bp->reg->time_sec); @@ -580,8 +586,7 @@ __ptp_ocp_settime_locked(struct ptp_ocp *bp, const struct timespec64 *ts) iowrite32(time_ns, &bp->reg->adjust_ns); iowrite32(time_sec, &bp->reg->adjust_sec); - ctrl = ioread32(&bp->reg->ctrl); - ctrl |= OCP_CTRL_ADJUST_TIME; + ctrl = OCP_CTRL_ADJUST_TIME | OCP_CTRL_ENABLE; iowrite32(ctrl, &bp->reg->ctrl); /* restore clock selection */ @@ -726,8 +731,7 @@ __ptp_ocp_clear_drift_locked(struct ptp_ocp *bp) iowrite32(0, &bp->reg->drift_ns); - ctrl = ioread32(&bp->reg->ctrl); - ctrl |= OCP_CTRL_ADJUST_DRIFT; + ctrl = OCP_CTRL_ADJUST_DRIFT | OCP_CTRL_ENABLE; iowrite32(ctrl, &bp->reg->ctrl); /* restore clock selection */ @@ -759,6 +763,28 @@ ptp_ocp_watchdog(struct timer_list *t) mod_timer(&bp->watchdog, jiffies + HZ); } +static void +ptp_ocp_estimate_pci_timing(struct ptp_ocp *bp) +{ + ktime_t start, end; + ktime_t delay; + u32 ctrl; + + ctrl = ioread32(&bp->reg->ctrl); + ctrl = OCP_CTRL_READ_TIME_REQ | OCP_CTRL_ENABLE; + + iowrite32(ctrl, &bp->reg->ctrl); + + start = ktime_get_ns(); + + ctrl = ioread32(&bp->reg->ctrl); + + end = ktime_get_ns(); + + delay = end - start; + bp->ts_window_adjust = (delay >> 5) * 3; +} + static int ptp_ocp_init_clock(struct ptp_ocp *bp) { @@ -766,9 +792,7 @@ ptp_ocp_init_clock(struct ptp_ocp *bp) bool sync; u32 ctrl; - /* make sure clock is enabled */ - ctrl = ioread32(&bp->reg->ctrl); - ctrl |= OCP_CTRL_ENABLE; + ctrl = OCP_CTRL_ENABLE; iowrite32(ctrl, &bp->reg->ctrl); /* NO DRIFT Correction */ @@ -787,6 +811,8 @@ ptp_ocp_init_clock(struct ptp_ocp *bp) return -ENODEV; } + ptp_ocp_estimate_pci_timing(bp); + sync = ioread32(&bp->reg->status) & OCP_STATUS_IN_SYNC; if (!sync) { ktime_get_clocktai_ts64(&ts); @@ -1217,7 +1243,7 @@ ptp_ocp_ts_irq(int irq, void *priv) ev.type = PTP_CLOCK_EXTTS; ev.index = ext->info->index; - ev.timestamp = sec * 1000000000ULL + nsec; + ev.timestamp = sec * NSEC_PER_SEC + nsec; ptp_clock_event(ext->bp->ptp, &ev); @@ -1817,6 +1843,34 @@ utc_tai_offset_store(struct device *dev, } static DEVICE_ATTR_RW(utc_tai_offset); +static ssize_t +ts_window_adjust_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%d\n", bp->ts_window_adjust); +} + +static ssize_t +ts_window_adjust_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + int err; + u32 val; + + err = kstrtou32(buf, 0, &val); + if (err) + return err; + + bp->ts_window_adjust = val; + + return count; +} +static DEVICE_ATTR_RW(ts_window_adjust); + static ssize_t irig_b_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1911,6 +1965,7 @@ static struct attribute *timecard_attrs[] = { &dev_attr_available_sma_outputs.attr, &dev_attr_irig_b_mode.attr, &dev_attr_utc_tai_offset.attr, + &dev_attr_ts_window_adjust.attr, NULL, }; ATTRIBUTE_GROUPS(timecard); From patchwork Wed Sep 15 02:16:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Lemon X-Patchwork-Id: 12495367 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F11B5C433F5 for ; Wed, 15 Sep 2021 02:17:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DAD4D60EE0 for ; Wed, 15 Sep 2021 02:17:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235897AbhIOCSd (ORCPT ); Tue, 14 Sep 2021 22:18:33 -0400 Received: from smtp8.emailarray.com ([65.39.216.67]:61003 "EHLO smtp8.emailarray.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236206AbhIOCSR (ORCPT ); Tue, 14 Sep 2021 22:18:17 -0400 Received: (qmail 92237 invoked by uid 89); 15 Sep 2021 02:16:58 -0000 Received: from unknown (HELO localhost) (amxlbW9uQGZsdWdzdmFtcC5jb21ANzEuMjEyLjEzOC4zOQ==) (POLARISLOCAL) by smtp8.emailarray.com with SMTP; 15 Sep 2021 02:16:58 -0000 From: Jonathan Lemon To: kuba@kernel.org, davem@davemloft.net, richardcochran@gmail.com Cc: netdev@vger.kernel.org, kernel-team@fb.com Subject: [PATCH net-next 18/18] docs: ABI: Add sysfs documentation for timecard Date: Tue, 14 Sep 2021 19:16:36 -0700 Message-Id: <20210915021636.153754-19-jonathan.lemon@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915021636.153754-1-jonathan.lemon@gmail.com> References: <20210915021636.153754-1-jonathan.lemon@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org This patch describes the sysfs interface implemented by the ptp_ocp driver, under /sys/class/timecard. Signed-off-by: Jonathan Lemon --- Documentation/ABI/testing/sysfs-timecard | 174 +++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-timecard diff --git a/Documentation/ABI/testing/sysfs-timecard b/Documentation/ABI/testing/sysfs-timecard new file mode 100644 index 000000000000..97f6773794a5 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-timecard @@ -0,0 +1,174 @@ +What: /sys/class/timecard/ +Date: September 2021 +Contact: Jonathan Lemon +Description: This directory contains files and directories + providing a standardized interface to the ancillary + features of the OpenCompute timecard. + +What: /sys/class/timecard/ocpN/ +Date: September 2021 +Contact: Jonathan Lemon +Description: This directory contains the attributes of the Nth timecard + registered. + +What: /sys/class/timecard/ocpN/available_clock_sources +Date: September 2021 +Contact: Jonathan Lemon +Description: (RO) The list of available time sources that the PHC + uses for clock adjustments. + + ==== ================================================= + NONE no adjustments + PPS adjustments come from the PPS1 selector (default) + TOD adjustments from the GNSS/TOD module + IRIG adjustments from external IRIG-B signal + DCF adjustments from external DCF signal + ==== ================================================= + +What: /sys/class/timecard/ocpN/available_sma_inputs +Date: September 2021 +Contact: Jonathan Lemon +Description: (RO) Set of available destinations (sinks) for a SMA + input signal. + + ===== ================================================ + 10Mhz signal is used as the 10Mhz reference clock + PPS1 signal is sent to the PPS1 selector + PPS2 signal is sent to the PPS2 selector + TS1 signal is sent to timestamper 1 + TS2 signal is sent to timestamper 2 + IRIG signal is sent to the IRIG-B module + DCF signal is sent to the DCF module + ===== ================================================ + +What: /sys/class/timecard/ocpN/available_sma_outputs +Date: May 2021 +Contact: Jonathan Lemon +Description: (RO) Set of available sources for a SMA output signal. + + ===== ================================================ + 10Mhz output is from the 10Mhz reference clock + PHC output PPS is from the PHC clock + MAC output PPS is from the Miniature Atomic Clock + GNSS output PPS is from the GNSS module + GNSS2 output PPS is from the second GNSS module + IRIG output is from the PHC, in IRIG-B format + DCF output is from the PHC, in DCF format + ===== ================================================ + +What: /sys/class/timecard/ocpN/clock_source +Date: September 2021 +Contact: Jonathan Lemon +Description: (RW) Contains the current synchronization source used by + the PHC. May be changed by writing one of the listed + values from the available_clock_sources attribute set. + +What: /sys/class/timecard/ocpN/gnss_sync +Date: September 2021 +Contact: Jonathan Lemon +Description: (RO) Indicates whether a valid GNSS signal is received, + or when the signal was lost. + +What: /sys/class/timecard/ocpN/i2c +Date: September 2021 +Contact: Jonathan Lemon +Description: This optional attribute links to the associated i2c device. + +What: /sys/class/timecard/ocpN/irig_b_mode +Date: September 2021 +Contact: Jonathan Lemon +Description: (RW) An integer from 0-7 indicating the timecode format + of the IRIG-B output signal: B00 + +What: /sys/class/timecard/ocpN/pps +Date: September 2021 +Contact: Jonathan Lemon +Description: This optional attribute links to the associated PPS device. + +What: /sys/class/timecard/ocpN/ptp +Date: September 2021 +Contact: Jonathan Lemon +Description: This attribute links to the associated PTP device. + +What: /sys/class/timecard/ocpN/serialnum +Date: September 2021 +Contact: Jonathan Lemon +Description: (RO) Provides the serial number of the timecard. + +What: /sys/class/timecard/ocpN/sma1 +What: /sys/class/timecard/ocpN/sma2 +What: /sys/class/timecard/ocpN/sma3 +What: /sys/class/timecard/ocpN/sma4 +Date: September 2021 +Contact: Jonathan Lemon +Description: (RW) These attributes specify the direction of the signal + on the associated SMA connectors, and also the signal sink + or source. + + The display format of the attribute is a space separated + list of signals, prefixed by the input/output direction. + + The signal direction may be changed (if supported) by + prefixing the signal list with either "in:" or "out:". + If neither prefix is present, then the direction is unchanged. + + The output signal may be changed by writing one of the listed + values from the available_sma_outputs attribute set. + + The input destinations may be changed by writing multiple + values from the available_sma_inputs attribute set, + separated by spaces. If there are duplicated input + destinations between connectors, the lowest numbered SMA + connector is given priority. + + Note that not all input combinations may make sense. + + The 10Mhz reference clock input is currently only valid + on SMA1 and may not be combined with other destination sinks. + +What: /sys/class/timecard/ocpN/ts_window_adjust +Date: September 2021 +Contact: Jonathan Lemon +Description: (RW) When retrieving the PHC with the PTP SYS_OFFSET_EXTENDED + ioctl, a system timestamp is made before and after the PHC + time is retrieved. The midpoint between the two system + timestamps is usually taken to be the SYS time associated + with the PHC time. This estimate may be wrong, as it depends + on PCI latencies, and when the PHC time was latched + + The attribute value reduces the end timestamp by the given + number of nanoseconds, so the computed midpoint matches the + retrieved PHC time. + + The initial value is set based on measured PCI latency and + the estimated point where the FPGA latches the PHC time. This + value may be changed by writing an unsigned integer. + +What: /sys/class/timecard/ocpN/ttyGNSS +What: /sys/class/timecard/ocpN/ttyGNSS2 +Date: September 2021 +Contact: Jonathan Lemon +Description: These optional attributes link to the TTY serial ports + associated with the GNSS devices. + +What: /sys/class/timecard/ocpN/ttyMAC +Date: September 2021 +Contact: Jonathan Lemon +Description: This optional attribute links to the TTY serial port + associated with the Miniature Atomic Clock. + +What: /sys/class/timecard/ocpN/ttyNMEA +Date: September 2021 +Contact: Jonathan Lemon +Description: This optional attribute links to the TTY serial port + which outputs the PHC time in NMEA ZDA format. + +What: /sys/class/timecard/ocpN/utc_tai_offset +Date: September 2021 +Contact: Jonathan Lemon +Description: (RW) The DCF and IRIG output signals are in UTC, while the + TimeCard operates on TAI. This attribute allows setting the + offset in seconds, which is added to the TAI timebase for + these formats. + + The offset may be changed by writing an unsigned integer.