Received: by 2002:a25:b794:0:0:0:0:0 with SMTP id n20csp1519280ybh; Sun, 4 Aug 2019 03:40:07 -0700 (PDT) X-Google-Smtp-Source: APXvYqwXJNXr8tGbZjA+cviZvFtd0rBzRJ+DVsK4uggNyCm34xdlfyFduWRFbgiNL0/Ak30bpHyU X-Received: by 2002:aa7:93a5:: with SMTP id x5mr67047066pff.87.1564915207721; Sun, 04 Aug 2019 03:40:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1564915207; cv=none; d=google.com; s=arc-20160816; b=zxONCKHvmEIUlxwtrIxJwKkIjbrduBfqScd2fBj/SD+65EV1d8QeLDIGAZZ9Z2u2KD MhK+aQ6la558keFP7ZS71DlyYgiZcSew0qi6uHQDfSUhgkkFXIVgpsWGvynTKe6DNU7s TspDKKAKcMSPd7P1x1utoW91PMDUdt6L18tk2ZmdGSnry4+jgsPOchGCKmJ0GuQIjpHW 08SBheA2N1ie8potCr2gYavlrXz1xOQVuVnA45iVPeaxwF7G8yGq8c3o4qESVpFgkI+M ilqmD9NnsjWVzWrpT7wzInVMiPLJXrw/flN07RBPd2+HjXTbxxAOnLAhWqMLgQZOZytC 7lNQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=bsvPZNxWbpWjqs7RZwx8NypqG26xMmRP/Bju8mfLJkM=; b=0ufHfe5t422TZBROUbfvn/uRrWz8llCFA3VCcjk7mY831vw7U0lb1KtLOzdcNmDIv8 smU0RV9CAWpAT4GxtEYXuIz/mNwo8pQY+OGHxfviVROqybNpYo2MIR4AJ3qSj7c3BQhh fNNRI3piKORrGlsVcER9etivDsS4BFhyyfFI9ejWKS8G/OLP+XZUDZYCa2kFYW+kGRV6 q2jVN6FHx0sKVpU1F/wFwrNKo6Z+lUjIU4HGfE9EtzpeQyh2DcRzNiDxa4PHMyDoBJA7 W4r1B8xZgkPdgyqK3Y8ajESHHW4mfHrFrS2NnwMhLy/mligWsxgFBDFFmtRyiLR/SkR0 kS8Q== ARC-Authentication-Results: i=1; mx.google.com; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c16si2085125plo.420.2019.08.04.03.39.22; Sun, 04 Aug 2019 03:40:07 -0700 (PDT) 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; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726411AbfHDKh6 (ORCPT + 99 others); Sun, 4 Aug 2019 06:37:58 -0400 Received: from mga01.intel.com ([192.55.52.88]:31912 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726342AbfHDKhz (ORCPT ); Sun, 4 Aug 2019 06:37:55 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Aug 2019 03:37:55 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,345,1559545200"; d="scan'208";a="167678942" Received: from hao-dev.bj.intel.com ([10.238.157.65]) by orsmga008.jf.intel.com with ESMTP; 04 Aug 2019 03:37:52 -0700 From: Wu Hao To: gregkh@linuxfoundation.org, mdf@kernel.org, linux-fpga@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-doc@vger.kernel.org, atull@kernel.org, Wu Hao , Ananda Ravuri , Russ Weight , Xu Yilun Subject: [PATCH v4 04/12] fpga: dfl: afu: add userclock sysfs interfaces. Date: Sun, 4 Aug 2019 18:20:14 +0800 Message-Id: <1564914022-3710-5-git-send-email-hao.wu@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564914022-3710-1-git-send-email-hao.wu@intel.com> References: <1564914022-3710-1-git-send-email-hao.wu@intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch introduces userclock sysfs interfaces for AFU, user could use these interfaces for clock setting to AFU. Please note that, this is only working for port header feature with revision 0, for later revisions, userclock setting is moved to a separated private feature, so one revision sysfs interface is exposed to userspace application for this purpose too. Signed-off-by: Ananda Ravuri Signed-off-by: Russ Weight Signed-off-by: Xu Yilun Signed-off-by: Wu Hao Acked-by: Alan Tull Signed-off-by: Moritz Fischer --- v2: rebased, and switched to use device_add/remove_groups for sysfs v3: update kernel version and date in sysfs doc v4: rebased. --- Documentation/ABI/testing/sysfs-platform-dfl-port | 35 +++++++ drivers/fpga/dfl-afu-main.c | 114 +++++++++++++++++++++- drivers/fpga/dfl.h | 9 ++ 3 files changed, 157 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-platform-dfl-port b/Documentation/ABI/testing/sysfs-platform-dfl-port index 1ab3e6f..5663441 100644 --- a/Documentation/ABI/testing/sysfs-platform-dfl-port +++ b/Documentation/ABI/testing/sysfs-platform-dfl-port @@ -46,3 +46,38 @@ Contact: Wu Hao Description: Read-write. Read or set AFU latency tolerance reporting value. Set ltr to 1 if the AFU can tolerate latency >= 40us or set it to 0 if it is latency sensitive. + +What: /sys/bus/platform/devices/dfl-port.0/revision +Date: August 2019 +KernelVersion: 5.4 +Contact: Wu Hao +Description: Read-only. Read this file to get the revision of port header + feature. + +What: /sys/bus/platform/devices/dfl-port.0/userclk_freqcmd +Date: August 2019 +KernelVersion: 5.4 +Contact: Wu Hao +Description: Write-only. User writes command to this interface to set + userclock to AFU. + +What: /sys/bus/platform/devices/dfl-port.0/userclk_freqsts +Date: August 2019 +KernelVersion: 5.4 +Contact: Wu Hao +Description: Read-only. Read this file to get the status of issued command + to userclck_freqcmd. + +What: /sys/bus/platform/devices/dfl-port.0/userclk_freqcntrcmd +Date: August 2019 +KernelVersion: 5.4 +Contact: Wu Hao +Description: Write-only. User writes command to this interface to set + userclock counter. + +What: /sys/bus/platform/devices/dfl-port.0/userclk_freqcntrsts +Date: August 2019 +KernelVersion: 5.4 +Contact: Wu Hao +Description: Read-only. Read this file to get the status of issued command + to userclck_freqcntrcmd. diff --git a/drivers/fpga/dfl-afu-main.c b/drivers/fpga/dfl-afu-main.c index 12175bb..407c97d 100644 --- a/drivers/fpga/dfl-afu-main.c +++ b/drivers/fpga/dfl-afu-main.c @@ -142,6 +142,17 @@ static int port_get_id(struct platform_device *pdev) static DEVICE_ATTR_RO(id); static ssize_t +revision_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + void __iomem *base; + + base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER); + + return sprintf(buf, "%x\n", dfl_feature_revision(base)); +} +static DEVICE_ATTR_RO(revision); + +static ssize_t ltr_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dfl_feature_platform_data *pdata = dev_get_platdata(dev); @@ -276,6 +287,7 @@ static int port_get_id(struct platform_device *pdev) static struct attribute *port_hdr_attrs[] = { &dev_attr_id.attr, + &dev_attr_revision.attr, &dev_attr_ltr.attr, &dev_attr_ap1_event.attr, &dev_attr_ap2_event.attr, @@ -284,14 +296,113 @@ static int port_get_id(struct platform_device *pdev) }; ATTRIBUTE_GROUPS(port_hdr); +static ssize_t +userclk_freqcmd_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct dfl_feature_platform_data *pdata = dev_get_platdata(dev); + u64 userclk_freq_cmd; + void __iomem *base; + + if (kstrtou64(buf, 0, &userclk_freq_cmd)) + return -EINVAL; + + base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER); + + mutex_lock(&pdata->lock); + writeq(userclk_freq_cmd, base + PORT_HDR_USRCLK_CMD0); + mutex_unlock(&pdata->lock); + + return count; +} +static DEVICE_ATTR_WO(userclk_freqcmd); + +static ssize_t +userclk_freqcntrcmd_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct dfl_feature_platform_data *pdata = dev_get_platdata(dev); + u64 userclk_freqcntr_cmd; + void __iomem *base; + + if (kstrtou64(buf, 0, &userclk_freqcntr_cmd)) + return -EINVAL; + + base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER); + + mutex_lock(&pdata->lock); + writeq(userclk_freqcntr_cmd, base + PORT_HDR_USRCLK_CMD1); + mutex_unlock(&pdata->lock); + + return count; +} +static DEVICE_ATTR_WO(userclk_freqcntrcmd); + +static ssize_t +userclk_freqsts_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + u64 userclk_freqsts; + void __iomem *base; + + base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER); + + userclk_freqsts = readq(base + PORT_HDR_USRCLK_STS0); + + return sprintf(buf, "0x%llx\n", (unsigned long long)userclk_freqsts); +} +static DEVICE_ATTR_RO(userclk_freqsts); + +static ssize_t +userclk_freqcntrsts_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + u64 userclk_freqcntrsts; + void __iomem *base; + + base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER); + + userclk_freqcntrsts = readq(base + PORT_HDR_USRCLK_STS1); + + return sprintf(buf, "0x%llx\n", + (unsigned long long)userclk_freqcntrsts); +} +static DEVICE_ATTR_RO(userclk_freqcntrsts); + +static struct attribute *port_hdr_userclk_attrs[] = { + &dev_attr_userclk_freqcmd.attr, + &dev_attr_userclk_freqcntrcmd.attr, + &dev_attr_userclk_freqsts.attr, + &dev_attr_userclk_freqcntrsts.attr, + NULL, +}; +ATTRIBUTE_GROUPS(port_hdr_userclk); + static int port_hdr_init(struct platform_device *pdev, struct dfl_feature *feature) { + int ret; + dev_dbg(&pdev->dev, "PORT HDR Init.\n"); port_reset(pdev); - return device_add_groups(&pdev->dev, port_hdr_groups); + ret = device_add_groups(&pdev->dev, port_hdr_groups); + if (ret) + return ret; + + /* + * if revision > 0, the userclock will be moved from port hdr register + * region to a separated private feature. + */ + if (dfl_feature_revision(feature->ioaddr) > 0) + return 0; + + ret = device_add_groups(&pdev->dev, port_hdr_userclk_groups); + if (ret) + device_remove_groups(&pdev->dev, port_hdr_groups); + + return ret; } static void port_hdr_uinit(struct platform_device *pdev, @@ -299,6 +410,7 @@ static void port_hdr_uinit(struct platform_device *pdev, { dev_dbg(&pdev->dev, "PORT HDR UInit.\n"); + device_remove_groups(&pdev->dev, port_hdr_userclk_groups); device_remove_groups(&pdev->dev, port_hdr_groups); } diff --git a/drivers/fpga/dfl.h b/drivers/fpga/dfl.h index 6625d73..c65ab29 100644 --- a/drivers/fpga/dfl.h +++ b/drivers/fpga/dfl.h @@ -120,6 +120,10 @@ #define PORT_HDR_CAP 0x30 #define PORT_HDR_CTRL 0x38 #define PORT_HDR_STS 0x40 +#define PORT_HDR_USRCLK_CMD0 0x50 +#define PORT_HDR_USRCLK_CMD1 0x58 +#define PORT_HDR_USRCLK_STS0 0x60 +#define PORT_HDR_USRCLK_STS1 0x68 /* Port Capability Register Bitfield */ #define PORT_CAP_PORT_NUM GENMASK_ULL(1, 0) /* ID of this port */ @@ -346,6 +350,11 @@ static inline bool dfl_feature_is_port(void __iomem *base) (FIELD_GET(DFH_ID, v) == DFH_ID_FIU_PORT); } +static inline u8 dfl_feature_revision(void __iomem *base) +{ + return (u8)FIELD_GET(DFH_REVISION, readq(base + DFH)); +} + /** * struct dfl_fpga_enum_info - DFL FPGA enumeration information * -- 1.8.3.1