summaryrefslogtreecommitdiffstats
path: root/drivers/fpga
diff options
context:
space:
mode:
authorWu Hao <hao.wu@intel.com>2018-06-29 20:53:30 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-07-15 07:55:46 -0400
commit1a1527cf5ddacc6716a3cacfa232111d92ffd93b (patch)
treeb0adb5811cb0cd0dcd8bdab87fe4893472114b09 /drivers/fpga
parent7514a4249c479c0b56a112306496a9aa3bad312b (diff)
fpga: dfl: add FPGA Accelerated Function Unit driver basic framework
On DFL FPGA devices, the Accelerated Function Unit (AFU), can be reprogrammed for different functions. It connects to the FPGA infrastructure (static FPGA region) via a Port. Port CSRs are implemented separately from the AFU CSRs to provide control and status of the Port. Once valid PR bitstream is programmed into the AFU, it allows access to the AFU CSRs in the AFU MMIO space. This patch only implements basic driver framework for AFU, including device file operation framework. Signed-off-by: Tim Whisonant <tim.whisonant@intel.com> Signed-off-by: Enno Luebbers <enno.luebbers@intel.com> Signed-off-by: Shiva Rao <shiva.rao@intel.com> Signed-off-by: Christopher Rauer <christopher.rauer@intel.com> Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com> Signed-off-by: Wu Hao <hao.wu@intel.com> Acked-by: Alan Tull <atull@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/fpga')
-rw-r--r--drivers/fpga/Kconfig9
-rw-r--r--drivers/fpga/Makefile2
-rw-r--r--drivers/fpga/dfl-afu-main.c162
3 files changed, 173 insertions, 0 deletions
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index f99f422feec9..1ebcef4bab5b 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -174,6 +174,15 @@ config FPGA_DFL_FME_REGION
174 help 174 help
175 Say Y to enable FPGA Region driver for FPGA Management Engine. 175 Say Y to enable FPGA Region driver for FPGA Management Engine.
176 176
177config FPGA_DFL_AFU
178 tristate "FPGA DFL AFU Driver"
179 depends on FPGA_DFL
180 help
181 This is the driver for FPGA Accelerated Function Unit (AFU) which
182 implements AFU and Port management features. A User AFU connects
183 to the FPGA infrastructure via a Port. There may be more than one
184 Port/AFU per DFL based FPGA device.
185
177config FPGA_DFL_PCI 186config FPGA_DFL_PCI
178 tristate "FPGA DFL PCIe Device Driver" 187 tristate "FPGA DFL PCIe Device Driver"
179 depends on PCI && FPGA_DFL 188 depends on PCI && FPGA_DFL
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 637c27512c28..1ac7749b2542 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -35,8 +35,10 @@ obj-$(CONFIG_FPGA_DFL_FME) += dfl-fme.o
35obj-$(CONFIG_FPGA_DFL_FME_MGR) += dfl-fme-mgr.o 35obj-$(CONFIG_FPGA_DFL_FME_MGR) += dfl-fme-mgr.o
36obj-$(CONFIG_FPGA_DFL_FME_BRIDGE) += dfl-fme-br.o 36obj-$(CONFIG_FPGA_DFL_FME_BRIDGE) += dfl-fme-br.o
37obj-$(CONFIG_FPGA_DFL_FME_REGION) += dfl-fme-region.o 37obj-$(CONFIG_FPGA_DFL_FME_REGION) += dfl-fme-region.o
38obj-$(CONFIG_FPGA_DFL_AFU) += dfl-afu.o
38 39
39dfl-fme-objs := dfl-fme-main.o dfl-fme-pr.o 40dfl-fme-objs := dfl-fme-main.o dfl-fme-pr.o
41dfl-afu-objs := dfl-afu-main.o
40 42
41# Drivers for FPGAs which implement DFL 43# Drivers for FPGAs which implement DFL
42obj-$(CONFIG_FPGA_DFL_PCI) += dfl-pci.o 44obj-$(CONFIG_FPGA_DFL_PCI) += dfl-pci.o
diff --git a/drivers/fpga/dfl-afu-main.c b/drivers/fpga/dfl-afu-main.c
new file mode 100644
index 000000000000..08f88cdb3bfc
--- /dev/null
+++ b/drivers/fpga/dfl-afu-main.c
@@ -0,0 +1,162 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Driver for FPGA Accelerated Function Unit (AFU)
4 *
5 * Copyright (C) 2017-2018 Intel Corporation, Inc.
6 *
7 * Authors:
8 * Wu Hao <hao.wu@intel.com>
9 * Xiao Guangrong <guangrong.xiao@linux.intel.com>
10 * Joseph Grecco <joe.grecco@intel.com>
11 * Enno Luebbers <enno.luebbers@intel.com>
12 * Tim Whisonant <tim.whisonant@intel.com>
13 * Ananda Ravuri <ananda.ravuri@intel.com>
14 * Henry Mitchel <henry.mitchel@intel.com>
15 */
16
17#include <linux/kernel.h>
18#include <linux/module.h>
19
20#include "dfl.h"
21
22static int port_hdr_init(struct platform_device *pdev,
23 struct dfl_feature *feature)
24{
25 dev_dbg(&pdev->dev, "PORT HDR Init.\n");
26
27 return 0;
28}
29
30static void port_hdr_uinit(struct platform_device *pdev,
31 struct dfl_feature *feature)
32{
33 dev_dbg(&pdev->dev, "PORT HDR UInit.\n");
34}
35
36static const struct dfl_feature_ops port_hdr_ops = {
37 .init = port_hdr_init,
38 .uinit = port_hdr_uinit,
39};
40
41static struct dfl_feature_driver port_feature_drvs[] = {
42 {
43 .id = PORT_FEATURE_ID_HEADER,
44 .ops = &port_hdr_ops,
45 },
46 {
47 .ops = NULL,
48 }
49};
50
51static int afu_open(struct inode *inode, struct file *filp)
52{
53 struct platform_device *fdev = dfl_fpga_inode_to_feature_dev(inode);
54 struct dfl_feature_platform_data *pdata;
55 int ret;
56
57 pdata = dev_get_platdata(&fdev->dev);
58 if (WARN_ON(!pdata))
59 return -ENODEV;
60
61 ret = dfl_feature_dev_use_begin(pdata);
62 if (ret)
63 return ret;
64
65 dev_dbg(&fdev->dev, "Device File Open\n");
66 filp->private_data = fdev;
67
68 return 0;
69}
70
71static int afu_release(struct inode *inode, struct file *filp)
72{
73 struct platform_device *pdev = filp->private_data;
74 struct dfl_feature_platform_data *pdata;
75
76 dev_dbg(&pdev->dev, "Device File Release\n");
77
78 pdata = dev_get_platdata(&pdev->dev);
79
80 dfl_feature_dev_use_end(pdata);
81
82 return 0;
83}
84
85static long afu_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
86{
87 struct platform_device *pdev = filp->private_data;
88 struct dfl_feature_platform_data *pdata;
89 struct dfl_feature *f;
90 long ret;
91
92 dev_dbg(&pdev->dev, "%s cmd 0x%x\n", __func__, cmd);
93
94 pdata = dev_get_platdata(&pdev->dev);
95
96 switch (cmd) {
97 default:
98 /*
99 * Let sub-feature's ioctl function to handle the cmd
100 * Sub-feature's ioctl returns -ENODEV when cmd is not
101 * handled in this sub feature, and returns 0 and other
102 * error code if cmd is handled.
103 */
104 dfl_fpga_dev_for_each_feature(pdata, f)
105 if (f->ops && f->ops->ioctl) {
106 ret = f->ops->ioctl(pdev, f, cmd, arg);
107 if (ret != -ENODEV)
108 return ret;
109 }
110 }
111
112 return -EINVAL;
113}
114
115static const struct file_operations afu_fops = {
116 .owner = THIS_MODULE,
117 .open = afu_open,
118 .release = afu_release,
119 .unlocked_ioctl = afu_ioctl,
120};
121
122static int afu_probe(struct platform_device *pdev)
123{
124 int ret;
125
126 dev_dbg(&pdev->dev, "%s\n", __func__);
127
128 ret = dfl_fpga_dev_feature_init(pdev, port_feature_drvs);
129 if (ret)
130 return ret;
131
132 ret = dfl_fpga_dev_ops_register(pdev, &afu_fops, THIS_MODULE);
133 if (ret)
134 dfl_fpga_dev_feature_uinit(pdev);
135
136 return ret;
137}
138
139static int afu_remove(struct platform_device *pdev)
140{
141 dev_dbg(&pdev->dev, "%s\n", __func__);
142
143 dfl_fpga_dev_ops_unregister(pdev);
144 dfl_fpga_dev_feature_uinit(pdev);
145
146 return 0;
147}
148
149static struct platform_driver afu_driver = {
150 .driver = {
151 .name = DFL_FPGA_FEATURE_DEV_PORT,
152 },
153 .probe = afu_probe,
154 .remove = afu_remove,
155};
156
157module_platform_driver(afu_driver);
158
159MODULE_DESCRIPTION("FPGA Accelerated Function Unit driver");
160MODULE_AUTHOR("Intel Corporation");
161MODULE_LICENSE("GPL v2");
162MODULE_ALIAS("platform:dfl-port");