Skip to content

Commit

Permalink
fpga: dfl: afu: add userclock sysfs interfaces.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Russ Weight <[email protected]>
Signed-off-by: Xu Yilun <[email protected]>
Signed-off-by: Wu Hao <[email protected]>
Acked-by: Alan Tull <[email protected]>
Signed-off-by: Moritz Fischer <[email protected]>
  • Loading branch information
WuHao270 authored and mfischer committed Sep 4, 2019
1 parent a80a4b8 commit f09991a
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 1 deletion.
28 changes: 28 additions & 0 deletions Documentation/ABI/testing/sysfs-platform-dfl-port
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,31 @@ Contact: Wu Hao <[email protected]>
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/userclk_freqcmd
Date: August 2019
KernelVersion: 5.4
Contact: Wu Hao <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
Description: Read-only. Read this file to get the status of issued command
to userclck_freqcntrcmd.
111 changes: 110 additions & 1 deletion drivers/fpga/dfl-afu-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,17 +274,126 @@ power_state_show(struct device *dev, struct device_attribute *attr, char *buf)
}
static DEVICE_ATTR_RO(power_state);

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)
{
struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
u64 userclk_freqsts;
void __iomem *base;

base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);

mutex_lock(&pdata->lock);
userclk_freqsts = readq(base + PORT_HDR_USRCLK_STS0);
mutex_unlock(&pdata->lock);

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)
{
struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
u64 userclk_freqcntrsts;
void __iomem *base;

base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);

mutex_lock(&pdata->lock);
userclk_freqcntrsts = readq(base + PORT_HDR_USRCLK_STS1);
mutex_unlock(&pdata->lock);

return sprintf(buf, "0x%llx\n",
(unsigned long long)userclk_freqcntrsts);
}
static DEVICE_ATTR_RO(userclk_freqcntrsts);

static struct attribute *port_hdr_attrs[] = {
&dev_attr_id.attr,
&dev_attr_ltr.attr,
&dev_attr_ap1_event.attr,
&dev_attr_ap2_event.attr,
&dev_attr_power_state.attr,
&dev_attr_userclk_freqcmd.attr,
&dev_attr_userclk_freqcntrcmd.attr,
&dev_attr_userclk_freqsts.attr,
&dev_attr_userclk_freqcntrsts.attr,
NULL,
};

static umode_t port_hdr_attrs_visible(struct kobject *kobj,
struct attribute *attr, int n)
{
struct device *dev = kobj_to_dev(kobj);
umode_t mode = attr->mode;
void __iomem *base;

base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);

if (dfl_feature_revision(base) > 0) {
/*
* userclk sysfs interfaces are only visible in case port
* revision is 0, as hardware with revision >0 doesn't
* support this.
*/
if (attr == &dev_attr_userclk_freqcmd.attr ||
attr == &dev_attr_userclk_freqcntrcmd.attr ||
attr == &dev_attr_userclk_freqsts.attr ||
attr == &dev_attr_userclk_freqcntrsts.attr)
mode = 0;
}

return mode;
}

static const struct attribute_group port_hdr_group = {
.attrs = port_hdr_attrs,
.attrs = port_hdr_attrs,
.is_visible = port_hdr_attrs_visible,
};

static int port_hdr_init(struct platform_device *pdev,
Expand Down
9 changes: 9 additions & 0 deletions drivers/fpga/dfl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -355,6 +359,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
*
Expand Down

0 comments on commit f09991a

Please sign in to comment.