Skip to content

Commit

Permalink
fpga: dfl: expose feature revision from struct dfl_device
Browse files Browse the repository at this point in the history
DFL device drivers have a common need for checking feature revision
information from the DFL header, as well as other common DFL information
like the already exposed feature id and type.

This patch exposes the feature revision information directly via the DFL
device data structure.

Since the DFL core code has already read the DFL header, this this patch
saves additional mmio reads from DFL device drivers too.

Acked-by: Wu Hao <[email protected]>
Acked-by: Matthew Gerlach <[email protected]>
Signed-off-by: Martin Hundebøll <[email protected]>
Signed-off-by: Moritz Fischer <[email protected]>
  • Loading branch information
hundeboll-silicom authored and mfischer committed Jul 29, 2021
1 parent 5f1895e commit 1604986
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 10 deletions.
27 changes: 17 additions & 10 deletions drivers/fpga/dfl.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ dfl_dev_add(struct dfl_feature_platform_data *pdata,

ddev->type = feature_dev_id_type(pdev);
ddev->feature_id = feature->id;
ddev->revision = feature->revision;
ddev->cdev = pdata->dfl_cdev;

/* add mmio resource */
Expand Down Expand Up @@ -717,6 +718,7 @@ struct build_feature_devs_info {
*/
struct dfl_feature_info {
u16 fid;
u8 revision;
struct resource mmio_res;
void __iomem *ioaddr;
struct list_head node;
Expand Down Expand Up @@ -796,6 +798,7 @@ static int build_info_commit_dev(struct build_feature_devs_info *binfo)
/* save resource information for each feature */
feature->dev = fdev;
feature->id = finfo->fid;
feature->revision = finfo->revision;

/*
* the FIU header feature has some fundamental functions (sriov
Expand Down Expand Up @@ -910,19 +913,17 @@ static void build_info_free(struct build_feature_devs_info *binfo)
devm_kfree(binfo->dev, binfo);
}

static inline u32 feature_size(void __iomem *start)
static inline u32 feature_size(u64 value)
{
u64 v = readq(start + DFH);
u32 ofst = FIELD_GET(DFH_NEXT_HDR_OFST, v);
u32 ofst = FIELD_GET(DFH_NEXT_HDR_OFST, value);
/* workaround for private features with invalid size, use 4K instead */
return ofst ? ofst : 4096;
}

static u16 feature_id(void __iomem *start)
static u16 feature_id(u64 value)
{
u64 v = readq(start + DFH);
u16 id = FIELD_GET(DFH_ID, v);
u8 type = FIELD_GET(DFH_TYPE, v);
u16 id = FIELD_GET(DFH_ID, value);
u8 type = FIELD_GET(DFH_TYPE, value);

if (type == DFH_TYPE_FIU)
return FEATURE_ID_FIU_HEADER;
Expand Down Expand Up @@ -1021,10 +1022,15 @@ create_feature_instance(struct build_feature_devs_info *binfo,
unsigned int irq_base, nr_irqs;
struct dfl_feature_info *finfo;
int ret;
u8 revision;
u64 v;

v = readq(binfo->ioaddr + ofst);
revision = FIELD_GET(DFH_REVISION, v);

/* read feature size and id if inputs are invalid */
size = size ? size : feature_size(binfo->ioaddr + ofst);
fid = fid ? fid : feature_id(binfo->ioaddr + ofst);
size = size ? size : feature_size(v);
fid = fid ? fid : feature_id(v);

if (binfo->len - ofst < size)
return -EINVAL;
Expand All @@ -1038,6 +1044,7 @@ create_feature_instance(struct build_feature_devs_info *binfo,
return -ENOMEM;

finfo->fid = fid;
finfo->revision = revision;
finfo->mmio_res.start = binfo->start + ofst;
finfo->mmio_res.end = finfo->mmio_res.start + size - 1;
finfo->mmio_res.flags = IORESOURCE_MEM;
Expand Down Expand Up @@ -1166,7 +1173,7 @@ static int parse_feature_private(struct build_feature_devs_info *binfo,
{
if (!is_feature_dev_detected(binfo)) {
dev_err(binfo->dev, "the private feature 0x%x does not belong to any AFU.\n",
feature_id(binfo->ioaddr + ofst));
feature_id(readq(binfo->ioaddr + ofst)));
return -EINVAL;
}

Expand Down
1 change: 1 addition & 0 deletions drivers/fpga/dfl.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ struct dfl_feature_irq_ctx {
struct dfl_feature {
struct platform_device *dev;
u16 id;
u8 revision;
int resource_index;
void __iomem *ioaddr;
struct dfl_feature_irq_ctx *irq_ctx;
Expand Down
1 change: 1 addition & 0 deletions include/linux/dfl.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct dfl_device {
int id;
u16 type;
u16 feature_id;
u8 revision;
struct resource mmio_res;
int *irqs;
unsigned int num_irqs;
Expand Down

0 comments on commit 1604986

Please sign in to comment.