mbox series

[v2,0/9] Xilinx AI engine kernel driver

Message ID 1605743289-26575-1-git-send-email-wendy.liang@xilinx.com
Headers show
Series Xilinx AI engine kernel driver | expand

Message

Jiaying Liang Nov. 18, 2020, 11:48 p.m. UTC
AI engine is the acceleration engine provided by Xilinx. These engines
provide high compute density for vector-based algorithms, and flexible
custom compute and data movement. It has core tiles for compute and
shim tiles to interface the FPGA fabric.

You can check the AI engine architecture document for more hardware details:
https://www.xilinx.com/support/documentation/architecture-manuals/am009-versal-ai-engine.pdf

This patch series adds a Linux kernel driver to manage the Xilinx AI
engine array device and AI engine partitions (groups of AI engine tiles
dedicated to an application).

v2:
* Fix dtschema check errors
* Fix test bot warning on interrupt implementation. Removed set but
  unused  varaible.
* Fix compilation unused function warning of firmware change in case
  ZynqMP firmware is not configured
* There are other warning on ZynqMP firmware reported from testbot
  which is not introduced by this patch set.
  "[PATCH] firmware: xlnx-zynqmp: fix compilation warning" is submitted
  for those fixes.

Izhar Ameer Shaikh (1):
  firmware: xilinx: Add IOCTL support for AIE ISR Clear

Nishad Saraf (2):
  misc: xilinx-ai-engine: Add support to request device management
    services
  misc: xilinx-ai-engine: Add support for servicing error interrupts

Wendy Liang (6):
  dt-binding: soc: xilinx: ai-engine: Add AI engine binding
  misc: Add Xilinx AI engine device driver
  misc: xilinx-ai-engine: Implement AI engine cleanup sequence
  misc: xilinx-ai-engine: expose AI engine tile memories to userspace
  misc: xilinx-ai-engine: add setting shim dma bd operation
  misc: xilinx-ai-engine: add request and release tiles

 .../bindings/soc/xilinx/xlnx,ai-engine.yaml        | 126 ++++
 MAINTAINERS                                        |   8 +
 drivers/firmware/xilinx/zynqmp.c                   |  14 +
 drivers/misc/Kconfig                               |  12 +
 drivers/misc/Makefile                              |   1 +
 drivers/misc/xilinx-ai-engine/Makefile             |  16 +
 drivers/misc/xilinx-ai-engine/ai-engine-aie.c      | 608 +++++++++++++++++++
 drivers/misc/xilinx-ai-engine/ai-engine-clock.c    | 244 ++++++++
 drivers/misc/xilinx-ai-engine/ai-engine-dev.c      | 492 +++++++++++++++
 drivers/misc/xilinx-ai-engine/ai-engine-dma.c      | 481 +++++++++++++++
 drivers/misc/xilinx-ai-engine/ai-engine-internal.h | 519 ++++++++++++++++
 .../misc/xilinx-ai-engine/ai-engine-interrupt.c    | 659 +++++++++++++++++++++
 drivers/misc/xilinx-ai-engine/ai-engine-mem.c      | 274 +++++++++
 drivers/misc/xilinx-ai-engine/ai-engine-part.c     | 635 ++++++++++++++++++++
 drivers/misc/xilinx-ai-engine/ai-engine-res.c      | 219 +++++++
 drivers/misc/xilinx-ai-engine/ai-engine-reset.c    | 159 +++++
 include/linux/firmware/xlnx-zynqmp.h               |   8 +
 include/uapi/linux/xlnx-ai-engine.h                | 236 ++++++++
 18 files changed, 4711 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/xilinx/xlnx,ai-engine.yaml
 create mode 100644 drivers/misc/xilinx-ai-engine/Makefile
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-aie.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-clock.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-dev.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-dma.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-internal.h
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-interrupt.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-mem.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-part.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-res.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-reset.c
 create mode 100644 include/uapi/linux/xlnx-ai-engine.h

Comments

Jiaying Liang Nov. 24, 2020, 3:24 a.m. UTC | #1
On 11/19/20 12:36 AM, Hillf Danton wrote:
> On Wed, 18 Nov 2020 15:48:09 -0800 Wendy Liang wrote:

>> +/**

>> + * aie_interrupt() - interrupt handler for AIE.

>> + * @irq: Interrupt number.

>> + * @data: AI engine device structure.

>> + * @return: IRQ_HANDLED.

>> + *

>> + * This thread function disables level 2 interrupt controllers and schedules a

>> + * task in workqueue to backtrack the source of error interrupt. Disabled

>> + * interrupts are re-enabled after successful completion of bottom half.

>> + */

>> +irqreturn_t aie_interrupt(int irq, void *data)

>> +{

>> +	struct aie_device *adev = data;

>> +	struct aie_partition *apart;

>> +	int ret;

>> +	bool sched_work = false;

>> +

>> +	ret = mutex_lock_interruptible(&adev->mlock);

>> +	if (ret) {

>> +		dev_err(&adev->dev,

>> +			"Failed to acquire lock. Process was interrupted by fatal signals\n");

>> +		return IRQ_NONE;

>> +	}

>> +

>> +	list_for_each_entry(apart, &adev->partitions, node) {

>> +		struct aie_location loc;

>> +		u32 ttype, l2_mask, l2_status, l2_bitmap_offset  = 0;

>> +

>> +		ret = mutex_lock_interruptible(&apart->mlock);

>> +		if (ret) {

>> +			dev_err(&apart->dev,

>> +				"Failed to acquire lock. Process was interrupted by fatal signals\n");

>> +			return IRQ_NONE;

> 

> Though quite unlikely, you need to release adev->mlock before

> going home.

Thanks to point it out, I will change in next version

Thanks,
Wendy
> 

>> +		}

>> +

>> +		for (loc.col = apart->range.start.col, loc.row = 0;

>> +		     loc.col < apart->range.start.col + apart->range.size.col;

>> +		     loc.col++) {

>> +			ttype = apart->adev->ops->get_tile_type(&loc);

>> +			if (ttype != AIE_TILE_TYPE_SHIMNOC)

>> +				continue;

>> +

>> +			l2_mask = aie_get_l2_mask(apart, &loc);

>> +			if (l2_mask) {

>> +				aie_resource_cpy_from_arr32(&apart->l2_mask,

>> +							    l2_bitmap_offset  *

>> +							    32, &l2_mask, 32);

>> +				aie_disable_l2_ctrl(apart, &loc, l2_mask);

>> +			}

>> +			l2_bitmap_offset++;

>> +

>> +			l2_status = aie_get_l2_status(apart, &loc);

>> +			if (l2_status) {

>> +				aie_clear_l2_intr(apart, &loc, l2_status);

>> +				sched_work = true;

>> +			} else {

>> +				aie_enable_l2_ctrl(apart, &loc, l2_mask);

>> +			}

>> +		}

>> +		mutex_unlock(&apart->mlock);

>> +	}

>> +

>> +	/* For ES1 silicon, interrupts are latched in NPI */

>> +	if (adev->version == VERSAL_ES1_REV_ID) {

>> +		ret = zynqmp_pm_clear_aie_npi_isr(adev->pm_node_id,

>> +						  AIE_NPI_ERROR_ID);

>> +		if (ret < 0)

>> +			dev_err(&adev->dev, "Failed to clear NPI ISR\n");

>> +	}

>> +

>> +	mutex_unlock(&adev->mlock);

>> +

>> +	if (sched_work)

>> +		schedule_work(&adev->backtrack);

>> +

>> +	return IRQ_HANDLED;

>> +}