From patchwork Thu Oct 20 23:12:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vadim Fedorenko X-Patchwork-Id: 13014125 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 Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 00AFEC433FE for ; Thu, 20 Oct 2022 23:13:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229787AbiJTXNE (ORCPT ); Thu, 20 Oct 2022 19:13:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33928 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229587AbiJTXND (ORCPT ); Thu, 20 Oct 2022 19:13:03 -0400 Received: from novek.ru (unknown [213.148.174.62]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 33973224AB6 for ; Thu, 20 Oct 2022 16:13:02 -0700 (PDT) Received: from nat1.ooonet.ru (gw.zelenaya.net [91.207.137.40]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by novek.ru (Postfix) with ESMTPSA id BD22F504EEA; Fri, 21 Oct 2022 02:09:20 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 novek.ru BD22F504EEA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=novek.ru; s=mail; t=1666307362; bh=mcBZqnZi+rzIBuZv1Kcg2q5X/hQ69dUYVSL3g9OdcTg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=delm7JEX3rPcAl68idCvMfB1ptUdYtNed9Ve97xEv1Xf9oigDs2u6YmpWT//eKbQc Msyfvm+ONanu8HKPUjgfVYc6plcWr2OG0Ja1uefGDO7iJRq8xp1VjrBkuUc4crvzuG DmOJM+wt5RSI+7zJTn8vbJqAP139uwHiSUS+96Sc= From: Vadim Fedorenko To: Richard Cochran , Jonathan Lemon , Jakub Kicinski Cc: netdev@vger.kernel.org, Vadim Fedorenko Subject: [PATCH net-next v5 1/5] ptp: ocp: upgrade serial line information Date: Fri, 21 Oct 2022 02:12:43 +0300 Message-Id: <20221020231247.7243-2-vfedorenko@novek.ru> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20221020231247.7243-1-vfedorenko@novek.ru> References: <20221020231247.7243-1-vfedorenko@novek.ru> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vadim Fedorenko Introduce structure to hold serial port line number and the baud rate it supports. Acked-by: Jonathan Lemon Signed-off-by: Jonathan Lemon Signed-off-by: Vadim Fedorenko --- drivers/ptp/ptp_ocp.c | 110 +++++++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 43 deletions(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index a48d9b7d2921..1ce0f2989a85 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -278,6 +278,11 @@ struct ptp_ocp_signal { bool running; }; +struct ptp_ocp_serial_port { + int line; + int baud; +}; + #define OCP_BOARD_ID_LEN 13 #define OCP_SERIAL_LEN 6 @@ -318,10 +323,10 @@ struct ptp_ocp { time64_t gnss_lost; int id; int n_irqs; - int gnss_port; - int gnss2_port; - int mac_port; /* miniature atomic clock */ - int nmea_port; + struct ptp_ocp_serial_port gnss_port; + struct ptp_ocp_serial_port gnss2_port; + struct ptp_ocp_serial_port mac_port; /* miniature atomic clock */ + struct ptp_ocp_serial_port nmea_port; bool fw_loader; u8 fw_tag; u16 fw_version; @@ -596,14 +601,23 @@ static struct ocp_resource ocp_fb_resource[] = { { OCP_SERIAL_RESOURCE(gnss_port), .offset = 0x00160000 + 0x1000, .irq_vec = 3, + .extra = &(struct ptp_ocp_serial_port) { + .baud = 115200, + }, }, { OCP_SERIAL_RESOURCE(gnss2_port), .offset = 0x00170000 + 0x1000, .irq_vec = 4, + .extra = &(struct ptp_ocp_serial_port) { + .baud = 115200, + }, }, { OCP_SERIAL_RESOURCE(mac_port), .offset = 0x00180000 + 0x1000, .irq_vec = 5, + .extra = &(struct ptp_ocp_serial_port) { + .baud = 57600, + }, }, { OCP_SERIAL_RESOURCE(nmea_port), @@ -1872,11 +1886,15 @@ ptp_ocp_serial_line(struct ptp_ocp *bp, struct ocp_resource *r) static int ptp_ocp_register_serial(struct ptp_ocp *bp, struct ocp_resource *r) { - int port; + struct ptp_ocp_serial_port *p = (struct ptp_ocp_serial_port *)r->extra; + struct ptp_ocp_serial_port port = {}; + + port.line = ptp_ocp_serial_line(bp, r); + if (port.line < 0) + return port.line; - port = ptp_ocp_serial_line(bp, r); - if (port < 0) - return port; + if (p) + port.baud = p->baud; bp_assign_entry(bp, r, port); @@ -3177,14 +3195,16 @@ ptp_ocp_summary_show(struct seq_file *s, void *data) bp = dev_get_drvdata(dev); seq_printf(s, "%7s: /dev/ptp%d\n", "PTP", ptp_clock_index(bp->ptp)); - if (bp->gnss_port != -1) - seq_printf(s, "%7s: /dev/ttyS%d\n", "GNSS1", bp->gnss_port); - if (bp->gnss2_port != -1) - seq_printf(s, "%7s: /dev/ttyS%d\n", "GNSS2", bp->gnss2_port); - if (bp->mac_port != -1) - seq_printf(s, "%7s: /dev/ttyS%d\n", "MAC", bp->mac_port); - if (bp->nmea_port != -1) - seq_printf(s, "%7s: /dev/ttyS%d\n", "NMEA", bp->nmea_port); + if (bp->gnss_port.line != -1) + seq_printf(s, "%7s: /dev/ttyS%d\n", "GNSS1", + bp->gnss_port.line); + if (bp->gnss2_port.line != -1) + seq_printf(s, "%7s: /dev/ttyS%d\n", "GNSS2", + bp->gnss2_port.line); + if (bp->mac_port.line != -1) + seq_printf(s, "%7s: /dev/ttyS%d\n", "MAC", bp->mac_port.line); + if (bp->nmea_port.line != -1) + seq_printf(s, "%7s: /dev/ttyS%d\n", "NMEA", bp->nmea_port.line); memset(sma_val, 0xff, sizeof(sma_val)); if (bp->sma_map1) { @@ -3508,10 +3528,10 @@ 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->gnss_port.line = -1; + bp->gnss2_port.line = -1; + bp->mac_port.line = -1; + bp->nmea_port.line = -1; bp->pdev = pdev; device_initialize(&bp->dev); @@ -3569,20 +3589,20 @@ ptp_ocp_complete(struct ptp_ocp *bp) struct pps_device *pps; char buf[32]; - if (bp->gnss_port != -1) { - sprintf(buf, "ttyS%d", bp->gnss_port); + if (bp->gnss_port.line != -1) { + sprintf(buf, "ttyS%d", bp->gnss_port.line); ptp_ocp_link_child(bp, buf, "ttyGNSS"); } - if (bp->gnss2_port != -1) { - sprintf(buf, "ttyS%d", bp->gnss2_port); + if (bp->gnss2_port.line != -1) { + sprintf(buf, "ttyS%d", bp->gnss2_port.line); ptp_ocp_link_child(bp, buf, "ttyGNSS2"); } - if (bp->mac_port != -1) { - sprintf(buf, "ttyS%d", bp->mac_port); + if (bp->mac_port.line != -1) { + sprintf(buf, "ttyS%d", bp->mac_port.line); ptp_ocp_link_child(bp, buf, "ttyMAC"); } - if (bp->nmea_port != -1) { - sprintf(buf, "ttyS%d", bp->nmea_port); + if (bp->nmea_port.line != -1) { + sprintf(buf, "ttyS%d", bp->nmea_port.line); ptp_ocp_link_child(bp, buf, "ttyNMEA"); } sprintf(buf, "ptp%d", ptp_clock_index(bp->ptp)); @@ -3638,16 +3658,20 @@ ptp_ocp_info(struct ptp_ocp *bp) ptp_ocp_phc_info(bp); - 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; + ptp_ocp_serial_info(dev, "GNSS", bp->gnss_port.line, + bp->gnss_port.baud); + ptp_ocp_serial_info(dev, "GNSS2", bp->gnss2_port.line, + bp->gnss2_port.baud); + ptp_ocp_serial_info(dev, "MAC", bp->mac_port.line, bp->mac_port.baud); + if (bp->nmea_out && bp->nmea_port.line != -1) { + bp->nmea_port.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); + bp->nmea_port.baud = nmea_baud[reg]; + + ptp_ocp_serial_info(dev, "NMEA", bp->nmea_port.line, + bp->nmea_port.baud); } } @@ -3688,14 +3712,14 @@ ptp_ocp_detach(struct ptp_ocp *bp) for (i = 0; i < 4; i++) if (bp->signal_out[i]) ptp_ocp_unregister_ext(bp->signal_out[i]); - 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) - serial8250_unregister_port(bp->nmea_port); + if (bp->gnss_port.line != -1) + serial8250_unregister_port(bp->gnss_port.line); + if (bp->gnss2_port.line != -1) + serial8250_unregister_port(bp->gnss2_port.line); + if (bp->mac_port.line != -1) + serial8250_unregister_port(bp->mac_port.line); + if (bp->nmea_port.line != -1) + serial8250_unregister_port(bp->nmea_port.line); platform_device_unregister(bp->spi_flash); platform_device_unregister(bp->i2c_ctrl); if (bp->i2c_clk) From patchwork Thu Oct 20 23:12:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vadim Fedorenko X-Patchwork-Id: 13014126 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 Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 76382C4332F for ; Thu, 20 Oct 2022 23:13:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229716AbiJTXNG (ORCPT ); Thu, 20 Oct 2022 19:13:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33940 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229819AbiJTXNF (ORCPT ); Thu, 20 Oct 2022 19:13:05 -0400 Received: from novek.ru (unknown [213.148.174.62]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7D32122C639 for ; Thu, 20 Oct 2022 16:13:03 -0700 (PDT) Received: from nat1.ooonet.ru (gw.zelenaya.net [91.207.137.40]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by novek.ru (Postfix) with ESMTPSA id 8710A504EEB; Fri, 21 Oct 2022 02:09:22 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 novek.ru 8710A504EEB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=novek.ru; s=mail; t=1666307364; bh=NQ7JgpcpTYwBk0aFOwQ6WzhQfwti5ZN14PSMXryo34I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=1N/8K3ZyW1pZ9H4hKM9aa98Ro7Y/CqvsTjiMvODxNvq1hNk9gKaD9aPgq6T8Hh42n apY8OsUUI7q5LcuWRD/gd4ZR5iijMy0dluOtEZLjbj9JItc2DhSV0u1d2cPXVqNd9S vBO/8y5yH4KXSm6GBJ2bYTZhwGR1FTE4x1v0eqGk= From: Vadim Fedorenko To: Richard Cochran , Jonathan Lemon , Jakub Kicinski Cc: netdev@vger.kernel.org, Vadim Fedorenko , Charles Parent Subject: [PATCH net-next v5 2/5] ptp: ocp: add Orolia timecard support Date: Fri, 21 Oct 2022 02:12:44 +0300 Message-Id: <20221020231247.7243-3-vfedorenko@novek.ru> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20221020231247.7243-1-vfedorenko@novek.ru> References: <20221020231247.7243-1-vfedorenko@novek.ru> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vadim Fedorenko This brings in the Orolia timecard support from the GitHub repository. The card uses different drivers to provide access to i2c EEPROM and firmware SPI flash. And it also has a bit different EEPROM map, but other parts of the code are the same and could be reused. Co-developed-by: Charles Parent Acked-by: Jonathan Lemon Signed-off-by: Jonathan Lemon Signed-off-by: Vadim Fedorenko --- drivers/ptp/ptp_ocp.c | 290 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 1ce0f2989a85..8c1ce630b67f 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -13,9 +13,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -28,6 +30,9 @@ #define PCI_VENDOR_ID_CELESTICA 0x18d4 #define PCI_DEVICE_ID_CELESTICA_TIMECARD 0x1008 +#define PCI_VENDOR_ID_OROLIA 0x1ad7 +#define PCI_DEVICE_ID_OROLIA_ARTCARD 0xa000 + static struct class timecard_class = { .owner = THIS_MODULE, .name = "timecard", @@ -310,6 +315,7 @@ struct ptp_ocp { struct ptp_ocp_ext_src *ts2; struct ptp_ocp_ext_src *ts3; struct ptp_ocp_ext_src *ts4; + struct ocp_art_gpio_reg __iomem *art_sma; struct img_reg __iomem *image; struct ptp_clock *ptp; struct ptp_clock_info ptp_info; @@ -370,8 +376,12 @@ static int ptp_ocp_signal_from_perout(struct ptp_ocp *bp, int gen, static int ptp_ocp_signal_enable(void *priv, u32 req, bool enable); static int ptp_ocp_sma_store(struct ptp_ocp *bp, const char *buf, int sma_nr); +static int ptp_ocp_art_board_init(struct ptp_ocp *bp, struct ocp_resource *r); + static const struct ocp_attr_group fb_timecard_groups[]; +static const struct ocp_attr_group art_timecard_groups[]; + struct ptp_ocp_eeprom_map { u16 off; u16 len; @@ -394,6 +404,12 @@ static struct ptp_ocp_eeprom_map fb_eeprom_map[] = { { } }; +static struct ptp_ocp_eeprom_map art_eeprom_map[] = { + { EEPROM_ENTRY(0x200 + 0x43, board_id) }, + { EEPROM_ENTRY(0x200 + 0x63, serial) }, + { } +}; + #define bp_assign_entry(bp, res, val) ({ \ uintptr_t addr = (uintptr_t)(bp) + (res)->bp_offset; \ *(typeof(val) *)addr = val; \ @@ -435,6 +451,13 @@ static struct ptp_ocp_eeprom_map fb_eeprom_map[] = { * 14: Signal Generator 4 * 15: TS3 * 16: TS4 + -- + * 8: Orolia TS1 + * 10: Orolia TS2 + * 11: Orolia TS0 (GNSS) + * 12: Orolia PPS + * 14: Orolia TS3 + * 15: Orolia TS4 */ static struct ocp_resource ocp_fb_resource[] = { @@ -661,9 +684,127 @@ static struct ocp_resource ocp_fb_resource[] = { { } }; +struct ocp_art_gpio_reg { + struct { + u32 gpio; + u32 __pad[3]; + } map[4]; +}; + +static struct ocp_resource ocp_art_resource[] = { + { + OCP_MEM_RESOURCE(reg), + .offset = 0x01000000, .size = 0x10000, + }, + { + OCP_SERIAL_RESOURCE(gnss_port), + .offset = 0x00160000 + 0x1000, .irq_vec = 3, + .extra = &(struct ptp_ocp_serial_port) { + .baud = 115200, + }, + }, + { + OCP_MEM_RESOURCE(art_sma), + .offset = 0x003C0000, .size = 0x1000, + }, + /* Timestamp associated with GNSS1 receiver PPS */ + { + OCP_EXT_RESOURCE(ts0), + .offset = 0x360000, .size = 0x20, .irq_vec = 12, + .extra = &(struct ptp_ocp_ext_info) { + .index = 0, + .irq_fcn = ptp_ocp_ts_irq, + .enable = ptp_ocp_ts_enable, + }, + }, + { + OCP_EXT_RESOURCE(ts1), + .offset = 0x380000, .size = 0x20, .irq_vec = 8, + .extra = &(struct ptp_ocp_ext_info) { + .index = 1, + .irq_fcn = ptp_ocp_ts_irq, + .enable = ptp_ocp_ts_enable, + }, + }, + { + OCP_EXT_RESOURCE(ts2), + .offset = 0x390000, .size = 0x20, .irq_vec = 10, + .extra = &(struct ptp_ocp_ext_info) { + .index = 2, + .irq_fcn = ptp_ocp_ts_irq, + .enable = ptp_ocp_ts_enable, + }, + }, + { + OCP_EXT_RESOURCE(ts3), + .offset = 0x3A0000, .size = 0x20, .irq_vec = 14, + .extra = &(struct ptp_ocp_ext_info) { + .index = 3, + .irq_fcn = ptp_ocp_ts_irq, + .enable = ptp_ocp_ts_enable, + }, + }, + { + OCP_EXT_RESOURCE(ts4), + .offset = 0x3B0000, .size = 0x20, .irq_vec = 15, + .extra = &(struct ptp_ocp_ext_info) { + .index = 4, + .irq_fcn = ptp_ocp_ts_irq, + .enable = ptp_ocp_ts_enable, + }, + }, + /* Timestamp associated with Internal PPS of the card */ + { + OCP_EXT_RESOURCE(pps), + .offset = 0x00330000, .size = 0x20, .irq_vec = 11, + .extra = &(struct ptp_ocp_ext_info) { + .index = 5, + .irq_fcn = ptp_ocp_ts_irq, + .enable = ptp_ocp_ts_enable, + }, + }, + { + OCP_SPI_RESOURCE(spi_flash), + .offset = 0x00310000, .size = 0x10000, .irq_vec = 9, + .extra = &(struct ptp_ocp_flash_info) { + .name = "spi_altera", .pci_offset = 0, + .data_size = sizeof(struct altera_spi_platform_data), + .data = &(struct altera_spi_platform_data) { + .num_chipselect = 1, + .num_devices = 1, + .devices = &(struct spi_board_info) { + .modalias = "spi-nor", + }, + }, + }, + }, + { + OCP_I2C_RESOURCE(i2c_ctrl), + .offset = 0x350000, .size = 0x100, .irq_vec = 4, + .extra = &(struct ptp_ocp_i2c_info) { + .name = "ocores-i2c", + .fixed_rate = 400000, + .data_size = sizeof(struct ocores_i2c_platform_data), + .data = &(struct ocores_i2c_platform_data) { + .clock_khz = 125000, + .bus_khz = 400, + .num_devices = 1, + .devices = &(struct i2c_board_info) { + I2C_BOARD_INFO("24c08", 0x50), + }, + }, + }, + }, + { + .setup = ptp_ocp_art_board_init, + }, + { } +}; + static const struct pci_device_id ptp_ocp_pcidev_id[] = { { PCI_DEVICE_DATA(FACEBOOK, TIMECARD, &ocp_fb_resource) }, { PCI_DEVICE_DATA(CELESTICA, TIMECARD, &ocp_fb_resource) }, + { PCI_DEVICE_DATA(OROLIA, ARTCARD, &ocp_art_resource) }, { } }; MODULE_DEVICE_TABLE(pci, ptp_ocp_pcidev_id); @@ -728,6 +869,19 @@ static const struct ocp_selector ptp_ocp_sma_out[] = { { } }; +static const struct ocp_selector ptp_ocp_art_sma_in[] = { + { .name = "PPS1", .value = 0x0001 }, + { .name = "10Mhz", .value = 0x0008 }, + { } +}; + +static const struct ocp_selector ptp_ocp_art_sma_out[] = { + { .name = "PHC", .value = 0x0002 }, + { .name = "GNSS", .value = 0x0004 }, + { .name = "10Mhz", .value = 0x0010 }, + { } +}; + struct ocp_sma_op { const struct ocp_selector *tbl[2]; void (*init)(struct ptp_ocp *bp); @@ -2275,6 +2429,118 @@ ptp_ocp_register_resources(struct ptp_ocp *bp, kernel_ulong_t driver_data) return err; } +static void +ptp_ocp_art_sma_init(struct ptp_ocp *bp) +{ + u32 reg; + int i; + + /* defaults */ + bp->sma[0].mode = SMA_MODE_IN; + bp->sma[1].mode = SMA_MODE_IN; + bp->sma[2].mode = SMA_MODE_OUT; + bp->sma[3].mode = SMA_MODE_OUT; + + bp->sma[0].default_fcn = 0x08; /* IN: 10Mhz */ + bp->sma[1].default_fcn = 0x01; /* IN: PPS1 */ + bp->sma[2].default_fcn = 0x10; /* OUT: 10Mhz */ + bp->sma[3].default_fcn = 0x02; /* OUT: PHC */ + + /* If no SMA map, the pin functions and directions are fixed. */ + if (!bp->art_sma) { + for (i = 0; i < 4; i++) { + bp->sma[i].fixed_fcn = true; + bp->sma[i].fixed_dir = true; + } + return; + } + + for (i = 0; i < 4; i++) { + reg = ioread32(&bp->art_sma->map[i].gpio); + + switch (reg & 0xff) { + case 0: + bp->sma[i].fixed_fcn = true; + bp->sma[i].fixed_dir = true; + break; + case 1: + case 8: + bp->sma[i].mode = SMA_MODE_IN; + break; + default: + bp->sma[i].mode = SMA_MODE_OUT; + break; + } + } +} + +static u32 +ptp_ocp_art_sma_get(struct ptp_ocp *bp, int sma_nr) +{ + if (bp->sma[sma_nr - 1].fixed_fcn) + return bp->sma[sma_nr - 1].default_fcn; + + return ioread32(&bp->art_sma->map[sma_nr - 1].gpio) & 0xff; +} + +/* note: store 0 is considered invalid. */ +static int +ptp_ocp_art_sma_set(struct ptp_ocp *bp, int sma_nr, u32 val) +{ + unsigned long flags; + u32 __iomem *gpio; + int err = 0; + u32 reg; + + val &= SMA_SELECT_MASK; + if (hweight32(val) > 1) + return -EINVAL; + + gpio = &bp->art_sma->map[sma_nr - 1].gpio; + + spin_lock_irqsave(&bp->lock, flags); + reg = ioread32(gpio); + if (((reg >> 16) & val) == 0) { + err = -EOPNOTSUPP; + } else { + reg = (reg & 0xff00) | (val & 0xff); + iowrite32(reg, gpio); + } + spin_unlock_irqrestore(&bp->lock, flags); + + return err; +} + +static const struct ocp_sma_op ocp_art_sma_op = { + .tbl = { ptp_ocp_art_sma_in, ptp_ocp_art_sma_out }, + .init = ptp_ocp_art_sma_init, + .get = ptp_ocp_art_sma_get, + .set_inputs = ptp_ocp_art_sma_set, + .set_output = ptp_ocp_art_sma_set, +}; + +/* ART specific board initializers; last "resource" registered. */ +static int +ptp_ocp_art_board_init(struct ptp_ocp *bp, struct ocp_resource *r) +{ + int err; + + bp->flash_start = 0x1000000; + bp->eeprom_map = art_eeprom_map; + bp->fw_cap = OCP_CAP_BASIC; + bp->fw_version = ioread32(&bp->reg->version); + bp->fw_tag = 2; + bp->sma_op = &ocp_art_sma_op; + + ptp_ocp_sma_init(bp); + + err = ptp_ocp_attr_group_add(bp, art_timecard_groups); + if (err) + return err; + + return ptp_ocp_init_clock(bp); +} + static ssize_t ptp_ocp_show_output(const struct ocp_selector *tbl, u32 val, char *buf, int def_val) @@ -3083,6 +3349,30 @@ static const struct ocp_attr_group fb_timecard_groups[] = { { }, }; +static struct attribute *art_timecard_attrs[] = { + &dev_attr_serialnum.attr, + &dev_attr_clock_source.attr, + &dev_attr_available_clock_sources.attr, + &dev_attr_utc_tai_offset.attr, + &dev_attr_ts_window_adjust.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, +}; + +static const struct attribute_group art_timecard_group = { + .attrs = art_timecard_attrs, +}; + +static const struct ocp_attr_group art_timecard_groups[] = { + { .cap = OCP_CAP_BASIC, .group = &art_timecard_group }, + { }, +}; + static void gpio_input_map(char *buf, struct ptp_ocp *bp, u16 map[][2], u16 bit, const char *def) From patchwork Thu Oct 20 23:12:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vadim Fedorenko X-Patchwork-Id: 13014127 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 Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 631D7C433FE for ; Thu, 20 Oct 2022 23:13:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229802AbiJTXNI (ORCPT ); Thu, 20 Oct 2022 19:13:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33946 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229868AbiJTXNF (ORCPT ); Thu, 20 Oct 2022 19:13:05 -0400 Received: from novek.ru (unknown [213.148.174.62]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 09116224AB6 for ; Thu, 20 Oct 2022 16:13:04 -0700 (PDT) Received: from nat1.ooonet.ru (gw.zelenaya.net [91.207.137.40]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by novek.ru (Postfix) with ESMTPSA id 213F1504EEC; Fri, 21 Oct 2022 02:09:25 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 novek.ru 213F1504EEC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=novek.ru; s=mail; t=1666307366; bh=8zDp4RD6jT1QPiHnRIyPkjV0ScPiq0VHYnOHpvb8aDc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kH4cABmbjy/kIqS49Pzaar8IdHM3433j2lE40eTKgKHm7iPGnz6+FAkA6CeeXcMzv nY1gNNHTTwQ7cALwxriCU4dp5AN4TSC/ISCF1XGgmBGySftbw3mvKR7fdp7Mu9r6jh U1Rh64UmhpXaBeeMZ0BgO1L7dqfu3T9pK/LOo+tI= From: Vadim Fedorenko To: Richard Cochran , Jonathan Lemon , Jakub Kicinski Cc: netdev@vger.kernel.org, Vadim Fedorenko , Charles Parent Subject: [PATCH net-next v5 3/5] ptp: ocp: add serial port of mRO50 MAC on ART card Date: Fri, 21 Oct 2022 02:12:45 +0300 Message-Id: <20221020231247.7243-4-vfedorenko@novek.ru> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20221020231247.7243-1-vfedorenko@novek.ru> References: <20221020231247.7243-1-vfedorenko@novek.ru> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vadim Fedorenko ART card provides interface to access to serial port of miniature atomic clock found on the card. Add support for this device and configure it during init phase. Acked-by: Jonathan Lemon Co-developed-by: Charles Parent Signed-off-by: Jonathan Lemon Signed-off-by: Vadim Fedorenko --- drivers/ptp/ptp_ocp.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 8c1ce630b67f..6c41a2e8f78d 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -208,6 +208,11 @@ struct frequency_reg { u32 ctrl; u32 status; }; + +struct board_config_reg { + u32 mro50_serial_activate; +}; + #define FREQ_STATUS_VALID BIT(31) #define FREQ_STATUS_ERROR BIT(30) #define FREQ_STATUS_OVERRUN BIT(29) @@ -299,6 +304,7 @@ struct ptp_ocp { struct tod_reg __iomem *tod; struct pps_reg __iomem *pps_to_ext; struct pps_reg __iomem *pps_to_clk; + struct board_config_reg __iomem *board_config; struct gpio_reg __iomem *pps_select; struct gpio_reg __iomem *sma_map1; struct gpio_reg __iomem *sma_map2; @@ -795,6 +801,17 @@ static struct ocp_resource ocp_art_resource[] = { }, }, }, + { + OCP_SERIAL_RESOURCE(mac_port), + .offset = 0x00190000, .irq_vec = 7, + .extra = &(struct ptp_ocp_serial_port) { + .baud = 9600, + }, + }, + { + OCP_MEM_RESOURCE(board_config), + .offset = 0x210000, .size = 0x1000, + }, { .setup = ptp_ocp_art_board_init, }, @@ -2532,6 +2549,9 @@ ptp_ocp_art_board_init(struct ptp_ocp *bp, struct ocp_resource *r) bp->fw_tag = 2; bp->sma_op = &ocp_art_sma_op; + /* Enable MAC serial port during initialisation */ + iowrite32(1, &bp->board_config->mro50_serial_activate); + ptp_ocp_sma_init(bp); err = ptp_ocp_attr_group_add(bp, art_timecard_groups); From patchwork Thu Oct 20 23:12:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vadim Fedorenko X-Patchwork-Id: 13014128 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 Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A2EFFC4332F for ; Thu, 20 Oct 2022 23:13:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229997AbiJTXNO (ORCPT ); Thu, 20 Oct 2022 19:13:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34064 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229868AbiJTXNK (ORCPT ); Thu, 20 Oct 2022 19:13:10 -0400 Received: from novek.ru (unknown [213.148.174.62]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8CC3E22C63C for ; Thu, 20 Oct 2022 16:13:06 -0700 (PDT) Received: from nat1.ooonet.ru (gw.zelenaya.net [91.207.137.40]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by novek.ru (Postfix) with ESMTPSA id 8FA3C504EED; Fri, 21 Oct 2022 02:09:26 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 novek.ru 8FA3C504EED DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=novek.ru; s=mail; t=1666307367; bh=oQ+WVEYQhjj2PD9jX+i5XrINKkfeVjcN2GkJ4Dnzsq4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rOtrRuUI1sAFLsiC+bgY25RZrI2muNhHRDbPYJJett8t2vFOx/HDQWg+h26XoMkrk ERfAMAReaGSCfGkOna2JZuVZe9tXTS/EPXj8h/U0F4G5Buo+bnQEvktqysig7Qa64A gy8k4VaPd8F5ehskN6mOtMzT70yP7GpVDnV73cCQ= From: Vadim Fedorenko To: Richard Cochran , Jonathan Lemon , Jakub Kicinski Cc: netdev@vger.kernel.org, Vadim Fedorenko , Charles Parent Subject: [PATCH net-next v5 4/5] ptp: ocp: expose config and temperature for ART card Date: Fri, 21 Oct 2022 02:12:46 +0300 Message-Id: <20221020231247.7243-5-vfedorenko@novek.ru> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20221020231247.7243-1-vfedorenko@novek.ru> References: <20221020231247.7243-1-vfedorenko@novek.ru> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vadim Fedorenko Orolia card has disciplining configuration and temperature table stored in EEPROM. This patch exposes them as binary attributes to have read and write access. Acked-by: Jonathan Lemon Co-developed-by: Charles Parent Signed-off-by: Jonathan Lemon Signed-off-by: Vadim Fedorenko --- drivers/ptp/ptp_ocp.c | 136 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 6c41a2e8f78d..0aee4e165bbf 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -690,6 +690,9 @@ static struct ocp_resource ocp_fb_resource[] = { { } }; +#define OCP_ART_CONFIG_SIZE 144 +#define OCP_ART_TEMP_TABLE_SIZE 368 + struct ocp_art_gpio_reg { struct { u32 gpio; @@ -3334,6 +3337,130 @@ DEVICE_FREQ_GROUP(freq2, 1); DEVICE_FREQ_GROUP(freq3, 2); DEVICE_FREQ_GROUP(freq4, 3); +static ssize_t +disciplining_config_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) +{ + struct ptp_ocp *bp = dev_get_drvdata(kobj_to_dev(kobj)); + size_t size = OCP_ART_CONFIG_SIZE; + struct nvmem_device *nvmem; + ssize_t err; + + nvmem = ptp_ocp_nvmem_device_get(bp, NULL); + if (IS_ERR(nvmem)) + return PTR_ERR(nvmem); + + if (off > size) { + err = 0; + goto out; + } + + if (off + count > size) + count = size - off; + + // the configuration is in the very beginning of the EEPROM + err = nvmem_device_read(nvmem, off, count, buf); + if (err != count) { + err = -EFAULT; + goto out; + } + +out: + ptp_ocp_nvmem_device_put(&nvmem); + + return err; +} + +static ssize_t +disciplining_config_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) +{ + struct ptp_ocp *bp = dev_get_drvdata(kobj_to_dev(kobj)); + struct nvmem_device *nvmem; + ssize_t err; + + /* Allow write of the whole area only */ + if (off || count != OCP_ART_CONFIG_SIZE) + return -EFAULT; + + nvmem = ptp_ocp_nvmem_device_get(bp, NULL); + if (IS_ERR(nvmem)) + return PTR_ERR(nvmem); + + err = nvmem_device_write(nvmem, 0x00, count, buf); + if (err != count) + err = -EFAULT; + + ptp_ocp_nvmem_device_put(&nvmem); + + return err; +} +static BIN_ATTR_RW(disciplining_config, OCP_ART_CONFIG_SIZE); + +static ssize_t +temperature_table_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) +{ + struct ptp_ocp *bp = dev_get_drvdata(kobj_to_dev(kobj)); + size_t size = OCP_ART_TEMP_TABLE_SIZE; + struct nvmem_device *nvmem; + ssize_t err; + + nvmem = ptp_ocp_nvmem_device_get(bp, NULL); + if (IS_ERR(nvmem)) + return PTR_ERR(nvmem); + + if (off > size) { + err = 0; + goto out; + } + + if (off + count > size) + count = size - off; + + // the configuration is in the very beginning of the EEPROM + err = nvmem_device_read(nvmem, 0x90 + off, count, buf); + if (err != count) { + err = -EFAULT; + goto out; + } + +out: + ptp_ocp_nvmem_device_put(&nvmem); + + return err; +} + +static ssize_t +temperature_table_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) +{ + struct ptp_ocp *bp = dev_get_drvdata(kobj_to_dev(kobj)); + struct nvmem_device *nvmem; + ssize_t err; + + /* Allow write of the whole area only */ + if (off || count != OCP_ART_TEMP_TABLE_SIZE) + return -EFAULT; + + nvmem = ptp_ocp_nvmem_device_get(bp, NULL); + if (IS_ERR(nvmem)) + return PTR_ERR(nvmem); + + err = nvmem_device_write(nvmem, 0x90, count, buf); + if (err != count) + err = -EFAULT; + + ptp_ocp_nvmem_device_put(&nvmem); + + return err; +} +static BIN_ATTR_RW(temperature_table, OCP_ART_TEMP_TABLE_SIZE); + static struct attribute *fb_timecard_attrs[] = { &dev_attr_serialnum.attr, &dev_attr_gnss_sync.attr, @@ -3353,9 +3480,11 @@ static struct attribute *fb_timecard_attrs[] = { &dev_attr_tod_correction.attr, NULL, }; + static const struct attribute_group fb_timecard_group = { .attrs = fb_timecard_attrs, }; + static const struct ocp_attr_group fb_timecard_groups[] = { { .cap = OCP_CAP_BASIC, .group = &fb_timecard_group }, { .cap = OCP_CAP_SIGNAL, .group = &fb_timecard_signal0_group }, @@ -3384,8 +3513,15 @@ static struct attribute *art_timecard_attrs[] = { NULL, }; +static struct bin_attribute *bin_art_timecard_attrs[] = { + &bin_attr_disciplining_config, + &bin_attr_temperature_table, + NULL, +}; + static const struct attribute_group art_timecard_group = { .attrs = art_timecard_attrs, + .bin_attrs = bin_art_timecard_attrs, }; static const struct ocp_attr_group art_timecard_groups[] = { From patchwork Thu Oct 20 23:12:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vadim Fedorenko X-Patchwork-Id: 13014129 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 Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 28049C43217 for ; Thu, 20 Oct 2022 23:13:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229868AbiJTXNP (ORCPT ); Thu, 20 Oct 2022 19:13:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34070 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229910AbiJTXNK (ORCPT ); Thu, 20 Oct 2022 19:13:10 -0400 Received: from novek.ru (unknown [213.148.174.62]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F34BB22E0CB for ; Thu, 20 Oct 2022 16:13:07 -0700 (PDT) Received: from nat1.ooonet.ru (gw.zelenaya.net [91.207.137.40]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by novek.ru (Postfix) with ESMTPSA id E6788504EEE; Fri, 21 Oct 2022 02:09:27 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 novek.ru E6788504EEE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=novek.ru; s=mail; t=1666307368; bh=Bq2dpyx2tKLyugj3hbeRz0WWXwhP3QACDrUf9UMGRvs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=g2mo/0jtU91uNSvrQVBK/9XShhN7PA9EU6eFT5wzRkUGdeev5Pvmm+lPvkUHJrRGQ Mf83FL3eL1wb3b9bPpj9txJ303586iAc1UHeubcHc/MDFGk7bHAX9/YkHeqZmCPP6e bqXMxjOIuwXBHhtSXUvROll/cxIyObOv1PlDgGKw= From: Vadim Fedorenko To: Richard Cochran , Jonathan Lemon , Jakub Kicinski Cc: netdev@vger.kernel.org, Vadim Fedorenko Subject: [PATCH net-next v5 5/5] ptp: ocp: remove flash image header check fallback Date: Fri, 21 Oct 2022 02:12:47 +0300 Message-Id: <20221020231247.7243-6-vfedorenko@novek.ru> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20221020231247.7243-1-vfedorenko@novek.ru> References: <20221020231247.7243-1-vfedorenko@novek.ru> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vadim Fedorenko Previously there was a fallback mode to flash firmware image without proper header. But now we have different supported vendors and flashing wrong image could destroy the hardware. Remove fallback mode and force header check. Both vendors have published firmware images with headers. Signed-off-by: Vadim Fedorenko --- drivers/ptp/ptp_ocp.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 0aee4e165bbf..9c378b49ff37 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -1530,11 +1530,9 @@ ptp_ocp_devlink_fw_image(struct devlink *devlink, const struct firmware *fw, hdr = (const struct ptp_ocp_firmware_header *)fw->data; if (memcmp(hdr->magic, OCP_FIRMWARE_MAGIC_HEADER, 4)) { devlink_flash_update_status_notify(devlink, - "No firmware header found, flashing raw image", + "No firmware header found, cancel firmware upgrade", NULL, 0, 0); - offset = 0; - length = fw->size; - goto out; + return -EINVAL; } if (be16_to_cpu(hdr->pci_vendor_id) != bp->pdev->vendor || @@ -1562,7 +1560,6 @@ ptp_ocp_devlink_fw_image(struct devlink *devlink, const struct firmware *fw, return -EINVAL; } -out: *data = &fw->data[offset]; *size = length;