mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
fpga: dfl: afu: add AFU state related sysfs interfaces
This patch introduces more sysfs interfaces for Accelerated Function Unit (AFU). These interfaces allow users to read current AFU Power State (APx), read / clear AFU Power (APx) events which are sticky to identify transient APx state, and manage AFU's LTR (latency tolerance reporting). Signed-off-by: Ananda Ravuri <[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]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
This commit is contained in:
parent
bdd4f30795
commit
d2ad5ac1cd
3 changed files with 180 additions and 0 deletions
|
|
@ -141,8 +141,145 @@ id_show(struct device *dev, struct device_attribute *attr, char *buf)
|
|||
}
|
||||
static DEVICE_ATTR_RO(id);
|
||||
|
||||
static ssize_t
|
||||
ltr_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
|
||||
void __iomem *base;
|
||||
u64 v;
|
||||
|
||||
base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
|
||||
|
||||
mutex_lock(&pdata->lock);
|
||||
v = readq(base + PORT_HDR_CTRL);
|
||||
mutex_unlock(&pdata->lock);
|
||||
|
||||
return sprintf(buf, "%x\n", (u8)FIELD_GET(PORT_CTRL_LATENCY, v));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ltr_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
|
||||
void __iomem *base;
|
||||
bool ltr;
|
||||
u64 v;
|
||||
|
||||
if (kstrtobool(buf, <r))
|
||||
return -EINVAL;
|
||||
|
||||
base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
|
||||
|
||||
mutex_lock(&pdata->lock);
|
||||
v = readq(base + PORT_HDR_CTRL);
|
||||
v &= ~PORT_CTRL_LATENCY;
|
||||
v |= FIELD_PREP(PORT_CTRL_LATENCY, ltr ? 1 : 0);
|
||||
writeq(v, base + PORT_HDR_CTRL);
|
||||
mutex_unlock(&pdata->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR_RW(ltr);
|
||||
|
||||
static ssize_t
|
||||
ap1_event_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
|
||||
void __iomem *base;
|
||||
u64 v;
|
||||
|
||||
base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
|
||||
|
||||
mutex_lock(&pdata->lock);
|
||||
v = readq(base + PORT_HDR_STS);
|
||||
mutex_unlock(&pdata->lock);
|
||||
|
||||
return sprintf(buf, "%x\n", (u8)FIELD_GET(PORT_STS_AP1_EVT, v));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ap1_event_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
|
||||
void __iomem *base;
|
||||
bool clear;
|
||||
|
||||
if (kstrtobool(buf, &clear) || !clear)
|
||||
return -EINVAL;
|
||||
|
||||
base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
|
||||
|
||||
mutex_lock(&pdata->lock);
|
||||
writeq(PORT_STS_AP1_EVT, base + PORT_HDR_STS);
|
||||
mutex_unlock(&pdata->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR_RW(ap1_event);
|
||||
|
||||
static ssize_t
|
||||
ap2_event_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
|
||||
void __iomem *base;
|
||||
u64 v;
|
||||
|
||||
base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
|
||||
|
||||
mutex_lock(&pdata->lock);
|
||||
v = readq(base + PORT_HDR_STS);
|
||||
mutex_unlock(&pdata->lock);
|
||||
|
||||
return sprintf(buf, "%x\n", (u8)FIELD_GET(PORT_STS_AP2_EVT, v));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ap2_event_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
|
||||
void __iomem *base;
|
||||
bool clear;
|
||||
|
||||
if (kstrtobool(buf, &clear) || !clear)
|
||||
return -EINVAL;
|
||||
|
||||
base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
|
||||
|
||||
mutex_lock(&pdata->lock);
|
||||
writeq(PORT_STS_AP2_EVT, base + PORT_HDR_STS);
|
||||
mutex_unlock(&pdata->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR_RW(ap2_event);
|
||||
|
||||
static ssize_t
|
||||
power_state_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
|
||||
void __iomem *base;
|
||||
u64 v;
|
||||
|
||||
base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
|
||||
|
||||
mutex_lock(&pdata->lock);
|
||||
v = readq(base + PORT_HDR_STS);
|
||||
mutex_unlock(&pdata->lock);
|
||||
|
||||
return sprintf(buf, "0x%x\n", (u8)FIELD_GET(PORT_STS_PWR_STATE, v));
|
||||
}
|
||||
static DEVICE_ATTR_RO(power_state);
|
||||
|
||||
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,
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(port_hdr);
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@
|
|||
#define PORT_HDR_NEXT_AFU NEXT_AFU
|
||||
#define PORT_HDR_CAP 0x30
|
||||
#define PORT_HDR_CTRL 0x38
|
||||
#define PORT_HDR_STS 0x40
|
||||
|
||||
/* Port Capability Register Bitfield */
|
||||
#define PORT_CAP_PORT_NUM GENMASK_ULL(1, 0) /* ID of this port */
|
||||
|
|
@ -130,6 +131,16 @@
|
|||
/* Latency tolerance reporting. '1' >= 40us, '0' < 40us.*/
|
||||
#define PORT_CTRL_LATENCY BIT_ULL(2)
|
||||
#define PORT_CTRL_SFTRST_ACK BIT_ULL(4) /* HW ack for reset */
|
||||
|
||||
/* Port Status Register Bitfield */
|
||||
#define PORT_STS_AP2_EVT BIT_ULL(13) /* AP2 event detected */
|
||||
#define PORT_STS_AP1_EVT BIT_ULL(12) /* AP1 event detected */
|
||||
#define PORT_STS_PWR_STATE GENMASK_ULL(11, 8) /* AFU power states */
|
||||
#define PORT_STS_PWR_STATE_NORM 0
|
||||
#define PORT_STS_PWR_STATE_AP1 1 /* 50% throttling */
|
||||
#define PORT_STS_PWR_STATE_AP2 2 /* 90% throttling */
|
||||
#define PORT_STS_PWR_STATE_AP6 6 /* 100% throttling */
|
||||
|
||||
/**
|
||||
* struct dfl_fpga_port_ops - port ops
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue