Re: [PATCH v2 01/13] intel_gna: add driver module

2021-04-07 Thread Maciej Kwapulinski


Andy Shevchenko  writes:

> On Wed, Mar 24, 2021 at 8:38 PM Maciej Kwapulinski
>  wrote:
>>

>> diff --git a/include/uapi/misc/intel/gna.h b/include/uapi/misc/intel/gna.h
>> new file mode 100644
>> index ..a7e435b74a0a
>> --- /dev/null
>> +++ b/include/uapi/misc/intel/gna.h
>> @@ -0,0 +1,155 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
>> +/* Copyright(c) 2017-2021 Intel Corporation */
>> +
>> +#ifndef _UAPI_GNA_H_
>> +#define _UAPI_GNA_H_
>> +
>> +#if defined(__cplusplus)
>> +extern "C" {
>> +#endif
>
>> +#include 
>> +#include 
>> +#include 
>
> Ordered?
>
What do You mean?

>>
..
>> +struct gna_compute_cfg {
>> +   __u32 layer_base;
>> +   __u32 layer_count;
>> +
>> +   /* List of GNA memory buffers */
>> +   __u64 buffers_ptr;
>> +   __u64 buffer_count;
>> +
>> +   __u8 active_list_on;
>> +   __u8 gna_mode;
>> +   __u8 hw_perf_encoding;
>> +   __u8 pad[5];
>> +};
>> +
>> +union gna_parameter {
>> +   struct {
>> +   __u64 id;
>> +   } in;
>> +
>> +   struct {
>> +   __u64 value;
>> +   } out;
>> +};
>> +
>> +union gna_memory_map {
>> +   struct {
>> +   __u64 address;
>> +   __u32 size;
>> +   __u32 pad;
>> +   } in;
>> +
>> +   struct {
>> +   __u64 memory_id;
>> +   } out;
>> +};
>> +
>> +union gna_compute {
>> +   struct {
>> +   struct gna_compute_cfg config;
>> +   } in;
>> +
>> +   struct {
>> +   __u64 request_id;
>> +   } out;
>> +};
>> +
>> +union gna_wait {
>> +   struct {
>> +   __u64 request_id;
>> +   __u32 timeout;
>> +   __u32 pad;
>> +   } in;
>> +
>> +   struct {
>> +   __u32 hw_status;
>> +   __u32 pad;
>> +   struct gna_drv_perf drv_perf;
>> +   struct gna_hw_perf hw_perf;
>> +   } out;
>> +};
>
> For all unions:
> How do you know which branch is used (out, in)? What field and where
> in the ABI points to that?

each of the unions above plays the role of in/out argument to its
corresponding ioctl call.

'in' part is used when ioctl() is called by client (userland
application) - data is written by app.

'out' part is read by app on exit from ioctl(), but only when ioctl()
retuns 0.

do You suggest adding the comment to gna.h for the above?

> .


Re: [PATCH v2 02/13] intel_gna: add component of hardware operation

2021-04-06 Thread Maciej Kwapulinski


Andy Shevchenko  writes:

> On Wed, Mar 24, 2021 at 8:38 PM Maciej Kwapulinski
>  wrote:
>> +#define gna_reg_write(addr, offset, value) writel((value), (addr) + 
>> (offset))
>
> No point And make them functions, not macros.
>
>> +
>> +#endif // __GNA_HW_H__
>> --
>> 2.28.0
>>

Andy, Thank You for all Your comments on these two patches.

I'm starting to work with them. Just as with v1 patch series, I'll
get back to You in case of any questions
Regards,
Maciej


[PATCH v2 12/13] intel_gna: add a 'misc' device

2021-03-24 Thread Maciej Kwapulinski
The new 'misc' device is the node for applications in user space to
interact with the driver.

Signed-off-by: Maciej Kwapulinski 
Tested-by: Savo Novakovic 
---
 drivers/misc/intel/gna/gna_device.c  | 69 ++--
 drivers/misc/intel/gna/gna_device.h  |  6 +++
 drivers/misc/intel/gna/gna_driver.c  |  2 +
 drivers/misc/intel/gna/gna_driver.h  |  2 +
 drivers/misc/intel/gna/gna_hw.c  | 28 +--
 drivers/misc/intel/gna/gna_ioctl.c   | 36 +++
 drivers/misc/intel/gna/gna_mem.c | 32 ++---
 drivers/misc/intel/gna/gna_request.c | 32 ++---
 drivers/misc/intel/gna/gna_score.c   | 28 +--
 9 files changed, 154 insertions(+), 81 deletions(-)

diff --git a/drivers/misc/intel/gna/gna_device.c 
b/drivers/misc/intel/gna/gna_device.c
index d8e1d4b8a9eb..3f7f4c07d1a1 100644
--- a/drivers/misc/intel/gna/gna_device.c
+++ b/drivers/misc/intel/gna/gna_device.c
@@ -91,9 +91,57 @@ const struct pci_device_id gna_pci_ids[] = {
 
 MODULE_DEVICE_TABLE(pci, gna_pci_ids);
 
+static int gna_open(struct inode *inode, struct file *f)
+{
+   return -EPERM;
+}
+
+static const struct file_operations gna_file_ops = {
+   .owner  =   THIS_MODULE,
+   .open   =   gna_open,
+};
+
+static void gna_dev_release(struct gna_private *gna_priv)
+{
+   misc_deregister(&gna_priv->misc);
+   kfree(gna_priv->misc.name);
+   gna_priv->misc.name = NULL;
+}
+
+static int gna_dev_create(struct gna_private *gna_priv, char *gna_name)
+{
+   struct pci_dev *pcidev;
+   int ret;
+
+   pcidev = gna_priv->pdev;
+
+   gna_priv->misc.minor = MISC_DYNAMIC_MINOR;
+   gna_priv->misc.name = kasprintf(GFP_KERNEL, "%s", gna_name);
+   gna_priv->misc.fops = &gna_file_ops;
+   gna_priv->misc.parent = &pcidev->dev;
+   gna_priv->misc.mode = 0666;
+
+   dev_dbg(&pcidev->dev, "registering device: %s\n",
+   gna_priv->misc.name);
+
+   ret = misc_register(&gna_priv->misc);
+   if (ret) {
+   dev_err(&pcidev->dev, "misc_register %s failed: %d\n",
+   gna_name, ret);
+   misc_deregister(&gna_priv->misc);
+   kfree(gna_priv->misc.name);
+   gna_priv->misc.name = NULL;
+   }
+
+   return ret;
+}
+
+
 static int gna_dev_init(struct gna_private *gna_priv, struct pci_dev *pcidev,
const struct pci_device_id *pci_id)
 {
+   // strlen(GNA_DV_NAME) + max minor number.
+   char gna_name[sizeof(GNA_DV_NAME) + sizeof("255") + 1];
u32 bld_reg;
int ret;
 
@@ -104,6 +152,8 @@ static int gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
gna_priv->info = *(struct gna_drv_info *)pci_id->driver_data;
gna_priv->drv_priv = &gna_drv_priv;
 
+   gna_priv->index = atomic_inc_return(&gna_priv->drv_priv->dev_last_idx);
+
bld_reg = gna_reg_read(gna_priv->bar0_base, GNA_MMIO_IBUFFS);
gna_priv->hw_info.in_buf_s = bld_reg & GENMASK(7, 0);
 
@@ -134,15 +184,26 @@ static int gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
 
init_waitqueue_head(&gna_priv->dev_busy_waitq);
 
-   gna_priv->request_wq = create_singlethread_workqueue(GNA_DV_NAME);
+   snprintf(gna_name, sizeof(gna_name), "%s%d", GNA_DV_NAME, 
gna_priv->index);
+
+   gna_priv->request_wq = create_singlethread_workqueue(gna_name);
if (!gna_priv->request_wq) {
-   dev_err(&pcidev->dev, "could not create %s workqueue\n", 
GNA_DV_NAME);
+   dev_err(&pcidev->dev, "could not create %s workqueue\n", 
gna_name);
ret = -EFAULT;
goto err_pci_drvdata_unset;
}
 
+   ret = gna_dev_create(gna_priv, gna_name);
+   if (ret) {
+   dev_err(&pcidev->dev, "could not create %s device\n", 
GNA_DV_NAME);
+   goto err_del_wq;
+   }
+
return 0;
 
+err_del_wq:
+   destroy_workqueue(gna_priv->request_wq);
+
 err_pci_drvdata_unset:
pci_set_drvdata(pcidev, NULL);
 
@@ -151,6 +212,8 @@ static int gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
 
 static void gna_dev_deinit(struct gna_private *gna_priv)
 {
+   gna_dev_release(gna_priv);
+
flush_workqueue(gna_priv->request_wq);
destroy_workqueue(gna_priv->request_wq);
 
@@ -300,7 +363,7 @@ int gna_getparam(struct gna_private *gna_priv, union 
gna_parameter *param)
param->out.value = gna_device_type_by_hwid(gna_priv->info.hwid);
break;
default:
-   dev_err(&gna_priv->pdev->dev, "unknown parameter id %llu\n", 
param->in.id);
+   dev_err(gna_p

[PATCH v2 13/13] intel_gna: add file operations to a 'misc' device

2021-03-24 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/intel/gna/gna_device.c | 60 -
 1 file changed, 59 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/intel/gna/gna_device.c 
b/drivers/misc/intel/gna/gna_device.c
index 3f7f4c07d1a1..3f74a0a3bd30 100644
--- a/drivers/misc/intel/gna/gna_device.c
+++ b/drivers/misc/intel/gna/gna_device.c
@@ -93,12 +93,70 @@ MODULE_DEVICE_TABLE(pci, gna_pci_ids);
 
 static int gna_open(struct inode *inode, struct file *f)
 {
-   return -EPERM;
+   struct gna_file_private *file_priv;
+   struct gna_private *gna_priv;
+
+   gna_priv = container_of(f->private_data, struct gna_private, misc);
+
+   file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
+   if (!file_priv)
+   return -ENOMEM;
+
+   file_priv->fd = f;
+   file_priv->gna_priv = gna_priv;
+
+   mutex_init(&file_priv->memlist_lock);
+   INIT_LIST_HEAD(&file_priv->memory_list);
+
+   mutex_lock(&gna_priv->flist_lock);
+   list_add_tail(&file_priv->flist, &gna_priv->file_list);
+   mutex_unlock(&gna_priv->flist_lock);
+
+   f->private_data = file_priv;
+
+   return 0;
+}
+
+static int gna_release(struct inode *inode, struct file *f)
+{
+   struct gna_file_private *iter_file, *temp_file;
+   struct gna_memory_object *iter_mo, *temp_mo;
+   struct gna_file_private *file_priv;
+   struct gna_private *gna_priv;
+
+   /* free all memory objects created by that file */
+   file_priv = (struct gna_file_private *)f->private_data;
+   gna_priv = file_priv->gna_priv;
+
+   mutex_lock(&file_priv->memlist_lock);
+   list_for_each_entry_safe(iter_mo, temp_mo, &file_priv->memory_list, 
file_mem_list) {
+   queue_work(gna_priv->request_wq, &iter_mo->work);
+   wait_event(iter_mo->waitq, true);
+   gna_memory_free(gna_priv, iter_mo);
+   }
+   mutex_unlock(&file_priv->memlist_lock);
+
+   gna_delete_file_requests(f, gna_priv);
+
+   mutex_lock(&gna_priv->flist_lock);
+   list_for_each_entry_safe(iter_file, temp_file, &gna_priv->file_list, 
flist) {
+   if (iter_file->fd == f) {
+   list_del(&iter_file->flist);
+   f->private_data = NULL;
+   kfree(iter_file);
+   break;
+   }
+   }
+   mutex_unlock(&gna_priv->flist_lock);
+
+   return 0;
 }
 
 static const struct file_operations gna_file_ops = {
.owner  =   THIS_MODULE,
.open   =   gna_open,
+   .release=   gna_release,
+   .unlocked_ioctl =   gna_ioctl,
 };
 
 static void gna_dev_release(struct gna_private *gna_priv)
-- 
2.28.0



[PATCH v2 09/13] intel_gna: add a work queue to process scoring requests

2021-03-24 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

The new workqueue is responsible to process the list of requests
in a FIFO manner. It waits for the hardware to complete on every
request until it is woken up by an interrupt that will be addressed
in following changes.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Anisha Dattatraya Kulkarni 

Signed-off-by: Anisha Dattatraya Kulkarni 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/intel/gna/gna_device.c  |  12 +++
 drivers/misc/intel/gna/gna_device.h  |   8 ++
 drivers/misc/intel/gna/gna_request.c | 116 +++
 drivers/misc/intel/gna/gna_request.h |   1 +
 4 files changed, 137 insertions(+)

diff --git a/drivers/misc/intel/gna/gna_device.c 
b/drivers/misc/intel/gna/gna_device.c
index e1a1f3142684..47f238677bc9 100644
--- a/drivers/misc/intel/gna/gna_device.c
+++ b/drivers/misc/intel/gna/gna_device.c
@@ -127,6 +127,15 @@ static int gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
mutex_init(&gna_priv->reqlist_lock);
INIT_LIST_HEAD(&gna_priv->request_list);
 
+   init_waitqueue_head(&gna_priv->dev_busy_waitq);
+
+   gna_priv->request_wq = create_singlethread_workqueue(GNA_DV_NAME);
+   if (!gna_priv->request_wq) {
+   dev_err(&pcidev->dev, "could not create %s workqueue\n", 
GNA_DV_NAME);
+   ret = -EFAULT;
+   goto err_pci_drvdata_unset;
+   }
+
return 0;
 
 err_pci_drvdata_unset:
@@ -137,6 +146,9 @@ static int gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
 
 static void gna_dev_deinit(struct gna_private *gna_priv)
 {
+   flush_workqueue(gna_priv->request_wq);
+   destroy_workqueue(gna_priv->request_wq);
+
idr_destroy(&gna_priv->memory_idr);
gna_mmu_free(gna_priv);
 }
diff --git a/drivers/misc/intel/gna/gna_device.h 
b/drivers/misc/intel/gna/gna_device.h
index 878a972ab5b3..23eae806f96d 100644
--- a/drivers/misc/intel/gna/gna_device.h
+++ b/drivers/misc/intel/gna/gna_device.h
@@ -14,6 +14,7 @@
 #include "gna_mem.h"
 
 struct gna_driver_private;
+struct workqueue_struct;
 struct device;
 
 struct gna_drv_info {
@@ -42,6 +43,8 @@ struct gna_private {
/* pdev->dev */
struct device *parent;
 
+   u32 hw_status;
+
/* device related resources */
void __iomem *bar0_base;
struct gna_drv_info info;
@@ -50,9 +53,14 @@ struct gna_private {
struct gna_mmu_object mmu;
struct mutex mmu_lock;
 
+   /* if true, then gna device is processing */
+   bool dev_busy;
+   struct wait_queue_head dev_busy_waitq;
+
struct list_head request_list;
/* protects request_list */
struct mutex reqlist_lock;
+   struct workqueue_struct *request_wq;
atomic_t request_count;
 
/* memory objects' store */
diff --git a/drivers/misc/intel/gna/gna_request.c 
b/drivers/misc/intel/gna/gna_request.c
index 383871eaebab..ba9bac358270 100644
--- a/drivers/misc/intel/gna/gna_request.c
+++ b/drivers/misc/intel/gna/gna_request.c
@@ -8,7 +8,118 @@
 
 #include "gna_device.h"
 #include "gna_driver.h"
+#include "gna_hw.h"
 #include "gna_request.h"
+#include "gna_score.h"
+
+static void gna_request_update_status(struct gna_request *score_request)
+{
+   struct gna_private *gna_priv = score_request->gna_priv;
+   void __iomem *addr = gna_priv->bar0_base;
+   /* The gna_priv's hw_status should be updated first */
+   u32 hw_status = gna_priv->hw_status;
+   u32 stall_cycles;
+   u32 total_cycles;
+
+   /* Technically, the time stamp can be a bit later than
+* when the hw actually completed scoring. Here we just
+* do our best in a deferred work, unless we want to
+* tax isr for a more accurate record.
+*/
+   score_request->drv_perf.hw_completed = ktime_get_ns();
+
+   score_request->hw_status = hw_status;
+
+   score_request->status = gna_parse_hw_status(gna_priv, hw_status);
+
+   if (gna_hw_perf_enabled(gna_priv)) {
+   if (hw_status & GNA_STS_STATISTICS_VALID) {
+   total_cycles = gna_reg_read(addr, GNA_MMIO_PTC);
+   stall_cycles = gna_reg_read(addr, GNA_MMIO_PSC);
+   score_request->hw_perf.total = total_cycles;
+   score_request->hw_perf.stall = stall_cycles;
+   } else
+   dev_warn(&gna_priv->pdev->dev, "GNA statistics 
missing\n");
+   }
+   if (unlikely(hw_status & GNA_ERROR))
+   gna_print_error_status(gna_priv, hw_status);
+}
+
+static void gna_request_process(struct work_struct *work)
+{
+   struct gna_request *score_

[PATCH v2 11/13] intel_gna: add ioctl handler

2021-03-24 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Add ioctl handler into GNA driver.
The ioctl interface provides the ability to do the following:
 - Map and unmap memory buffers for GNA computation requests.
 - Retrieve capabilities of the underlying GNA IP.
 - Submit GNA computation requests.
 - Request notification of scoring completion.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/intel/gna/Kbuild   |   2 +-
 drivers/misc/intel/gna/gna_device.c |  44 +
 drivers/misc/intel/gna/gna_device.h |   3 +
 drivers/misc/intel/gna/gna_ioctl.c  | 249 
 drivers/misc/intel/gna/gna_ioctl.h  |  11 ++
 5 files changed, 308 insertions(+), 1 deletion(-)
 create mode 100644 drivers/misc/intel/gna/gna_ioctl.c
 create mode 100644 drivers/misc/intel/gna/gna_ioctl.h

diff --git a/drivers/misc/intel/gna/Kbuild b/drivers/misc/intel/gna/Kbuild
index 9dac467839c9..879cc76204c3 100644
--- a/drivers/misc/intel/gna/Kbuild
+++ b/drivers/misc/intel/gna/Kbuild
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-intel_gna-y := gna_device.o gna_driver.o gna_mem.o gna_request.o gna_score.o 
gna_hw.o
+intel_gna-y := gna_device.o gna_driver.o gna_mem.o gna_ioctl.o gna_request.o 
gna_score.o gna_hw.o
 
 obj-$(CONFIG_INTEL_GNA) += intel_gna.o
diff --git a/drivers/misc/intel/gna/gna_device.c 
b/drivers/misc/intel/gna/gna_device.c
index 67917106a262..d8e1d4b8a9eb 100644
--- a/drivers/misc/intel/gna/gna_device.c
+++ b/drivers/misc/intel/gna/gna_device.c
@@ -5,8 +5,12 @@
 #include 
 #include 
 
+#include 
+
 #include "gna_device.h"
 #include "gna_driver.h"
+#include "gna_hw.h"
+#include "gna_ioctl.h"
 #include "gna_request.h"
 
 #define GNA_DEV_HWID_CNL   0x5A11
@@ -262,3 +266,43 @@ void gna_remove(struct pci_dev *pcidev)
 
pci_free_irq_vectors(pcidev);
 }
+
+static u32 gna_device_type_by_hwid(u32 hwid)
+{
+   switch (hwid) {
+   case GNA_DEV_HWID_CNL:
+   return GNA_DEV_TYPE_0_9;
+   case GNA_DEV_HWID_GLK:
+   case GNA_DEV_HWID_EHL:
+   case GNA_DEV_HWID_ICL:
+   return GNA_DEV_TYPE_1_0;
+   case GNA_DEV_HWID_JSL:
+   case GNA_DEV_HWID_TGL:
+   return GNA_DEV_TYPE_2_0;
+   default:
+   return 0;
+   }
+}
+
+int gna_getparam(struct gna_private *gna_priv, union gna_parameter *param)
+{
+   switch (param->in.id) {
+   case GNA_PARAM_DEVICE_ID:
+   param->out.value = gna_priv->info.hwid;
+   break;
+   case GNA_PARAM_RECOVERY_TIMEOUT:
+   param->out.value = 
jiffies_to_msecs(gna_priv->drv_priv->recovery_timeout_jiffies) / 1000;
+   break;
+   case GNA_PARAM_INPUT_BUFFER_S:
+   param->out.value = gna_priv->hw_info.in_buf_s;
+   break;
+   case GNA_PARAM_DEVICE_TYPE:
+   param->out.value = gna_device_type_by_hwid(gna_priv->info.hwid);
+   break;
+   default:
+   dev_err(&gna_priv->pdev->dev, "unknown parameter id %llu\n", 
param->in.id);
+   return -EINVAL;
+   }
+
+   return 0;
+}
diff --git a/drivers/misc/intel/gna/gna_device.h 
b/drivers/misc/intel/gna/gna_device.h
index 7ba25f6f8492..aa7fadcf93b1 100644
--- a/drivers/misc/intel/gna/gna_device.h
+++ b/drivers/misc/intel/gna/gna_device.h
@@ -15,6 +15,7 @@
 
 struct gna_driver_private;
 struct workqueue_struct;
+union gna_parameter;
 struct device;
 
 struct gna_drv_info {
@@ -77,4 +78,6 @@ int gna_probe(struct pci_dev *dev, const struct pci_device_id 
*id);
 
 void gna_remove(struct pci_dev *dev);
 
+int gna_getparam(struct gna_private *gna_priv, union gna_parameter *param);
+
 #endif /* __GNA_DEVICE_H__ */
diff --git a/drivers/misc/intel/gna/gna_ioctl.c 
b/drivers/misc/intel/gna/gna_ioctl.c
new file mode 100644
index ..79ce3aeb27cf
--- /dev/null
+++ b/drivers/misc/intel/gna/gna_ioctl.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright(c) 2017-2021 Intel Corporation
+
+#include 
+
+#include 
+
+#include "gna_driver.h"
+#include "gna_device.h"
+#include "gna_ioctl.h"
+#include "gna_mem.h"
+#include "gna_request.h"
+#include "gna_score.h"
+
+static int gna_ioctl_score(struct gna_file_private *file_priv, void __user 
*argptr)
+{
+   union gna_compute score_args;
+   struct gna_private *gna_priv;
+   u64 request_id;
+   int ret;
+
+   gna_priv = file_priv->gna_priv;
+
+   if (copy_from_user(&score_args, argptr, sizeof(score_args))) {
+   dev_err(&gna_priv->pdev->dev, "could not copy score ioctl 
config from user\n");
+   return -EFAULT;
+   }
+
+   ret = gna_validate_score_config(&sc

[PATCH v2 10/13] intel_gna: add interrupt handler

2021-03-24 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

An interrupt is generated by the hardware when a scoring job is
done. The interrupt handler wakes up the work queue to resume
the processing on the current request.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/intel/gna/gna_device.c | 45 -
 drivers/misc/intel/gna/gna_device.h |  2 ++
 drivers/misc/intel/gna/gna_hw.h |  1 -
 3 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/intel/gna/gna_device.c 
b/drivers/misc/intel/gna/gna_device.c
index 47f238677bc9..67917106a262 100644
--- a/drivers/misc/intel/gna/gna_device.c
+++ b/drivers/misc/intel/gna/gna_device.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 // Copyright(c) 2017-2021 Intel Corporation
 
+#include 
 #include 
 #include 
 
@@ -153,6 +154,16 @@ static void gna_dev_deinit(struct gna_private *gna_priv)
gna_mmu_free(gna_priv);
 }
 
+static irqreturn_t gna_interrupt(int irq, void *priv)
+{
+   struct gna_private *gna_priv;
+
+   gna_priv = (struct gna_private *)priv;
+   gna_priv->dev_busy = false;
+   wake_up(&gna_priv->dev_busy_waitq);
+   return IRQ_HANDLED;
+}
+
 int gna_probe(struct pci_dev *pcidev, const struct pci_device_id *pci_id)
 {
struct gna_private *gna_priv;
@@ -201,14 +212,42 @@ int gna_probe(struct pci_dev *pcidev, const struct 
pci_device_id *pci_id)
 
pci_set_master(pcidev);
 
+   ret = pci_alloc_irq_vectors(pcidev, 1, 1, PCI_IRQ_ALL_TYPES);
+   if (ret < 0)
+   return ret;
+
+   gna_priv->irq = pci_irq_vector(pcidev, 0);
+   if (unlikely(gna_priv->irq < 0)) {
+   dev_err(&pcidev->dev, "could not obtain irq number\n");
+   ret = -EIO;
+   goto err_free_irq_vector;
+   }
+
+   ret = request_irq(gna_priv->irq, gna_interrupt,
+   IRQF_SHARED, GNA_DV_NAME, gna_priv);
+
+   if (ret) {
+   dev_err(&pcidev->dev, "could not register for interrupt\n");
+   goto err_free_irq_vector;
+   }
+
+   dev_dbg(&pcidev->dev, "irq num %d\n", gna_priv->irq);
+
ret = gna_dev_init(gna_priv, pcidev, pci_id);
if (ret) {
dev_err(&pcidev->dev, "could not initialize %s device\n", 
GNA_DV_NAME);
-   return ret;
+   goto err_free_irq;
}
 
 
return 0;
+
+err_free_irq:
+   free_irq(gna_priv->irq, gna_priv);
+err_free_irq_vector:
+   pci_free_irq_vectors(pcidev);
+
+   return ret;
 }
 
 void gna_remove(struct pci_dev *pcidev)
@@ -217,5 +256,9 @@ void gna_remove(struct pci_dev *pcidev)
 
gna_priv = pci_get_drvdata(pcidev);
 
+   free_irq(gna_priv->irq, gna_priv);
+
gna_dev_deinit(gna_priv);
+
+   pci_free_irq_vectors(pcidev);
 }
diff --git a/drivers/misc/intel/gna/gna_device.h 
b/drivers/misc/intel/gna/gna_device.h
index 23eae806f96d..7ba25f6f8492 100644
--- a/drivers/misc/intel/gna/gna_device.h
+++ b/drivers/misc/intel/gna/gna_device.h
@@ -43,6 +43,8 @@ struct gna_private {
/* pdev->dev */
struct device *parent;
 
+   int irq;
+   /* hardware status set by interrupt handler */
u32 hw_status;
 
/* device related resources */
diff --git a/drivers/misc/intel/gna/gna_hw.h b/drivers/misc/intel/gna/gna_hw.h
index dd682f95094e..904e551f4f17 100644
--- a/drivers/misc/intel/gna/gna_hw.h
+++ b/drivers/misc/intel/gna/gna_hw.h
@@ -6,7 +6,6 @@
 
 #include 
 #include 
-#include 
 #include 
 
 /* GNA MMIO registers */
-- 
2.28.0



[PATCH v2 07/13] intel_gna: add request component

2021-03-24 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

The scoring work submitted to the GNA driver is implemented as a
list of requests that will be processed by the hardware.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Anisha Dattatraya Kulkarni 

Signed-off-by: Anisha Dattatraya Kulkarni 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/intel/gna/Kbuild|   2 +-
 drivers/misc/intel/gna/gna_device.c  |   6 +
 drivers/misc/intel/gna/gna_device.h  |   6 +
 drivers/misc/intel/gna/gna_mem.c |   3 +
 drivers/misc/intel/gna/gna_request.c | 347 +++
 drivers/misc/intel/gna/gna_request.h |  61 +
 6 files changed, 424 insertions(+), 1 deletion(-)
 create mode 100644 drivers/misc/intel/gna/gna_request.c
 create mode 100644 drivers/misc/intel/gna/gna_request.h

diff --git a/drivers/misc/intel/gna/Kbuild b/drivers/misc/intel/gna/Kbuild
index e5cd953d83b2..5dbbd3f0a543 100644
--- a/drivers/misc/intel/gna/Kbuild
+++ b/drivers/misc/intel/gna/Kbuild
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-intel_gna-y := gna_device.o gna_driver.o gna_mem.o gna_hw.o
+intel_gna-y := gna_device.o gna_driver.o gna_mem.o gna_request.o gna_hw.o
 
 obj-$(CONFIG_INTEL_GNA) += intel_gna.o
diff --git a/drivers/misc/intel/gna/gna_device.c 
b/drivers/misc/intel/gna/gna_device.c
index 9838d003426f..14ce24fd18ff 100644
--- a/drivers/misc/intel/gna/gna_device.c
+++ b/drivers/misc/intel/gna/gna_device.c
@@ -6,6 +6,7 @@
 
 #include "gna_device.h"
 #include "gna_driver.h"
+#include "gna_request.h"
 
 #define GNA_DEV_HWID_CNL   0x5A11
 #define GNA_DEV_HWID_EHL   0x4511
@@ -118,6 +119,11 @@ static int gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
idr_init(&gna_priv->memory_idr);
mutex_init(&gna_priv->memidr_lock);
 
+   atomic_set(&gna_priv->request_count, 0);
+
+   mutex_init(&gna_priv->reqlist_lock);
+   INIT_LIST_HEAD(&gna_priv->request_list);
+
return 0;
 
 err_pci_drvdata_unset:
diff --git a/drivers/misc/intel/gna/gna_device.h 
b/drivers/misc/intel/gna/gna_device.h
index 799788d70033..b54d0ea9b9ef 100644
--- a/drivers/misc/intel/gna/gna_device.h
+++ b/drivers/misc/intel/gna/gna_device.h
@@ -6,6 +6,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -44,6 +45,11 @@ struct gna_private {
struct gna_mmu_object mmu;
struct mutex mmu_lock;
 
+   struct list_head request_list;
+   /* protects request_list */
+   struct mutex reqlist_lock;
+   atomic_t request_count;
+
/* memory objects' store */
struct idr memory_idr;
/* lock protecting memory_idr */
diff --git a/drivers/misc/intel/gna/gna_mem.c b/drivers/misc/intel/gna/gna_mem.c
index f3828b503ff6..ce1691d68edb 100644
--- a/drivers/misc/intel/gna/gna_mem.c
+++ b/drivers/misc/intel/gna/gna_mem.c
@@ -17,6 +17,7 @@
 #include "gna_device.h"
 #include "gna_driver.h"
 #include "gna_mem.h"
+#include "gna_request.h"
 
 static void gna_mmu_init(struct gna_private *gna_priv)
 {
@@ -392,6 +393,8 @@ static void gna_memory_release(struct work_struct *work)
 
mo = container_of(work, struct gna_memory_object, work);
 
+   gna_delete_memory_requests(mo->memory_id, mo->gna_priv);
+
mo->user_ptr = NULL;
 
wake_up_interruptible(&mo->waitq);
diff --git a/drivers/misc/intel/gna/gna_request.c 
b/drivers/misc/intel/gna/gna_request.c
new file mode 100644
index ..383871eaebab
--- /dev/null
+++ b/drivers/misc/intel/gna/gna_request.c
@@ -0,0 +1,347 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright(c) 2017-2021 Intel Corporation
+
+#include 
+#include 
+#include 
+#include 
+
+#include "gna_device.h"
+#include "gna_driver.h"
+#include "gna_request.h"
+
+static struct gna_request *gna_request_create(struct gna_file_private 
*file_priv,
+  struct gna_compute_cfg *compute_cfg)
+{
+   struct gna_request *score_request;
+   struct gna_private *gna_priv;
+
+   gna_priv = file_priv->gna_priv;
+   if (IS_ERR(gna_priv))
+   return NULL;
+
+   score_request = kzalloc(sizeof(*score_request), GFP_KERNEL);
+   if (!score_request)
+   return NULL;
+   kref_init(&score_request->refcount);
+
+   dev_dbg(&gna_priv->pdev->dev, "layer_base %d layer_count %d\n",
+   compute_cfg->layer_base, compute_cfg->layer_count);
+
+   score_request->request_id = atomic_inc_return(&gna_priv->request_count);
+   score_request->compute_cfg = *compute_cfg;
+   score_request->fd = file_priv->fd;
+   score_request->gna_priv = gna_priv;
+   score_request->state = NEW;
+   init_waitqueue_he

[PATCH v2 06/13] intel_gna: add hardware ids

2021-03-24 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Add PCI ids of Intel(R) Gaussian & Neural Accelerator on supported
platforms.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/intel/gna/gna_device.c | 76 +
 drivers/misc/intel/gna/gna_device.h |  5 +-
 drivers/misc/intel/gna/gna_driver.c |  1 +
 3 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/intel/gna/gna_device.c 
b/drivers/misc/intel/gna/gna_device.c
index 3d559f22ee93..9838d003426f 100644
--- a/drivers/misc/intel/gna/gna_device.c
+++ b/drivers/misc/intel/gna/gna_device.c
@@ -7,8 +7,84 @@
 #include "gna_device.h"
 #include "gna_driver.h"
 
+#define GNA_DEV_HWID_CNL   0x5A11
+#define GNA_DEV_HWID_EHL   0x4511
+#define GNA_DEV_HWID_GLK   0x3190
+#define GNA_DEV_HWID_ICL   0x8A11
+#define GNA_DEV_HWID_JSL   0x4E11
+#define GNA_DEV_HWID_TGL   0x9A11
+
 #define GNA_BAR0   0
 
+#define GNA_FEATURES \
+   .max_hw_mem = 256 * 1024 * 1024, \
+   .num_pagetables = 64, \
+   .num_page_entries = PAGE_SIZE / sizeof(u32), \
+   /* desc_info all in bytes */ \
+   .desc_info = { \
+   .rsvd_size = 256, \
+   .cfg_size = 256, \
+   .desc_size = 784, \
+   .mmu_info = { \
+   .vamax_size = 4, \
+   .rsvd_size = 12, \
+   .pd_size = 4 * 64, \
+   }, \
+   }
+
+#define GNA_GEN1_FEATURES \
+   GNA_FEATURES, \
+   .max_layer_count = 1024
+
+#define GNA_GEN2_FEATURES \
+   GNA_FEATURES, \
+   .max_layer_count = 4096
+
+static const struct gna_drv_info cnl_drv_info = {
+   .hwid = GNA_DEV_HWID_CNL,
+   GNA_GEN1_FEATURES
+};
+
+static const struct gna_drv_info glk_drv_info = {
+   .hwid = GNA_DEV_HWID_GLK,
+   GNA_GEN1_FEATURES
+};
+
+static const struct gna_drv_info ehl_drv_info = {
+   .hwid = GNA_DEV_HWID_EHL,
+   GNA_GEN1_FEATURES
+};
+
+static const struct gna_drv_info icl_drv_info = {
+   .hwid = GNA_DEV_HWID_ICL,
+   GNA_GEN1_FEATURES
+};
+
+static const struct gna_drv_info jsl_drv_info = {
+   .hwid = GNA_DEV_HWID_JSL,
+   GNA_GEN2_FEATURES
+};
+
+static const struct gna_drv_info tgl_drv_info = {
+   .hwid = GNA_DEV_HWID_TGL,
+   GNA_GEN2_FEATURES
+};
+
+#define INTEL_GNA_DEVICE(hwid, info) \
+   { PCI_VDEVICE(INTEL, hwid), (kernel_ulong_t)(info) }
+
+const struct pci_device_id gna_pci_ids[] = {
+   INTEL_GNA_DEVICE(GNA_DEV_HWID_CNL, &cnl_drv_info),
+   INTEL_GNA_DEVICE(GNA_DEV_HWID_EHL, &ehl_drv_info),
+   INTEL_GNA_DEVICE(GNA_DEV_HWID_GLK, &glk_drv_info),
+   INTEL_GNA_DEVICE(GNA_DEV_HWID_ICL, &icl_drv_info),
+   INTEL_GNA_DEVICE(GNA_DEV_HWID_JSL, &jsl_drv_info),
+   INTEL_GNA_DEVICE(GNA_DEV_HWID_TGL, &tgl_drv_info),
+   { }
+};
+
+MODULE_DEVICE_TABLE(pci, gna_pci_ids);
+
 static int gna_dev_init(struct gna_private *gna_priv, struct pci_dev *pcidev,
const struct pci_device_id *pci_id)
 {
diff --git a/drivers/misc/intel/gna/gna_device.h 
b/drivers/misc/intel/gna/gna_device.h
index a5657ab9f62a..799788d70033 100644
--- a/drivers/misc/intel/gna/gna_device.h
+++ b/drivers/misc/intel/gna/gna_device.h
@@ -7,13 +7,12 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "gna_hw.h"
 #include "gna_mem.h"
 
 struct gna_driver_private;
-struct pci_device_id;
-struct pci_dev;
 struct device;
 
 struct gna_drv_info {
@@ -51,6 +50,8 @@ struct gna_private {
struct mutex memidr_lock;
 };
 
+extern const struct pci_device_id gna_pci_ids[];
+
 int gna_probe(struct pci_dev *dev, const struct pci_device_id *id);
 
 void gna_remove(struct pci_dev *dev);
diff --git a/drivers/misc/intel/gna/gna_driver.c 
b/drivers/misc/intel/gna/gna_driver.c
index 79f4d8522bdc..a8f69a970f7a 100644
--- a/drivers/misc/intel/gna/gna_driver.c
+++ b/drivers/misc/intel/gna/gna_driver.c
@@ -16,6 +16,7 @@ struct gna_driver_private gna_drv_priv;
 
 static struct pci_driver gna_driver = {
.name = GNA_DV_NAME,
+   .id_table = gna_pci_ids,
.probe = gna_probe,
.remove = gna_remove,
 };
-- 
2.28.0



[PATCH v2 05/13] intel_gna: initialize mmu

2021-03-24 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Setup mmu in the driver with a new memory component.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-Developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/intel/gna/gna_device.c | 29 +++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/intel/gna/gna_device.c 
b/drivers/misc/intel/gna/gna_device.c
index 25137d0ac519..3d559f22ee93 100644
--- a/drivers/misc/intel/gna/gna_device.c
+++ b/drivers/misc/intel/gna/gna_device.c
@@ -9,10 +9,11 @@
 
 #define GNA_BAR0   0
 
-static void gna_dev_init(struct gna_private *gna_priv, struct pci_dev *pcidev,
+static int gna_dev_init(struct gna_private *gna_priv, struct pci_dev *pcidev,
const struct pci_device_id *pci_id)
 {
u32 bld_reg;
+   int ret;
 
pci_set_drvdata(pcidev, gna_priv);
 
@@ -24,10 +25,29 @@ static void gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
bld_reg = gna_reg_read(gna_priv->bar0_base, GNA_MMIO_IBUFFS);
gna_priv->hw_info.in_buf_s = bld_reg & GENMASK(7, 0);
 
+   if (gna_mmu_alloc(gna_priv)) {
+   dev_err(&pcidev->dev, "mmu allocation failed\n");
+   ret = -EFAULT;
+   goto err_pci_drvdata_unset;
+
+   }
+   dev_dbg(&pcidev->dev, "maximum memory size %llu num pd %d\n",
+   gna_priv->info.max_hw_mem, gna_priv->info.num_pagetables);
+   dev_dbg(&pcidev->dev, "desc rsvd size %d mmu vamax size %d\n",
+   gna_priv->info.desc_info.rsvd_size,
+   gna_priv->info.desc_info.mmu_info.vamax_size);
+
mutex_init(&gna_priv->mmu_lock);
 
idr_init(&gna_priv->memory_idr);
mutex_init(&gna_priv->memidr_lock);
+
+   return 0;
+
+err_pci_drvdata_unset:
+   pci_set_drvdata(pcidev, NULL);
+
+   return ret;
 }
 
 static void gna_dev_deinit(struct gna_private *gna_priv)
@@ -84,7 +104,12 @@ int gna_probe(struct pci_dev *pcidev, const struct 
pci_device_id *pci_id)
 
pci_set_master(pcidev);
 
-   gna_dev_init(gna_priv, pcidev, pci_id);
+   ret = gna_dev_init(gna_priv, pcidev, pci_id);
+   if (ret) {
+   dev_err(&pcidev->dev, "could not initialize %s device\n", 
GNA_DV_NAME);
+   return ret;
+   }
+
 
return 0;
 }
-- 
2.28.0



[PATCH v2 08/13] intel_gna: implement scoring

2021-03-24 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Add a new component for scoring logic such as configuring and kicking
off the hardware.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/intel/gna/Kbuild   |   2 +-
 drivers/misc/intel/gna/gna_device.c |   3 +
 drivers/misc/intel/gna/gna_device.h |   5 +
 drivers/misc/intel/gna/gna_score.c  | 298 
 drivers/misc/intel/gna/gna_score.h  |  18 ++
 5 files changed, 325 insertions(+), 1 deletion(-)
 create mode 100644 drivers/misc/intel/gna/gna_score.c
 create mode 100644 drivers/misc/intel/gna/gna_score.h

diff --git a/drivers/misc/intel/gna/Kbuild b/drivers/misc/intel/gna/Kbuild
index 5dbbd3f0a543..9dac467839c9 100644
--- a/drivers/misc/intel/gna/Kbuild
+++ b/drivers/misc/intel/gna/Kbuild
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-intel_gna-y := gna_device.o gna_driver.o gna_mem.o gna_request.o gna_hw.o
+intel_gna-y := gna_device.o gna_driver.o gna_mem.o gna_request.o gna_score.o 
gna_hw.o
 
 obj-$(CONFIG_INTEL_GNA) += intel_gna.o
diff --git a/drivers/misc/intel/gna/gna_device.c 
b/drivers/misc/intel/gna/gna_device.c
index 14ce24fd18ff..e1a1f3142684 100644
--- a/drivers/misc/intel/gna/gna_device.c
+++ b/drivers/misc/intel/gna/gna_device.c
@@ -119,6 +119,9 @@ static int gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
idr_init(&gna_priv->memory_idr);
mutex_init(&gna_priv->memidr_lock);
 
+   mutex_init(&gna_priv->flist_lock);
+   INIT_LIST_HEAD(&gna_priv->file_list);
+
atomic_set(&gna_priv->request_count, 0);
 
mutex_init(&gna_priv->reqlist_lock);
diff --git a/drivers/misc/intel/gna/gna_device.h 
b/drivers/misc/intel/gna/gna_device.h
index b54d0ea9b9ef..878a972ab5b3 100644
--- a/drivers/misc/intel/gna/gna_device.h
+++ b/drivers/misc/intel/gna/gna_device.h
@@ -33,6 +33,11 @@ struct gna_hw_info {
 struct gna_private {
struct gna_driver_private *drv_priv;
 
+   /* list of opened files */
+   struct list_head file_list;
+   /* protects file_list */
+   struct mutex flist_lock;
+
struct pci_dev *pdev;
/* pdev->dev */
struct device *parent;
diff --git a/drivers/misc/intel/gna/gna_score.c 
b/drivers/misc/intel/gna/gna_score.c
new file mode 100644
index ..794039d2da43
--- /dev/null
+++ b/drivers/misc/intel/gna/gna_score.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright(c) 2017-2021 Intel Corporation
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "gna_device.h"
+#include "gna_driver.h"
+#include "gna_request.h"
+#include "gna_score.h"
+
+int gna_validate_score_config(struct gna_compute_cfg *compute_cfg,
+ struct gna_file_private *file_priv)
+{
+   struct gna_private *gna_priv;
+   size_t buffers_size;
+
+   gna_priv = file_priv->gna_priv;
+
+   if (compute_cfg->gna_mode > GNA_MODE_XNN) {
+   dev_err(&gna_priv->pdev->dev, "invalid mode\n");
+   return -EINVAL;
+   }
+
+   if (compute_cfg->layer_count > gna_priv->info.max_layer_count) {
+   dev_err(&gna_priv->pdev->dev, "max layer count exceeded\n");
+   return -EINVAL;
+   }
+
+   if (compute_cfg->buffer_count == 0) {
+   dev_err(&gna_priv->pdev->dev, "no buffers\n");
+   return -EINVAL;
+   }
+
+   buffers_size = sizeof(struct gna_buffer) * compute_cfg->buffer_count;
+   if (!access_ok(u64_to_user_ptr(compute_cfg->buffers_ptr), 
buffers_size)) {
+   dev_err(&gna_priv->pdev->dev, "invalid buffers pointer\n");
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int gna_do_patch_memory(struct gna_private *gna_priv, struct 
gna_memory_object *mo,
+  struct gna_memory_patch *patch, void *vaddr)
+{
+   size_t size;
+   void *dest;
+   u64 value;
+
+   value = patch->value;
+   size = patch->size;
+   dest = (u8 *)vaddr + patch->offset;
+   dev_dbg(&gna_priv->pdev->dev, "patch offset: %llu, size: %zu, value: 
%llu\n",
+   patch->offset, size, value);
+
+   switch (size) {
+   case 0:
+   return -EFAULT;
+   case sizeof(u8):
+   *((u8 *)dest) = (u8)value;
+   break;
+   case sizeof(u16):
+   *((u16 *)dest) = (u16)value;
+   break;
+   case sizeof(u32):
+   *((u32 *)dest) = (u32)value;
+   break;
+   case sizeof(u64):
+ 

[PATCH v2 04/13] intel_gna: add memory handling

2021-03-24 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Patch adds memory handling - mapping, DMA, pinning.
The GNA driver maps and unmaps the physical pages for 64-byte aligned
buffer allocated by user space program. The pages of mapped memory
are being locked only during actual computation.

Patch adds configuration of the DMA scatter gather list for physical pages
and generation of page table and page directory to be programmed in the GNA HW
at the time of scoring initiation.

GNA’s MMU is being configured based on specific request memory usage.
As the MMU can address up to 256MB a single scoring request is limited
to this amount of memory being used.

GNA Library can allocate any number of memory regions for GNA usage.
Its number and total capacity are limited by the OSs’ resources.
Due to GNA MMU restrictions, even when using multiple memory regions,
the sum of all the memory regions used within a single inference
request must be less than 256MB.

At least a single GNA memory region is needed to be allocated
(and can be shared by multiple models). At the other extreme,
each GNA tensor (e.g., weights/biases/inputs/outputs) could use
its own, separate GNA memory region.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/intel/gna/Kbuild   |   2 +-
 drivers/misc/intel/gna/gna_device.c |  20 ++
 drivers/misc/intel/gna/gna_device.h |  13 +
 drivers/misc/intel/gna/gna_driver.c |   1 +
 drivers/misc/intel/gna/gna_driver.h |  16 +
 drivers/misc/intel/gna/gna_mem.c| 470 
 drivers/misc/intel/gna/gna_mem.h| 107 +++
 7 files changed, 628 insertions(+), 1 deletion(-)
 create mode 100644 drivers/misc/intel/gna/gna_mem.c
 create mode 100644 drivers/misc/intel/gna/gna_mem.h

diff --git a/drivers/misc/intel/gna/Kbuild b/drivers/misc/intel/gna/Kbuild
index 0cf083bb211a..e5cd953d83b2 100644
--- a/drivers/misc/intel/gna/Kbuild
+++ b/drivers/misc/intel/gna/Kbuild
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-intel_gna-y := gna_device.o gna_driver.o gna_hw.o
+intel_gna-y := gna_device.o gna_driver.o gna_mem.o gna_hw.o
 
 obj-$(CONFIG_INTEL_GNA) += intel_gna.o
diff --git a/drivers/misc/intel/gna/gna_device.c 
b/drivers/misc/intel/gna/gna_device.c
index 6bac481b2247..25137d0ac519 100644
--- a/drivers/misc/intel/gna/gna_device.c
+++ b/drivers/misc/intel/gna/gna_device.c
@@ -23,6 +23,17 @@ static void gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
 
bld_reg = gna_reg_read(gna_priv->bar0_base, GNA_MMIO_IBUFFS);
gna_priv->hw_info.in_buf_s = bld_reg & GENMASK(7, 0);
+
+   mutex_init(&gna_priv->mmu_lock);
+
+   idr_init(&gna_priv->memory_idr);
+   mutex_init(&gna_priv->memidr_lock);
+}
+
+static void gna_dev_deinit(struct gna_private *gna_priv)
+{
+   idr_destroy(&gna_priv->memory_idr);
+   gna_mmu_free(gna_priv);
 }
 
 int gna_probe(struct pci_dev *pcidev, const struct pci_device_id *pci_id)
@@ -77,3 +88,12 @@ int gna_probe(struct pci_dev *pcidev, const struct 
pci_device_id *pci_id)
 
return 0;
 }
+
+void gna_remove(struct pci_dev *pcidev)
+{
+   struct gna_private *gna_priv;
+
+   gna_priv = pci_get_drvdata(pcidev);
+
+   gna_dev_deinit(gna_priv);
+}
diff --git a/drivers/misc/intel/gna/gna_device.h 
b/drivers/misc/intel/gna/gna_device.h
index 7704eeda90f6..a5657ab9f62a 100644
--- a/drivers/misc/intel/gna/gna_device.h
+++ b/drivers/misc/intel/gna/gna_device.h
@@ -5,8 +5,11 @@
 #define __GNA_DEVICE_H__
 
 #include 
+#include 
+#include 
 
 #include "gna_hw.h"
+#include "gna_mem.h"
 
 struct gna_driver_private;
 struct pci_device_id;
@@ -38,8 +41,18 @@ struct gna_private {
void __iomem *bar0_base;
struct gna_drv_info info;
struct gna_hw_info hw_info;
+
+   struct gna_mmu_object mmu;
+   struct mutex mmu_lock;
+
+   /* memory objects' store */
+   struct idr memory_idr;
+   /* lock protecting memory_idr */
+   struct mutex memidr_lock;
 };
 
 int gna_probe(struct pci_dev *dev, const struct pci_device_id *id);
 
+void gna_remove(struct pci_dev *dev);
+
 #endif /* __GNA_DEVICE_H__ */
diff --git a/drivers/misc/intel/gna/gna_driver.c 
b/drivers/misc/intel/gna/gna_driver.c
index f4922a388be7..79f4d8522bdc 100644
--- a/drivers/misc/intel/gna/gna_driver.c
+++ b/drivers/misc/intel/gna/gna_driver.c
@@ -17,6 +17,7 @@ struct gna_driver_private gna_drv_priv;
 static struct pci_driver gna_driver = {
.name = GNA_DV_NAME,
.probe = gna_probe,
+   .remove = gna_remove,
 };
 
 static int __init gna_drv_init(void)
diff --git a/drivers/misc/intel/gna/gna_driver.h 
b/drivers/misc/intel/gna/gna_driver.h
index ed507ea10866..69087317d668 100644
--- a/drivers/misc/intel/gna/gna_driver.h
+++ b/drivers/misc/intel/gna/gna_driver.h
@@ -4,12 +4,28 @@
 #ifndef __

[PATCH v2 03/13] intel_gna: read hardware info in the driver

2021-03-24 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Get the hardware information from register MMIO_IBUFFS

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/intel/gna/gna_device.c | 5 +
 drivers/misc/intel/gna/gna_device.h | 5 +
 2 files changed, 10 insertions(+)

diff --git a/drivers/misc/intel/gna/gna_device.c 
b/drivers/misc/intel/gna/gna_device.c
index 431113297879..6bac481b2247 100644
--- a/drivers/misc/intel/gna/gna_device.c
+++ b/drivers/misc/intel/gna/gna_device.c
@@ -12,12 +12,17 @@
 static void gna_dev_init(struct gna_private *gna_priv, struct pci_dev *pcidev,
const struct pci_device_id *pci_id)
 {
+   u32 bld_reg;
+
pci_set_drvdata(pcidev, gna_priv);
 
gna_priv->parent = &pcidev->dev;
gna_priv->pdev = pcidev;
gna_priv->info = *(struct gna_drv_info *)pci_id->driver_data;
gna_priv->drv_priv = &gna_drv_priv;
+
+   bld_reg = gna_reg_read(gna_priv->bar0_base, GNA_MMIO_IBUFFS);
+   gna_priv->hw_info.in_buf_s = bld_reg & GENMASK(7, 0);
 }
 
 int gna_probe(struct pci_dev *pcidev, const struct pci_device_id *pci_id)
diff --git a/drivers/misc/intel/gna/gna_device.h 
b/drivers/misc/intel/gna/gna_device.h
index 39dc03d53feb..7704eeda90f6 100644
--- a/drivers/misc/intel/gna/gna_device.h
+++ b/drivers/misc/intel/gna/gna_device.h
@@ -23,6 +23,10 @@ struct gna_drv_info {
struct gna_desc_info desc_info;
 };
 
+struct gna_hw_info {
+   u8 in_buf_s;
+};
+
 struct gna_private {
struct gna_driver_private *drv_priv;
 
@@ -33,6 +37,7 @@ struct gna_private {
/* device related resources */
void __iomem *bar0_base;
struct gna_drv_info info;
+   struct gna_hw_info hw_info;
 };
 
 int gna_probe(struct pci_dev *dev, const struct pci_device_id *id);
-- 
2.28.0



[PATCH v2 01/13] intel_gna: add driver module

2021-03-24 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Add a new PCI driver for Intel(R) Gaussian & Neural Accelerator
with basic support like module loading and unloading. The full
function of the driver will be added by further changes.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 Documentation/misc-devices/index.rst  |   1 +
 Documentation/misc-devices/intel/gna.rst  |  48 ++
 .../userspace-api/ioctl/ioctl-number.rst  |   1 +
 MAINTAINERS   |   7 +
 drivers/misc/Kconfig  |   1 +
 drivers/misc/Makefile |   1 +
 drivers/misc/intel/gna/Kbuild |   5 +
 drivers/misc/intel/gna/Kconfig|  13 ++
 drivers/misc/intel/gna/gna_device.c   |  74 +
 drivers/misc/intel/gna/gna_device.h   |  36 
 drivers/misc/intel/gna/gna_driver.c   |  39 +
 drivers/misc/intel/gna/gna_driver.h   |  15 ++
 include/uapi/misc/intel/gna.h | 155 ++
 13 files changed, 396 insertions(+)
 create mode 100644 Documentation/misc-devices/intel/gna.rst
 create mode 100644 drivers/misc/intel/gna/Kbuild
 create mode 100644 drivers/misc/intel/gna/Kconfig
 create mode 100644 drivers/misc/intel/gna/gna_device.c
 create mode 100644 drivers/misc/intel/gna/gna_device.h
 create mode 100644 drivers/misc/intel/gna/gna_driver.c
 create mode 100644 drivers/misc/intel/gna/gna_driver.h
 create mode 100644 include/uapi/misc/intel/gna.h

diff --git a/Documentation/misc-devices/index.rst 
b/Documentation/misc-devices/index.rst
index 64420b3314fe..1b187ee121b0 100644
--- a/Documentation/misc-devices/index.rst
+++ b/Documentation/misc-devices/index.rst
@@ -19,6 +19,7 @@ fit into other categories.
bh1770glc
eeprom
c2port
+   intel/gna
ibmvmc
ics932s401
isl29003
diff --git a/Documentation/misc-devices/intel/gna.rst 
b/Documentation/misc-devices/intel/gna.rst
new file mode 100644
index ..9baeec5ceb5c
--- /dev/null
+++ b/Documentation/misc-devices/intel/gna.rst
@@ -0,0 +1,48 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+=
+Intel(R) Gaussian & Neural Accelerator (Intel(R) GNA)
+=
+
+Acronyms
+
+GNA- Gaussian & Neural Accelerator
+GMM- Gaussian Mixer Model
+CNN- Convolutional Neural Network
+RNN- Recurrent Neural Networks
+DNN- Deep Neural Networks
+
+Introduction
+
+The Intel(R) GNA is an internal PCI fixed device available on several Intel 
platforms/SoCs.
+Feature set depends on the Intel chipset SKU.
+
+Intel(R) GNA provides hardware accelerated computation for GMMs and Neural 
Networks.
+It supports several layer types: affine, recurrent, and convolutional among 
others.
+Hardware also provides helper layer types for copying and transposing matrices.
+
+Linux Driver
+
+The driver also registers a character device to expose file operations via dev 
node.
+
+The driver probes/removes PCI device, implements file operations, handles 
runtime
+power management, and interacts with hardware through MMIO registers.
+
+Multiple processes can independently file many requests to the driver. These 
requests are
+processed in a FIFO manner. The hardware can process one request at a time by 
using a FIFO
+queue.
+
+IOCTL
+-
+Intel(R) GNA driver controls the device through IOCTL interfaces.
+Following IOCTL commands are supported:
+
+GNA_IOCTL_PARAM_GET gets driver and device capabilities.
+
+GNA_IOCTL_MEMORY_MAP locks user pages and GNA MMU setups for DMA transfer.
+
+GNA_IOCTL_MEMORY_UNMAP unlocks user pages and releases GNA MMU structures.
+
+GNA_IOCTL_COMPUTE submits a request to the device queue.
+
+GNA_IOCTL_WAIT blocks and waits on the submitted request.
diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst 
b/Documentation/userspace-api/ioctl/ioctl-number.rst
index a4c75a28c839..9ec2b32f656a 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -115,6 +115,7 @@ Code  Seq#Include File  
 Comments
 'B'   C0-FF  advanced bbus   
<mailto:maas...@uni-freiburg.de>
 'C'   alllinux/soundcard.h   conflict!
 'C'   01-2F  linux/capi.hconflict!
+'C'   01-5F  uapi/misc/intel/gna.h   conflict!
 'C'   F0-FF  drivers/net/wan/cosa.h  conflict!
 'D'   allarch/s390/include/asm/dasd.h
 'D'   40-5F  drivers/scsi/dpt/dtpi_ioctl.h
diff --git a/MAINTAINERS b/MAINTAINERS
index b

[PATCH v2 02/13] intel_gna: add component of hardware operation

2021-03-24 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Add definitions and utilities to interact with the hardware
device.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/intel/gna/Kbuild   |   2 +-
 drivers/misc/intel/gna/gna_device.h |   4 +
 drivers/misc/intel/gna/gna_hw.c | 125 
 drivers/misc/intel/gna/gna_hw.h |  62 ++
 4 files changed, 192 insertions(+), 1 deletion(-)
 create mode 100644 drivers/misc/intel/gna/gna_hw.c
 create mode 100644 drivers/misc/intel/gna/gna_hw.h

diff --git a/drivers/misc/intel/gna/Kbuild b/drivers/misc/intel/gna/Kbuild
index 5d3becc71683..0cf083bb211a 100644
--- a/drivers/misc/intel/gna/Kbuild
+++ b/drivers/misc/intel/gna/Kbuild
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-intel_gna-y := gna_device.o gna_driver.o
+intel_gna-y := gna_device.o gna_driver.o gna_hw.o
 
 obj-$(CONFIG_INTEL_GNA) += intel_gna.o
diff --git a/drivers/misc/intel/gna/gna_device.h 
b/drivers/misc/intel/gna/gna_device.h
index d0b47f75f47f..39dc03d53feb 100644
--- a/drivers/misc/intel/gna/gna_device.h
+++ b/drivers/misc/intel/gna/gna_device.h
@@ -6,6 +6,8 @@
 
 #include 
 
+#include "gna_hw.h"
+
 struct gna_driver_private;
 struct pci_device_id;
 struct pci_dev;
@@ -17,6 +19,8 @@ struct gna_drv_info {
u32 num_page_entries;
u32 max_layer_count;
u64 max_hw_mem;
+
+   struct gna_desc_info desc_info;
 };
 
 struct gna_private {
diff --git a/drivers/misc/intel/gna/gna_hw.c b/drivers/misc/intel/gna/gna_hw.c
new file mode 100644
index ..7d2f4ef00136
--- /dev/null
+++ b/drivers/misc/intel/gna/gna_hw.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright(c) 2017-2021 Intel Corporation
+
+#include 
+
+#include 
+
+#include "gna_device.h"
+#include "gna_driver.h"
+#include "gna_hw.h"
+
+int gna_parse_hw_status(struct gna_private *gna_priv, u32 hw_status)
+{
+   int status;
+
+   if (hw_status & GNA_ERROR) {
+   dev_dbg(&gna_priv->pdev->dev, "GNA completed with errors: 
%#x\n", hw_status);
+   status = -EIO;
+   } else if (hw_status & GNA_STS_SCORE_COMPLETED) {
+   status = 0;
+   dev_dbg(&gna_priv->pdev->dev, "GNA completed successfully: 
%#x\n", hw_status);
+   } else {
+   dev_err(&gna_priv->pdev->dev, "GNA not completed, status: 
%#x\n", hw_status);
+   status = -ENODATA;
+   }
+
+   return status;
+}
+
+void gna_print_error_status(struct gna_private *gna_priv, u32 hw_status)
+{
+   if (hw_status & GNA_STS_PARAM_OOR)
+   dev_dbg(&gna_priv->pdev->dev, "GNA error: Param Out Range 
Error\n");
+
+   if (hw_status & GNA_STS_VA_OOR)
+   dev_dbg(&gna_priv->pdev->dev, "GNA error: VA Out of Range 
Error\n");
+
+   if (hw_status & GNA_STS_PCI_MMU_ERR)
+   dev_dbg(&gna_priv->pdev->dev, "GNA error: PCI MMU Error\n");
+
+   if (hw_status & GNA_STS_PCI_DMA_ERR)
+   dev_dbg(&gna_priv->pdev->dev, "GNA error: PCI MMU Error\n");
+
+   if (hw_status & GNA_STS_PCI_UNEXCOMPL_ERR)
+   dev_dbg(&gna_priv->pdev->dev, "GNA error: PCI Unexpected 
Completion Error\n");
+
+   if (hw_status & GNA_STS_SATURATE)
+   dev_dbg(&gna_priv->pdev->dev, "GNA error: Saturation Reached 
!\n");
+}
+
+bool gna_hw_perf_enabled(struct gna_private *gna_priv)
+{
+   void __iomem *addr = gna_priv->bar0_base;
+   u32 ctrl = gna_reg_read(addr, GNA_MMIO_CTRL);
+
+   return FIELD_GET(GNA_CTRL_COMP_STATS_EN, ctrl) ? true : false;
+}
+
+void gna_start_scoring(struct gna_private *gna_priv, void __iomem *addr,
+  struct gna_compute_cfg *compute_cfg)
+{
+   u32 ctrl = gna_reg_read(addr, GNA_MMIO_CTRL);
+
+   ctrl |= GNA_CTRL_START_ACCEL | GNA_CTRL_COMP_INT_EN | 
GNA_CTRL_ERR_INT_EN;
+
+   ctrl &= ~GNA_CTRL_COMP_STATS_EN;
+   ctrl |= FIELD_PREP(GNA_CTRL_COMP_STATS_EN,
+   compute_cfg->hw_perf_encoding & 
FIELD_MAX(GNA_CTRL_COMP_STATS_EN));
+
+   ctrl &= ~GNA_CTRL_ACTIVE_LIST_EN;
+   ctrl |= FIELD_PREP(GNA_CTRL_ACTIVE_LIST_EN,
+   compute_cfg->active_list_on & 
FIELD_MAX(GNA_CTRL_ACTIVE_LIST_EN));
+
+   ctrl &= ~GNA_CTRL_OP_MODE;
+   ctrl |= FIELD_PREP(GNA_CTRL_OP_MODE,
+   compute_cfg->gna_mode & FIELD_MAX(GNA_CTRL_OP_MODE));
+
+   gna_reg_write(addr, GNA_MMIO_CTRL, ctrl);
+
+   dev_dbg(&gna_priv->pdev->dev, "scoring started...\n");
+}
+
+static void gna_clear_saturation(struct gna_privat

[PATCH v2 00/13] Driver of Intel(R) Gaussian & Neural Accelerator

2021-03-24 Thread Maciej Kwapulinski
Dear kernel maintainers,

This submission is a kernel driver to support Intel(R) Gaussian & Neural
Accelerator (Intel(R) GNA). Intel(R) GNA is a PCI-based neural co-processor
available on multiple Intel platforms. AI developers and users can offload
continuous inference workloads to an Intel(R) GNA device in order to free
processor resources and save power. Noise reduction and speech recognition
are the examples of the workloads Intel(R) GNA deals with while its usage
is not limited to the two.

For a list of processors equipped with Intel(R) GNA device, please refer to
this link:
https://docs.openvinotoolkit.org/latest/openvino_docs_IE_DG_supported_plugins_GNA.html

We think contributing this driver to the upstream kernel project is the
best way for developers and users to get the latest Intel(R) GNA support in
a Linux kernel, through the mainline to any Linux distributions installed
on their systems. Upstreaming also enables contribution from developers
around the world to the driver once it is merged.

The driver works with Intel(R) libraries in user space. The Intel(R) driver
exposes a few IOCTL interfaces for use by libraries in user space. The
libraries are open sourced and are available at:
https://github.com/intel/gna

---

Changelogs:

v1->v2:
 - driver's new layout:
   - driver name: gna -> intel_gna
   - module name: gna -> intel_gna
   - device file name: /dev/gnaN -> /dev/intel_gnaN
   - driver's source directory: drivers/misc/gna/ -> drivers/misc/intel/gna/
   - UAPI: include/uapi/misc/gna.h -> include/uapi/misc/intel/gna.h
   - DOC: Documentation/misc-devices/gna.rst ->
   Documentation/misc-devices/intel/gna.rst
 - 'MISC' device framework used
 - fixes throughout GNA device's PCI management
 - header files' includes and forward declarations cleanup
 - ISR made static
 - unused comments cleanup
 - "_priv_" segment removed from function names
 - tested: v5.11-rc3 -> v5.11
 - number of other/minor fixes

---

Maciej Kwapulinski (1):
  intel_gna: add a 'misc' device

Tomasz Jankowski (12):
  intel_gna: add driver module
  intel_gna: add component of hardware operation
  intel_gna: read hardware info in the driver
  intel_gna: add memory handling
  intel_gna: initialize mmu
  intel_gna: add hardware ids
  intel_gna: add request component
  intel_gna: implement scoring
  intel_gna: add a work queue to process scoring requests
  intel_gna: add interrupt handler
  intel_gna: add ioctl handler
  intel_gna: add file operations to a 'misc' device

 Documentation/misc-devices/index.rst  |   1 +
 Documentation/misc-devices/intel/gna.rst  |  48 ++
 .../userspace-api/ioctl/ioctl-number.rst  |   1 +
 MAINTAINERS   |   7 +
 drivers/misc/Kconfig  |   1 +
 drivers/misc/Makefile |   1 +
 drivers/misc/intel/gna/Kbuild |   5 +
 drivers/misc/intel/gna/Kconfig|  13 +
 drivers/misc/intel/gna/gna_device.c   | 429 
 drivers/misc/intel/gna/gna_device.h   |  89 
 drivers/misc/intel/gna/gna_driver.c   |  43 ++
 drivers/misc/intel/gna/gna_driver.h   |  33 ++
 drivers/misc/intel/gna/gna_hw.c   | 125 +
 drivers/misc/intel/gna/gna_hw.h   |  61 +++
 drivers/misc/intel/gna/gna_ioctl.c| 249 +
 drivers/misc/intel/gna/gna_ioctl.h|  11 +
 drivers/misc/intel/gna/gna_mem.c  | 473 ++
 drivers/misc/intel/gna/gna_mem.h  | 107 
 drivers/misc/intel/gna/gna_request.c  | 463 +
 drivers/misc/intel/gna/gna_request.h  |  62 +++
 drivers/misc/intel/gna/gna_score.c| 298 +++
 drivers/misc/intel/gna/gna_score.h|  18 +
 include/uapi/misc/intel/gna.h | 155 ++
 23 files changed, 2693 insertions(+)
 create mode 100644 Documentation/misc-devices/intel/gna.rst
 create mode 100644 drivers/misc/intel/gna/Kbuild
 create mode 100644 drivers/misc/intel/gna/Kconfig
 create mode 100644 drivers/misc/intel/gna/gna_device.c
 create mode 100644 drivers/misc/intel/gna/gna_device.h
 create mode 100644 drivers/misc/intel/gna/gna_driver.c
 create mode 100644 drivers/misc/intel/gna/gna_driver.h
 create mode 100644 drivers/misc/intel/gna/gna_hw.c
 create mode 100644 drivers/misc/intel/gna/gna_hw.h
 create mode 100644 drivers/misc/intel/gna/gna_ioctl.c
 create mode 100644 drivers/misc/intel/gna/gna_ioctl.h
 create mode 100644 drivers/misc/intel/gna/gna_mem.c
 create mode 100644 drivers/misc/intel/gna/gna_mem.h
 create mode 100644 drivers/misc/intel/gna/gna_request.c
 create mode 100644 drivers/misc/intel/gna/gna_request.h
 create mode 100644 drivers/misc/intel/gna/gna_score.c
 create mode 100644 drivers/misc/intel/gna/gna_score.h
 create mode 100644 include/uapi/misc/intel/gna.h

-- 
2.28.0



Re: [PATCH v1 01/12] gna: add driver module

2021-03-09 Thread Maciej Kwapulinski


Greg Kroah-Hartman  writes:

> On Fri, Feb 26, 2021 at 01:59:14PM +0100, Maciej Kwapulinski wrote:
>> 
>> Greg Kroah-Hartman  writes:
>> 
>> > On Tue, Feb 16, 2021 at 05:05:14PM +0100, Maciej Kwapulinski wrote:
>> 
>> >> --- /dev/null
>> >> +++ b/drivers/misc/gna/gna_driver.h
>> >> @@ -0,0 +1,41 @@
>> >> +/* SPDX-License-Identifier: GPL-2.0-only */
>> >> +/* Copyright(c) 2017-2021 Intel Corporation */
>> >> +
>> >> +#ifndef __GNA_DRIVER_H__
>> >> +#define __GNA_DRIVER_H__
>> >> +
>> >> +#include 
>> >> +#include 
>> >> +#include 
>> >> +
>> >> +#define GNA_DRV_NAME "gna"
>> >
>> > Way too generic, no one knows what "gna" is.
>> >
>> 
>> "intel gna" is much more verbose in search engines.
>> As we do not (plan to) have more "gna" drivers, is the following ok?:
>> 
>> intel-gna
>> 
>> the change would imply the following:
>> 
>> prompt$ lspci -s 00:00.3 -
>> 00:00.3 System peripheral: Intel Corporation Device 3190 (rev 03)
>>  Subsystem: Intel Corporation Device 2072
>>   
>>  Kernel driver in use: intel-gna
>>  Kernel modules: gna
>> 
>> is it ok?
>
> Why not intel-gna as the kernel module as well?
>
>> also, how about the interface to library (it's part of one of next patches)?:
>> prompt$ file /dev/gna0
>> /dev/gna0: character special (235/0)
>> 
>> can "gna" stay intact here?
>
> Again, I have no idea what "gna" is, so you might want to pick something
> more descriptive?
>
>> I'm pointing this out, because gna exists on the market for a while and
>> changing the above may have some impact we'd like to avoid.
>
> If it exists but Linux does not support it, how would anyone know about
> it?  :)
>
> Please use real terms where possible.
>
> thanks,
>
> greg k-h

summarizing gna name justification topic, is the intel_gna.ko driver's
following layout within kernel code OK for You?:
1. driver/module name:
   prompt$ lspci -s 00:00.3 -
   00:00.3 System peripheral: Intel Corporation Device 3190 (rev 03)
 
 Kernel driver in use: intel_gna
 Kernel modules: intel_gna

2. mv drivers/misc/gna/* drivers/misc/intel_gna/

3. prompt$ file /dev/intel_gna0 
/dev/intel_gna0: character special (10/120)

# ..., /dev/intel_gna1, /dev/intel_gna2 for subsequent devices


Re: [PATCH v1 01/12] gna: add driver module

2021-03-01 Thread Maciej Kwapulinski


Greg Kroah-Hartman  writes:

> On Mon, Mar 01, 2021 at 11:39:23AM +0100, Maciej Kwapulinski wrote:
>> 
>> Maciej Kwapulinski  writes:
>> 
>> > Greg Kroah-Hartman  writes:
>> >
>> >> On Mon, Mar 01, 2021 at 11:18:59AM +0100, Maciej Kwapulinski wrote:
>> >>> 
>> >>> Andy Shevchenko  writes:
>> >>> 
>> >>> > On Tue, Feb 16, 2021 at 6:11 PM Maciej Kwapulinski
>> >>> >  wrote:
>> >>> >>
>> >>> 
>> >>> >> +static int __init gna_drv_init(void)
>> >>> >> +{
>> >>> >> +   int ret;
>> >>> >> +
>> >>> >> +   mutex_init(&gna_drv_priv.lock);
>> >>> >> +
>> >>> >> +   gna_class = class_create(THIS_MODULE, "gna");
>> >>> >> +   if (IS_ERR(gna_class)) {
>> >>> >> +   pr_err("class device create failed\n");
>> >>> >> +   return PTR_ERR(gna_class);
>> >>> >> +   }
>> >>> >> +   gna_class->devnode = gna_devnode;
>> >>> >> +
>> >>> >> +   ret = pci_register_driver(&gna_driver);
>> >>> >
>> >>> > Is it possible to decouple a PCI glue driver from the class as many
>> >>> > other existing examples are doing?
>> >>> >
>> >>> 
>> >>> I see many pci drivers (including staging) that do have it glued though.
>> >>> 
>> >>> Examples are:
>> >>> 1. "static int __init kp2000_pcie_init(void)" (commit on May 20 09:34:11
>> >>> 2019)
>> >>> 2. "static int __init hl_init(void)" (commit on Mon Feb 18 09:46:43 2019)
>> >>> 
>> >>> Please give me more details.
>> >>
>> >> Never use a staging driver for any type of example, _EXECPT_ for a bad
>> >> one.  There's a reason the code is in staging and not in the "real" part
>> >> of the kernel.
>> >
>> > ok.
>> >
>> > another one (1) is not staging..
>> 
>> I meant "static int __init hl_init(void)" is not staging one
>
> Still doesn't mean it is a good thing to do.  Again, why isn't this
> driver just using the misc driver interface instead?  It's much simpler
> to use and should work just fine for this tiny driver, instead of having
> to create a custom class just for it.
>

ok


Re: [PATCH v1 01/12] gna: add driver module

2021-03-01 Thread Maciej Kwapulinski


Maciej Kwapulinski  writes:

> Greg Kroah-Hartman  writes:
>
>> On Mon, Mar 01, 2021 at 11:18:59AM +0100, Maciej Kwapulinski wrote:
>>> 
>>> Andy Shevchenko  writes:
>>> 
>>> > On Tue, Feb 16, 2021 at 6:11 PM Maciej Kwapulinski
>>> >  wrote:
>>> >>
>>> 
>>> >> +static int __init gna_drv_init(void)
>>> >> +{
>>> >> +   int ret;
>>> >> +
>>> >> +   mutex_init(&gna_drv_priv.lock);
>>> >> +
>>> >> +   gna_class = class_create(THIS_MODULE, "gna");
>>> >> +   if (IS_ERR(gna_class)) {
>>> >> +   pr_err("class device create failed\n");
>>> >> +   return PTR_ERR(gna_class);
>>> >> +   }
>>> >> +   gna_class->devnode = gna_devnode;
>>> >> +
>>> >> +   ret = pci_register_driver(&gna_driver);
>>> >
>>> > Is it possible to decouple a PCI glue driver from the class as many
>>> > other existing examples are doing?
>>> >
>>> 
>>> I see many pci drivers (including staging) that do have it glued though.
>>> 
>>> Examples are:
>>> 1. "static int __init kp2000_pcie_init(void)" (commit on May 20 09:34:11
>>> 2019)
>>> 2. "static int __init hl_init(void)" (commit on Mon Feb 18 09:46:43 2019)
>>> 
>>> Please give me more details.
>>
>> Never use a staging driver for any type of example, _EXECPT_ for a bad
>> one.  There's a reason the code is in staging and not in the "real" part
>> of the kernel.
>
> ok.
>
> another one (1) is not staging..

I meant "static int __init hl_init(void)" is not staging one


Re: [PATCH v1 01/12] gna: add driver module

2021-03-01 Thread Maciej Kwapulinski


Greg Kroah-Hartman  writes:

> On Mon, Mar 01, 2021 at 11:18:59AM +0100, Maciej Kwapulinski wrote:
>> 
>> Andy Shevchenko  writes:
>> 
>> > On Tue, Feb 16, 2021 at 6:11 PM Maciej Kwapulinski
>> >  wrote:
>> >>
>> 
>> >> +static int __init gna_drv_init(void)
>> >> +{
>> >> +   int ret;
>> >> +
>> >> +   mutex_init(&gna_drv_priv.lock);
>> >> +
>> >> +   gna_class = class_create(THIS_MODULE, "gna");
>> >> +   if (IS_ERR(gna_class)) {
>> >> +   pr_err("class device create failed\n");
>> >> +   return PTR_ERR(gna_class);
>> >> +   }
>> >> +   gna_class->devnode = gna_devnode;
>> >> +
>> >> +   ret = pci_register_driver(&gna_driver);
>> >
>> > Is it possible to decouple a PCI glue driver from the class as many
>> > other existing examples are doing?
>> >
>> 
>> I see many pci drivers (including staging) that do have it glued though.
>> 
>> Examples are:
>> 1. "static int __init kp2000_pcie_init(void)" (commit on May 20 09:34:11
>> 2019)
>> 2. "static int __init hl_init(void)" (commit on Mon Feb 18 09:46:43 2019)
>> 
>> Please give me more details.
>
> Never use a staging driver for any type of example, _EXECPT_ for a bad
> one.  There's a reason the code is in staging and not in the "real" part
> of the kernel.

ok.

another one (1) is not staging..


Re: [PATCH v1 01/12] gna: add driver module

2021-03-01 Thread Maciej Kwapulinski


Andy Shevchenko  writes:

> On Tue, Feb 16, 2021 at 6:11 PM Maciej Kwapulinski
>  wrote:
>>

>> +static int __init gna_drv_init(void)
>> +{
>> +   int ret;
>> +
>> +   mutex_init(&gna_drv_priv.lock);
>> +
>> +   gna_class = class_create(THIS_MODULE, "gna");
>> +   if (IS_ERR(gna_class)) {
>> +   pr_err("class device create failed\n");
>> +   return PTR_ERR(gna_class);
>> +   }
>> +   gna_class->devnode = gna_devnode;
>> +
>> +   ret = pci_register_driver(&gna_driver);
>
> Is it possible to decouple a PCI glue driver from the class as many
> other existing examples are doing?
>

I see many pci drivers (including staging) that do have it glued though.

Examples are:
1. "static int __init kp2000_pcie_init(void)" (commit on May 20 09:34:11
2019)
2. "static int __init hl_init(void)" (commit on Mon Feb 18 09:46:43 2019)

Please give me more details.


Re: [PATCH v1 01/12] gna: add driver module

2021-02-26 Thread Maciej Kwapulinski


Andy Shevchenko  writes:

> On Tue, Feb 16, 2021 at 6:11 PM Maciej Kwapulinski
>  wrote:
>>

>> +#define GNA_DRV_VER"1.2.0"
>
> Nowadays the version is the Git SHA sum.
>

right, "version" is present in about 7% of all modules

do You mean version should be skipped over (automatically generated)
srcversion field? or maybe You suggest any (better) technique?


Re: [PATCH v1 01/12] gna: add driver module

2021-02-26 Thread Maciej Kwapulinski


Greg Kroah-Hartman  writes:

> On Tue, Feb 16, 2021 at 05:05:14PM +0100, Maciej Kwapulinski wrote:

>> --- /dev/null
>> +++ b/drivers/misc/gna/gna_driver.h
>> @@ -0,0 +1,41 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/* Copyright(c) 2017-2021 Intel Corporation */
>> +
>> +#ifndef __GNA_DRIVER_H__
>> +#define __GNA_DRIVER_H__
>> +
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#define GNA_DRV_NAME"gna"
>
> Way too generic, no one knows what "gna" is.
>

"intel gna" is much more verbose in search engines.
As we do not (plan to) have more "gna" drivers, is the following ok?:

intel-gna

the change would imply the following:

prompt$ lspci -s 00:00.3 -
00:00.3 System peripheral: Intel Corporation Device 3190 (rev 03)
Subsystem: Intel Corporation Device 2072
  
Kernel driver in use: intel-gna
Kernel modules: gna

is it ok?

also, how about the interface to library (it's part of one of next patches)?:
prompt$ file /dev/gna0
/dev/gna0: character special (235/0)

can "gna" stay intact here?

I'm pointing this out, because gna exists on the market for a while and
changing the above may have some impact we'd like to avoid.

>



Re: [PATCH v1 01/12] gna: add driver module

2021-02-19 Thread Maciej Kwapulinski


Andy Shevchenko  writes:

> On Tue, Feb 16, 2021 at 6:11 PM Maciej Kwapulinski
>  wrote:
>>

>> +err_clear_master:
>> +   pci_clear_master(pcidev);
>> +err_release_regions:
>> +   pci_release_regions(pcidev);
>> +end:
>> +   dev_err(&pcidev->dev, "gna probe failed with %d\n", ret);
>> +   return ret;
>
> These are all completely redundant.
>

following is refactor of gna_probe(), but without pci_release_regions(),
smatch (v7fcfe259) produces warning:
  drivers/misc/gna/gna_device.c:78 gna_probe() warn: 'pcidev' not
  released on lines: 56,65.

here's the code refactored:

int gna_probe(struct pci_dev *pcidev, const struct pci_device_id *pci_id)
{
struct gna_private *gna_priv;
int ret;

ret = pcim_enable_device(pcidev);
if (ret) {
dev_err(&pcidev->dev, "pci device can't be enabled\n");
return ret;
}

ret = pci_request_regions(pcidev, GNA_DRV_NAME);
if (ret)
return ret;

ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64));
if (ret) {
dev_err(&pcidev->dev, "pci_set_dma_mask returned error %d\n", 
ret);
return ret;
}

pci_set_master(pcidev);

/* init gna device */
gna_priv = devm_kzalloc(&pcidev->dev, sizeof(*gna_priv), GFP_KERNEL);
if (!gna_priv) {
//pci_release_regions(pcidev);
return -ENOMEM; // line 56
}
/* Map BAR0 */
gna_priv->bar0.iostart = pci_resource_start(pcidev, 0);
gna_priv->bar0.iosize = pci_resource_len(pcidev, 0);
gna_priv->bar0.mem_addr = pcim_iomap(pcidev, 0, 0);
if (!gna_priv->bar0.mem_addr) {
//pci_release_regions(pcidev);
dev_err(&pcidev->dev, "could not map BAR 0\n");
return -EINVAL;   // line 65
}

dev_dbg(&pcidev->dev, "bar0 io start: 0x%llx\n", (unsigned long 
long)gna_priv->bar0.iostart);
dev_dbg(&pcidev->dev, "bar0 io size: %llu\n", (unsigned long 
long)gna_priv->bar0.iosize);
dev_dbg(&pcidev->dev, "bar0 memory address: %p\n", 
gna_priv->bar0.mem_addr);

ret = gna_dev_init(gna_priv, pcidev, pci_id);
if (ret) {
dev_err(&pcidev->dev, "could not initialize gna private 
structure\n");
return ret;
}

return 0;
}

I've also added 'noinline' directive to pci_release_regions(), to see if
it is called by the core code on "rmmod gna", but can't see the call.

Is the smatch tool that causes problems here?
Do You suggest other way to handle the problem?


Re: [PATCH v1 01/12] gna: add driver module

2021-02-16 Thread Maciej Kwapulinski


Greg Kroah-Hartman  writes:

> On Tue, Feb 16, 2021 at 05:05:14PM +0100, Maciej Kwapulinski wrote:
>> --- /dev/null
>> +++ b/drivers/misc/gna/gna_driver.c
>> @@ -0,0 +1,65 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +// Copyright(c) 2017-2021 Intel Corporation
>> +
>> +#define pr_fmt(fmt) KBUILD_MODNAME " " fmt
>
> You are a driver, you should never need a pr_* call, so this should not
> be needed.  You should always just use dev_* instead.
>

Hi Greg and all other Reviewers.

Thank You for all the comments so far.

I'm starting preparing PATCH v2 series based on them.
I'll also answer comments individually where need arises.

regards,
Maciej


[PATCH v1 11/12] gna: add ioctl handler

2021-02-16 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Add ioctl handler into GNA driver.
The ioctl interface provides the ability to do the following:
 - Map and unmap memory buffers for GNA computation requests.
 - Retrieve capabilities of the underlying GNA IP.
 - Submit GNA computation requests.
 - Request notification of scoring completion.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/gna/Kbuild   |   2 +-
 drivers/misc/gna/gna_device.c |  40 ++
 drivers/misc/gna/gna_device.h |   2 +
 drivers/misc/gna/gna_ioctl.c  | 249 ++
 drivers/misc/gna/gna_ioctl.h  |  11 ++
 5 files changed, 303 insertions(+), 1 deletion(-)
 create mode 100644 drivers/misc/gna/gna_ioctl.c
 create mode 100644 drivers/misc/gna/gna_ioctl.h

diff --git a/drivers/misc/gna/Kbuild b/drivers/misc/gna/Kbuild
index 049e142894aa..ea91603e59f2 100644
--- a/drivers/misc/gna/Kbuild
+++ b/drivers/misc/gna/Kbuild
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-gna-y := gna_device.o gna_driver.o gna_mem.o gna_request.o gna_score.o gna_hw.o
+gna-y := gna_device.o gna_driver.o gna_mem.o gna_ioctl.o gna_request.o 
gna_score.o gna_hw.o
 
 obj-$(CONFIG_INTEL_GNA) += gna.o
diff --git a/drivers/misc/gna/gna_device.c b/drivers/misc/gna/gna_device.c
index 5198326e8af4..9faf0456fee2 100644
--- a/drivers/misc/gna/gna_device.c
+++ b/drivers/misc/gna/gna_device.c
@@ -252,3 +252,43 @@ void gna_remove(struct pci_dev *pcidev)
pci_clear_master(pcidev);
pci_release_regions(pcidev);
 }
+
+static u32 gna_device_type_by_hwid(u32 hwid)
+{
+   switch (hwid) {
+   case GNA_DEV_HWID_CNL:
+   return GNA_DEV_TYPE_0_9;
+   case GNA_DEV_HWID_GLK:
+   case GNA_DEV_HWID_EHL:
+   case GNA_DEV_HWID_ICL:
+   return GNA_DEV_TYPE_1_0;
+   case GNA_DEV_HWID_JSL:
+   case GNA_DEV_HWID_TGL:
+   return GNA_DEV_TYPE_2_0;
+   default:
+   return 0;
+   }
+}
+
+int gna_getparam(struct gna_private *gna_priv, union gna_parameter *param)
+{
+   switch (param->in.id) {
+   case GNA_PARAM_DEVICE_ID:
+   param->out.value = gna_priv->info.hwid;
+   break;
+   case GNA_PARAM_RECOVERY_TIMEOUT:
+   param->out.value = recovery_timeout;
+   break;
+   case GNA_PARAM_INPUT_BUFFER_S:
+   param->out.value = gna_priv->hw_info.in_buf_s;
+   break;
+   case GNA_PARAM_DEVICE_TYPE:
+   param->out.value = gna_device_type_by_hwid(gna_priv->info.hwid);
+   break;
+   default:
+   dev_err(&gna_priv->dev, "unknown parameter id %llu\n", 
param->in.id);
+   return -EINVAL;
+   }
+
+   return 0;
+}
diff --git a/drivers/misc/gna/gna_device.h b/drivers/misc/gna/gna_device.h
index 77cd1a458367..531e2b904d6a 100644
--- a/drivers/misc/gna/gna_device.h
+++ b/drivers/misc/gna/gna_device.h
@@ -82,4 +82,6 @@ int gna_probe(struct pci_dev *dev, const struct pci_device_id 
*id);
 
 void gna_remove(struct pci_dev *dev);
 
+int gna_getparam(struct gna_private *gna_priv, union gna_parameter *param);
+
 #endif /* __GNA_DEVICE_H__ */
diff --git a/drivers/misc/gna/gna_ioctl.c b/drivers/misc/gna/gna_ioctl.c
new file mode 100644
index ..a408336d4b6c
--- /dev/null
+++ b/drivers/misc/gna/gna_ioctl.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright(c) 2017-2021 Intel Corporation
+
+#include 
+
+#include 
+
+#include "gna_driver.h"
+#include "gna_device.h"
+#include "gna_ioctl.h"
+#include "gna_mem.h"
+#include "gna_request.h"
+#include "gna_score.h"
+
+static int gna_ioctl_score(struct gna_file_private *file_priv, void __user 
*argptr)
+{
+   union gna_compute score_args;
+   struct gna_private *gna_priv;
+   u64 request_id;
+   int ret;
+
+   gna_priv = file_priv->gna_priv;
+
+   if (copy_from_user(&score_args, argptr, sizeof(score_args))) {
+   dev_err(&gna_priv->dev, "could not copy score ioctl config from 
user\n");
+   return -EFAULT;
+   }
+
+   ret = gna_validate_score_config(&score_args.in.config, file_priv);
+   if (ret) {
+   dev_err(&gna_priv->dev, "request not valid\n");
+   return ret;
+   }
+
+   ret = gna_enqueue_request(&score_args.in.config, file_priv, 
&request_id);
+   if (ret) {
+   dev_err(&gna_priv->dev, "could not enqueue score request %d\n", 
ret);
+   return ret;
+   }
+
+   score_args.out.request_id = request_id;
+   if (copy_to_user(argptr, &score_args, sizeof(score_args))) {
+   dev_err(&gna_priv->dev, "could 

[PATCH v1 10/12] gna: add interrupt handler

2021-02-16 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

An interrupt is generated by the hardware when a scoring job is
done. The interrupt handler wakes up the work queue to resume
the processing on the current request.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/gna/gna_device.c | 32 ++--
 drivers/misc/gna/gna_device.h |  2 ++
 drivers/misc/gna/gna_hw.c | 10 ++
 drivers/misc/gna/gna_hw.h |  2 ++
 4 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/gna/gna_device.c b/drivers/misc/gna/gna_device.c
index a229f51fb17b..5198326e8af4 100644
--- a/drivers/misc/gna/gna_device.c
+++ b/drivers/misc/gna/gna_device.c
@@ -182,6 +182,27 @@ int gna_probe(struct pci_dev *pcidev, const struct 
pci_device_id *pci_id)
goto err_clear_master;
}
 
+   ret = pci_alloc_irq_vectors(pcidev, 1, 1, PCI_IRQ_ALL_TYPES);
+   if (ret < 0)
+   goto err_clear_master;
+
+   gna_priv->irq = pci_irq_vector(pcidev, 0);
+   if (unlikely(gna_priv->irq < 0)) {
+   dev_err(&pcidev->dev, "could not obtain irq number\n");
+   ret = -EIO;
+   goto err_free_irq_vector;
+   }
+
+   ret = request_irq(gna_priv->irq, gna_interrupt,
+  IRQF_SHARED, GNA_DRV_NAME, gna_priv);
+
+   if (ret) {
+   dev_err(&pcidev->dev, "could not register for interrupt\n");
+   goto err_free_irq_vector;
+   }
+
+   dev_dbg(&pcidev->dev, "irq num %d\n", gna_priv->irq);
+
/* Map BAR0 */
gna_priv->bar0.iostart = pci_resource_start(pcidev, 0);
gna_priv->bar0.iosize = pci_resource_len(pcidev, 0);
@@ -189,7 +210,7 @@ int gna_probe(struct pci_dev *pcidev, const struct 
pci_device_id *pci_id)
if (!gna_priv->bar0.mem_addr) {
dev_err(&pcidev->dev, "could not map BAR 0\n");
ret = -EINVAL;
-   goto err_clear_master;
+   goto err_free_irq;
}
 
dev_dbg(&pcidev->dev, "bar0 io start: 0x%llx\n", (unsigned long 
long)gna_priv->bar0.iostart);
@@ -199,11 +220,15 @@ int gna_probe(struct pci_dev *pcidev, const struct 
pci_device_id *pci_id)
ret = gna_dev_init(gna_priv, pcidev, pci_id);
if (ret) {
dev_err(&pcidev->dev, "could not initialize gna private 
structure\n");
-   goto err_clear_master;
+   goto err_free_irq;
}
 
return 0;
 
+err_free_irq:
+   free_irq(gna_priv->irq, gna_priv);
+err_free_irq_vector:
+   pci_free_irq_vectors(pcidev);
 err_clear_master:
pci_clear_master(pcidev);
 err_release_regions:
@@ -219,7 +244,10 @@ void gna_remove(struct pci_dev *pcidev)
 
gna_priv = pci_get_drvdata(pcidev);
 
+   free_irq(gna_priv->irq, gna_priv);
+
gna_dev_deinit(gna_priv);
+   pci_free_irq_vectors(pcidev);
 
pci_clear_master(pcidev);
pci_release_regions(pcidev);
diff --git a/drivers/misc/gna/gna_device.h b/drivers/misc/gna/gna_device.h
index 0855972cd085..77cd1a458367 100644
--- a/drivers/misc/gna/gna_device.h
+++ b/drivers/misc/gna/gna_device.h
@@ -46,12 +46,14 @@ struct gna_private {
struct device dev;
struct cdev cdev;
 
+   /* hardware status set by interrupt handler */
u32 hw_status;
 
/* device related resources */
struct gna_pci_bar bar0;
struct gna_drv_info info;
struct gna_hw_info hw_info;
+   int irq;
 
struct gna_mmu_object mmu;
/* lock protecting mmu structure */
diff --git a/drivers/misc/gna/gna_hw.c b/drivers/misc/gna/gna_hw.c
index 48e09e5f3ca8..6146cbd43004 100644
--- a/drivers/misc/gna/gna_hw.c
+++ b/drivers/misc/gna/gna_hw.c
@@ -124,3 +124,13 @@ void gna_abort_hw(struct gna_private *gna_priv)
if (i == 0)
dev_err(&gna_priv->dev, "abort did not complete\n");
 }
+
+irqreturn_t gna_interrupt(int irq, void *priv)
+{
+   struct gna_private *gna_priv;
+
+   gna_priv = (struct gna_private *)priv;
+   gna_priv->busy = false;
+   wake_up(&gna_priv->busy_waitq);
+   return IRQ_HANDLED;
+}
diff --git a/drivers/misc/gna/gna_hw.h b/drivers/misc/gna/gna_hw.h
index 4da29870c4dc..4dfa05937943 100644
--- a/drivers/misc/gna/gna_hw.h
+++ b/drivers/misc/gna/gna_hw.h
@@ -6,6 +6,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 /* GNA MMIO registers */
@@ -70,6 +71,7 @@ struct gna_desc_info {
 struct gna_private;
 struct gna_compute_cfg;
 
+irqreturn_t gna_interrupt(int irq, void *ctx);
 void gna_abort_hw(struct gna_private *gna_priv);
 bool gna_hw_perf_enabled(struct gna_private *gna_priv);
 int gna_parse_hw_status(struct gna_private *gna_priv, u32 hw_status);
-- 
2.28.0



[PATCH v1 09/12] gna: add a work queue to process scoring requests

2021-02-16 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

The new workqueue is responsible to process the list of requests
in a FIFO manner. It waits for the hardware to complete on every
request until it is woken up by an interrupt that will be addressed
in following changes.

Signed-off-by: Tomasz Jankowski 
Co-developed-by: Anisha Dattatraya Kulkarni 

Signed-off-by: Anisha Dattatraya Kulkarni 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/gna/gna_device.c  |  21 +-
 drivers/misc/gna/gna_device.h  |   8 +++
 drivers/misc/gna/gna_driver.c  |   5 ++
 drivers/misc/gna/gna_hw.c  |   8 +++
 drivers/misc/gna/gna_hw.h  |   1 +
 drivers/misc/gna/gna_request.c | 119 +
 drivers/misc/gna/gna_request.h |   1 +
 7 files changed, 162 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/gna/gna_device.c b/drivers/misc/gna/gna_device.c
index 7a124ea1..a229f51fb17b 100644
--- a/drivers/misc/gna/gna_device.c
+++ b/drivers/misc/gna/gna_device.c
@@ -89,6 +89,7 @@ static int gna_dev_init(struct gna_private *gna_priv, struct 
pci_dev *pcidev,
const struct pci_device_id *pci_id)
 {
u32 bld_reg;
+   int ret;
 
pci_set_drvdata(pcidev, gna_priv);
 
@@ -102,7 +103,9 @@ static int gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
 
if (gna_mmu_alloc(gna_priv)) {
dev_err(&gna_priv->dev, "gna mmu allocation failed\n");
-   return -EFAULT;
+   ret = -EFAULT;
+   goto err_pci_drvdata_unset;
+
}
dev_dbg(&pcidev->dev, "maximum memory size %llu num pd %d\n",
gna_priv->info.max_hw_mem, gna_priv->info.num_pagetables);
@@ -111,6 +114,7 @@ static int gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
gna_priv->info.desc_info.mmu_info.vamax_size);
 
mutex_init(&gna_priv->mmu_lock);
+   init_waitqueue_head(&gna_priv->busy_waitq);
 
mutex_init(&gna_priv->filelist_lock);
INIT_LIST_HEAD(&gna_priv->file_list);
@@ -119,15 +123,30 @@ static int gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
 
idr_init(&gna_priv->memory_idr);
mutex_init(&gna_priv->memidr_lock);
+
+   gna_priv->request_wq = create_singlethread_workqueue("gna_request_wq");
+   if (!gna_priv->request_wq) {
+   dev_err(&pcidev->dev, "could not create wq for gna device\n");
+   ret = -EFAULT;
+   goto err_pci_drvdata_unset;
+   }
mutex_init(&gna_priv->reqlist_lock);
INIT_LIST_HEAD(&gna_priv->request_list);
 
return 0;
+
+err_pci_drvdata_unset:
+   pci_set_drvdata(pcidev, NULL);
+
+   return ret;
 }
 
 /* Reverse gna_dev_init() */
 static void gna_dev_deinit(struct gna_private *gna_priv)
 {
+   flush_workqueue(gna_priv->request_wq);
+   destroy_workqueue(gna_priv->request_wq);
+
idr_destroy(&gna_priv->memory_idr);
gna_mmu_free(gna_priv);
pci_set_drvdata(gna_priv->pdev, NULL);
diff --git a/drivers/misc/gna/gna_device.h b/drivers/misc/gna/gna_device.h
index 59b074704d1a..0855972cd085 100644
--- a/drivers/misc/gna/gna_device.h
+++ b/drivers/misc/gna/gna_device.h
@@ -46,6 +46,8 @@ struct gna_private {
struct device dev;
struct cdev cdev;
 
+   u32 hw_status;
+
/* device related resources */
struct gna_pci_bar bar0;
struct gna_drv_info info;
@@ -55,9 +57,15 @@ struct gna_private {
/* lock protecting mmu structure */
struct mutex mmu_lock;
 
+   /* device busy indicator */
+   bool busy;
+
+   struct wait_queue_head busy_waitq;
+
/* requests */
struct list_head request_list;
struct mutex reqlist_lock;  /* protects request_list */
+   struct workqueue_struct *request_wq;
atomic_t request_count;
 
/* memory objects */
diff --git a/drivers/misc/gna/gna_driver.c b/drivers/misc/gna/gna_driver.c
index 80981c448f3a..cb638dfa81ac 100644
--- a/drivers/misc/gna/gna_driver.c
+++ b/drivers/misc/gna/gna_driver.c
@@ -9,6 +9,11 @@
 #include "gna_device.h"
 #include "gna_driver.h"
 
+/* recovery timeout in seconds */
+int recovery_timeout = 60;
+module_param(recovery_timeout, int, 0644);
+MODULE_PARM_DESC(recovery_timeout, "Recovery timeout");
+
 struct gna_driver_private gna_drv_priv;
 
 struct class *gna_class;
diff --git a/drivers/misc/gna/gna_hw.c b/drivers/misc/gna/gna_hw.c
index 3b85c4b75fd8..48e09e5f3ca8 100644
--- a/drivers/misc/gna/gna_hw.c
+++ b/drivers/misc/gna/gna_hw.c
@@ -49,6 +49,14 @@ void gna_print_error_status(struct gna_private *gna_priv, 
u32 hw_status)
dev_dbg(&gna_p

[PATCH v1 08/12] gna: implement scoring

2021-02-16 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Add a new component for scoring logic such as configuring and kicking
off the hardware.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/gna/Kbuild   |   2 +-
 drivers/misc/gna/gna_device.c |   3 +
 drivers/misc/gna/gna_device.h |   5 +
 drivers/misc/gna/gna_hw.h |   2 -
 drivers/misc/gna/gna_score.c  | 299 ++
 drivers/misc/gna/gna_score.h  |  20 +++
 6 files changed, 328 insertions(+), 3 deletions(-)
 create mode 100644 drivers/misc/gna/gna_score.c
 create mode 100644 drivers/misc/gna/gna_score.h

diff --git a/drivers/misc/gna/Kbuild b/drivers/misc/gna/Kbuild
index f47775759a6e..049e142894aa 100644
--- a/drivers/misc/gna/Kbuild
+++ b/drivers/misc/gna/Kbuild
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-gna-y := gna_device.o gna_driver.o gna_mem.o gna_request.o gna_hw.o
+gna-y := gna_device.o gna_driver.o gna_mem.o gna_request.o gna_score.o gna_hw.o
 
 obj-$(CONFIG_INTEL_GNA) += gna.o
diff --git a/drivers/misc/gna/gna_device.c b/drivers/misc/gna/gna_device.c
index cd8ee86bbc58..7a124ea1 100644
--- a/drivers/misc/gna/gna_device.c
+++ b/drivers/misc/gna/gna_device.c
@@ -112,6 +112,9 @@ static int gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
 
mutex_init(&gna_priv->mmu_lock);
 
+   mutex_init(&gna_priv->filelist_lock);
+   INIT_LIST_HEAD(&gna_priv->file_list);
+
atomic_set(&gna_priv->request_count, 0);
 
idr_init(&gna_priv->memory_idr);
diff --git a/drivers/misc/gna/gna_device.h b/drivers/misc/gna/gna_device.h
index 445c81c698fb..59b074704d1a 100644
--- a/drivers/misc/gna/gna_device.h
+++ b/drivers/misc/gna/gna_device.h
@@ -35,6 +35,11 @@ struct gna_hw_info {
 struct gna_private {
struct gna_driver_private *drv_priv;
 
+   /* list of opened files */
+   struct list_head file_list;
+   /* lock protecting file_list */
+   struct mutex filelist_lock;
+
/* device objects */
struct pci_dev *pdev;
struct device *parent; /* pdev->dev */
diff --git a/drivers/misc/gna/gna_hw.h b/drivers/misc/gna/gna_hw.h
index e09e562aae50..941f54b0f29a 100644
--- a/drivers/misc/gna/gna_hw.h
+++ b/drivers/misc/gna/gna_hw.h
@@ -33,8 +33,6 @@
 /* minimum size of XNN layer descriptors in bytes (at least 1 layer) */
 #define XNN_LYR_DSC_SIZE   (128)
 
-#define GMM_CFG_SIZE   (128)
-
 #define GNA_VAMAXADDR_OFFSET   0x200
 
 #define GNA_PGDIRN_OFFSET  0x210
diff --git a/drivers/misc/gna/gna_score.c b/drivers/misc/gna/gna_score.c
new file mode 100644
index ..e708e449e1ee
--- /dev/null
+++ b/drivers/misc/gna/gna_score.c
@@ -0,0 +1,299 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright(c) 2017-2021 Intel Corporation
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "gna_device.h"
+#include "gna_driver.h"
+#include "gna_request.h"
+#include "gna_score.h"
+
+int gna_validate_score_config(struct gna_compute_cfg *compute_cfg,
+ struct gna_file_private *file_priv)
+{
+   struct gna_private *gna_priv;
+   size_t buffers_size;
+
+   gna_priv = file_priv->gna_priv;
+
+   if (compute_cfg->gna_mode > GNA_MODE_XNN) {
+   dev_err(&gna_priv->dev, "gna mode invalid\n");
+   return -EINVAL;
+   }
+
+   if (compute_cfg->layer_count > gna_priv->info.max_layer_count) {
+   dev_err(&gna_priv->dev, "max layer count exceeded\n");
+   return -EINVAL;
+   }
+
+   if (compute_cfg->buffer_count == 0) {
+   dev_err(&gna_priv->dev, "no buffers\n");
+   return -EINVAL;
+   }
+
+   buffers_size = sizeof(struct gna_buffer) * compute_cfg->buffer_count;
+   if (!access_ok(u64_to_user_ptr(compute_cfg->buffers_ptr), 
buffers_size)) {
+   dev_err(&gna_priv->dev, "invalid buffers pointer\n");
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int gna_do_patch_memory(struct gna_private *gna_priv, struct 
gna_memory_object *mo,
+  struct gna_memory_patch *patch, void *vaddr)
+{
+   size_t size;
+   void *dest;
+   u64 value;
+
+   value = patch->value;
+   size = patch->size;
+   dest = (u8 *)vaddr + patch->offset;
+   dev_dbg(&gna_priv->dev, "patch offset: %llu, size: %zu, value: %llu\n",
+   patch->offset, size, value);
+
+   switch (size) {
+   case 0:
+   return -EFAULT;
+ 

[PATCH v1 07/12] gna: add request component

2021-02-16 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

The scoring work submitted to the GNA driver is implemented as a
list of requests that will be processed by the hardware.

Signed-off-by: Tomasz Jankowski 
Co-developed-by: Anisha Dattatraya Kulkarni 

Signed-off-by: Anisha Dattatraya Kulkarni 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/gna/Kbuild|   2 +-
 drivers/misc/gna/gna_device.c  |   5 +
 drivers/misc/gna/gna_device.h  |   5 +
 drivers/misc/gna/gna_mem.c |   3 +
 drivers/misc/gna/gna_request.c | 347 +
 drivers/misc/gna/gna_request.h |  61 ++
 6 files changed, 422 insertions(+), 1 deletion(-)
 create mode 100644 drivers/misc/gna/gna_request.c
 create mode 100644 drivers/misc/gna/gna_request.h

diff --git a/drivers/misc/gna/Kbuild b/drivers/misc/gna/Kbuild
index 860b14c0e8d0..f47775759a6e 100644
--- a/drivers/misc/gna/Kbuild
+++ b/drivers/misc/gna/Kbuild
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-gna-y := gna_device.o gna_driver.o gna_mem.o gna_hw.o
+gna-y := gna_device.o gna_driver.o gna_mem.o gna_request.o gna_hw.o
 
 obj-$(CONFIG_INTEL_GNA) += gna.o
diff --git a/drivers/misc/gna/gna_device.c b/drivers/misc/gna/gna_device.c
index 7031a5d7c16c..cd8ee86bbc58 100644
--- a/drivers/misc/gna/gna_device.c
+++ b/drivers/misc/gna/gna_device.c
@@ -7,6 +7,7 @@
 #include "gna_device.h"
 #include "gna_driver.h"
 #include "gna_hw.h"
+#include "gna_request.h"
 
 #define GNA_DEV_HWID_CNL   0x5A11
 #define GNA_DEV_HWID_EHL   0x4511
@@ -111,8 +112,12 @@ static int gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
 
mutex_init(&gna_priv->mmu_lock);
 
+   atomic_set(&gna_priv->request_count, 0);
+
idr_init(&gna_priv->memory_idr);
mutex_init(&gna_priv->memidr_lock);
+   mutex_init(&gna_priv->reqlist_lock);
+   INIT_LIST_HEAD(&gna_priv->request_list);
 
return 0;
 }
diff --git a/drivers/misc/gna/gna_device.h b/drivers/misc/gna/gna_device.h
index 22c47f2c03ec..445c81c698fb 100644
--- a/drivers/misc/gna/gna_device.h
+++ b/drivers/misc/gna/gna_device.h
@@ -50,6 +50,11 @@ struct gna_private {
/* lock protecting mmu structure */
struct mutex mmu_lock;
 
+   /* requests */
+   struct list_head request_list;
+   struct mutex reqlist_lock;  /* protects request_list */
+   atomic_t request_count;
+
/* memory objects */
struct idr memory_idr;
/* lock protecting memory_idr */
diff --git a/drivers/misc/gna/gna_mem.c b/drivers/misc/gna/gna_mem.c
index a2ac3c31b4fb..09c4f401c3fa 100644
--- a/drivers/misc/gna/gna_mem.c
+++ b/drivers/misc/gna/gna_mem.c
@@ -19,6 +19,7 @@
 #include "gna_device.h"
 #include "gna_driver.h"
 #include "gna_mem.h"
+#include "gna_request.h"
 
 static void gna_mmu_init(struct gna_private *gna_priv)
 {
@@ -391,6 +392,8 @@ static void gna_memory_release(struct work_struct *work)
 
mo = container_of(work, struct gna_memory_object, work);
 
+   gna_delete_memory_requests(mo->memory_id, mo->gna_priv);
+
mo->user_ptr = NULL;
 
wake_up_interruptible(&mo->waitq);
diff --git a/drivers/misc/gna/gna_request.c b/drivers/misc/gna/gna_request.c
new file mode 100644
index ..a7a55fe68eed
--- /dev/null
+++ b/drivers/misc/gna/gna_request.c
@@ -0,0 +1,347 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright(c) 2017-2021 Intel Corporation
+
+#include 
+#include 
+#include 
+#include 
+
+#include "gna_device.h"
+#include "gna_driver.h"
+#include "gna_request.h"
+
+static struct gna_request *gna_request_create(struct gna_file_private 
*file_priv,
+  struct gna_compute_cfg *compute_cfg)
+{
+   struct gna_request *score_request;
+   struct gna_private *gna_priv;
+
+   gna_priv = file_priv->gna_priv;
+   if (IS_ERR(gna_priv))
+   return NULL;
+
+   score_request = kzalloc(sizeof(*score_request), GFP_KERNEL);
+   if (!score_request)
+   return NULL;
+   kref_init(&score_request->refcount);
+
+   dev_dbg(&gna_priv->dev, "layer_base %d layer_count %d\n",
+   compute_cfg->layer_base, compute_cfg->layer_count);
+
+   score_request->request_id = atomic_inc_return(&gna_priv->request_count);
+   score_request->compute_cfg = *compute_cfg;
+   score_request->fd = file_priv->fd;
+   score_request->gna_priv = gna_priv;
+   score_request->state = NEW;
+   init_waitqueue_head(&score_request->waitq);
+
+   return score_request;
+}
+
+/*
+ * returns true if [inner_offset, inner_size) is embraced by [0, outer_size). 
False otherwise.
+ */
+

[PATCH v1 06/12] gna: add hardware ids

2021-02-16 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Add PCI ids of Intel(R) Gaussian & Neural Accelerator on supported
platforms.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/gna/gna_device.c | 76 +++
 drivers/misc/gna/gna_device.h |  2 +
 drivers/misc/gna/gna_driver.c |  1 +
 3 files changed, 79 insertions(+)

diff --git a/drivers/misc/gna/gna_device.c b/drivers/misc/gna/gna_device.c
index d6a6d3cab570..7031a5d7c16c 100644
--- a/drivers/misc/gna/gna_device.c
+++ b/drivers/misc/gna/gna_device.c
@@ -8,6 +8,82 @@
 #include "gna_driver.h"
 #include "gna_hw.h"
 
+#define GNA_DEV_HWID_CNL   0x5A11
+#define GNA_DEV_HWID_EHL   0x4511
+#define GNA_DEV_HWID_GLK   0x3190
+#define GNA_DEV_HWID_ICL   0x8A11
+#define GNA_DEV_HWID_JSL   0x4E11
+#define GNA_DEV_HWID_TGL   0x9A11
+
+#define GNA_FEATURES \
+   .max_hw_mem = 256 * 1024 * 1024, \
+   .num_pagetables = 64, \
+   .num_page_entries = PAGE_SIZE / sizeof(u32), \
+   /* desc_info all in bytes */ \
+   .desc_info = { \
+   .rsvd_size = 256, \
+   .cfg_size = 256, \
+   .desc_size = 784, \
+   .mmu_info = { \
+   .vamax_size = 4, \
+   .rsvd_size = 12, \
+   .pd_size = 4 * 64, \
+   }, \
+   }
+
+#define GNA_GEN1_FEATURES \
+   GNA_FEATURES, \
+   .max_layer_count = 1024
+
+#define GNA_GEN2_FEATURES \
+   GNA_FEATURES, \
+   .max_layer_count = 4096
+
+static const struct gna_drv_info cnl_drv_info = {
+   .hwid = GNA_DEV_HWID_CNL,
+   GNA_GEN1_FEATURES
+};
+
+static const struct gna_drv_info glk_drv_info = {
+   .hwid = GNA_DEV_HWID_GLK,
+   GNA_GEN1_FEATURES
+};
+
+static const struct gna_drv_info ehl_drv_info = {
+   .hwid = GNA_DEV_HWID_EHL,
+   GNA_GEN1_FEATURES
+};
+
+static const struct gna_drv_info icl_drv_info = {
+   .hwid = GNA_DEV_HWID_ICL,
+   GNA_GEN1_FEATURES
+};
+
+static const struct gna_drv_info jsl_drv_info = {
+   .hwid = GNA_DEV_HWID_JSL,
+   GNA_GEN2_FEATURES
+};
+
+static const struct gna_drv_info tgl_drv_info = {
+   .hwid = GNA_DEV_HWID_TGL,
+   GNA_GEN2_FEATURES
+};
+
+#define INTEL_GNA_DEVICE(hwid, info) \
+   { PCI_VDEVICE(INTEL, hwid), (kernel_ulong_t)(info) }
+
+const struct pci_device_id gna_pci_ids[] = {
+   INTEL_GNA_DEVICE(GNA_DEV_HWID_CNL, &cnl_drv_info),
+   INTEL_GNA_DEVICE(GNA_DEV_HWID_EHL, &ehl_drv_info),
+   INTEL_GNA_DEVICE(GNA_DEV_HWID_GLK, &glk_drv_info),
+   INTEL_GNA_DEVICE(GNA_DEV_HWID_ICL, &icl_drv_info),
+   INTEL_GNA_DEVICE(GNA_DEV_HWID_JSL, &jsl_drv_info),
+   INTEL_GNA_DEVICE(GNA_DEV_HWID_TGL, &tgl_drv_info),
+   { }
+};
+
+MODULE_DEVICE_TABLE(pci, gna_pci_ids);
+
 static int gna_dev_init(struct gna_private *gna_priv, struct pci_dev *pcidev,
const struct pci_device_id *pci_id)
 {
diff --git a/drivers/misc/gna/gna_device.h b/drivers/misc/gna/gna_device.h
index ee234e474d43..22c47f2c03ec 100644
--- a/drivers/misc/gna/gna_device.h
+++ b/drivers/misc/gna/gna_device.h
@@ -56,6 +56,8 @@ struct gna_private {
struct mutex memidr_lock;
 };
 
+extern const struct pci_device_id gna_pci_ids[];
+
 int gna_probe(struct pci_dev *dev, const struct pci_device_id *id);
 
 void gna_remove(struct pci_dev *dev);
diff --git a/drivers/misc/gna/gna_driver.c b/drivers/misc/gna/gna_driver.c
index 81f0f003f377..80981c448f3a 100644
--- a/drivers/misc/gna/gna_driver.c
+++ b/drivers/misc/gna/gna_driver.c
@@ -15,6 +15,7 @@ struct class *gna_class;
 
 static struct pci_driver gna_driver = {
.name = GNA_DRV_NAME,
+   .id_table = gna_pci_ids,
.probe = gna_probe,
.remove = gna_remove,
 };
-- 
2.28.0



[PATCH v1 04/12] gna: add memory handling

2021-02-16 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Patch adds memory handling - mapping, DMA, pinning.
The GNA driver maps and unmaps the physical pages for 64-byte aligned
buffer allocated by user space program. The pages of mapped memory
are being locked only during actual computation.

Patch adds configuration of the DMA scatter gather list for physical pages
and generation of page table and page directory to be programmed in the GNA HW
at the time of scoring initiation.

GNA’s MMU is being configured based on specific request memory usage.
As the MMU can address up to 256MB a single scoring request is limited
to this amount of memory being used.

GNA Library can allocate any number of memory regions for GNA usage.
Its number and total capacity are limited by the OSs’ resources.
Due to GNA MMU restrictions, even when using multiple memory regions,
the sum of all the memory regions used within a single inference
request must be less than 256MB.

At least a single GNA memory region is needed to be allocated
(and can be shared by multiple models). At the other extreme,
each GNA tensor (e.g., weights/biases/inputs/outputs) could use
its own, separate GNA memory region.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/gna/Kbuild   |   2 +-
 drivers/misc/gna/gna_device.c |   6 +
 drivers/misc/gna/gna_device.h |  11 +-
 drivers/misc/gna/gna_mem.c| 469 ++
 drivers/misc/gna/gna_mem.h| 107 
 5 files changed, 593 insertions(+), 2 deletions(-)
 create mode 100644 drivers/misc/gna/gna_mem.c
 create mode 100644 drivers/misc/gna/gna_mem.h

diff --git a/drivers/misc/gna/Kbuild b/drivers/misc/gna/Kbuild
index 8620d88588e5..860b14c0e8d0 100644
--- a/drivers/misc/gna/Kbuild
+++ b/drivers/misc/gna/Kbuild
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-gna-y := gna_device.o gna_driver.o gna_hw.o
+gna-y := gna_device.o gna_driver.o gna_mem.o gna_hw.o
 
 obj-$(CONFIG_INTEL_GNA) += gna.o
diff --git a/drivers/misc/gna/gna_device.c b/drivers/misc/gna/gna_device.c
index 869507594f9e..f962c7e1e5e9 100644
--- a/drivers/misc/gna/gna_device.c
+++ b/drivers/misc/gna/gna_device.c
@@ -23,12 +23,18 @@ static int gna_dev_init(struct gna_private *gna_priv, 
struct pci_dev *pcidev,
bld_reg = gna_reg_read(gna_priv->bar0.mem_addr, GNA_MMIO_IBUFFS);
gna_priv->hw_info.in_buf_s = bld_reg & GENMASK(7, 0);
 
+   mutex_init(&gna_priv->mmu_lock);
+
+   idr_init(&gna_priv->memory_idr);
+   mutex_init(&gna_priv->memidr_lock);
+
return 0;
 }
 
 /* Reverse gna_dev_init() */
 static void gna_dev_deinit(struct gna_private *gna_priv)
 {
+   idr_destroy(&gna_priv->memory_idr);
pci_set_drvdata(gna_priv->pdev, NULL);
 }
 
diff --git a/drivers/misc/gna/gna_device.h b/drivers/misc/gna/gna_device.h
index add8088ffa28..ee234e474d43 100644
--- a/drivers/misc/gna/gna_device.h
+++ b/drivers/misc/gna/gna_device.h
@@ -10,7 +10,7 @@
 
 #include 
 
-#include "gna_hw.h"
+#include "gna_mem.h"
 
 struct gna_drv_info {
u32 hwid;
@@ -45,6 +45,15 @@ struct gna_private {
struct gna_pci_bar bar0;
struct gna_drv_info info;
struct gna_hw_info hw_info;
+
+   struct gna_mmu_object mmu;
+   /* lock protecting mmu structure */
+   struct mutex mmu_lock;
+
+   /* memory objects */
+   struct idr memory_idr;
+   /* lock protecting memory_idr */
+   struct mutex memidr_lock;
 };
 
 int gna_probe(struct pci_dev *dev, const struct pci_device_id *id);
diff --git a/drivers/misc/gna/gna_mem.c b/drivers/misc/gna/gna_mem.c
new file mode 100644
index ..a2ac3c31b4fb
--- /dev/null
+++ b/drivers/misc/gna/gna_mem.c
@@ -0,0 +1,469 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright(c) 2017-2021 Intel Corporation
+
+#define pr_fmt(fmt) KBUILD_MODNAME " " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "gna_device.h"
+#include "gna_driver.h"
+#include "gna_mem.h"
+
+static void gna_mmu_init(struct gna_private *gna_priv)
+{
+   struct gna_mmu_object *mmu;
+   dma_addr_t pagetable_dma;
+   u32 *pgdirn;
+   int i;
+
+   mmu = &gna_priv->mmu;
+
+   pgdirn = mmu->hwdesc->mmu.pagedir_n;
+
+   for (i = 0; i < mmu->num_pagetables; i++) {
+   pagetable_dma = mmu->pagetables_dma[i];
+   pgdirn[i] = pagetable_dma >> PAGE_SHIFT;
+   }
+
+   for (; i < GNA_PGDIRN_LEN; i++)
+   pgdirn[i] = GNA_PGDIR_INVALID;
+}
+
+/* descriptor and page tables allocation */
+int gna_mmu_alloc(struct gna_private *gna_priv)
+{
+   struct gna_mmu_object *mmu;
+   int desc_size;
+   int i;
+
+   if (gn

[PATCH v1 05/12] gna: initialize mmu

2021-02-16 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Setup mmu in the driver with a new memory component.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/gna/gna_device.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/misc/gna/gna_device.c b/drivers/misc/gna/gna_device.c
index f962c7e1e5e9..d6a6d3cab570 100644
--- a/drivers/misc/gna/gna_device.c
+++ b/drivers/misc/gna/gna_device.c
@@ -23,6 +23,16 @@ static int gna_dev_init(struct gna_private *gna_priv, struct 
pci_dev *pcidev,
bld_reg = gna_reg_read(gna_priv->bar0.mem_addr, GNA_MMIO_IBUFFS);
gna_priv->hw_info.in_buf_s = bld_reg & GENMASK(7, 0);
 
+   if (gna_mmu_alloc(gna_priv)) {
+   dev_err(&gna_priv->dev, "gna mmu allocation failed\n");
+   return -EFAULT;
+   }
+   dev_dbg(&pcidev->dev, "maximum memory size %llu num pd %d\n",
+   gna_priv->info.max_hw_mem, gna_priv->info.num_pagetables);
+   dev_dbg(&pcidev->dev, "desc rsvd size %d mmu vamax size %d\n",
+   gna_priv->info.desc_info.rsvd_size,
+   gna_priv->info.desc_info.mmu_info.vamax_size);
+
mutex_init(&gna_priv->mmu_lock);
 
idr_init(&gna_priv->memory_idr);
@@ -35,6 +45,7 @@ static int gna_dev_init(struct gna_private *gna_priv, struct 
pci_dev *pcidev,
 static void gna_dev_deinit(struct gna_private *gna_priv)
 {
idr_destroy(&gna_priv->memory_idr);
+   gna_mmu_free(gna_priv);
pci_set_drvdata(gna_priv->pdev, NULL);
 }
 
-- 
2.28.0



[PATCH v1 03/12] gna: read hardware info in the driver

2021-02-16 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Get the hardware information from register MMIO_IBUFFS

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/gna/gna_device.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/misc/gna/gna_device.c b/drivers/misc/gna/gna_device.c
index a6ef7e790e9e..869507594f9e 100644
--- a/drivers/misc/gna/gna_device.c
+++ b/drivers/misc/gna/gna_device.c
@@ -6,10 +6,13 @@
 
 #include "gna_device.h"
 #include "gna_driver.h"
+#include "gna_hw.h"
 
 static int gna_dev_init(struct gna_private *gna_priv, struct pci_dev *pcidev,
const struct pci_device_id *pci_id)
 {
+   u32 bld_reg;
+
pci_set_drvdata(pcidev, gna_priv);
 
gna_priv->parent = &pcidev->dev;
@@ -17,6 +20,9 @@ static int gna_dev_init(struct gna_private *gna_priv, struct 
pci_dev *pcidev,
gna_priv->info = *(struct gna_drv_info *)pci_id->driver_data;
gna_priv->drv_priv = &gna_drv_priv;
 
+   bld_reg = gna_reg_read(gna_priv->bar0.mem_addr, GNA_MMIO_IBUFFS);
+   gna_priv->hw_info.in_buf_s = bld_reg & GENMASK(7, 0);
+
return 0;
 }
 
-- 
2.28.0



[PATCH v1 02/12] gna: add component of hardware operation

2021-02-16 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Add definitions and utilities to interact with the hardware
device.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/gna/Kbuild   |   2 +-
 drivers/misc/gna/gna_device.h |   4 ++
 drivers/misc/gna/gna_hw.c | 118 ++
 drivers/misc/gna/gna_hw.h |  84 
 4 files changed, 207 insertions(+), 1 deletion(-)
 create mode 100644 drivers/misc/gna/gna_hw.c
 create mode 100644 drivers/misc/gna/gna_hw.h

diff --git a/drivers/misc/gna/Kbuild b/drivers/misc/gna/Kbuild
index 863956d5761a..8620d88588e5 100644
--- a/drivers/misc/gna/Kbuild
+++ b/drivers/misc/gna/Kbuild
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-gna-y := gna_device.o gna_driver.o
+gna-y := gna_device.o gna_driver.o gna_hw.o
 
 obj-$(CONFIG_INTEL_GNA) += gna.o
diff --git a/drivers/misc/gna/gna_device.h b/drivers/misc/gna/gna_device.h
index 736bc5af5081..add8088ffa28 100644
--- a/drivers/misc/gna/gna_device.h
+++ b/drivers/misc/gna/gna_device.h
@@ -10,12 +10,16 @@
 
 #include 
 
+#include "gna_hw.h"
+
 struct gna_drv_info {
u32 hwid;
u32 num_pagetables;
u32 num_page_entries;
u32 max_layer_count;
u64 max_hw_mem;
+
+   struct gna_desc_info desc_info;
 };
 
 struct gna_pci_bar {
diff --git a/drivers/misc/gna/gna_hw.c b/drivers/misc/gna/gna_hw.c
new file mode 100644
index ..3b85c4b75fd8
--- /dev/null
+++ b/drivers/misc/gna/gna_hw.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright(c) 2017-2021 Intel Corporation
+
+#include 
+#include 
+
+#include 
+
+#include "gna_device.h"
+#include "gna_driver.h"
+#include "gna_hw.h"
+
+int gna_parse_hw_status(struct gna_private *gna_priv, u32 hw_status)
+{
+   int status;
+
+   if (hw_status & GNA_ERROR) {
+   dev_dbg(&gna_priv->dev, "GNA completed with errors: %#x\n", 
hw_status);
+   status = -EIO;
+   } else if (hw_status & GNA_STS_SCORE_COMPLETED) {
+   status = 0;
+   dev_dbg(&gna_priv->dev, "GNA completed successfully: %#x\n", 
hw_status);
+   } else {
+   dev_err(&gna_priv->dev, "GNA not completed, status: %#x\n", 
hw_status);
+   status = -ENODATA;
+   }
+
+   return status;
+}
+
+void gna_print_error_status(struct gna_private *gna_priv, u32 hw_status)
+{
+   if (hw_status & GNA_STS_PARAM_OOR)
+   dev_dbg(&gna_priv->dev, "GNA error: Param Out Range Error\n");
+
+   if (hw_status & GNA_STS_VA_OOR)
+   dev_dbg(&gna_priv->dev, "GNA error: VA Out of Range Error\n");
+
+   if (hw_status & GNA_STS_PCI_MMU_ERR)
+   dev_dbg(&gna_priv->dev, "GNA error: PCI MMU Error\n");
+
+   if (hw_status & GNA_STS_PCI_DMA_ERR)
+   dev_dbg(&gna_priv->dev, "GNA error: PCI MMU Error\n");
+
+   if (hw_status & GNA_STS_PCI_UNEXCOMPL_ERR)
+   dev_dbg(&gna_priv->dev, "GNA error: PCI Unexpected Completion 
Error\n");
+
+   if (hw_status & GNA_STS_SATURATE)
+   dev_dbg(&gna_priv->dev, "GNA error: Saturation Reached !\n");
+}
+
+void gna_start_scoring(struct gna_private *gna_priv, void __iomem *addr,
+  struct gna_compute_cfg *compute_cfg)
+{
+   u32 ctrl = gna_reg_read(addr, GNA_MMIO_CTRL);
+
+   ctrl |= GNA_CTRL_START_ACCEL | GNA_CTRL_COMP_INT_EN | 
GNA_CTRL_ERR_INT_EN;
+
+   ctrl &= ~GNA_CTRL_COMP_STATS_EN;
+   ctrl |= FIELD_PREP(GNA_CTRL_COMP_STATS_EN,
+   compute_cfg->hw_perf_encoding & 
FIELD_MAX(GNA_CTRL_COMP_STATS_EN));
+
+   ctrl &= ~GNA_CTRL_ACTIVE_LIST_EN;
+   ctrl |= FIELD_PREP(GNA_CTRL_ACTIVE_LIST_EN,
+   compute_cfg->active_list_on & 
FIELD_MAX(GNA_CTRL_ACTIVE_LIST_EN));
+
+   ctrl &= ~GNA_CTRL_OP_MODE;
+   ctrl |= FIELD_PREP(GNA_CTRL_OP_MODE,
+   compute_cfg->gna_mode & FIELD_MAX(GNA_CTRL_OP_MODE));
+
+   gna_reg_write(addr, GNA_MMIO_CTRL, ctrl);
+
+   dev_dbg(&gna_priv->dev, "scoring started...\n");
+}
+
+static void gna_clear_saturation(struct gna_private *gna_priv)
+{
+   void __iomem *addr = gna_priv->bar0.mem_addr;
+   u32 val;
+
+   val = gna_reg_read(addr, GNA_MMIO_STS);
+   if (val & GNA_STS_SATURATE) {
+   dev_dbg(&gna_priv->dev, "saturation reached\n");
+   dev_dbg(&gna_priv->dev, "gna status: %#x\n", val);
+
+   val = val & GNA_STS_SATURATE;
+   gna_reg_write(addr, GNA_MMIO_STS, val);
+   }
+

[PATCH v1 12/12] gna: add a char device

2021-02-16 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

The new char device is the node for applications in user space to
interact with the driver.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 drivers/misc/gna/gna_device.c | 157 ++
 drivers/misc/gna/gna_driver.c |  23 -
 2 files changed, 178 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/gna/gna_device.c b/drivers/misc/gna/gna_device.c
index 9faf0456fee2..7b2d3b4f863b 100644
--- a/drivers/misc/gna/gna_device.c
+++ b/drivers/misc/gna/gna_device.c
@@ -1,12 +1,14 @@
 // SPDX-License-Identifier: GPL-2.0-only
 // Copyright(c) 2017-2021 Intel Corporation
 
+#include 
 #include 
 #include 
 
 #include "gna_device.h"
 #include "gna_driver.h"
 #include "gna_hw.h"
+#include "gna_ioctl.h"
 #include "gna_request.h"
 
 #define GNA_DEV_HWID_CNL   0x5A11
@@ -85,6 +87,150 @@ const struct pci_device_id gna_pci_ids[] = {
 
 MODULE_DEVICE_TABLE(pci, gna_pci_ids);
 
+static inline struct gna_private *inode_to_gna(struct inode *inode)
+{
+   return container_of(inode->i_cdev, struct gna_private, cdev);
+}
+
+static int gna_open(struct inode *inode, struct file *f)
+{
+   struct gna_file_private *file_priv;
+   struct gna_private *gna_priv;
+
+   gna_priv = inode_to_gna(inode);
+   if (!gna_priv)
+   return -ENODEV;
+
+   file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
+   if (!file_priv)
+   return -ENOMEM;
+
+   file_priv->fd = f;
+   file_priv->gna_priv = gna_priv;
+
+   mutex_init(&file_priv->memlist_lock);
+   INIT_LIST_HEAD(&file_priv->memory_list);
+
+   mutex_lock(&gna_priv->filelist_lock);
+   list_add_tail(&file_priv->flist, &gna_priv->file_list);
+   mutex_unlock(&gna_priv->filelist_lock);
+
+   f->private_data = file_priv;
+
+   return 0;
+}
+
+static int gna_release(struct inode *inode, struct file *f)
+{
+   struct gna_file_private *iter_file, *temp_file;
+   struct gna_memory_object *iter_mo, *temp_mo;
+   struct gna_file_private *file_priv;
+   struct gna_private *gna_priv;
+
+   gna_priv = inode_to_gna(inode);
+   if (!gna_priv)
+   return -ENODEV;
+
+   /* free all memory objects created by that file */
+   file_priv = (struct gna_file_private *)f->private_data;
+   mutex_lock(&file_priv->memlist_lock);
+   list_for_each_entry_safe(iter_mo, temp_mo, &file_priv->memory_list, 
file_mem_list) {
+   queue_work(gna_priv->request_wq, &iter_mo->work);
+   wait_event(iter_mo->waitq, true);
+   gna_memory_free(gna_priv, iter_mo);
+   }
+   mutex_unlock(&file_priv->memlist_lock);
+
+   gna_delete_file_requests(f, gna_priv);
+
+   /* delete itself from device's file list */
+   mutex_lock(&gna_priv->filelist_lock);
+   list_for_each_entry_safe(iter_file, temp_file, &gna_priv->file_list, 
flist) {
+   if (iter_file->fd == f) {
+   list_del(&iter_file->flist);
+   f->private_data = NULL;
+   kfree(iter_file);
+   break;
+   }
+   }
+   mutex_unlock(&gna_priv->filelist_lock);
+
+   return 0;
+}
+
+static const struct file_operations gna_file_ops = {
+   .owner  =   THIS_MODULE,
+   .open   =   gna_open,
+   .release=   gna_release,
+   .unlocked_ioctl =   gna_ioctl,
+};
+
+/* Reverse gna_dev_create() */
+static void gna_dev_release(struct gna_private *gna_priv)
+{
+   cdev_device_del(&gna_priv->cdev, &gna_priv->dev);
+
+   mutex_lock(&gna_drv_priv.lock);
+   __clear_bit(MINOR(gna_priv->dev.devt), gna_drv_priv.dev_map);
+   mutex_unlock(&gna_drv_priv.lock);
+
+   dev_set_drvdata(&gna_priv->dev, NULL);
+}
+
+static int gna_dev_create(struct gna_private *gna_priv)
+{
+   struct pci_dev *pcidev;
+   struct device *dev;
+   dev_t gna_devt;
+   int dev_num;
+   int major;
+   int minor;
+   int ret;
+
+   pcidev = gna_priv->pdev;
+
+   mutex_lock(&gna_drv_priv.lock);
+
+   dev_num = find_first_zero_bit(gna_drv_priv.dev_map, GNA_MAX_DEVICES);
+   if (dev_num == GNA_MAX_DEVICES) {
+   mutex_unlock(&gna_drv_priv.lock);
+   dev_err(&pcidev->dev, "number of gna devices reached 
maximum\n");
+   return -ENODEV;
+   }
+
+   set_bit(dev_num, gna_drv_priv.dev_map);
+   major = MAJOR(gna_drv_priv.devt);
+   minor = gna_drv_priv.minor++;
+
+   mutex_unlock(&gna_drv_priv.lock);
+
+   gna

[PATCH v1 01/12] gna: add driver module

2021-02-16 Thread Maciej Kwapulinski
From: Tomasz Jankowski 

Add a new PCI driver for Intel(R) Gaussian & Neural Accelerator
with basic support like module loading and unloading. The full
function of the driver will be added by further changes.

Signed-off-by: Tomasz Jankowski 
Tested-by: Savo Novakovic 
Co-developed-by: Jianxun Zhang 
Signed-off-by: Jianxun Zhang 
Co-developed-by: Maciej Kwapulinski 
Signed-off-by: Maciej Kwapulinski 
---
 Documentation/misc-devices/gna.rst|  48 ++
 Documentation/misc-devices/index.rst  |   1 +
 .../userspace-api/ioctl/ioctl-number.rst  |   1 +
 MAINTAINERS   |   7 +
 drivers/misc/Kconfig  |   1 +
 drivers/misc/Makefile |   1 +
 drivers/misc/gna/Kbuild   |   5 +
 drivers/misc/gna/Kconfig  |  13 ++
 drivers/misc/gna/gna_device.c | 100 +++
 drivers/misc/gna/gna_device.h |  50 ++
 drivers/misc/gna/gna_driver.c |  65 
 drivers/misc/gna/gna_driver.h |  41 +
 include/uapi/misc/gna.h   | 155 ++
 13 files changed, 488 insertions(+)
 create mode 100644 Documentation/misc-devices/gna.rst
 create mode 100644 drivers/misc/gna/Kbuild
 create mode 100644 drivers/misc/gna/Kconfig
 create mode 100644 drivers/misc/gna/gna_device.c
 create mode 100644 drivers/misc/gna/gna_device.h
 create mode 100644 drivers/misc/gna/gna_driver.c
 create mode 100644 drivers/misc/gna/gna_driver.h
 create mode 100644 include/uapi/misc/gna.h

diff --git a/Documentation/misc-devices/gna.rst 
b/Documentation/misc-devices/gna.rst
new file mode 100644
index ..ed3d5a89271d
--- /dev/null
+++ b/Documentation/misc-devices/gna.rst
@@ -0,0 +1,48 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+=
+Intel(R) Gaussian & Neural Accelerator (Intel(R) GNA)
+=
+
+Acronyms
+
+GNA- Gaussian & Neural Accelerator
+GMM- Gaussian Mixer Model
+CNN- Convolutional Neural Network
+RNN- Recurrent Neural Networks
+DNN- Deep Neural Networks
+
+Introduction
+
+The Intel(R) GNA is an Internal PCI fixed device available on several Intel 
platforms/SoCs.
+Feature set depends on the Intel Chipset SKU.
+
+Intel(R) GNA provides hardware accelerated computation for GMMs and Neural 
Networks.
+It supports several layer types: affine, recurrent, and convolutional among 
others.
+Hardware also provides helper layer types for copying and transposing matrices.
+
+Linux Driver
+
+Intel(R) GNA driver is a pci driver as Intel(R) GNA is a PCI device.
+The driver also registers a character device to expose file operations via dev 
node.
+
+The driver probes/removes PCI device, implements file operations, handles 
runtime
+power management, and interacts with hardware through MMIO registers.
+
+Multiple processes can independently file many requests to the driver. These 
requests are
+processed in a FIFO manner. The hardware can process one request at a time by 
using a FIFO
+queue.
+
+IOCTL
+-
+Intel(R) GNA driver controls the device through IOCTL interfaces.
+Following IOCTL commands are supported:
+  GNA_IOCTL_PARAM_GET gets driver and device capabilities.
+
+  GNA_IOCTL_MEMORY_MAP lock user pages and GNA MMU setups for DMA transfer.
+
+  GNA_IOCTL_MEMORY_UNMAP unlocks user pages and releases GNA MMU structures.
+
+  GNA_IOCTL_COMPUTE submits a request to the device queue.
+
+  GNA_IOCTL_WAIT blocks and waits on the submitted request.
diff --git a/Documentation/misc-devices/index.rst 
b/Documentation/misc-devices/index.rst
index 64420b3314fe..8cc01280e555 100644
--- a/Documentation/misc-devices/index.rst
+++ b/Documentation/misc-devices/index.rst
@@ -19,6 +19,7 @@ fit into other categories.
bh1770glc
eeprom
c2port
+   gna
ibmvmc
ics932s401
isl29003
diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst 
b/Documentation/userspace-api/ioctl/ioctl-number.rst
index a4c75a28c839..9fad36a43f4a 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -115,6 +115,7 @@ Code  Seq#Include File  
 Comments
 'B'   C0-FF  advanced bbus   
<mailto:maas...@uni-freiburg.de>
 'C'   alllinux/soundcard.h   conflict!
 'C'   01-2F  linux/capi.hconflict!
+'C'   01-5F  uapi/misc/gna.h conflict!
 'C'   F0-FF  drivers/net/wan/cosa.h  conflict!
 'D'   allarch/s390/include/asm/dasd.h
 'D'   40-5F  drivers/scsi/dpt/dtpi_ioctl.h
diff --git a/MAINTAINERS b

[PATCH v1 00/12] Driver of Intel(R) Gaussian & Neural Accelerator

2021-02-16 Thread Maciej Kwapulinski
Dear kernel maintainers,

This submission is a kernel driver to support Intel(R) Gaussian & Neural 
Accelerator (Intel(R) GNA). Intel(R) GNA is a PCI-based neural co-processor 
available on multiple Intel platforms. AI developers and users can offload 
continuous inference workloads to an Intel(R) GNA device in order to free 
processor resources and save power. Noise reduction and speech recognition are 
the examples of the workloads Intel(R) GNA deals with while its usage is not 
limited to the two.

For a list of processors equipped with Intel(R) GNA device, please refer to 
this link:
https://docs.openvinotoolkit.org/latest/openvino_docs_IE_DG_supported_plugins_GNA.html
 

We think contributing this driver to the upstream kernel project is the best 
way for developers and users to get the latest Intel(R) GNA support in a Linux 
kernel, through the mainline to any Linux distributions installed on their 
systems. Upstreaming also enables contribution from developers around the world 
to the driver once it is merged.

The driver works with Intel(R) libraries in user space. The Intel(R) driver 
exposes a few IOCTL interfaces for use by libraries in user space. The 
libraries are open sourced and are available at:
https://github.com/intel/gna

Prior to the submission, these items were tested or examined against GNA driver 
patch series put on top of v5.11-rc3 tag of mainline kernel:

Linux Kernel patch submission checklist
https://www.kernel.org/doc/html/latest/process/submit-checklist.html?highlight=submit%20checklist

1. If you use a facility then #include the file that defines/declares that 
facility. Don’t depend on other header files pulling in ones that you use.
(Checked)

2. Builds cleanly:
   with applicable or modified CONFIG options =y, =m, and =n. No gcc 
warnings/errors, no linker warnings/errors.
   Passes allnoconfig, allmodconfig
   Builds successfully when using O=builddir
(Tested by building kernel with Intel(R) GNA driver config set to ‘m’, ‘y’, and 
‘n’; allmodconfig, allnoconfig and O=builddir)

3. Builds on multiple CPU architectures by using local cross-compile tools or 
some other build farm.
(x86_64 architecture tested - this is architecture where GNA is present and 
validated, please refer to drivers/misc/gna/Kconfig)

4. ppc64 is a good architecture for cross-compilation checking because it tends 
to use unsigned long for 64-bit quantities.
(x86_64 architecture tested - this is architecture where GNA is present and 
validated, please refer to drivers/misc/gna/Kconfig)

5. Check your patch for general style as detailed in 
Documentation/process/coding-style.rst. Check for trivial violations with the 
patch style checker prior to submission (scripts/checkpatch.pl). You should be 
able to justify all violations that remain in your patch.
(Checked. Some warnings were in the output. We checked them and feel they can 
be ignored.)

6. Any new or modified CONFIG options do not muck up the config menu and 
default to off unless they meet the exception criteria documented in 
Documentation/kbuild/kconfig-language.rst Menu attributes: default value.
(No explicit default value is provided because Kbuild system sets it off by 
default.)

7. All new Kconfig options have help text.
(Checked)

8. Has been carefully reviewed with respect to relevant Kconfig combinations. 
This is very hard to get right with testing – brainpower pays off here.
(Checked)

10. Use make checkstack and fix any problems that it finds.
Note
checkstack does not point out problems explicitly, but any one function 
that uses more than 512 bytes on the stack is a candidate for change.
(Checked)

11. Include kernel-doc to document global kernel APIs. (Not required for static 
functions, but OK there also.) Use make htmldocs or make pdfdocs to check the 
kernel-doc and fix any issues.
(Addressed by adding new gna.rst in Documentation; tested with output from 
‘make htmldocs’)

12. Has been tested with CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT, 
CONFIG_DEBUG_SLAB, CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES, 
CONFIG_DEBUG_SPINLOCK, CONFIG_DEBUG_ATOMIC_SLEEP, CONFIG_PROVE_RCU and 
CONFIG_DEBUG_OBJECTS_RCU_HEAD all simultaneously enabled.
(Checked)

13. Has been build- and runtime tested with and without CONFIG_SMP and 
CONFIG_PREEMPT.
(Checked)

15. All new /proc entries are documented under Documentation/.
(The driver doesn’t introduce any new procs)

16. All new kernel boot parameters are documented in 
Documentation/admin-guide/kernel-parameters.rst.
(The driver doesn’t add boot parameters)

17. All new module parameters are documented with MODULE_PARM_DESC().
(Checked)

21. Newly-added code has been compiled with gcc -W (use make EXTRA_CFLAGS=-W). 
This will generate lots of noise, but is good for finding bugs like “warning: 
comparison between signed.
and unsigned”.
(Checked)

24. If any ioctl’s are added by the patch, then also update 
Documentation/userspace-api/ioctl/ioctl-number.rst.
(Updated)

The above results