From patchwork Tue Nov 29 21:37:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vadim Fedorenko X-Patchwork-Id: 13059243 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DF8EEC4321E for ; Tue, 29 Nov 2022 21:39:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=p5ATRZ0eUE0hrv6AKYoNQnHdo8qbtTwW/wa6CpSEUmE=; b=zpei53H8CBFW6t mOdFZCU6ZCgui+Nh/GhxXpcPpl9l2GSTPbb3cF+x3kw0J2H0eY+GqmbjkeMDPhE0lyuv3tSUhmgMf IEqvMAgCJbDHUBOhgERCM1VrsyixQKMu80OMlNYhVe6VNrQ1WmQXQfjF0CrxiL7Q5NgTMGDPtlF+u UaIeD0McuGB9NHmx1pBXTBcgoV9WAqbsvobWDT0v5YEdSqiiPHR9PS83POg4ZWdMVnm274qO648XE 7GKtIA4mPmfHJVLRLyqLSeLIMmQ1534cyeA7FH6Ss6n4xP25VDT5xS1qNVlaJwIxqXBw8/GFB/QIZ eyohPvyvtJN/Ad0oRA2A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1p08JD-00BQ2c-Ej; Tue, 29 Nov 2022 21:38:31 +0000 Received: from [213.148.174.62] (helo=novek.ru) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1p08J1-00BPxO-4c for linux-arm-kernel@lists.infradead.org; Tue, 29 Nov 2022 21:38:21 +0000 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 2DF63504F87; Wed, 30 Nov 2022 00:33:56 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 novek.ru 2DF63504F87 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=novek.ru; s=mail; t=1669757638; bh=fcSY/EdhUZvRyDuXygfRL0ws7XmTP433EmDuD6s0mdM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QMRAnYGw6ynzeBwyyAVm/Bf0UIub+2eMMiauK4hcZKxr/huxkJgippPlZTldfGbcB 5jpHOi4mtkr5OHaIEvoB009hhfTw4cUr1VvuHP6As2MJVOCupUlHxHOFEl3f26Dv+J hYK3y4RQ7oU2bfEAvOJb+EQSpwOigBy6SzK6KavM= From: Vadim Fedorenko To: Jakub Kicinski , Jiri Pirko , Arkadiusz Kubalewski , Jonathan Lemon , Paolo Abeni Cc: netdev@vger.kernel.org, Vadim Fedorenko , linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org Subject: [RFC PATCH v4 4/4] ptp_ocp: implement DPLL ops Date: Wed, 30 Nov 2022 00:37:24 +0300 Message-Id: <20221129213724.10119-5-vfedorenko@novek.ru> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20221129213724.10119-1-vfedorenko@novek.ru> References: <20221129213724.10119-1-vfedorenko@novek.ru> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221129_133819_635101_CD715BE7 X-CRM114-Status: GOOD ( 20.55 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Vadim Fedorenko Implement basic DPLL operations in ptp_ocp driver as the simplest example of using new subsystem. Signed-off-by: Vadim Fedorenko --- drivers/ptp/Kconfig | 1 + drivers/ptp/ptp_ocp.c | 123 +++++++++++++++++++++++++++++------------- 2 files changed, 87 insertions(+), 37 deletions(-) diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig index fe4971b65c64..8c4cfabc1bfa 100644 --- a/drivers/ptp/Kconfig +++ b/drivers/ptp/Kconfig @@ -177,6 +177,7 @@ config PTP_1588_CLOCK_OCP depends on COMMON_CLK select NET_DEVLINK select CRC16 + select DPLL help This driver adds support for an OpenCompute time card. diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 154d58cbd9ce..605853ac4a12 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #define PCI_VENDOR_ID_FACEBOOK 0x1d9b #define PCI_DEVICE_ID_FACEBOOK_TIMECARD 0x0400 @@ -353,6 +355,7 @@ struct ptp_ocp { struct ptp_ocp_signal signal[4]; struct ptp_ocp_sma_connector sma[4]; const struct ocp_sma_op *sma_op; + struct dpll_device *dpll; }; #define OCP_REQ_TIMESTAMP BIT(0) @@ -835,18 +838,19 @@ static DEFINE_IDR(ptp_ocp_idr); struct ocp_selector { const char *name; int value; + int dpll_type; }; static const struct ocp_selector ptp_ocp_clock[] = { - { .name = "NONE", .value = 0 }, - { .name = "TOD", .value = 1 }, - { .name = "IRIG", .value = 2 }, - { .name = "PPS", .value = 3 }, - { .name = "PTP", .value = 4 }, - { .name = "RTC", .value = 5 }, - { .name = "DCF", .value = 6 }, - { .name = "REGS", .value = 0xfe }, - { .name = "EXT", .value = 0xff }, + { .name = "NONE", .value = 0, .dpll_type = 0 }, + { .name = "TOD", .value = 1, .dpll_type = 0 }, + { .name = "IRIG", .value = 2, .dpll_type = 0 }, + { .name = "PPS", .value = 3, .dpll_type = 0 }, + { .name = "PTP", .value = 4, .dpll_type = 0 }, + { .name = "RTC", .value = 5, .dpll_type = 0 }, + { .name = "DCF", .value = 6, .dpll_type = 0 }, + { .name = "REGS", .value = 0xfe, .dpll_type = 0 }, + { .name = "EXT", .value = 0xff, .dpll_type = 0 }, { } }; @@ -855,37 +859,37 @@ static const struct ocp_selector ptp_ocp_clock[] = { #define SMA_SELECT_MASK GENMASK(14, 0) static const struct ocp_selector ptp_ocp_sma_in[] = { - { .name = "10Mhz", .value = 0x0000 }, - { .name = "PPS1", .value = 0x0001 }, - { .name = "PPS2", .value = 0x0002 }, - { .name = "TS1", .value = 0x0004 }, - { .name = "TS2", .value = 0x0008 }, - { .name = "IRIG", .value = 0x0010 }, - { .name = "DCF", .value = 0x0020 }, - { .name = "TS3", .value = 0x0040 }, - { .name = "TS4", .value = 0x0080 }, - { .name = "FREQ1", .value = 0x0100 }, - { .name = "FREQ2", .value = 0x0200 }, - { .name = "FREQ3", .value = 0x0400 }, - { .name = "FREQ4", .value = 0x0800 }, - { .name = "None", .value = SMA_DISABLE }, + { .name = "10Mhz", .value = 0x0000, .dpll_type = DPLL_PIN_SIGNAL_TYPE_10_MHZ }, + { .name = "PPS1", .value = 0x0001, .dpll_type = DPLL_PIN_SIGNAL_TYPE_1_PPS }, + { .name = "PPS2", .value = 0x0002, .dpll_type = DPLL_PIN_SIGNAL_TYPE_1_PPS }, + { .name = "TS1", .value = 0x0004, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "TS2", .value = 0x0008, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "IRIG", .value = 0x0010, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "DCF", .value = 0x0020, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "TS3", .value = 0x0040, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "TS4", .value = 0x0080, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "FREQ1", .value = 0x0100, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "FREQ2", .value = 0x0200, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "FREQ3", .value = 0x0400, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "FREQ4", .value = 0x0800, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "None", .value = SMA_DISABLE, .dpll_type = 0 }, { } }; static const struct ocp_selector ptp_ocp_sma_out[] = { - { .name = "10Mhz", .value = 0x0000 }, - { .name = "PHC", .value = 0x0001 }, - { .name = "MAC", .value = 0x0002 }, - { .name = "GNSS1", .value = 0x0004 }, - { .name = "GNSS2", .value = 0x0008 }, - { .name = "IRIG", .value = 0x0010 }, - { .name = "DCF", .value = 0x0020 }, - { .name = "GEN1", .value = 0x0040 }, - { .name = "GEN2", .value = 0x0080 }, - { .name = "GEN3", .value = 0x0100 }, - { .name = "GEN4", .value = 0x0200 }, - { .name = "GND", .value = 0x2000 }, - { .name = "VCC", .value = 0x4000 }, + { .name = "10Mhz", .value = 0x0000, .dpll_type = DPLL_PIN_SIGNAL_TYPE_10_MHZ }, + { .name = "PHC", .value = 0x0001, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "MAC", .value = 0x0002, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "GNSS1", .value = 0x0004, .dpll_type = DPLL_PIN_SIGNAL_TYPE_1_PPS }, + { .name = "GNSS2", .value = 0x0008, .dpll_type = DPLL_PIN_SIGNAL_TYPE_1_PPS }, + { .name = "IRIG", .value = 0x0010, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "DCF", .value = 0x0020, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "GEN1", .value = 0x0040, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "GEN2", .value = 0x0080, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "GEN3", .value = 0x0100, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "GEN4", .value = 0x0200, .dpll_type = DPLL_PIN_SIGNAL_TYPE_CUSTOM_FREQ }, + { .name = "GND", .value = 0x2000, .dpll_type = 0 }, + { .name = "VCC", .value = 0x4000, .dpll_type = 0 }, { } }; @@ -4175,12 +4179,41 @@ ptp_ocp_detach(struct ptp_ocp *bp) device_unregister(&bp->dev); } +static int ptp_ocp_dpll_get_attr(struct dpll_device *dpll, struct dpll_attr *attr) +{ + struct ptp_ocp *bp = (struct ptp_ocp *)dpll_priv(dpll); + int sync; + + sync = ioread32(&bp->reg->status) & OCP_STATUS_IN_SYNC; + dpll_attr_lock_status_set(attr, sync ? DPLL_LOCK_STATUS_LOCKED : DPLL_LOCK_STATUS_UNLOCKED); + + return 0; +} + +static int ptp_ocp_dpll_pin_get_attr(struct dpll_device *dpll, struct dpll_pin *pin, + struct dpll_pin_attr *attr) +{ + dpll_pin_attr_type_set(attr, DPLL_PIN_TYPE_EXT); + return 0; +} + +static struct dpll_device_ops dpll_ops = { + .get = ptp_ocp_dpll_get_attr, +}; + +static struct dpll_pin_ops dpll_pin_ops = { + .get = ptp_ocp_dpll_pin_get_attr, +}; + static int ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + const u8 dpll_cookie[DPLL_COOKIE_LEN] = { "OCP" }; + char pin_desc[PIN_DESC_LEN]; struct devlink *devlink; + struct dpll_pin *pin; struct ptp_ocp *bp; - int err; + int err, i; devlink = devlink_alloc(&ptp_ocp_devlink_ops, sizeof(*bp), &pdev->dev); if (!devlink) { @@ -4230,6 +4263,20 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id) ptp_ocp_info(bp); devlink_register(devlink); + + bp->dpll = dpll_device_alloc(&dpll_ops, DPLL_TYPE_PPS, dpll_cookie, pdev->bus->number, bp, &pdev->dev); + if (!bp->dpll) { + dev_err(&pdev->dev, "dpll_device_alloc failed\n"); + goto out; + } + dpll_device_register(bp->dpll); + + for (i = 0; i < 4; i++) { + snprintf(pin_desc, PIN_DESC_LEN, "sma%d", i + 1); + pin = dpll_pin_alloc(pin_desc, PIN_DESC_LEN); + dpll_pin_register(bp->dpll, pin, &dpll_pin_ops, bp); + } + return 0; out: @@ -4247,6 +4294,8 @@ ptp_ocp_remove(struct pci_dev *pdev) struct ptp_ocp *bp = pci_get_drvdata(pdev); struct devlink *devlink = priv_to_devlink(bp); + dpll_device_unregister(bp->dpll); + dpll_device_free(bp->dpll); devlink_unregister(devlink); ptp_ocp_detach(bp); pci_disable_device(pdev);