Received: by 10.223.164.202 with SMTP id h10csp1021037wrb; Fri, 17 Nov 2017 12:30:50 -0800 (PST) X-Google-Smtp-Source: AGs4zMYwwrML6KPhftWwe2Ze5C5FwNn0G2WMJB5iDyXkvxUh/uSzzxNHFKcvJlpVj9yhNn7adNb6 X-Received: by 10.159.218.75 with SMTP id x11mr2439096plv.141.1510950650407; Fri, 17 Nov 2017 12:30:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510950650; cv=none; d=google.com; s=arc-20160816; b=JkgHG+g2AsSuIeevzNUo1e5/HmjxMq51ahjAWt8+lMrb6TYOV/eNgUzapc/iaLMCZq Qcj10DY3/1M7mGSR/49jRAPfxx/QG6dhj3iUjGmXg9JKq65fno/ra6Xo9Ps92Q1NXCBL y4Q/SKmSf/9c/LYg/7ZG3A6JZvmIzEQhgSRryeKRujHY+8F9VYhCbI/5hqjQ5RoXj65H 4kcTT9hSw04juhy0sjCBafqvPyxpPzMkTtbP5Ia1fNMZAx2tRkdL+fEZluTOBeJbqwLg VPJLLs6Fsrs9vp9p5Tpk+p54hQOXDpMV+TgSNBPhTe6JFP4LafuXyVr7iq/GSLbQPA1V +3QQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:spamdiagnosticmetadata :spamdiagnosticoutput:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature:arc-authentication-results; bh=psl6IpdfkboQS4MBR9aWGg0U2EE/D1+p8e60/XfZ+S4=; b=uanXekm8ywHbZXMRoYC2gr/ryE79wrSvao73da4Sl/4AibBdBxlgF6SqNTrpmnNuay wXF9XXm9QVYEL5k9WDA4WgomUCeqWJhFKp/IjUohul0Q5Lyh5VR1AIQXwS4fBoo7twu7 Ajcdf3Efc6g4Onlv8wP4JHS5k2QWR8iVQ1U/6h3OL8ivwwRF7HgiZKbD23pULYyalXM/ +34xHwt5tzz/l+mfbBmGPYt16Kb0Zv1DIlZmsur3AAOBKBN1FIwJFXoJvwYpzIK74nkj jt+6GYRoBXHgusxI2qUqkI7mXaKin5aAHcsQB1bk2WQD1WWSvFV8km+pjcq2nv1q46H0 BQYw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@CAVIUMNETWORKS.onmicrosoft.com header.s=selector1-cavium-com header.b=ZOIXmzWw; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m15si3246691pga.413.2017.11.17.12.30.36; Fri, 17 Nov 2017 12:30:50 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@CAVIUMNETWORKS.onmicrosoft.com header.s=selector1-cavium-com header.b=ZOIXmzWw; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934750AbdKQNuH (ORCPT + 92 others); Fri, 17 Nov 2017 08:50:07 -0500 Received: from mail-by2nam01on0058.outbound.protection.outlook.com ([104.47.34.58]:37882 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S933460AbdKQNtq (ORCPT ); Fri, 17 Nov 2017 08:49:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-cavium-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=psl6IpdfkboQS4MBR9aWGg0U2EE/D1+p8e60/XfZ+S4=; b=ZOIXmzWwzLpplZI75B8a2EylczvwiJVzGD28Pivo3dhzY8Nkk+b9y96q1OSLX0a9nz6z+7tu7FB/N0p+ujvGLdmLzX4sjXjCXQtnC4O/Gr4CCJrMNvC2VVzQo9tA0tkFL7HbOme97OYDraARwuZ4e1+oYuTyMMQdV1HcZY00zb4= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Aleksey.Makarov@cavium.com; Received: from localhost.localdomain (46.242.12.6) by BN3PR07MB2481.namprd07.prod.outlook.com (10.167.4.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.239.5; Fri, 17 Nov 2017 13:49:40 +0000 From: Aleksey Makarov To: netdev@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, "Goutham, Sunil" , Radoslaw Biernacki , Aleksey Makarov , Robert Richter , David Daney Subject: [PATCH net-next v2 1/2] net: add support for Cavium PTP coprocessor Date: Fri, 17 Nov 2017 16:49:06 +0300 Message-Id: <20171117134909.8954-2-aleksey.makarov@cavium.com> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171117134909.8954-1-aleksey.makarov@cavium.com> References: <20171117134909.8954-1-aleksey.makarov@cavium.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [46.242.12.6] X-ClientProxiedBy: AM5PR0701CA0062.eurprd07.prod.outlook.com (10.169.145.152) To BN3PR07MB2481.namprd07.prod.outlook.com (10.167.4.22) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: c333a430-2025-4463-64f3-08d52dc20ed2 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(4534020)(4602075)(4627115)(201703031133081)(201702281549075)(2017052603258);SRVR:BN3PR07MB2481; X-Microsoft-Exchange-Diagnostics: 1;BN3PR07MB2481;3:3ZlBWj0Laupp+wsb8vXosGTt51/CIRQXlB7Wp1Id6ZsTQn3efuQaJ0zCqHKuaZInLzqbFOIdY23k34a5hCRbMCMKI9MOSij5bTTtyepjQu2ChxqYoXzZbPZ2yvrVKyEdcO/0R7jQz32zrXeu6S/1wRPMqKBiZRcU40/ht7JJwIiAZiyt5X3i/9JyDY4zKnHC/5uFrwQUxrS8TM56SvQKctI9jaybZun4sq6ipQiEZZ4Ai7W5Y1xvZHxxW6sdXw/7;25:+1w88yH00yakO8/6IK3o0T4TQGkw3HibWvFr1OR+T1NQUDj+IVQDfzzhHO3t+gpE+wMpPkfZY4drPqDEcGQ/HWAOrUAzGqfnKRBZGKJSW9WkNSnOftKvA2846rJ1FIw+CVy/qCY16lwHVmdPbWS1Ya+17MOp62U1KyQjs6iisLGuK3An5HZ88qG58egl33XzKVCaLxsyIQLv3OzNYzYF2i0VMg3I299qV1ehSyUrKVpwWH/6ekCS0dJqBqhzYYatVdqHTiroVCM6kwE630HxLxMe4yB8BYJ4jp5qq2n4opnIRWFNBR3nQtIgwgkNVdNERONGLw0AATUJrIE1g+LN5Q==;31:NUffW1farXGAq0mQNMM2M7t98RATdpe7PanAKpP22Y7mC35kT4Jf9Pb3VJSS9ux6LQUCgZ/E4rur/4BDzK7oIbgTDbkOu56bBN5+qBv0pgoRKigWTO1OfHQ2mmqYkfitxlkwcpvYT+3zh+uxFNvmo8cjE6tndR0CPRbICt69EnDzKZgrIue5t0VGBpkAQfXMWCxGJT+0KiRhRlt83Gz6VrFUea9Gn552XY13BVW2KOM= X-MS-TrafficTypeDiagnostic: BN3PR07MB2481: X-Microsoft-Exchange-Diagnostics: 1;BN3PR07MB2481;20:MMd2pPxWRySmSWvgemnIcc8NbK+GkMSFiVq5lF4rk3JHmpqq2CKBMsRiYbuEWErl0i5mn3wKlZrDKZ53iShP5UN2Uq/jaD/BGjUpEBMlElp8U5eI3BHQn/MZbPx57Up+K+TZYkFJ+ihDBWmVDHAu8c29zGWgr3yAtQ4Cd8jIEmh1Tb5eBfX9pCkRXkfhKZESXhjDpi8jPca3LVvH6Ul0kzSW71LvBjQgu8sDOn4BqsnQb1Dd25hw2j2Lxjb7hxFRXj3KPMAuzujZ21PXt9jV2nF5hKiBE4DoTmH5NeUTXq4efjv93QSPA1rwiV3NPzogxYzPuqIeUrRrfOSNHQpMQh7k0tY9pgTqcUJKni9cFCVAI4BBk/uB/ALt7Birl9yvcaZW3vYpSD+4XlaixX8QIr3Gg4rsJvgjr0fTKM+ZZ6utqtZDs1RC8MhQ5M4j/gHNGlm854fWTIVIljC1NLQ7180kmw35mK0REPBkaSZmzgAI59IlS5mqZP8vjYiX5BMD;4:w6GV7hzpqWQVyGBdO0Y+wRnHGXatzIHXT99e2qH0iuH/vAJ31CWqZ4dT54meOxVqdIuQ+B9R2MqHQtNYUhHYMel42wUl3+sDRT3BzuqtKxy5G3Wl4cVdxVqsTlSWRwXpt76PZoCDzXmtaHxEb5sz6lb0KspOXcSrDJIXnOJ23HhdjW9g3fqQgAlEgTkU/eqvtu1QniFiw3Aux1nP/NAlwzP3QAGNO+x327iqaOPf1xztg7/Pu3bqK3Rg5B0TS0lQZfQd/eEvzdctZtaSYnMsVQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(5005006)(8121501046)(3231022)(3002001)(93006095)(93001095)(10201501046)(100000703101)(100105400095)(6041248)(20161123564025)(20161123558100)(20161123562025)(20161123560025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123555025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:BN3PR07MB2481;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:BN3PR07MB2481; X-Forefront-PRVS: 049486C505 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6069001)(6009001)(346002)(376002)(189002)(199003)(105586002)(2361001)(48376002)(106356001)(47776003)(2351001)(189998001)(8936002)(50986999)(76176999)(5003940100001)(97736004)(107886003)(66066001)(101416001)(6506006)(478600001)(316002)(54906003)(16586007)(25786009)(1076002)(72206003)(6486002)(50466002)(16526018)(33646002)(6116002)(3846002)(36756003)(50226002)(8676002)(7736002)(6512007)(6916009)(2906002)(2950100002)(6666003)(5660300001)(305945005)(86362001)(4326008)(53936002)(575784001)(81156014)(81166006)(68736007)(2004002);DIR:OUT;SFP:1101;SCL:1;SRVR:BN3PR07MB2481;H:localhost.localdomain;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; Received-SPF: None (protection.outlook.com: cavium.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BN3PR07MB2481;23:RVYup9TktLosVpQ8hHwkis46jYjgvSh9MdQVnlAJy?= =?us-ascii?Q?whAgQuJGlycfAxF3imON2xp9ONVtNbBNga3rDXYSeEMmlvizWJ2LNP5GisVM?= =?us-ascii?Q?N5t68bHsyAIpyUcF/9zqTHXpFPqoNh4ajo46tjJfA5cZOeKnGv8F2avonQUH?= =?us-ascii?Q?pnGRi7IKiYn3D0l7vu/Qm1olNItA7WLH1qcU7TwCWJM2R8yXYXmt8m9lpJc9?= =?us-ascii?Q?Jne3Hc7PqXglAmc0dHz4JBwoTpQSs5cUB/PZJ2be72ChLLMoujiOTC2z2zV0?= =?us-ascii?Q?ZsIlyYcfS95wZWlktwe9qI4yD49B5oJgDny+IYkxEBwKvd6ydhMuqIr86yy4?= =?us-ascii?Q?HWbLA7hw2mT6POezWQC4QrhztImAthgiAUVu1FC3QYCEk7pUV0lWFZxY6c21?= =?us-ascii?Q?d2LQlMRspPDvVrf+4d60YENj1dkf4xPLmAb6TYq2bINHYI1Fqhk2iSUso+oC?= =?us-ascii?Q?jr5ANDs8cmgawBxqIGJdv7KrYcCxG+ZrLqud8EgW7PtvqWbHOOOXGJRFJBsq?= =?us-ascii?Q?K9bBBpf0rRgZvrP/aXQJWDFZlaASNn3E/W/H/4QM4MRzPMw1ltbV1I0bDgoJ?= =?us-ascii?Q?8hDteQUb3xmJhqjlN8DIt+xwGySR3cH46U2WP8/I9nfnDQ2SnIh1EVL+Viq7?= =?us-ascii?Q?y/18GR9AS4hQHKHND7XehKW3xKXD/oSHpik02Z3NDP+J0DnqtysY1awSUpU8?= =?us-ascii?Q?hJFWAFLfXqEDROrgk4qveWHske+h6OlVXorSah8MjGhof05YPPhJW2T9IgCw?= =?us-ascii?Q?OzziOsHbPy/HgQfTL/Kv2ePiOxiClP/PBJARVNmdthuaU0FUntHqp15+2f2W?= =?us-ascii?Q?G0oG5kiTlHSharFBTj2a6S1BlEnwqaeJSjWYa4EaPjAbAp7FV3GHXQoPEHKx?= =?us-ascii?Q?pwwM9HTHpHgbUOKwqnYr6stGXkfLshrrrvhSdhykChCrQ04y734p8vIAMIfb?= =?us-ascii?Q?dFEfMx03De8x6Z92JdwfqQyhNgWNbRxNOjUHSaPxyu+TXBuHxRFUZDIrPhfC?= =?us-ascii?Q?yg6rGPrLRAb5wfqCbJEPApDWSWHws4n59SyT24MEIa/n4ZiIYQ6CCAqsXaws?= =?us-ascii?Q?zEkMVWVngtSbJn5w3fidZPJOixbD1SvPWt9B+Qewxov4VK3x2Flgz0Gypxom?= =?us-ascii?Q?vi0VIsN6Sksdi5DyZuWqx7zU2s4xahWgI9qsA4g06Pv5M1kilQOr328M5ZNh?= =?us-ascii?Q?uSiwNBstyO+pf59aHz5T+vhAWNV/0HMpDC88ZZBuOz8FxUMGdzqVQ78G8mDZ?= =?us-ascii?Q?qiVD7fyES+/48aD11g=3D?= X-Microsoft-Exchange-Diagnostics: 1;BN3PR07MB2481;6:zE1+xFTmctWc91HyRkeJtpxjTkZfdoQVfeEztdbGlMVypwv9RMLNDIQumRPZoEaaLojWxuLQjcF4uZVqrv/DAqe2D/Sdv+IjdTqow5PMESF86zkQkE4danm82OXn5BunpgKvEi8JcAB8kVU3TFBKIIUpbLuWA4/pC63ipEVkTZHsf1oA1DhZB1yWB4srTRkT9Mg8msg5SXFRVMeB4CB3ve3G8SQ0hEhROHa9Pcb1AdAsEHNWG7ScrVMvrrJomhTaFvRlNwXmohK10ihXGQazUWp3V5oWHS8VXzmo1e9kfk6rjAUGjDqlpcCOhrJUb5c3LizusBtH4koqTWKYNOc88gs4u9ZWnLE4SiswPxfMt6w=;5:BFeTel+Ig1Ao25xXe/RkA4wezHcACRWVFpHG2ca4f39vyQMYbSg6NWt08/9PfjO6LAdgi90LLQQguqDpPrZjurAhel7JYGTOhP7VqEcugyJ+d6ojq53ejEcBtKQFdLuQBiPAZNUi5IGTzj+6JZek/edX4l+UP2BGuxfVaqUd72U=;24:OTo/KfqruKhmjyQTnr10pp9EtWMAIqmlq0vRf95BYy4tfEHkVjfn7ZHO3fVWXofaGtkm8oUcdDdZ9XP5HRiEzvBi7XppdloK/F6X/hYNK/E=;7:nkn0R6IMrU9uaweDV4lCZhNX8HTpwhKOq5mBTI1HklOaaQ0jFtLfcuW4JIOstKKp9QelmB116UN9+lWIPz3da1Ctp3bjFb14hINDhRVJ0mSp/lQNeyeM7He/itVHa51VTqLUwA58MIfTJKady51j2MTwYkRfM7iJTVRKV4tm3HPMcjd6cnaKOb3xzWgwbo3S2XhXDCW6b7VzpuTx69+9qsWD0Fk8LOXBQJtIw2zT3IfqKx4DHXAv73niEUiqTiGd SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: cavium.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Nov 2017 13:49:40.9930 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c333a430-2025-4463-64f3-08d52dc20ed2 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 711e4ccf-2e9b-4bcf-a551-4094005b6194 X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN3PR07MB2481 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Radoslaw Biernacki This patch adds support for the Precision Time Protocol Clocks and Timestamping hardware found on Cavium ThunderX processors. Signed-off-by: Radoslaw Biernacki Signed-off-by: Aleksey Makarov --- drivers/net/ethernet/cavium/Kconfig | 13 + drivers/net/ethernet/cavium/Makefile | 1 + drivers/net/ethernet/cavium/common/Makefile | 1 + drivers/net/ethernet/cavium/common/cavium_ptp.c | 334 ++++++++++++++++++++++++ drivers/net/ethernet/cavium/common/cavium_ptp.h | 78 ++++++ 5 files changed, 427 insertions(+) create mode 100644 drivers/net/ethernet/cavium/common/Makefile create mode 100644 drivers/net/ethernet/cavium/common/cavium_ptp.c create mode 100644 drivers/net/ethernet/cavium/common/cavium_ptp.h diff --git a/drivers/net/ethernet/cavium/Kconfig b/drivers/net/ethernet/cavium/Kconfig index 63be75eb34d2..fabe0ffcc2d4 100644 --- a/drivers/net/ethernet/cavium/Kconfig +++ b/drivers/net/ethernet/cavium/Kconfig @@ -50,6 +50,19 @@ config THUNDER_NIC_RGX This driver supports configuring XCV block of RGX interface present on CN81XX chip. +config CAVIUM_PTP + tristate "Cavium PTP coprocessor as PTP clock" + depends on 64BIT + depends on PTP_1588_CLOCK + select CAVIUM_RST + default y + ---help--- + This driver adds support for the Precision Time Protocol Clocks and + Timestamping coprocessor (PTP) found on Cavium processors. + PTP provides timestamping mechanism that is suitable for use in IEEE 1588 + Precision Time Protocol or other purposes. Timestamps can be used in + BGX, TNS, GTI, and NIC blocks. + config LIQUIDIO tristate "Cavium LiquidIO support" depends on 64BIT diff --git a/drivers/net/ethernet/cavium/Makefile b/drivers/net/ethernet/cavium/Makefile index 872da9f7c31a..946bba84e81d 100644 --- a/drivers/net/ethernet/cavium/Makefile +++ b/drivers/net/ethernet/cavium/Makefile @@ -1,6 +1,7 @@ # # Makefile for the Cavium ethernet device drivers. # +obj-$(CONFIG_NET_VENDOR_CAVIUM) += common/ obj-$(CONFIG_NET_VENDOR_CAVIUM) += thunder/ obj-$(CONFIG_NET_VENDOR_CAVIUM) += liquidio/ obj-$(CONFIG_NET_VENDOR_CAVIUM) += octeon/ diff --git a/drivers/net/ethernet/cavium/common/Makefile b/drivers/net/ethernet/cavium/common/Makefile new file mode 100644 index 000000000000..dd8561b8060b --- /dev/null +++ b/drivers/net/ethernet/cavium/common/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_CAVIUM_PTP) += cavium_ptp.o diff --git a/drivers/net/ethernet/cavium/common/cavium_ptp.c b/drivers/net/ethernet/cavium/common/cavium_ptp.c new file mode 100644 index 000000000000..f4c738db27fd --- /dev/null +++ b/drivers/net/ethernet/cavium/common/cavium_ptp.c @@ -0,0 +1,334 @@ +/* + * cavium_ptp.c - PTP 1588 clock on Cavium hardware + * + * Copyright (c) 2003-2015, 2017 Cavium, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * This file may also be available under a different license from Cavium. + * Contact Cavium, Inc. for more information + */ + +#include +#include +#include +#include + +#include "cavium_ptp.h" + +#define DRV_NAME "Cavium PTP Driver" + +#define PCI_DEVICE_ID_CAVIUM_PTP 0xA00C +#define PCI_DEVICE_ID_CAVIUM_RST 0xA00E + +#define PCI_PTP_BAR_NO 0 +#define PCI_RST_BAR_NO 0 + +#define PTP_CLOCK_CFG 0xF00ULL +#define PTP_CLOCK_CFG_PTP_EN BIT(0) +#define PTP_CLOCK_LO 0xF08ULL +#define PTP_CLOCK_HI 0xF10ULL +#define PTP_CLOCK_COMP 0xF18ULL + +#define RST_BOOT 0x1600ULL +#define CLOCK_BASE_RATE 50000000ULL + +static u64 ptp_cavium_clock_get(void) +{ + struct pci_dev *pdev; + void __iomem *base; + u64 ret = CLOCK_BASE_RATE * 16; + + pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM, + PCI_DEVICE_ID_CAVIUM_RST, NULL); + if (!pdev) + goto error; + + base = pci_ioremap_bar(pdev, PCI_RST_BAR_NO); + if (!base) + goto error_put_pdev; + + ret = CLOCK_BASE_RATE * ((readq(base + RST_BOOT) >> 33) & 0x3f); + + iounmap(base); + +error_put_pdev: + pci_dev_put(pdev); + +error: + return ret; +} + +struct cavium_ptp *cavium_ptp_get(void) +{ + struct cavium_ptp *ptp; + struct pci_dev *pdev; + + pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM, + PCI_DEVICE_ID_CAVIUM_PTP, NULL); + if (!pdev) + return ERR_PTR(-ENODEV); + + ptp = pci_get_drvdata(pdev); + if (!ptp) { + pci_dev_put(pdev); + ptp = ERR_PTR(-EPROBE_DEFER); + } + + return ptp; +} +EXPORT_SYMBOL(cavium_ptp_get); + +void cavium_ptp_put(struct cavium_ptp *ptp) +{ + pci_dev_put(ptp->pdev); +} +EXPORT_SYMBOL(cavium_ptp_put); + +/** + * cavium_ptp_adjfreq() - Adjust ptp frequency + * @ptp: PTP clock info + * @ppb: how much to adjust by, in parts-per-billion + */ +static int cavium_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb) +{ + struct cavium_ptp *clock = + container_of(ptp_info, struct cavium_ptp, ptp_info); + unsigned long flags; + u64 comp; + u64 adj; + bool neg_adj = false; + + if (ppb < 0) { + neg_adj = true; + ppb = -ppb; + } + + /* The hardware adds the clock compensation value to the PTP clock + * on every coprocessor clock cycle. Typical convention is that it + * represent number of nanosecond betwen each cycle. In this + * convention compensation value is in 64 bit fixed-point + * representation where upper 32 bits are number of nanoseconds + * and lower is fractions of nanosecond. + * The ppb represent the ratio in "parts per bilion" by which the + * compensation value should be corrected. + * To calculate new compenstation value we use 64bit fixed point + * arithmetic on following formula comp = tbase + tbase * ppb / 1G + * where tbase is the basic compensation value calculated initialy + * in cavium_ptp_init() -> tbase = 1/Hz. Then we use endian + * independent structure definition to write data to PTP register. + */ + comp = ((u64)1000000000ull << 32) / clock->clock_rate; + adj = comp * ppb; + adj = div_u64(adj, 1000000000ull); + comp = neg_adj ? comp - adj : comp + adj; + + spin_lock_irqsave(&clock->spin_lock, flags); + writeq(comp, clock->reg_base + PTP_CLOCK_COMP); + spin_unlock_irqrestore(&clock->spin_lock, flags); + + return 0; +} + +/** + * cavium_ptp_adjtime() - Adjust ptp time + * @ptp: PTP clock info + * @delta: how much to adjust by, in nanosecs + */ +static int cavium_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta) +{ + struct cavium_ptp *clock = + container_of(ptp_info, struct cavium_ptp, ptp_info); + unsigned long flags; + + spin_lock_irqsave(&clock->spin_lock, flags); + timecounter_adjtime(&clock->time_counter, delta); + spin_unlock_irqrestore(&clock->spin_lock, flags); + + /* Sync, for network driver to get latest value */ + smp_mb(); + + return 0; +} + +/** + * cavium_ptp_gettime() - Get hardware clock time with adjustment + * @ptp: PTP clock info + * @ts: timespec + */ +static int cavium_ptp_gettime(struct ptp_clock_info *ptp_info, + struct timespec64 *ts) +{ + struct cavium_ptp *clock = + container_of(ptp_info, struct cavium_ptp, ptp_info); + unsigned long flags; + u64 nsec; + + spin_lock_irqsave(&clock->spin_lock, flags); + nsec = timecounter_read(&clock->time_counter); + spin_unlock_irqrestore(&clock->spin_lock, flags); + + *ts = ns_to_timespec64(nsec); + + return 0; +} + +/** + * cavium_ptp_settime() - Set hardware clock time. Reset adjustment + * @ptp: PTP clock info + * @ts: timespec + */ +static int cavium_ptp_settime(struct ptp_clock_info *ptp_info, + const struct timespec64 *ts) +{ + struct cavium_ptp *clock = + container_of(ptp_info, struct cavium_ptp, ptp_info); + unsigned long flags; + u64 nsec; + + nsec = timespec64_to_ns(ts); + + spin_lock_irqsave(&clock->spin_lock, flags); + timecounter_init(&clock->time_counter, &clock->cycle_counter, nsec); + spin_unlock_irqrestore(&clock->spin_lock, flags); + + return 0; +} + +/** + * cavium_ptp_enable() - Check if PTP is enabled + * @ptp: PTP clock info + * @rq: request + * @on: is it on + */ +static int cavium_ptp_enable(struct ptp_clock_info *ptp_info, + struct ptp_clock_request *rq, int on) +{ + return -EOPNOTSUPP; +} + +static u64 cavium_ptp_cc_read(const struct cyclecounter *cc) +{ + struct cavium_ptp *clock = + container_of(cc, struct cavium_ptp, cycle_counter); + + return readq(clock->reg_base + PTP_CLOCK_HI); +} + +static int cavium_ptp_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct device *dev = &pdev->dev; + struct cavium_ptp *clock; + struct cyclecounter *cc; + u64 clock_cfg; + u64 clock_comp; + int err; + + clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL); + if (!clock) + return -ENOMEM; + + clock->pdev = pdev; + + err = pcim_enable_device(pdev); + if (err) + return err; + + err = pcim_iomap_regions(pdev, 1 << PCI_PTP_BAR_NO, pci_name(pdev)); + if (err) + return err; + + clock->reg_base = pcim_iomap_table(pdev)[PCI_PTP_BAR_NO]; + + spin_lock_init(&clock->spin_lock); + + cc = &clock->cycle_counter; + cc->read = cavium_ptp_cc_read; + cc->mask = CYCLECOUNTER_MASK(64); + cc->mult = 1; + cc->shift = 0; + + timecounter_init(&clock->time_counter, &clock->cycle_counter, + ktime_to_ns(ktime_get_real())); + + clock->clock_rate = ptp_cavium_clock_get(); + + clock->ptp_info = (struct ptp_clock_info) { + .owner = THIS_MODULE, + .name = "ThunderX PTP", + .max_adj = 1000000000ull, + .n_ext_ts = 0, + .n_pins = 0, + .pps = 0, + .adjfreq = cavium_ptp_adjfreq, + .adjtime = cavium_ptp_adjtime, + .gettime64 = cavium_ptp_gettime, + .settime64 = cavium_ptp_settime, + .enable = cavium_ptp_enable, + }; + + clock_cfg = readq(clock->reg_base + PTP_CLOCK_CFG); + clock_cfg |= PTP_CLOCK_CFG_PTP_EN; + writeq(clock_cfg, clock->reg_base + PTP_CLOCK_CFG); + + clock_comp = ((u64)1000000000ull << 32) / clock->clock_rate; + writeq(clock_comp, clock->reg_base + PTP_CLOCK_COMP); + + clock->ptp_clock = ptp_clock_register(&clock->ptp_info, dev); + if (IS_ERR(clock->ptp_clock)) { + clock_cfg = readq(clock->reg_base + PTP_CLOCK_CFG); + clock_cfg &= ~PTP_CLOCK_CFG_PTP_EN; + writeq(clock_cfg, clock->reg_base + PTP_CLOCK_CFG); + return PTR_ERR(clock->ptp_clock); + } + + pci_set_drvdata(pdev, clock); + return 0; +} + +static void cavium_ptp_remove(struct pci_dev *pdev) +{ + struct cavium_ptp *clock = pci_get_drvdata(pdev); + u64 clock_cfg; + + pci_set_drvdata(pdev, NULL); + + ptp_clock_unregister(clock->ptp_clock); + + clock_cfg = readq(clock->reg_base + PTP_CLOCK_CFG); + clock_cfg &= ~PTP_CLOCK_CFG_PTP_EN; + writeq(clock_cfg, clock->reg_base + PTP_CLOCK_CFG); +} + +static const struct pci_device_id cavium_ptp_id_table[] = { + { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVICE_ID_CAVIUM_PTP) }, + { 0, } +}; + +static struct pci_driver cavium_ptp_driver = { + .name = DRV_NAME, + .id_table = cavium_ptp_id_table, + .probe = cavium_ptp_probe, + .remove = cavium_ptp_remove, +}; + +static int __init cavium_ptp_init_module(void) +{ + return pci_register_driver(&cavium_ptp_driver); +} + +static void __exit cavium_ptp_cleanup_module(void) +{ + pci_unregister_driver(&cavium_ptp_driver); +} + +module_init(cavium_ptp_init_module); +module_exit(cavium_ptp_cleanup_module); + +MODULE_DESCRIPTION(DRV_NAME); +MODULE_AUTHOR("Cavium Networks "); +MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(pci, cavium_ptp_id_table); diff --git a/drivers/net/ethernet/cavium/common/cavium_ptp.h b/drivers/net/ethernet/cavium/common/cavium_ptp.h new file mode 100644 index 000000000000..7a9dcb027a93 --- /dev/null +++ b/drivers/net/ethernet/cavium/common/cavium_ptp.h @@ -0,0 +1,78 @@ +/* + * cavium_ptp.h - PTP 1588 clock on Cavium hardware + * + * Copyright (c) 2003-2015, 2017 Cavium, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * This file may also be available under a different license from Cavium. + * Contact Cavium, Inc. for more information + */ + +#ifndef CAVIUM_PTP_H +#define CAVIUM_PTP_H + +#include +#include + +struct cavium_ptp { + struct pci_dev *pdev; + + /* Serialize access to cycle_counter, time_counter and hw_registers */ + spinlock_t spin_lock; + struct cyclecounter cycle_counter; + struct timecounter time_counter; + void __iomem *reg_base; + + u32 clock_rate; + + struct ptp_clock_info ptp_info; + struct ptp_clock *ptp_clock; +}; + +#ifdef CONFIG_CAVIUM_PTP + +struct cavium_ptp *cavium_ptp_get(void); +void cavium_ptp_put(struct cavium_ptp *ptp); + +static inline u64 cavium_ptp_tstamp2time(struct cavium_ptp *ptp, u64 tstamp) +{ + unsigned long flags; + u64 ret; + + spin_lock_irqsave(&ptp->spin_lock, flags); + ret = timecounter_cyc2time(&ptp->time_counter, tstamp); + spin_unlock_irqrestore(&ptp->spin_lock, flags); + + return ret; +} + +static inline int cavium_ptp_clock_index(struct cavium_ptp *clock) +{ + return ptp_clock_index(clock->ptp_clock); +} + +#else + +static inline struct cavium_ptp *cavium_ptp_get(void) +{ + return ERR_PTR(-ENODEV); +} + +static inline void cavium_ptp_put(struct cavium_ptp *ptp) {} + +static inline u64 cavium_ptp_tstamp2time(struct cavium_ptp *ptp, u64 tstamp) +{ + return 0; +} + +static inline int cavium_ptp_clock_index(struct cavium_ptp *clock) +{ + return -1; +} + +#endif + +#endif -- 2.15.0 From 1584198424433413631@xxx Thu Nov 16 05:15:49 +0000 2017 X-GM-THRID: 1584198424433413631 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread