Skip to contentSkip to conversation

Intel Vision Processing Unit base enabling part 1

PATCH In review [email protected] 5 participants 33 messages Nov 30, 2020 – Dec 2, 2020

Subsystems (3)
lore
Share & tools
lore
#1 lore raw

PATCH 1/22 Add Vision Processing Unit (VPU) documentation.

In reply to [email protected]

From: mark gross <[email protected]>

The Intel VPU needs a complicated SW stack to make it work. Add a directory to hold VPU related documentation including an architectural overview of the SW stack that the patches implement.

---
 Documentation/index.rst                  |   3 +-
 Documentation/vpu/index.rst              |  16 ++
 Documentation/vpu/vpu-stack-overview.rst | 267 +++++++++++++++++++++++
 3 files changed, 285 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/vpu/index.rst
 create mode 100644 Documentation/vpu/vpu-stack-overview.rst
Documentation/index.rst +2 -1
index 57719744774c..0a2cc0204e8f 100644
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GPL-2.0
+.. SPDX-License-Identifier: GPL-2.0-only
 
 
 .. The Linux Kernel documentation master file, created by
@@ -137,6 +137,7 @@ needed).
    misc-devices/index
    scheduler/index
    mhi/index
+   vpu/index
 
 Architecture-agnostic documentation
 -----------------------------------
Documentation/vpu/index.rst new file +16 -0
new file mode 100644
index 000000000000..7e290e048910
@@ -0,0 +1,16 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+============================================
+Vision Processor Unit Documentation
+============================================
+
+This documentation contains information for the Intel VPU stack.
+
+.. class:: toc-title
+
+	   Table of contents
+
+.. toctree::
+   :maxdepth: 2
+
+   vpu-stack-overview
Documentation/vpu/vpu-stack-overview.rst new file +267 -0

267 lines not on this page · raw message

Signature · 1 line
2.17.1
#2 lore raw

PATCH 2/22 dt-bindings: Add bindings for Keem Bay IPC driver

In reply to [email protected]

From: Daniele Alessandrelli <[email protected]>

Add DT binding documentation for the Intel Keem Bay IPC driver, which enables communication between the Computing Sub-System (CSS) and the Multimedia Sub-System (MSS) of the Intel Movidius SoC code named Keem Bay.

---
 .../bindings/soc/intel/intel,keembay-ipc.yaml | 63 +++++++++++++++++++
 1 file changed, 63 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/intel/intel,keembay-ipc.yaml
Documentation/devicetree/bindings/soc/intel/intel,keembay-ipc.yaml new file +63 -0
new file mode 100644
index 000000000000..6e21c54d8f34
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2020 Intel Corporation
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/soc/intel/intel,keembay-ipc.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Keem Bay IPC
+
+maintainers:
+  - Daniele Alessandrelli <[email protected]>
+
+description:
+  The Keem Bay IPC driver enables Inter-Processor Communication (IPC) with the
+  Visual Processor Unit (VPU) embedded in the Intel Movidius SoC code named
+  Keem Bay.
+
+properties:
+  compatible:
+    const: intel,keembay-ipc
+
+  reg:
+    items:
+      - description: The CSS (CPU) FIFO registers
+      - description: The MSS (VPU) FIFO registers
+
+  reg-names:
+    items:
+      - const: css_fifo
+      - const: mss_fifo
+
+  interrupts:
+    items:
+      - description: CSS FIFO not-empty interrupt
+
+  interrupt-controller: true
+
+  memory-region:
+    items:
+      - description: Reserved memory region used for CSS IPC buffers
+      - description: Reserved memory region used for MSS IPC buffers
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - memory-region
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    ipc@203300f0 {
+          compatible = "intel,keembay-ipc";
+          reg = <0x203300f0 0x310>, /* CPU TIM FIFO */
+                <0x208200f0 0x310>; /* VPU TIM FIFO */
+          reg-names = "css_fifo", "mss_fifo";
+          interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+          memory-region = <&css_ipc_reserved>, <&mss_ipc_reserved>;
+    };
Signature · 1 line
2.17.1
#6 lore raw

PATCH 6/22 misc: xlink-pcie: Add documentation for XLink PCIe driver

In reply to [email protected]

From: Srikanth Thokala <[email protected]>

Provide overview of XLink PCIe driver implementation

---
 Documentation/vpu/index.rst      |  1 +
 Documentation/vpu/xlink-pcie.rst | 91 ++++++++++++++++++++++++++++++++
 2 files changed, 92 insertions(+)
 create mode 100644 Documentation/vpu/xlink-pcie.rst
Documentation/vpu/index.rst +1 -0
index 7e290e048910..661cc700ee45 100644
@@ -14,3 +14,4 @@ This documentation contains information for the Intel VPU stack.
    :maxdepth: 2
 
    vpu-stack-overview
+   xlink-pcie
Documentation/vpu/xlink-pcie.rst new file +91 -0

91 lines not on this page · raw message

Signature · 1 line
2.17.1
#0 lore raw

cover Intel Vision Processing Unit base enabling part 1

From: mark gross <[email protected]>

The Intel Vision Processing Unit (VPU) is an IP block that is showing up for the first time as part of the Keem Bay SOC. Keem Bay is a quad core A53 Arm SOC. It is designed to be used as a stand alone SOC as well as in an PCIe Vision Processing accelerator add in card.

This part 1 of the patches make up the base or core of the stack needed to enable both use cases for the VPU.

Part 2 includes 11 more patches that depend on part 1. Those should be ready in a couple of weeks or less.

I am trying something a bit new with this sequence where I've been working with the driver developers as a "pre-maintainer" reviewing and enforcing the kernel expectations as I understand them. Its taken a couple of months to get this code to the point I feel its ready for public posting. My goal is to make sure it meets expectations for quality and compliance with kernel expectations and there will be mostly technical / design issues to talk about.

Thanks for looking at these and providing feedback.

--mark
p.s. I have had a problem my MTA configuration between mutt and git send-email where I was using msmpt to send from mutt (because 15+ years ago its the first way I got to work and never changed) while my worstation MTA that git send-email uses was un-configured resulting in my return-path naming my workstion withing the firewall. I suck at email administration.

I appologies for the multiple copies.

Daniele Alessandrelli (2):
dt-bindings: Add bindings for Keem Bay IPC driver
keembay-ipc: Add Keem Bay IPC module

Paul Murphy (2):
dt-bindings: Add bindings for Keem Bay VPU IPC driver
keembay-vpu-ipc: Add Keem Bay VPU IPC module

Seamus Kelly (8):
xlink-ipc: Add xlink ipc device tree bindings
xlink-ipc: Add xlink ipc driver
xlink-core: Add xlink core device tree bindings
xlink-core: Add xlink core driver xLink
xlink-core: Enable xlink protocol over pcie
xlink-core: Enable VPU IP management and runtime control
xlink-core: add async channel and events
xlink-core: factorize xlink_ioctl function by creating sub-functions
for each ioctl command

Srikanth Thokala (9):
misc: xlink-pcie: Add documentation for XLink PCIe driver
misc: xlink-pcie: lh: Add PCIe EPF driver for Local Host
misc: xlink-pcie: lh: Add PCIe EP DMA functionality
misc: xlink-pcie: lh: Add core communication logic
misc: xlink-pcie: lh: Prepare changes for adding remote host driver
misc: xlink-pcie: rh: Add PCIe EP driver for Remote Host
misc: xlink-pcie: rh: Add core communication logic
misc: xlink-pcie: Add XLink API interface
misc: xlink-pcie: Add asynchronous event notification support for
XLink

mark gross (1):
Add Vision Processing Unit (VPU) documentation.

 .../misc/intel,keembay-xlink-ipc.yaml         |   49 +
 .../bindings/misc/intel,keembay-xlink.yaml    |   27 +
 .../bindings/soc/intel/intel,keembay-ipc.yaml |   63 +
 .../soc/intel/intel,keembay-vpu-ipc.yaml      |  151 ++
 Documentation/index.rst                       |    3 +-
 Documentation/vpu/index.rst                   |   19 +
 Documentation/vpu/vpu-stack-overview.rst      |  267 +++
 Documentation/vpu/xlink-core.rst              |   80 +
 Documentation/vpu/xlink-ipc.rst               |   50 +
 Documentation/vpu/xlink-pcie.rst              |   91 +
 MAINTAINERS                                   |   41 +
 drivers/misc/Kconfig                          |    3 +
 drivers/misc/Makefile                         |    3 +
 drivers/misc/xlink-core/Kconfig               |   33 +
 drivers/misc/xlink-core/Makefile              |    5 +
 drivers/misc/xlink-core/xlink-core.c          | 1335 +++++++++++
 drivers/misc/xlink-core/xlink-core.h          |   24 +
 drivers/misc/xlink-core/xlink-defs.h          |  181 ++
 drivers/misc/xlink-core/xlink-dispatcher.c    |  436 ++++
 drivers/misc/xlink-core/xlink-dispatcher.h    |   26 +
 drivers/misc/xlink-core/xlink-ioctl.c         |  584 +++++
 drivers/misc/xlink-core/xlink-ioctl.h         |   36 +
 drivers/misc/xlink-core/xlink-multiplexer.c   | 1164 ++++++++++
 drivers/misc/xlink-core/xlink-multiplexer.h   |   35 +
 drivers/misc/xlink-core/xlink-platform.c      |  273 +++
 drivers/misc/xlink-core/xlink-platform.h      |   65 +
 drivers/misc/xlink-ipc/Kconfig                |    7 +
 drivers/misc/xlink-ipc/Makefile               |    4 +
 drivers/misc/xlink-ipc/xlink-ipc.c            |  879 +++++++
 drivers/misc/xlink-pcie/Kconfig               |   20 +
 drivers/misc/xlink-pcie/Makefile              |    2 +
 drivers/misc/xlink-pcie/common/core.h         |  247 ++
 drivers/misc/xlink-pcie/common/interface.c    |  126 +
 drivers/misc/xlink-pcie/common/util.c         |  375 +++
 drivers/misc/xlink-pcie/common/util.h         |   70 +
 drivers/misc/xlink-pcie/common/xpcie.h        |  120 +
 drivers/misc/xlink-pcie/local_host/Makefile   |    6 +
 drivers/misc/xlink-pcie/local_host/core.c     |  905 ++++++++
 drivers/misc/xlink-pcie/local_host/dma.c      |  577 +++++
 drivers/misc/xlink-pcie/local_host/epf.c      |  523 +++++
 drivers/misc/xlink-pcie/local_host/epf.h      |  106 +
 drivers/misc/xlink-pcie/remote_host/Makefile  |    6 +
 drivers/misc/xlink-pcie/remote_host/core.c    |  647 ++++++
 drivers/misc/xlink-pcie/remote_host/main.c    |   96 +
 drivers/misc/xlink-pcie/remote_host/pci.c     |  525 +++++
 drivers/misc/xlink-pcie/remote_host/pci.h     |   67 +
 drivers/soc/Kconfig                           |    1 +
 drivers/soc/Makefile                          |    1 +
 drivers/soc/intel/Kconfig                     |   32 +
 drivers/soc/intel/Makefile                    |    5 +
 drivers/soc/intel/keembay-ipc.c               | 1669 ++++++++++++++
 drivers/soc/intel/keembay-vpu-ipc.c           | 2036 +++++++++++++++++
 include/linux/soc/intel/keembay-ipc.h         |   30 +
 include/linux/soc/intel/keembay-vpu-ipc.h     |   62 +
 include/linux/xlink-ipc.h                     |   48 +
 include/linux/xlink.h                         |  146 ++
 include/linux/xlink_drv_inf.h                 |   72 +
 include/uapi/misc/xlink_uapi.h                |  145 ++
 58 files changed, 14598 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/misc/intel,keembay-xlink-ipc.yaml
 create mode 100644 Documentation/devicetree/bindings/misc/intel,keembay-xlink.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/intel/intel,keembay-ipc.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/intel/intel,keembay-vpu-ipc.yaml
 create mode 100644 Documentation/vpu/index.rst
 create mode 100644 Documentation/vpu/vpu-stack-overview.rst
 create mode 100644 Documentation/vpu/xlink-core.rst
 create mode 100644 Documentation/vpu/xlink-ipc.rst
 create mode 100644 Documentation/vpu/xlink-pcie.rst
 create mode 100644 drivers/misc/xlink-core/Kconfig
 create mode 100644 drivers/misc/xlink-core/Makefile
 create mode 100644 drivers/misc/xlink-core/xlink-core.c
 create mode 100644 drivers/misc/xlink-core/xlink-core.h
 create mode 100644 drivers/misc/xlink-core/xlink-defs.h
 create mode 100644 drivers/misc/xlink-core/xlink-dispatcher.c
 create mode 100644 drivers/misc/xlink-core/xlink-dispatcher.h
 create mode 100644 drivers/misc/xlink-core/xlink-ioctl.c
 create mode 100644 drivers/misc/xlink-core/xlink-ioctl.h
 create mode 100644 drivers/misc/xlink-core/xlink-multiplexer.c
 create mode 100644 drivers/misc/xlink-core/xlink-multiplexer.h
 create mode 100644 drivers/misc/xlink-core/xlink-platform.c
 create mode 100644 drivers/misc/xlink-core/xlink-platform.h
 create mode 100644 drivers/misc/xlink-ipc/Kconfig
 create mode 100644 drivers/misc/xlink-ipc/Makefile
 create mode 100644 drivers/misc/xlink-ipc/xlink-ipc.c
 create mode 100644 drivers/misc/xlink-pcie/Kconfig
 create mode 100644 drivers/misc/xlink-pcie/Makefile
 create mode 100644 drivers/misc/xlink-pcie/common/core.h
 create mode 100644 drivers/misc/xlink-pcie/common/interface.c
 create mode 100644 drivers/misc/xlink-pcie/common/util.c
 create mode 100644 drivers/misc/xlink-pcie/common/util.h
 create mode 100644 drivers/misc/xlink-pcie/common/xpcie.h
 create mode 100644 drivers/misc/xlink-pcie/local_host/Makefile
 create mode 100644 drivers/misc/xlink-pcie/local_host/core.c
 create mode 100644 drivers/misc/xlink-pcie/local_host/dma.c
 create mode 100644 drivers/misc/xlink-pcie/local_host/epf.c
 create mode 100644 drivers/misc/xlink-pcie/local_host/epf.h
 create mode 100644 drivers/misc/xlink-pcie/remote_host/Makefile
 create mode 100644 drivers/misc/xlink-pcie/remote_host/core.c
 create mode 100644 drivers/misc/xlink-pcie/remote_host/main.c
 create mode 100644 drivers/misc/xlink-pcie/remote_host/pci.c
 create mode 100644 drivers/misc/xlink-pcie/remote_host/pci.h
 create mode 100644 drivers/soc/intel/Kconfig
 create mode 100644 drivers/soc/intel/Makefile
 create mode 100644 drivers/soc/intel/keembay-ipc.c
 create mode 100644 drivers/soc/intel/keembay-vpu-ipc.c
 create mode 100644 include/linux/soc/intel/keembay-ipc.h
 create mode 100644 include/linux/soc/intel/keembay-vpu-ipc.h
 create mode 100644 include/linux/xlink-ipc.h
 create mode 100644 include/linux/xlink.h
 create mode 100644 include/linux/xlink_drv_inf.h
 create mode 100644 include/uapi/misc/xlink_uapi.h
Signature · 1 line
2.17.1
#7 lore raw

PATCH 7/22 misc: xlink-pcie: lh: Add PCIe EPF driver for Local Host

From: Srikanth Thokala <[email protected]>

Add PCIe EPF driver for local host (lh) to configure BAR's and other HW resources. Underlying PCIe HW controller is a Synopsys DWC PCIe core.

Cc Derek Kiernan <[email protected]>
Cc Dragan Cvetic <[email protected]>
Cc Arnd Bergmann <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
---
 MAINTAINERS                                 |   6 +
 drivers/misc/Kconfig                        |   1 +
 drivers/misc/Makefile                       |   1 +
 drivers/misc/xlink-pcie/Kconfig             |   9 +
 drivers/misc/xlink-pcie/Makefile            |   1 +
 drivers/misc/xlink-pcie/local_host/Makefile |   2 +
 drivers/misc/xlink-pcie/local_host/epf.c    | 414 ++++++++++++++++++++
 drivers/misc/xlink-pcie/local_host/epf.h    |  39 ++
 drivers/misc/xlink-pcie/local_host/xpcie.h  |  54 +++
 9 files changed, 527 insertions(+)
 create mode 100644 drivers/misc/xlink-pcie/Kconfig
 create mode 100644 drivers/misc/xlink-pcie/Makefile
 create mode 100644 drivers/misc/xlink-pcie/local_host/Makefile
 create mode 100644 drivers/misc/xlink-pcie/local_host/epf.c
 create mode 100644 drivers/misc/xlink-pcie/local_host/epf.h
 create mode 100644 drivers/misc/xlink-pcie/local_host/xpcie.h
MAINTAINERS +6 -0
index f95cef927d19..9af8685967ac 100644
@@ -1952,6 +1952,12 @@ F:	Documentation/devicetree/bindings/arm/intel,keembay.yaml
 F:	arch/arm64/boot/dts/intel/keembay-evm.dts
 F:	arch/arm64/boot/dts/intel/keembay-soc.dtsi
 
+ARM KEEMBAY XLINK PCIE SUPPORT
+M:	Srikanth Thokala <[email protected]>
+M:	Mark Gross <[email protected]>
+S:	Maintained
+F:	drivers/misc/xlink-pcie/
+
 ARM/INTEL RESEARCH IMOTE/STARGATE 2 MACHINE SUPPORT
 M:	Jonathan Cameron <[email protected]>
 L:	[email protected] (moderated for non-subscribers)
drivers/misc/Kconfig +1 -0
index fafa8b0d8099..dfb98e444c6e 100644
@@ -481,4 +481,5 @@ source "drivers/misc/ocxl/Kconfig"
 source "drivers/misc/cardreader/Kconfig"
 source "drivers/misc/habanalabs/Kconfig"
 source "drivers/misc/uacce/Kconfig"
+source "drivers/misc/xlink-pcie/Kconfig"
 endmenu
drivers/misc/Makefile +1 -0
index d23231e73330..d17621fc43d5 100644
@@ -57,3 +57,4 @@ obj-$(CONFIG_HABANA_AI)		+= habanalabs/
 obj-$(CONFIG_UACCE)		+= uacce/
 obj-$(CONFIG_XILINX_SDFEC)	+= xilinx_sdfec.o
 obj-$(CONFIG_HISI_HIKEY_USB)	+= hisi_hikey_usb.o
+obj-y                           += xlink-pcie/
drivers/misc/xlink-pcie/Kconfig new file +9 -0
new file mode 100644
index 000000000000..46aa401d79b7
@@ -0,0 +1,9 @@
+config XLINK_PCIE_LH_DRIVER
+	tristate "XLink PCIe Local Host driver"
+	depends on PCI_ENDPOINT && ARCH_KEEMBAY
+	help
+	  This option enables XLink PCIe Local Host driver.
+
+	  Choose M here to compile this driver as a module, name is mxlk_ep.
+	  This driver is used for XLink communication over PCIe and is to be
+	  loaded on the Intel Keem Bay platform.
drivers/misc/xlink-pcie/Makefile new file +1 -0
new file mode 100644
index 000000000000..d693d382e9c6
@@ -0,0 +1 @@
+obj-$(CONFIG_XLINK_PCIE_LH_DRIVER) += local_host/
drivers/misc/xlink-pcie/local_host/Makefile new file +2 -0
new file mode 100644
index 000000000000..514d3f0c91bc
@@ -0,0 +1,2 @@
+obj-$(CONFIG_XLINK_PCIE_LH_DRIVER) += mxlk_ep.o
+mxlk_ep-objs := epf.o
drivers/misc/xlink-pcie/local_host/epf.c new file +414 -0

414 lines not on this page · raw message

drivers/misc/xlink-pcie/local_host/epf.h new file +39 -0
new file mode 100644
index 000000000000..2b38c87b3701
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*****************************************************************************
+ *
+ * Intel Keem Bay XLink PCIe Driver
+ *
+ * Copyright (C) 2020 Intel Corporation
+ *
+ ****************************************************************************/
+
+#ifndef XPCIE_EPF_HEADER_
+#define XPCIE_EPF_HEADER_
+
+#include <linux/pci-epc.h>
+#include <linux/pci-epf.h>
+
+#include "xpcie.h"
+
+#define XPCIE_DRIVER_NAME "mxlk_pcie_epf"
+#define XPCIE_DRIVER_DESC "Intel(R) xLink PCIe endpoint function driver"
+
+#define KEEMBAY_XPCIE_STEPPING_MAXLEN 8
+
+struct xpcie_epf {
+	struct pci_epf *epf;
+	void *vaddr[BAR_5 + 1];
+	enum pci_barno comm_bar;
+	enum pci_barno bar4;
+	const struct pci_epc_features *epc_features;
+	struct xpcie xpcie;
+	int irq;
+	int irq_dma;
+	int irq_err;
+	void __iomem *apb_base;
+	void __iomem *dma_base;
+	void __iomem *dbi_base;
+	char stepping[KEEMBAY_XPCIE_STEPPING_MAXLEN];
+};
+
+#endif /* XPCIE_EPF_HEADER_ */
drivers/misc/xlink-pcie/local_host/xpcie.h new file +54 -0

54 lines not on this page · raw message

Signature · 1 line
2.17.1
#15 lore raw

PATCH 8/22 misc: xlink-pcie: lh: Add PCIe EP DMA functionality

In reply to [email protected]

From: Srikanth Thokala <[email protected]>

Add Synopsys PCIe DWC core embedded-DMA functionality for local host

---
 drivers/misc/xlink-pcie/local_host/Makefile |   1 +
 drivers/misc/xlink-pcie/local_host/dma.c    | 577 ++++++++++++++++++++
 drivers/misc/xlink-pcie/local_host/epf.c    |  15 +-
 drivers/misc/xlink-pcie/local_host/epf.h    |  41 ++
 4 files changed, 631 insertions(+), 3 deletions(-)
 create mode 100644 drivers/misc/xlink-pcie/local_host/dma.c
drivers/misc/xlink-pcie/local_host/Makefile +1 -0
index 514d3f0c91bc..54fc118e2dd1 100644
@@ -1,2 +1,3 @@
 obj-$(CONFIG_XLINK_PCIE_LH_DRIVER) += mxlk_ep.o
 mxlk_ep-objs := epf.o
+mxlk_ep-objs += dma.o
drivers/misc/xlink-pcie/local_host/dma.c new file +577 -0

577 lines not on this page · raw message

drivers/misc/xlink-pcie/local_host/epf.c +12 -3
index ae07b364734d..fc29180aa508 100644
@@ -45,6 +45,8 @@ static irqreturn_t intel_xpcie_err_interrupt(int irq, void *args)
 
 	xpcie_epf = container_of(xpcie, struct xpcie_epf, xpcie);
 	val = ioread32(xpcie_epf->apb_base + PCIE_REGS_PCIE_ERR_INTR_FLAGS);
+	if (val & LINK_REQ_RST_FLG)
+		intel_xpcie_ep_dma_reset(xpcie_epf->epf);
 
 	iowrite32(val, xpcie_epf->apb_base + PCIE_REGS_PCIE_ERR_INTR_FLAGS);
 
@@ -325,8 +327,17 @@ static int intel_xpcie_epf_bind(struct pci_epf *epf)
 		goto err_cleanup_bars;
 	}
 
+	ret = intel_xpcie_ep_dma_init(epf);
+	if (ret) {
+		dev_err(&epf->dev, "DMA initialization failed\n");
+		goto err_free_err_irq;
+	}
+
 	return 0;
 
+err_free_err_irq:
+	free_irq(xpcie_epf->irq_err, &xpcie_epf->xpcie);
+
 err_cleanup_bars:
 	intel_xpcie_cleanup_bars(epf);
 
@@ -335,11 +346,9 @@ static int intel_xpcie_epf_bind(struct pci_epf *epf)
 
 static void intel_xpcie_epf_unbind(struct pci_epf *epf)
 {
-	struct xpcie_epf *xpcie_epf = epf_get_drvdata(epf);
 	struct pci_epc *epc = epf->epc;
 
-	free_irq(xpcie_epf->irq, &xpcie_epf->xpcie);
-	free_irq(xpcie_epf->irq_err, &xpcie_epf->xpcie);
+	intel_xpcie_ep_dma_uninit(epf);
 
 	pci_epc_stop(epc);
 
drivers/misc/xlink-pcie/local_host/epf.h +41 -0

53 lines not on this page · raw message

Signature · 1 line
2.17.1
#19 lore raw

PATCH 11/22 misc: xlink-pcie: rh: Add PCIe EP driver for Remote Host

In reply to [email protected]

From: Srikanth Thokala <[email protected]>

Add PCIe Endpoint driver that configures PCIe BARs and MSIs on the Remote Host

---
 MAINTAINERS                                  |   2 +-
 drivers/misc/xlink-pcie/Kconfig              |  11 +
 drivers/misc/xlink-pcie/Makefile             |   1 +
 drivers/misc/xlink-pcie/common/xpcie.h       |   1 +
 drivers/misc/xlink-pcie/remote_host/Makefile |   3 +
 drivers/misc/xlink-pcie/remote_host/main.c   |  93 ++++
 drivers/misc/xlink-pcie/remote_host/pci.c    | 451 +++++++++++++++++++
 drivers/misc/xlink-pcie/remote_host/pci.h    |  64 +++
 8 files changed, 625 insertions(+), 1 deletion(-)
 create mode 100644 drivers/misc/xlink-pcie/remote_host/Makefile
 create mode 100644 drivers/misc/xlink-pcie/remote_host/main.c
 create mode 100644 drivers/misc/xlink-pcie/remote_host/pci.c
 create mode 100644 drivers/misc/xlink-pcie/remote_host/pci.h
MAINTAINERS +1 -1
index 9af8685967ac..b3468dea6557 100644
@@ -1952,7 +1952,7 @@ F:	Documentation/devicetree/bindings/arm/intel,keembay.yaml
 F:	arch/arm64/boot/dts/intel/keembay-evm.dts
 F:	arch/arm64/boot/dts/intel/keembay-soc.dtsi
 
-ARM KEEMBAY XLINK PCIE SUPPORT
+ARM/INTEL KEEMBAY XLINK PCIE SUPPORT
 M:	Srikanth Thokala <[email protected]>
 M:	Mark Gross <[email protected]>
 S:	Maintained
drivers/misc/xlink-pcie/Kconfig +11 -0
index 46aa401d79b7..448b9bfbdfa2 100644
@@ -1,3 +1,14 @@
+config XLINK_PCIE_RH_DRIVER
+	tristate "XLink PCIe Remote Host driver"
+	depends on PCI && X86_64
+	help
+	  This option enables XLink PCIe Remote Host driver.
+
+	  Choose M here to compile this driver as a module, name is mxlk.
+	  This driver is used for XLink communication over PCIe,
+	  and is to be loaded on the IA host which is connected to
+	  the Intel Keem Bay.
+
 config XLINK_PCIE_LH_DRIVER
 	tristate "XLink PCIe Local Host driver"
 	depends on PCI_ENDPOINT && ARCH_KEEMBAY
drivers/misc/xlink-pcie/Makefile +1 -0
index d693d382e9c6..1dd984d8d88c 100644
@@ -1 +1,2 @@
+obj-$(CONFIG_XLINK_PCIE_RH_DRIVER) += remote_host/
 obj-$(CONFIG_XLINK_PCIE_LH_DRIVER) += local_host/
drivers/misc/xlink-pcie/common/xpcie.h +1 -0
index 5ae0b3dbd503..c62443d61865 100644
@@ -89,6 +89,7 @@ struct xpcie_mmio {
 struct xpcie {
 	u32 status;
 	bool legacy_a0;
+	void *bar0;
 	void *mmio;
 	void *bar4;
 
drivers/misc/xlink-pcie/remote_host/Makefile new file +3 -0
new file mode 100644
index 000000000000..96374a43023e
@@ -0,0 +1,3 @@
+obj-$(CONFIG_XLINK_PCIE_RH_DRIVER) += mxlk.o
+mxlk-objs := main.o
+mxlk-objs += pci.o
drivers/misc/xlink-pcie/remote_host/main.c new file +93 -0

93 lines not on this page · raw message

drivers/misc/xlink-pcie/remote_host/pci.c new file +451 -0

451 lines not on this page · raw message

drivers/misc/xlink-pcie/remote_host/pci.h new file +64 -0

64 lines not on this page · raw message

Signature · 1 line
2.17.1
#16 lore raw

PATCH 9/22 misc: xlink-pcie: lh: Add core communication logic

In reply to [email protected]

From: Srikanth Thokala <[email protected]>

Add logic to establish communication with the remote host which is through ring buffer management and MSI/Doorbell interrupts

---
 drivers/misc/xlink-pcie/local_host/Makefile |   2 +
 drivers/misc/xlink-pcie/local_host/core.c   | 894 ++++++++++++++++++++
 drivers/misc/xlink-pcie/local_host/core.h   | 247 ++++++
 drivers/misc/xlink-pcie/local_host/epf.c    | 116 ++-
 drivers/misc/xlink-pcie/local_host/epf.h    |  26 +
 drivers/misc/xlink-pcie/local_host/util.c   | 375 ++++++++
 drivers/misc/xlink-pcie/local_host/util.h   |  70 ++
 drivers/misc/xlink-pcie/local_host/xpcie.h  |  65 ++
 include/linux/xlink_drv_inf.h               |  60 ++
 9 files changed, 1847 insertions(+), 8 deletions(-)
 create mode 100644 drivers/misc/xlink-pcie/local_host/core.c
 create mode 100644 drivers/misc/xlink-pcie/local_host/core.h
 create mode 100644 drivers/misc/xlink-pcie/local_host/util.c
 create mode 100644 drivers/misc/xlink-pcie/local_host/util.h
 create mode 100644 include/linux/xlink_drv_inf.h
drivers/misc/xlink-pcie/local_host/Makefile +2 -0
index 54fc118e2dd1..28761751d43b 100644
@@ -1,3 +1,5 @@
 obj-$(CONFIG_XLINK_PCIE_LH_DRIVER) += mxlk_ep.o
 mxlk_ep-objs := epf.o
 mxlk_ep-objs += dma.o
+mxlk_ep-objs += core.o
+mxlk_ep-objs += util.o
drivers/misc/xlink-pcie/local_host/core.c new file +894 -0

894 lines not on this page · raw message

drivers/misc/xlink-pcie/local_host/core.h new file +247 -0

247 lines not on this page · raw message

drivers/misc/xlink-pcie/local_host/epf.c +108 -8

185 lines not on this page · raw message

drivers/misc/xlink-pcie/local_host/epf.h +26 -0
index 6ce5260e67be..675c07455ffa 100644
@@ -14,6 +14,7 @@
 #include <linux/pci-epf.h>
 
 #include "xpcie.h"
+#include "util.h"
 
 #define XPCIE_DRIVER_NAME "mxlk_pcie_epf"
 #define XPCIE_DRIVER_DESC "Intel(R) xLink PCIe endpoint function driver"
@@ -26,6 +27,7 @@
 #define XPCIE_NUM_RX_DESCS	(64)
 
 extern bool dma_ll_mode;
+extern u32 xlink_sw_id;
 
 struct xpcie_dma_ll_desc {
 	u32 dma_ch_control1;
@@ -67,14 +69,38 @@ struct xpcie_epf {
 	void __iomem *dbi_base;
 	char stepping[KEEMBAY_XPCIE_STEPPING_MAXLEN];
 
+	irq_handler_t			core_irq_callback;
+	dma_addr_t			tx_phys;
+	void				*tx_virt;
+	size_t				tx_size;
+	dma_addr_t			rx_phys;
+	void				*rx_virt;
+	size_t				rx_size;
+
 	struct xpcie_dma_ll_desc_buf	tx_desc_buf[DMA_CHAN_NUM];
 	struct xpcie_dma_ll_desc_buf	rx_desc_buf[DMA_CHAN_NUM];
 };
 
+static inline struct device *xpcie_to_dev(struct xpcie *xpcie)
+{
+	struct xpcie_epf *xpcie_epf = container_of(xpcie,
+						   struct xpcie_epf, xpcie);
+
+	return &xpcie_epf->epf->dev;
+}
+
 int intel_xpcie_ep_dma_init(struct pci_epf *epf);
 int intel_xpcie_ep_dma_uninit(struct pci_epf *epf);
 int intel_xpcie_ep_dma_reset(struct pci_epf *epf);
 int intel_xpcie_ep_dma_read_ll(struct pci_epf *epf, int chan, int descs_num);
 int intel_xpcie_ep_dma_write_ll(struct pci_epf *epf, int chan, int descs_num);
 
+void intel_xpcie_register_host_irq(struct xpcie *xpcie,
+				   irq_handler_t func);
+int intel_xpcie_raise_irq(struct xpcie *xpcie,
+			  enum xpcie_doorbell_type type);
+int intel_xpcie_copy_from_host_ll(struct xpcie *xpcie,
+				  int chan, int descs_num);
+int intel_xpcie_copy_to_host_ll(struct xpcie *xpcie,
+				int chan, int descs_num);
 #endif /* XPCIE_EPF_HEADER_ */
drivers/misc/xlink-pcie/local_host/util.c new file +375 -0

375 lines not on this page · raw message

drivers/misc/xlink-pcie/local_host/util.h new file +70 -0

70 lines not on this page · raw message

drivers/misc/xlink-pcie/local_host/xpcie.h +65 -0

91 lines not on this page · raw message

include/linux/xlink_drv_inf.h new file +60 -0

60 lines not on this page · raw message

Signature · 1 line
2.17.1
#20 lore raw

PATCH 12/22 misc: xlink-pcie: rh: Add core communication logic

In reply to [email protected]

From: Srikanth Thokala <[email protected]>

Add logic to establish communication with the local host which is through ring buffer management and MSI/Doorbell interrupts

---
 drivers/misc/xlink-pcie/common/core.h        |  11 +-
 drivers/misc/xlink-pcie/remote_host/Makefile |   2 +
 drivers/misc/xlink-pcie/remote_host/core.c   | 647 +++++++++++++++++++
 drivers/misc/xlink-pcie/remote_host/pci.c    |  48 +-
 4 files changed, 696 insertions(+), 12 deletions(-)
 create mode 100644 drivers/misc/xlink-pcie/remote_host/core.c
drivers/misc/xlink-pcie/common/core.h +4 -7
index 84985ef41a64..eec8566c19d9 100644
@@ -10,15 +10,11 @@
 #ifndef XPCIE_CORE_HEADER_
 #define XPCIE_CORE_HEADER_
 
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/workqueue.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/mempool.h>
 #include <linux/dma-mapping.h>
-#include <linux/cache.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/wait.h>
+#include <linux/workqueue.h>
 
 #include <linux/xlink_drv_inf.h>
 
@@ -64,6 +60,7 @@ struct xpcie_buf_desc {
 struct xpcie_stream {
 	size_t frag;
 	struct xpcie_pipe pipe;
+	struct xpcie_buf_desc **ddr;
 };
 
 struct xpcie_list {
drivers/misc/xlink-pcie/remote_host/Makefile +2 -0
index 96374a43023e..e8074dbb1161 100644
@@ -1,3 +1,5 @@
 obj-$(CONFIG_XLINK_PCIE_RH_DRIVER) += mxlk.o
 mxlk-objs := main.o
 mxlk-objs += pci.o
+mxlk-objs += core.o
+mxlk-objs += ../common/util.o
drivers/misc/xlink-pcie/remote_host/core.c new file +647 -0

647 lines not on this page · raw message

drivers/misc/xlink-pcie/remote_host/pci.c +43 -5

81 lines not on this page · raw message

Signature · 1 line
2.17.1
#24 lore raw

PATCH 16/22 xlink-ipc: Add xlink ipc driver

In reply to [email protected]

From: Seamus Kelly <[email protected]>

Add xLink driver, which interfaces the xLink Core driver with the Keem Bay VPU IPC driver, thus enabling xLink to control and communicate with the VPU IP present on the Intel Keem Bay SoC.

Specifically the driver enables xLink Core to:

* Boot / Reset the VPU IP
* Register to VPU IP event notifications (device connected, device disconnected, WDT event)
* Query the status of the VPU IP (OFF, BUSY, READY, ERROR, RECOVERY)
* Exchange data with the VPU IP, using the Keem Bay IPC mechanism
- Including the ability to send 'volatile' data (i.e., small amount of data, up to 128-bytes that was not allocated in the CPU/VPU shared memory region)

Cc Jonathan Corbet <[email protected]>
Cc Cc: Derek Kiernan <[email protected]>
Cc Dragan Cvetic <[email protected]>
Cc Arnd Bergmann <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
---
 Documentation/vpu/index.rst        |   1 +
 Documentation/vpu/xlink-ipc.rst    |  50 ++
 MAINTAINERS                        |   6 +
 drivers/misc/Kconfig               |   1 +
 drivers/misc/Makefile              |   1 +
 drivers/misc/xlink-ipc/Kconfig     |   7 +
 drivers/misc/xlink-ipc/Makefile    |   4 +
 drivers/misc/xlink-ipc/xlink-ipc.c | 879 +++++++++++++++++++++++++++++
 include/linux/xlink-ipc.h          |  48 ++
 9 files changed, 997 insertions(+)
 create mode 100644 Documentation/vpu/xlink-ipc.rst
 create mode 100644 drivers/misc/xlink-ipc/Kconfig
 create mode 100644 drivers/misc/xlink-ipc/Makefile
 create mode 100644 drivers/misc/xlink-ipc/xlink-ipc.c
 create mode 100644 include/linux/xlink-ipc.h
Documentation/vpu/index.rst +1 -0
index 661cc700ee45..49c78bb65b83 100644
@@ -15,3 +15,4 @@ This documentation contains information for the Intel VPU stack.
 
    vpu-stack-overview
    xlink-pcie
+   xlink-ipc
Documentation/vpu/xlink-ipc.rst new file +50 -0

50 lines not on this page · raw message

MAINTAINERS +6 -0
index b3468dea6557..ebc2cce7251f 100644
@@ -1952,6 +1952,12 @@ F:	Documentation/devicetree/bindings/arm/intel,keembay.yaml
 F:	arch/arm64/boot/dts/intel/keembay-evm.dts
 F:	arch/arm64/boot/dts/intel/keembay-soc.dtsi
 
+ARM/INTEL XLINK IPC SUPPORT
+M:	Seamus Kelly <[email protected]>
+M:	Mark Gross <[email protected]>
+S:	Maintained
+F:	drivers/misc/xlink-ipc/
+
 ARM/INTEL KEEMBAY XLINK PCIE SUPPORT
 M:	Srikanth Thokala <[email protected]>
 M:	Mark Gross <[email protected]>
drivers/misc/Kconfig +1 -0
index dfb98e444c6e..1f81ea915b95 100644
@@ -482,4 +482,5 @@ source "drivers/misc/cardreader/Kconfig"
 source "drivers/misc/habanalabs/Kconfig"
 source "drivers/misc/uacce/Kconfig"
 source "drivers/misc/xlink-pcie/Kconfig"
+source "drivers/misc/xlink-ipc/Kconfig"
 endmenu
drivers/misc/Makefile +1 -0
index d17621fc43d5..b51495a2f1e0 100644
@@ -58,3 +58,4 @@ obj-$(CONFIG_UACCE)		+= uacce/
 obj-$(CONFIG_XILINX_SDFEC)	+= xilinx_sdfec.o
 obj-$(CONFIG_HISI_HIKEY_USB)	+= hisi_hikey_usb.o
 obj-y                           += xlink-pcie/
+obj-$(CONFIG_XLINK_IPC)		+= xlink-ipc/
drivers/misc/xlink-ipc/Kconfig new file +7 -0
new file mode 100644
index 000000000000..6aa2592fe9a3
@@ -0,0 +1,7 @@
+config XLINK_IPC
+	tristate "Support for XLINK IPC"
+	depends on KEEMBAY_VPU_IPC
+	help
+	  XLINK IPC enables the communication/control IPC Sub-System.
+
+	  Select M if you have an Intel SoC with a Vision Processing Unit (VPU)
drivers/misc/xlink-ipc/Makefile new file +4 -0
new file mode 100644
index 000000000000..f92c95525e23
@@ -0,0 +1,4 @@
+#
+# Makefile for xlink IPC Linux driver
+#
+obj-$(CONFIG_XLINK_IPC) += xlink-ipc.o
drivers/misc/xlink-ipc/xlink-ipc.c new file +879 -0

879 lines not on this page · raw message

include/linux/xlink-ipc.h new file +48 -0

48 lines not on this page · raw message

Signature · 1 line
2.17.1
#28 lore raw

PATCH 20/22 xlink-core: Enable VPU IP management and runtime control

In reply to [email protected]

From: Seamus Kelly <[email protected]>

Enable VPU management including, enumeration, boot and runtime control.

Add APIs:
write control data:
used to transmit small, local data
start vpu:
calls boot_device API ( soon to be deprecated )
stop vpu
calls reset_device API ( soon to be deprecated )
reset vpu
calls reset_device API ( soon to be deprecated )
get device name:
Returns the device name for the input device id
This could be a char device path, for example "/dev/ttyUSB0" for a serial device; or it could be a device string description, for example, for PCIE "00:00.0 Host bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (rev 01)"
get device list:
Returns the list of software device IDs for all connected physical devices
get device status:
returns the current state of the input device
OFF - The device is off (D3cold/Slot power removed). BUSY - device is busy and not available (device is booting) READY - device is available for use
ERROR - device HW failure is detected
RECOVERY - device is in recovery mode, waiting for recovery operations
boot device:
When used on the remote host - starts the SOC device by calling corresponding function from VPU Driver.
Takes firmware's 'binary_name' as input.
For Linux, the firmware image is expected to be located in '/lib/firmware' folder or its subfolders.
For Linux, 'binary_name' is not a path but an image name that will be searched in the default Linux search paths ('/lib/firmware'). When used on the local host - triggers the booting of VPUIP device.
reset device:
When used on the remote host - resets the device by calling corresponding VPU Driver function.
When used on the local host - resets the VPUIP device
get device mode:
query and returns the current device power mode
set device mode:
used for device throttling or entering various power modes

Cc Arnd Bergmann <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
---
 drivers/misc/xlink-core/xlink-core.c        | 408 +++++++++++++++++++-
 drivers/misc/xlink-core/xlink-defs.h        |   2 +
 drivers/misc/xlink-core/xlink-multiplexer.c |  56 +++
 drivers/misc/xlink-core/xlink-platform.c    |  86 +++++
 include/linux/xlink.h                       |  27 ++
 5 files changed, 573 insertions(+), 6 deletions(-)
drivers/misc/xlink-core/xlink-core.c +402 -6
index e7d5f68a5ba1..a600068840d3 100644
@@ -81,6 +81,8 @@ struct keembay_xlink_dev {
 	struct mutex lock;  // protect access to xlink_dev
 };
 
+static u8 volbuf[XLINK_MAX_BUF_SIZE]; // buffer for volatile transactions
+
 /*
  * global variable pointing to our xlink device.
  *
@@ -260,14 +262,27 @@ static int kmb_xlink_remove(struct platform_device *pdev)
 
 static long xlink_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	int interface = NULL_INTERFACE;
 	struct xlink_handle		devh	= {0};
 	struct xlinkopenchannel		op	= {0};
 	struct xlinkwritedata		wr	= {0};
 	struct xlinkreaddata		rd	= {0};
+	struct xlinkreadtobuffer	rdtobuf = {0};
 	struct xlinkconnect		con	= {0};
 	struct xlinkrelease		rel	= {0};
-	u8 volbuf[XLINK_MAX_BUF_SIZE];
+	struct xlinkstartvpu		startvpu = {0};
+	struct xlinkgetdevicename	devn	= {0};
+	struct xlinkgetdevicelist	devl	= {0};
+	struct xlinkgetdevicestatus	devs	= {0};
+	struct xlinkbootdevice		boot	= {0};
+	struct xlinkresetdevice		res	= {0};
+	struct xlinkdevmode		devm	= {0};
+	u32 sw_device_id_list[XLINK_MAX_DEVICE_LIST_SIZE];
+	char name[XLINK_MAX_DEVICE_NAME_SIZE];
+	int interface = NULL_INTERFACE;
+	u32 device_status = 0;
+	u32 num_devices = 0;
+	u32 device_mode = 0;
+	char filename[64];
 	u8 reladdr;
 	u8 *rdaddr;
 	u32 size;
@@ -328,6 +343,26 @@ static long xlink_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		if (copy_to_user((void __user *)rd.return_code, (void *)&rc, sizeof(rc)))
 			return -EFAULT;
 		break;
+	case XL_READ_TO_BUFFER:
+		if (copy_from_user(&rdtobuf, (void __user *)arg,
+				   sizeof(struct xlinkreadtobuffer)))
+			return -EFAULT;
+		if (copy_from_user(&devh, (void __user *)rdtobuf.handle,
+				   sizeof(struct xlink_handle)))
+			return -EFAULT;
+		rc = xlink_read_data_to_buffer(&devh, rdtobuf.chan,
+					       (u8 *)volbuf, &size);
+		if (!rc) {
+			if (copy_to_user((void __user *)rdtobuf.pmessage, (void *)volbuf,
+					 size))
+				return -EFAULT;
+			if (copy_to_user((void __user *)rdtobuf.size, (void *)&size,
+					 sizeof(size)))
+				return -EFAULT;
+		}
+		if (copy_to_user((void __user *)rdtobuf.return_code, (void *)&rc, sizeof(rc)))
+			return -EFAULT;
+		break;
 	case XL_WRITE_DATA:
 		if (copy_from_user(&wr, (void __user *)arg,
 				   sizeof(struct xlinkwritedata)))
@@ -346,16 +381,40 @@ static long xlink_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		}
 		break;
 	case XL_WRITE_VOLATILE:
-		if (copy_from_user(&wr,  (void __user *)arg, sizeof(struct xlinkwritedata)))
+		if (copy_from_user(&wr, (void __user *)arg,
+				   sizeof(struct xlinkwritedata)))
 			return -EFAULT;
 		if (copy_from_user(&devh, (void __user *)wr.handle,
 				   sizeof(struct xlink_handle)))
 			return -EFAULT;
 		if (wr.size <= XLINK_MAX_BUF_SIZE) {
-			if (copy_from_user(volbuf, (void __user *)wr.pmessage, wr.size))
+			if (copy_from_user(volbuf, (void __user *)wr.pmessage,
+					   wr.size))
 				return -EFAULT;
-			rc = xlink_write_volatile_user(&devh, wr.chan, volbuf, wr.size);
-			if (copy_to_user((void __user *)wr.return_code, (void *)&rc, sizeof(rc)))
+			rc = xlink_write_volatile_user(&devh, wr.chan, volbuf,
+						       wr.size);
+			if (copy_to_user((void __user *)wr.return_code, (void *)&rc,
+					 sizeof(rc)))
+				return -EFAULT;
+		} else {
+			return -EFAULT;
+		}
+		break;
+	case XL_WRITE_CONTROL_DATA:
+		if (copy_from_user(&wr, (void __user *)arg,
+				   sizeof(struct xlinkwritedata)))
+			return -EFAULT;
+		if (copy_from_user(&devh, (void __user *)wr.handle,
+				   sizeof(struct xlink_handle)))
+			return -EFAULT;
+		if (wr.size <= XLINK_MAX_CONTROL_DATA_SIZE) {
+			if (copy_from_user(volbuf, (void __user *)wr.pmessage,
+					   wr.size))
+				return -EFAULT;
+			rc = xlink_write_control_data(&devh, wr.chan, volbuf,
+						      wr.size);
+			if (copy_to_user((void __user *)wr.return_code,
+					 (void *)&rc, sizeof(rc)))
 				return -EFAULT;
 		} else {
 			return -EFAULT;
@@ -390,6 +449,26 @@ static long xlink_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		if (copy_to_user((void __user *)op.return_code, (void *)&rc, sizeof(rc)))
 			return -EFAULT;
 		break;
+	case XL_START_VPU:
+		if (copy_from_user(&startvpu, (void __user *)arg,
+				   sizeof(struct xlinkstartvpu)))
+			return -EFAULT;
+		if (startvpu.namesize > sizeof(filename))
+			return -EINVAL;
+		memset(filename, 0, sizeof(filename));
+		if (copy_from_user(filename, (void __user *)startvpu.filename,
+				   startvpu.namesize))
+			return -EFAULT;
+		rc = xlink_start_vpu(filename);
+		if (copy_to_user((void __user *)startvpu.return_code, (void *)&rc, sizeof(rc)))
+			return -EFAULT;
+		break;
+	case XL_STOP_VPU:
+		rc = xlink_stop_vpu();
+		break;
+	case XL_RESET_VPU:
+		rc = xlink_stop_vpu();
+		break;
 	case XL_DISCONNECT:
 		if (copy_from_user(&con, (void __user *)arg,
 				   sizeof(struct xlinkconnect)))
@@ -401,6 +480,124 @@ static long xlink_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		if (copy_to_user((void __user *)con.return_code, (void *)&rc, sizeof(rc)))
 			return -EFAULT;
 		break;
+	case XL_GET_DEVICE_NAME:
+		if (copy_from_user(&devn, (void __user *)arg,
+				   sizeof(struct xlinkgetdevicename)))
+			return -EFAULT;
+		if (copy_from_user(&devh, (void __user *)devn.handle,
+				   sizeof(struct xlink_handle)))
+			return -EFAULT;
+		if (devn.name_size <= XLINK_MAX_DEVICE_NAME_SIZE) {
+			rc = xlink_get_device_name(&devh, name, devn.name_size);
+			if (!rc) {
+				if (copy_to_user((void __user *)devn.name, (void *)name,
+						 devn.name_size))
+					return -EFAULT;
+			}
+		} else {
+			rc = X_LINK_ERROR;
+		}
+		if (copy_to_user((void __user *)devn.return_code, (void *)&rc, sizeof(rc)))
+			return -EFAULT;
+		break;
+	case XL_GET_DEVICE_LIST:
+		if (copy_from_user(&devl, (void __user *)arg,
+				   sizeof(struct xlinkgetdevicelist)))
+			return -EFAULT;
+		rc = xlink_get_device_list(sw_device_id_list, &num_devices);
+		if (!rc && num_devices <= XLINK_MAX_DEVICE_LIST_SIZE) {
+			/* TODO: this next copy is dangerous! we have no idea
+			 * how large the devl.sw_device_id_list buffer is
+			 * provided by the user. if num_devices is too large,
+			 * the copy will overflow the buffer.
+			 */
+			if (copy_to_user((void __user *)devl.sw_device_id_list,
+					 (void *)sw_device_id_list,
+					 (sizeof(*sw_device_id_list)
+					 * num_devices)))
+				return -EFAULT;
+			if (copy_to_user((void __user *)devl.num_devices, (void *)&num_devices,
+					 (sizeof(num_devices))))
+				return -EFAULT;
+		}
+		if (copy_to_user((void __user *)devl.return_code, (void *)&rc, sizeof(rc)))
+			return -EFAULT;
+		break;
+	case XL_GET_DEVICE_STATUS:
+		if (copy_from_user(&devs, (void __user *)arg,
+				   sizeof(struct xlinkgetdevicestatus)))
+			return -EFAULT;
+		if (copy_from_user(&devh, (void __user *)devs.handle,
+				   sizeof(struct xlink_handle)))
+			return -EFAULT;
+		rc = xlink_get_device_status(&devh, &device_status);
+		if (!rc) {
+			if (copy_to_user((void __user *)devs.device_status,
+					 (void *)&device_status,
+					 sizeof(device_status)))
+				return -EFAULT;
+		}
+		if (copy_to_user((void __user *)devs.return_code, (void *)&rc, sizeof(rc)))
+			return -EFAULT;
+		break;
+	case XL_BOOT_DEVICE:
+		if (copy_from_user(&boot, (void __user *)arg,
+				   sizeof(struct xlinkbootdevice)))
+			return -EFAULT;
+		if (copy_from_user(&devh, (void __user *)boot.handle,
+				   sizeof(struct xlink_handle)))
+			return -EFAULT;
+		if (boot.binary_name_size > sizeof(filename))
+			return -EINVAL;
+		memset(filename, 0, sizeof(filename));
+		if (copy_from_user(filename, (void __user *)boot.binary_name,
+				   boot.binary_name_size))
+			return -EFAULT;
+		rc = xlink_boot_device(&devh, filename);
+		if (copy_to_user((void __user *)boot.return_code, (void *)&rc, sizeof(rc)))
+			return -EFAULT;
+		break;
+	case XL_RESET_DEVICE:
+		if (copy_from_user(&res, (void __user *)arg,
+				   sizeof(struct xlinkresetdevice)))
+			return -EFAULT;
+		if (copy_from_user(&devh, (void __user *)res.handle,
+				   sizeof(struct xlink_handle)))
+			return -EFAULT;
+		rc = xlink_reset_device(&devh);
+		if (copy_to_user((void __user *)res.return_code, (void *)&rc, sizeof(rc)))
+			return -EFAULT;
+		break;
+	case XL_GET_DEVICE_MODE:
+		if (copy_from_user(&devm, (void __user *)arg,
+				   sizeof(struct xlinkdevmode)))
+			return -EFAULT;
+		if (copy_from_user(&devh, (void __user *)devm.handle,
+				   sizeof(struct xlink_handle)))
+			return -EFAULT;
+		rc = xlink_get_device_mode(&devh, &device_mode);
+		if (!rc) {
+			if (copy_to_user((void __user *)devm.device_mode, (void *)&device_mode,
+					 sizeof(device_mode)))
+				return -EFAULT;
+		}
+		if (copy_to_user((void __user *)devm.return_code, (void *)&rc, sizeof(rc)))
+			return -EFAULT;
+		break;
+	case XL_SET_DEVICE_MODE:
+		if (copy_from_user(&devm, (void __user *)arg,
+				   sizeof(struct xlinkdevmode)))
+			return -EFAULT;
+		if (copy_from_user(&devh, (void __user *)devm.handle,
+				   sizeof(struct xlink_handle)))
+			return -EFAULT;
+		if (copy_from_user(&device_mode, (void __user *)devm.device_mode,
+				   sizeof(device_mode)))
+			return -EFAULT;
+		rc = xlink_set_device_mode(&devh, device_mode);
+		if (copy_to_user((void __user *)devm.return_code, (void *)&rc, sizeof(rc)))
+			return -EFAULT;
+		break;
 	}
 	if (rc)
 		return -EIO;
@@ -411,6 +608,30 @@ static long xlink_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 /*
  * xlink Kernel API.
  */
+enum xlink_error xlink_stop_vpu(void)
+{
+#ifdef CONFIG_XLINK_LOCAL_HOST
+	int rc;
+
+	rc = xlink_ipc_reset_device(0x0); // stop vpu slice 0
+	if (rc)
+		return X_LINK_ERROR;
+#endif
+	return X_LINK_SUCCESS;
+}
+EXPORT_SYMBOL(xlink_stop_vpu);
+enum xlink_error xlink_start_vpu(char *filename)
+{
+#ifdef CONFIG_XLINK_LOCAL_HOST
+	int rc;
+
+	rc = xlink_ipc_boot_device(0x0, filename); // start vpu slice 0
+	if (rc)
+		return X_LINK_ERROR;
+#endif
+	return X_LINK_SUCCESS;
+}
+EXPORT_SYMBOL(xlink_start_vpu);
 
 enum xlink_error xlink_initialize(void)
 {
@@ -649,6 +870,33 @@ static enum xlink_error xlink_write_data_user(struct xlink_handle *handle,
 	return rc;
 }
 
+enum xlink_error xlink_write_control_data(struct xlink_handle *handle,
+					  u16 chan, u8 const *pmessage,
+					  u32 size)
+{
+	struct xlink_event *event;
+	struct xlink_link *link;
+	int event_queued = 0;
+	enum xlink_error rc;
+
+	if (!xlink || !handle)
+		return X_LINK_ERROR;
+	if (size > XLINK_MAX_CONTROL_DATA_SIZE)
+		return X_LINK_ERROR; // TODO: XLink Parameter Error
+	link = get_link_by_sw_device_id(handle->sw_device_id);
+	if (!link)
+		return X_LINK_ERROR;
+	event = xlink_create_event(link->id, XLINK_WRITE_CONTROL_REQ,
+				   &link->handle, chan, size, 0);
+	if (!event)
+		return X_LINK_ERROR;
+	memcpy(event->header.control_data, pmessage, size);
+	rc = xlink_multiplexer_tx(event, &event_queued);
+	if (!event_queued)
+		xlink_destroy_event(event);
+	return rc;
+}
+EXPORT_SYMBOL(xlink_write_control_data);
 static enum xlink_error xlink_write_volatile_user(struct xlink_handle *handle,
 						  u16 chan, u8 const *message,
 						  u32 size)
@@ -844,6 +1092,154 @@ enum xlink_error xlink_disconnect(struct xlink_handle *handle)
 }
 EXPORT_SYMBOL(xlink_disconnect);
 
+enum xlink_error xlink_get_device_list(u32 *sw_device_id_list,
+				       u32 *num_devices)
+{
+	u32 interface_nmb_devices = 0;
+	enum xlink_error rc;
+	int i;
+
+	if (!xlink)
+		return X_LINK_ERROR;
+	if (!sw_device_id_list || !num_devices)
+		return X_LINK_ERROR;
+	/* loop through each interface and combine the lists */
+	for (i = 0; i < NMB_OF_INTERFACES; i++) {
+		rc = xlink_platform_get_device_list(i, sw_device_id_list,
+						    &interface_nmb_devices);
+		if (!rc) {
+			*num_devices += interface_nmb_devices;
+			sw_device_id_list += interface_nmb_devices;
+		}
+		interface_nmb_devices = 0;
+	}
+	return X_LINK_SUCCESS;
+}
+EXPORT_SYMBOL(xlink_get_device_list);
+enum xlink_error xlink_get_device_name(struct xlink_handle *handle, char *name,
+				       size_t name_size)
+{
+	enum xlink_error rc;
+	int interface;
+
+	if (!xlink || !handle)
+		return X_LINK_ERROR;
+	if (!name || !name_size)
+		return X_LINK_ERROR;
+	interface = get_interface_from_sw_device_id(handle->sw_device_id);
+	if (interface == NULL_INTERFACE)
+		return X_LINK_ERROR;
+	rc = xlink_platform_get_device_name(interface, handle->sw_device_id,
+					    name, name_size);
+	if (rc)
+		rc = X_LINK_ERROR;
+	else
+		rc = X_LINK_SUCCESS;
+	return rc;
+}
+EXPORT_SYMBOL(xlink_get_device_name);
+enum xlink_error xlink_get_device_status(struct xlink_handle *handle,
+					 u32 *device_status)
+{
+	enum xlink_error rc;
+	u32 interface;
+
+	if (!xlink)
+		return X_LINK_ERROR;
+	if (!device_status)
+		return X_LINK_ERROR;
+	interface = get_interface_from_sw_device_id(handle->sw_device_id);
+	if (interface == NULL_INTERFACE)
+		return X_LINK_ERROR;
+	rc = xlink_platform_get_device_status(interface, handle->sw_device_id,
+					      device_status);
+	if (rc)
+		rc = X_LINK_ERROR;
+	else
+		rc = X_LINK_SUCCESS;
+	return rc;
+}
+EXPORT_SYMBOL(xlink_get_device_status);
+enum xlink_error xlink_boot_device(struct xlink_handle *handle,
+				   const char *binary_name)
+{
+	enum xlink_error rc;
+	u32 interface;
+
+	if (!xlink || !handle)
+		return X_LINK_ERROR;
+	if (!binary_name)
+		return X_LINK_ERROR;
+	interface = get_interface_from_sw_device_id(handle->sw_device_id);
+	if (interface == NULL_INTERFACE)
+		return X_LINK_ERROR;
+	rc = xlink_platform_boot_device(interface, handle->sw_device_id,
+					binary_name);
+	if (rc)
+		rc = X_LINK_ERROR;
+	else
+		rc = X_LINK_SUCCESS;
+	return rc;
+}
+EXPORT_SYMBOL(xlink_boot_device);
+enum xlink_error xlink_reset_device(struct xlink_handle *handle)
+{
+	enum xlink_error rc;
+	u32 interface;
+
+	if (!xlink || !handle)
+		return X_LINK_ERROR;
+	interface = get_interface_from_sw_device_id(handle->sw_device_id);
+	if (interface == NULL_INTERFACE)
+		return X_LINK_ERROR;
+	rc = xlink_platform_reset_device(interface, handle->sw_device_id);
+	if (rc)
+		rc = X_LINK_ERROR;
+	else
+		rc = X_LINK_SUCCESS;
+	return rc;
+}
+EXPORT_SYMBOL(xlink_reset_device);
+enum xlink_error xlink_set_device_mode(struct xlink_handle *handle,
+				       enum xlink_device_power_mode power_mode)
+{
+	enum xlink_error rc;
+	u32 interface;
+
+	if (!xlink || !handle)
+		return X_LINK_ERROR;
+	interface = get_interface_from_sw_device_id(handle->sw_device_id);
+	if (interface == NULL_INTERFACE)
+		return X_LINK_ERROR;
+	rc = xlink_platform_set_device_mode(interface, handle->sw_device_id,
+					    power_mode);
+	if (rc)
+		rc = X_LINK_ERROR;
+	else
+		rc = X_LINK_SUCCESS;
+	return rc;
+}
+EXPORT_SYMBOL(xlink_set_device_mode);
+enum xlink_error xlink_get_device_mode(struct xlink_handle *handle,
+				       enum xlink_device_power_mode *power_mode)
+{
+	enum xlink_error rc;
+	u32 interface;
+
+	if (!xlink || !handle)
+		return X_LINK_ERROR;
+	interface = get_interface_from_sw_device_id(handle->sw_device_id);
+	if (interface == NULL_INTERFACE)
+		return X_LINK_ERROR;
+	rc = xlink_platform_get_device_mode(interface, handle->sw_device_id,
+					    power_mode);
+	if (rc)
+		rc = X_LINK_ERROR;
+	else
+		rc = X_LINK_SUCCESS;
+	return rc;
+}
+EXPORT_SYMBOL(xlink_get_device_mode);
 /* Device tree driver match. */
 static const struct of_device_id kmb_xlink_of_match[] = {
 	{
drivers/misc/xlink-core/xlink-defs.h +2 -0
index 09aee36d5542..8985f6631175 100644
@@ -101,6 +101,7 @@ enum xlink_event_type {
 	XLINK_OPEN_CHANNEL_REQ,
 	XLINK_CLOSE_CHANNEL_REQ,
 	XLINK_PING_REQ,
+	XLINK_WRITE_CONTROL_REQ,
 	XLINK_REQ_LAST,
 	// response events
 	XLINK_WRITE_RESP = 0x10,
@@ -111,6 +112,7 @@ enum xlink_event_type {
 	XLINK_OPEN_CHANNEL_RESP,
 	XLINK_CLOSE_CHANNEL_RESP,
 	XLINK_PING_RESP,
+	XLINK_WRITE_CONTROL_RESP,
 	XLINK_RESP_LAST,
 };
 
drivers/misc/xlink-core/xlink-multiplexer.c +56 -0

92 lines not on this page · raw message

drivers/misc/xlink-core/xlink-platform.c +86 -0

104 lines not on this page · raw message

include/linux/xlink.h +27 -0
index c22439d5aade..b00dbc719530 100644
@@ -78,6 +78,10 @@ enum xlink_error xlink_write_data(struct xlink_handle *handle,
 enum xlink_error xlink_write_volatile(struct xlink_handle *handle,
 				      u16 chan, u8 const *message, u32 size);
 
+enum xlink_error xlink_write_control_data(struct xlink_handle *handle,
+					  u16 chan, u8 const *message,
+					  u32 size);
+
 enum xlink_error xlink_read_data(struct xlink_handle *handle,
 				 u16 chan, u8 **message, u32 *size);
 
@@ -90,6 +94,29 @@ enum xlink_error xlink_release_data(struct xlink_handle *handle,
 
 enum xlink_error xlink_disconnect(struct xlink_handle *handle);
 
+enum xlink_error xlink_get_device_list(u32 *sw_device_id_list, u32 *num_devices);
+
+enum xlink_error xlink_get_device_name(struct xlink_handle *handle, char *name,
+				       size_t name_size);
+
+enum xlink_error xlink_get_device_status(struct xlink_handle *handle,
+					 u32 *device_status);
+
+enum xlink_error xlink_boot_device(struct xlink_handle *handle,
+				   const char *binary_name);
+
+enum xlink_error xlink_reset_device(struct xlink_handle *handle);
+
+enum xlink_error xlink_set_device_mode(struct xlink_handle *handle,
+				       enum xlink_device_power_mode power_mode);
+
+enum xlink_error xlink_get_device_mode(struct xlink_handle *handle,
+				       enum xlink_device_power_mode *power_mode);
+
+enum xlink_error xlink_start_vpu(char *filename); /* depreciated */
+
+enum xlink_error xlink_stop_vpu(void); /* depreciated */
+
 /* API functions to be implemented
  *
  * enum xlink_error xlink_write_crc_data(struct xlink_handle *handle,
Signature · 1 line
2.17.1
#3 lore raw

PATCH 3/22 keembay-ipc: Add Keem Bay IPC module

In reply to [email protected]

From: Daniele Alessandrelli <[email protected]>

On the Intel Movidius SoC code named Keem Bay, communication between the Computing Sub-System (CSS), i.e., the CPU, and the Multimedia Sub-System (MSS), i.e., the VPU is enabled by the Keem Bay Inter-Processor Communication (IPC) mechanism.

Add the driver for using Keem Bay IPC from within the Linux Kernel.

Keem Bay IPC uses the following terminology:

- Node: A processing entity that can use the IPC to communicate;
currently, we just have two nodes, CPU (CSS) and VPU (MSS).

- Link: Two nodes that can communicate over IPC form an IPC link
(currently, we just have one link, the one between the CPU and VPU).

- Channel: An IPC link can provide multiple IPC channels. IPC channels allow communication multiplexing, i.e., the same IPC link can be used by different applications for different communications. Each channel is identified by a channel ID, which must be unique within a single IPC link. Channels are divided in two categories, High-Speed (HS) channels and General-Purpose (GP) channels. HS channels have higher priority over GP channels.

Keem Bay IPC mechanism is based on shared memory and hardware FIFOs. Both the CPU and the VPU have their own hardware FIFO. When the CPU wants to send an IPC message to the VPU, it writes to the VPU FIFO (MSS FIFO); similarly, when MSS wants to send an IPC message to the CPU, it writes to the CPU FIFO (CSS FIFO).

A FIFO entry is simply a pointer to an IPC buffer (aka IPC header) stored in a portion of memory shared between the CPU and the VPU. Specifically, the FIFO entry contains the (VPU) physical address of the IPC buffer being transferred.

In turn, the IPC buffer contains the (VPU) physical address of the payload (which must be located in shared memory too) as well as other information (payload size, IPC channel ID, etc.).

Each IPC node instantiates a pool of IPC buffers from its own IPC buffer memory region. When instantiated, IPC buffers are marked as free. When the node needs to send an IPC message, it gets the first free buffer it finds (from its own pool), marks it as allocated (used), and puts its physical address into the IPC FIFO of the destination node. The destination node (which is notified by an interrupt when there are entries pending in its FIFO) extract the physical address from the FIFO and process the IPC buffer, marking it as free once done (so that the sender can reuse the buffer).

Cc Paul Walmsley <[email protected]>
Cc Palmer Dabbelt <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Damien Le Moal <[email protected]>
Cc Peng Fan <[email protected]>
Cc Shawn Guo <[email protected]>
Cc Leonard Crestez <[email protected]>
---
 MAINTAINERS                           |    8 +
 drivers/soc/Kconfig                   |    1 +
 drivers/soc/Makefile                  |    1 +
 drivers/soc/intel/Kconfig             |   17 +
 drivers/soc/intel/Makefile            |    4 +
 drivers/soc/intel/keembay-ipc.c       | 1669 +++++++++++++++++++++++++
 include/linux/soc/intel/keembay-ipc.h |   30 +
 7 files changed, 1730 insertions(+)
 create mode 100644 drivers/soc/intel/Kconfig
 create mode 100644 drivers/soc/intel/Makefile
 create mode 100644 drivers/soc/intel/keembay-ipc.c
 create mode 100644 include/linux/soc/intel/keembay-ipc.h
MAINTAINERS +8 -0
index e451dcce054f..64475ba4ea9d 100644
@@ -8955,6 +8955,14 @@ M:	Deepak Saxena <[email protected]>
 S:	Maintained
 F:	drivers/char/hw_random/ixp4xx-rng.c
 
+INTEL KEEM BAY IPC DRIVER
+M:	Daniele Alessandrelli <[email protected]>
+M:	Mark Gross <[email protected]>
+S:	Maintained
+F:	Documentation/devicetree/bindings/soc/intel/intel,keembay-ipc.yaml
+F:	drivers/soc/intel/keembay-ipc.c
+F:	include/linux/soc/intel/keembay-ipc.h
+
 INTEL MANAGEMENT ENGINE (mei)
 M:	Tomas Winkler <[email protected]>
 L:	[email protected]
drivers/soc/Kconfig +1 -0
index 425ab6f7e375..c21a85bc3899 100644
@@ -8,6 +8,7 @@ source "drivers/soc/atmel/Kconfig"
 source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/fsl/Kconfig"
 source "drivers/soc/imx/Kconfig"
+source "drivers/soc/intel/Kconfig"
 source "drivers/soc/ixp4xx/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
drivers/soc/Makefile +1 -0
index 36452bed86ef..fbd587640e1f 100644
@@ -12,6 +12,7 @@ obj-$(CONFIG_MACH_DOVE)		+= dove/
 obj-y				+= fsl/
 obj-$(CONFIG_ARCH_GEMINI)	+= gemini/
 obj-y				+= imx/
+obj-y				+= intel/
 obj-$(CONFIG_ARCH_IXP4XX)	+= ixp4xx/
 obj-$(CONFIG_SOC_XWAY)		+= lantiq/
 obj-y				+= mediatek/
drivers/soc/intel/Kconfig new file +17 -0
new file mode 100644
index 000000000000..1f5c05b97649
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Keem Bay SoC drivers
+#
+
+menu "Intel SoC drivers"
+
+config KEEMBAY_IPC
+	tristate "Support for Intel Keem Bay IPC"
+	depends on ARCH_KEEMBAY || (ARM64 && COMPILE_TEST)
+	help
+	  Keem Bay IPC enables communication between the Keem Bay CPU
+	  Sub-System (CSS) and the Keem Bay Media Sub-System (MSS).
+
+	  Select this if you are compiling the Kernel for an Intel SoC that
+	  includes the Intel Vision Processing Unit (VPU) such as Keem Bay.
+endmenu
drivers/soc/intel/Makefile new file +4 -0
new file mode 100644
index 000000000000..ecf0246e7822
@@ -0,0 +1,4 @@
+#
+# Makefile for Keem Bay IPC Linux driver
+#
+obj-$(CONFIG_KEEMBAY_IPC) += keembay-ipc.o
drivers/soc/intel/keembay-ipc.c new file +1669 -0

1,669 lines not on this page · raw message

include/linux/soc/intel/keembay-ipc.h new file +30 -0
new file mode 100644
index 000000000000..bbcf387ecdbd
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Keem Bay IPC Linux Kernel API
+ *
+ * Copyright (C) 2018-2020 Intel Corporation
+ */
+
+#ifndef __KEEMBAY_IPC_H
+#define __KEEMBAY_IPC_H
+
+#include <linux/types.h>
+
+/* The possible node IDs. */
+enum {
+	KMB_IPC_NODE_ARM_CSS = 0,
+	KMB_IPC_NODE_LEON_MSS,
+};
+
+int intel_keembay_ipc_open_channel(struct device *dev, u8 node_id, u16 chan_id);
+
+int intel_keembay_ipc_close_channel(struct device *dev, u8 node_id,
+				    u16 chan_id);
+
+int intel_keembay_ipc_send(struct device *dev, u8 node_id, u16 chan_id,
+			   u32 vpu_addr, size_t size);
+
+int intel_keembay_ipc_recv(struct device *dev, u8 node_id, u16 chan_id,
+			   u32 *vpu_addr, size_t *size, u32 timeout);
+
+#endif /* __KEEMBAY_IPC_H */
Signature · 1 line
2.17.1
#4 lore raw

PATCH 4/22 dt-bindings: Add bindings for Keem Bay VPU IPC driver

In reply to [email protected]

From: Paul Murphy <[email protected]>

Add DT bindings documentation for the Keem Bay VPU IPC driver.

---
 .../soc/intel/intel,keembay-vpu-ipc.yaml      | 151 ++++++++++++++++++
 1 file changed, 151 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/intel/intel,keembay-vpu-ipc.yaml
Documentation/devicetree/bindings/soc/intel/intel,keembay-vpu-ipc.yaml new file +151 -0
new file mode 100644
index 000000000000..60d4a028563c
@@ -0,0 +1,151 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (c) Intel Corporation. All rights reserved.
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/soc/intel/intel,keembay-vpu-ipc.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Intel Keem Bay VPU IPC
+
+maintainers:
+  - Paul Murphy <[email protected]>
+
+description:
+  The VPU IPC driver facilitates loading of firmware, control, and communication
+  with the VPU over the IPC FIFO in the Intel Keem Bay SoC.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+        - const: intel,keembay-vpu-ipc
+
+  reg:
+    items:
+      - description: NCE WDT registers
+      - description: NCE TIM_GEN_CONFIG registers
+      - description: MSS WDT registers
+      - description: MSS TIM_GEN_CONFIG registers
+
+  reg-names:
+    items:
+      - const: nce_wdt
+      - const: nce_tim_cfg
+      - const: mss_wdt
+      - const: mss_tim_cfg
+
+  memory-region:
+    items:
+      - description: reference to the VPU reserved memory region
+      - description: reference to the X509 reserved memory region
+      - description: reference to the MSS IPC area
+
+  clocks:
+    items:
+      - description: cpu clock
+      - description: pll 0 out 0 rate
+      - description: pll 0 out 1 rate
+      - description: pll 0 out 2 rate
+      - description: pll 0 out 3 rate
+      - description: pll 1 out 0 rate
+      - description: pll 1 out 1 rate
+      - description: pll 1 out 2 rate
+      - description: pll 1 out 3 rate
+      - description: pll 2 out 0 rate
+      - description: pll 2 out 1 rate
+      - description: pll 2 out 2 rate
+      - description: pll 2 out 3 rate
+
+  clocks-names:
+    items:
+      - const: cpu_clock
+      - const: pll_0_out_0
+      - const: pll_0_out_1
+      - const: pll_0_out_2
+      - const: pll_0_out_3
+      - const: pll_1_out_0
+      - const: pll_1_out_1
+      - const: pll_1_out_2
+      - const: pll_1_out_3
+      - const: pll_2_out_0
+      - const: pll_2_out_1
+      - const: pll_2_out_2
+      - const: pll_2_out_3
+
+  interrupts:
+    items:
+      - description: number of NCE sub-system WDT timeout IRQ
+      - description: number of MSS sub-system WDT timeout IRQ
+
+  interrupt-names:
+    items:
+      - const: nce_wdt
+      - const: mss_wdt
+
+  intel,keembay-vpu-ipc-nce-wdt-redirect:
+    $ref: "/schemas/types.yaml#/definitions/uint32"
+    description:
+      Number to which we will request that the NCE sub-system
+      re-directs it's WDT timeout IRQ
+
+  intel,keembay-vpu-ipc-mss-wdt-redirect:
+    $ref: "/schemas/types.yaml#/definitions/uint32"
+    description:
+      Number to which we will request that the MSS sub-system
+      re-directs it's WDT timeout IRQ
+
+  intel,keembay-vpu-ipc-imr:
+    $ref: "/schemas/types.yaml#/definitions/uint32"
+    description:
+      IMR (isolated memory region) number which we will request
+      the runtime service uses to protect the VPU memory region
+      before authentication
+
+  intel,keembay-vpu-ipc-id:
+    $ref: "/schemas/types.yaml#/definitions/uint32"
+    description: The VPU ID to be passed to the VPU firmware.
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    vpu-ipc@3f00209c {
+        compatible = "intel,keembay-vpu-ipc";
+        reg = <0x3f00209c 0x10>,
+              <0x3f003008 0x4>,
+              <0x2082009c 0x10>,
+              <0x20821008 0x4>;
+        reg-names = "nce_wdt",
+                    "nce_tim_cfg",
+                    "mss_wdt",
+                    "mss_tim_cfg";
+        memory-region = <&vpu_reserved>,
+                        <&vpu_x509_reserved>,
+                        <&mss_ipc_reserved>;
+        clocks = <&scmi_clk 0>,
+                 <&scmi_clk 0>,
+                 <&scmi_clk 1>,
+                 <&scmi_clk 2>,
+                 <&scmi_clk 3>,
+                 <&scmi_clk 4>,
+                 <&scmi_clk 5>,
+                 <&scmi_clk 6>,
+                 <&scmi_clk 7>,
+                 <&scmi_clk 8>,
+                 <&scmi_clk 9>,
+                 <&scmi_clk 10>,
+                 <&scmi_clk 11>;
+        clock-names = "cpu_clock",
+                      "pll_0_out_0", "pll_0_out_1",
+                      "pll_0_out_2", "pll_0_out_3",
+                      "pll_1_out_0", "pll_1_out_1",
+                      "pll_1_out_2", "pll_1_out_3",
+                      "pll_2_out_0", "pll_2_out_1",
+                      "pll_2_out_2", "pll_2_out_3";
+        interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "nce_wdt", "mss_wdt";
+        intel,keembay-vpu-ipc-nce-wdt-redirect = <63>;
+        intel,keembay-vpu-ipc-mss-wdt-redirect = <47>;
+        intel,keembay-vpu-ipc-imr = <9>;
+        intel,keembay-vpu-ipc-id = <0>;
+    };
Signature · 1 line
2.17.1
#22 lore raw

PATCH 14/22 misc: xlink-pcie: Add asynchronous event notification support for XLink

In reply to [email protected]

From: Srikanth Thokala <[email protected]>

Add support to notify XLink layer upon PCIe link UP/DOWN events

---
 drivers/misc/xlink-pcie/common/core.h      |  3 ++
 drivers/misc/xlink-pcie/common/interface.c | 17 ++++++++++
 drivers/misc/xlink-pcie/local_host/core.c  | 11 +++++++
 drivers/misc/xlink-pcie/remote_host/main.c |  3 ++
 drivers/misc/xlink-pcie/remote_host/pci.c  | 36 ++++++++++++++++++++++
 drivers/misc/xlink-pcie/remote_host/pci.h  |  3 ++
 include/linux/xlink_drv_inf.h              | 12 ++++++++
 7 files changed, 85 insertions(+)
drivers/misc/xlink-pcie/common/core.h +3 -0
index eec8566c19d9..34b6c268aac5 100644
@@ -241,4 +241,7 @@ int intel_xpcie_pci_connect_device(u32 id);
 int intel_xpcie_pci_read(u32 id, void *data, size_t *size, u32 timeout);
 int intel_xpcie_pci_write(u32 id, void *data, size_t *size, u32 timeout);
 int intel_xpcie_pci_reset_device(u32 id);
+int intel_xpcie_pci_register_device_event(u32 sw_device_id,
+					  xlink_device_event event_notif_fn);
+int intel_xpcie_pci_unregister_device_event(u32 sw_device_id);
 #endif /* XPCIE_CORE_HEADER_ */
drivers/misc/xlink-pcie/common/interface.c +17 -0
index 56c1d9ed9d8f..4ad291ff97c8 100644
@@ -107,3 +107,20 @@ int xlink_pcie_reset_device(u32 sw_device_id)
 	return intel_xpcie_pci_reset_device(sw_device_id);
 }
 EXPORT_SYMBOL(xlink_pcie_reset_device);
+
+int xlink_pcie_register_device_event(u32 sw_device_id,
+				     xlink_device_event event_notif_fn)
+{
+	if (!event_notif_fn)
+		return -EINVAL;
+
+	return intel_xpcie_pci_register_device_event(sw_device_id,
+						     event_notif_fn);
+}
+EXPORT_SYMBOL(xlink_pcie_register_device_event);
+
+int xlink_pcie_unregister_device_event(u32 sw_device_id)
+{
+	return intel_xpcie_pci_unregister_device_event(sw_device_id);
+}
+EXPORT_SYMBOL(xlink_pcie_unregister_device_event);
drivers/misc/xlink-pcie/local_host/core.c +11 -0
index 0f83b5ffc4f2..628c383113ca 100644
@@ -892,3 +892,14 @@ int intel_xpcie_pci_reset_device(u32 id)
 {
 	return 0;
 }
+
+int intel_xpcie_pci_register_device_event(u32 sw_device_id,
+					  xlink_device_event event_notif_fn)
+{
+	return 0;
+}
+
+int intel_xpcie_pci_unregister_device_event(u32 sw_device_id)
+{
+	return 0;
+}
drivers/misc/xlink-pcie/remote_host/main.c +3 -0
index 810da1509418..421635321f1b 100644
@@ -55,6 +55,8 @@ static int intel_xpcie_probe(struct pci_dev *pdev,
 	if (new_device)
 		intel_xpcie_list_add_device(xdev);
 
+	intel_xpcie_pci_notify_event(xdev, NOTIFY_DEVICE_CONNECTED);
+
 	return ret;
 }
 
@@ -64,6 +66,7 @@ static void intel_xpcie_remove(struct pci_dev *pdev)
 
 	if (xdev) {
 		intel_xpcie_pci_cleanup(xdev);
+		intel_xpcie_pci_notify_event(xdev, NOTIFY_DEVICE_DISCONNECTED);
 		intel_xpcie_remove_device(xdev);
 	}
 }
drivers/misc/xlink-pcie/remote_host/pci.c +36 -0
index f92a78f41324..0046bff5f604 100644
@@ -8,6 +8,7 @@
  ****************************************************************************/
 
 #include <linux/mutex.h>
+#include <linux/pci.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/workqueue.h>
@@ -487,3 +488,38 @@ int intel_xpcie_pci_reset_device(u32 id)
 
 	return intel_xpcie_pci_prepare_dev_reset(xdev, true);
 }
+
+int intel_xpcie_pci_register_device_event(u32 sw_device_id,
+					  xlink_device_event event_notif_fn)
+{
+	struct xpcie_dev *xdev = intel_xpcie_get_device_by_id(sw_device_id);
+
+	if (!xdev)
+		return -ENOMEM;
+
+	xdev->event_fn = event_notif_fn;
+
+	return 0;
+}
+
+int intel_xpcie_pci_unregister_device_event(u32 sw_device_id)
+{
+	struct xpcie_dev *xdev = intel_xpcie_get_device_by_id(sw_device_id);
+
+	if (!xdev)
+		return -ENOMEM;
+
+	xdev->event_fn = NULL;
+
+	return 0;
+}
+
+void intel_xpcie_pci_notify_event(struct xpcie_dev *xdev,
+				  enum xlink_device_event_type event_type)
+{
+	if (event_type >= NUM_EVENT_TYPE)
+		return;
+
+	if (xdev->event_fn)
+		xdev->event_fn(xdev->devid, event_type);
+}
drivers/misc/xlink-pcie/remote_host/pci.h +3 -0
index 72de3701f83a..a05dedf36a12 100644
@@ -38,6 +38,7 @@ struct xpcie_dev {
 	irq_handler_t core_irq_callback;
 
 	struct xpcie xpcie;
+	xlink_device_event event_fn;
 };
 
 static inline struct device *xpcie_to_dev(struct xpcie *xpcie)
@@ -60,5 +61,7 @@ struct xpcie_dev *intel_xpcie_create_device(u32 sw_device_id,
 void intel_xpcie_remove_device(struct xpcie_dev *xdev);
 void intel_xpcie_list_add_device(struct xpcie_dev *xdev);
 void intel_xpcie_list_del_device(struct xpcie_dev *xdev);
+void intel_xpcie_pci_notify_event(struct xpcie_dev *xdev,
+				  enum xlink_device_event_type event_type);
 
 #endif /* XPCIE_PCI_HEADER_ */
include/linux/xlink_drv_inf.h +12 -0
index ffe8f4c253e6..5ca0ae1ae2e3 100644
@@ -44,6 +44,15 @@ enum _xlink_device_status {
 	_XLINK_DEV_READY
 };
 
+enum xlink_device_event_type {
+	NOTIFY_DEVICE_DISCONNECTED,
+	NOTIFY_DEVICE_CONNECTED,
+	NUM_EVENT_TYPE
+};
+
+typedef int (*xlink_device_event)(u32 sw_device_id,
+				  enum xlink_device_event_type event_type);
+
 int xlink_pcie_get_device_list(u32 *sw_device_id_list,
 			       u32 *num_devices);
 int xlink_pcie_get_device_name(u32 sw_device_id, char *device_name,
@@ -57,4 +66,7 @@ int xlink_pcie_read(u32 sw_device_id, void *data, size_t *const size,
 int xlink_pcie_write(u32 sw_device_id, void *data, size_t *const size,
 		     u32 timeout);
 int xlink_pcie_reset_device(u32 sw_device_id);
+int xlink_pcie_register_device_event(u32 sw_device_id,
+				     xlink_device_event event_notif_fn);
+int xlink_pcie_unregister_device_event(u32 sw_device_id);
 #endif
Signature · 1 line
2.17.1
#18 lore raw

PATCH 10/22 misc: xlink-pcie: lh: Prepare changes for adding remote host driver

In reply to [email protected]

From: Srikanth Thokala <[email protected]>

Move logic that can be reused between local host and remote host to common/ folder

---
 drivers/misc/xlink-pcie/{local_host => common}/core.h  | 0
 drivers/misc/xlink-pcie/{local_host => common}/util.c  | 0
 drivers/misc/xlink-pcie/{local_host => common}/util.h  | 0
 drivers/misc/xlink-pcie/{local_host => common}/xpcie.h | 0
 drivers/misc/xlink-pcie/local_host/Makefile            | 2 +-
 drivers/misc/xlink-pcie/local_host/core.c              | 4 ++--
 drivers/misc/xlink-pcie/local_host/epf.h               | 4 ++--
 7 files changed, 5 insertions(+), 5 deletions(-)
 rename drivers/misc/xlink-pcie/{local_host => common}/core.h (100%)
 rename drivers/misc/xlink-pcie/{local_host => common}/util.c (100%)
 rename drivers/misc/xlink-pcie/{local_host => common}/util.h (100%)
 rename drivers/misc/xlink-pcie/{local_host => common}/xpcie.h (100%)
drivers/misc/xlink-pcie/common/core.h renamed from drivers/misc/xlink-pcie/local_host/core.h +0 -0
similarity index 100%
rename from drivers/misc/xlink-pcie/local_host/core.h
rename to drivers/misc/xlink-pcie/common/core.h
drivers/misc/xlink-pcie/common/util.c renamed from drivers/misc/xlink-pcie/local_host/util.c +0 -0
similarity index 100%
rename from drivers/misc/xlink-pcie/local_host/util.c
rename to drivers/misc/xlink-pcie/common/util.c
drivers/misc/xlink-pcie/common/util.h renamed from drivers/misc/xlink-pcie/local_host/util.h +0 -0
similarity index 100%
rename from drivers/misc/xlink-pcie/local_host/util.h
rename to drivers/misc/xlink-pcie/common/util.h
drivers/misc/xlink-pcie/common/xpcie.h renamed from drivers/misc/xlink-pcie/local_host/xpcie.h +0 -0
similarity index 100%
rename from drivers/misc/xlink-pcie/local_host/xpcie.h
rename to drivers/misc/xlink-pcie/common/xpcie.h
drivers/misc/xlink-pcie/local_host/Makefile +1 -1
index 28761751d43b..65df94c7e860 100644
@@ -2,4 +2,4 @@ obj-$(CONFIG_XLINK_PCIE_LH_DRIVER) += mxlk_ep.o
 mxlk_ep-objs := epf.o
 mxlk_ep-objs += dma.o
 mxlk_ep-objs += core.o
-mxlk_ep-objs += util.o
+mxlk_ep-objs += ../common/util.o
drivers/misc/xlink-pcie/local_host/core.c +2 -2
index aecaaa783153..0f83b5ffc4f2 100644
@@ -10,8 +10,8 @@
 #include <linux/of_reserved_mem.h>
 
 #include "epf.h"
-#include "core.h"
-#include "util.h"
+#include "../common/core.h"
+#include "../common/util.h"
 
 static struct xpcie *global_xpcie;
 
drivers/misc/xlink-pcie/local_host/epf.h +2 -2
index 675c07455ffa..9cfd96923c6f 100644
@@ -13,8 +13,8 @@
 #include <linux/pci-epc.h>
 #include <linux/pci-epf.h>
 
-#include "xpcie.h"
-#include "util.h"
+#include "../common/xpcie.h"
+#include "../common/util.h"
 
 #define XPCIE_DRIVER_NAME "mxlk_pcie_epf"
 #define XPCIE_DRIVER_DESC "Intel(R) xLink PCIe endpoint function driver"
Signature · 1 line
2.17.1
#21 lore raw

PATCH 13/22 misc: xlink-pcie: Add XLink API interface

In reply to [email protected]

From: Srikanth Thokala <[email protected]>

Provide interface for XLink layer to interact with XLink PCIe transport layer on both local host and remote host.

---
 drivers/misc/xlink-pcie/common/interface.c   | 109 +++++++++++++++++++
 drivers/misc/xlink-pcie/local_host/Makefile  |   1 +
 drivers/misc/xlink-pcie/remote_host/Makefile |   1 +
 3 files changed, 111 insertions(+)
 create mode 100644 drivers/misc/xlink-pcie/common/interface.c
drivers/misc/xlink-pcie/common/interface.c new file +109 -0
new file mode 100644
index 000000000000..56c1d9ed9d8f
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*****************************************************************************
+ *
+ * Intel Keem Bay XLink PCIe Driver
+ *
+ * Copyright (C) 2020 Intel Corporation
+ *
+ ****************************************************************************/
+
+#include <linux/xlink_drv_inf.h>
+
+#include "core.h"
+#include "xpcie.h"
+
+/* Define xpcie driver interface API */
+int xlink_pcie_get_device_list(u32 *sw_device_id_list, u32 *num_devices)
+{
+	if (!sw_device_id_list || !num_devices)
+		return -EINVAL;
+
+	*num_devices = intel_xpcie_get_device_num(sw_device_id_list);
+
+	return 0;
+}
+EXPORT_SYMBOL(xlink_pcie_get_device_list);
+
+int xlink_pcie_get_device_name(u32 sw_device_id, char *device_name,
+			       size_t name_size)
+{
+	if (!device_name)
+		return -EINVAL;
+
+	return intel_xpcie_get_device_name_by_id(sw_device_id,
+						 device_name, name_size);
+}
+EXPORT_SYMBOL(xlink_pcie_get_device_name);
+
+int xlink_pcie_get_device_status(u32 sw_device_id, u32 *device_status)
+{
+	u32 status;
+	int rc;
+
+	if (!device_status)
+		return -EINVAL;
+
+	rc = intel_xpcie_get_device_status_by_id(sw_device_id, &status);
+	if (rc)
+		return rc;
+
+	switch (status) {
+	case XPCIE_STATUS_READY:
+	case XPCIE_STATUS_RUN:
+		*device_status = _XLINK_DEV_READY;
+		break;
+	case XPCIE_STATUS_ERROR:
+		*device_status = _XLINK_DEV_ERROR;
+		break;
+	case XPCIE_STATUS_RECOVERY:
+		*device_status = _XLINK_DEV_RECOVERY;
+		break;
+	case XPCIE_STATUS_OFF:
+		*device_status = _XLINK_DEV_OFF;
+		break;
+	default:
+		*device_status = _XLINK_DEV_BUSY;
+		break;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(xlink_pcie_get_device_status);
+
+int xlink_pcie_boot_device(u32 sw_device_id, const char *binary_name)
+{
+	return 0;
+}
+EXPORT_SYMBOL(xlink_pcie_boot_device);
+
+int xlink_pcie_connect(u32 sw_device_id)
+{
+	return intel_xpcie_pci_connect_device(sw_device_id);
+}
+EXPORT_SYMBOL(xlink_pcie_connect);
+
+int xlink_pcie_read(u32 sw_device_id, void *data, size_t *const size,
+		    u32 timeout)
+{
+	if (!data || !size)
+		return -EINVAL;
+
+	return intel_xpcie_pci_read(sw_device_id, data, size, timeout);
+}
+EXPORT_SYMBOL(xlink_pcie_read);
+
+int xlink_pcie_write(u32 sw_device_id, void *data, size_t *const size,
+		     u32 timeout)
+{
+	if (!data || !size)
+		return -EINVAL;
+
+	return intel_xpcie_pci_write(sw_device_id, data, size, timeout);
+}
+EXPORT_SYMBOL(xlink_pcie_write);
+
+int xlink_pcie_reset_device(u32 sw_device_id)
+{
+	return intel_xpcie_pci_reset_device(sw_device_id);
+}
+EXPORT_SYMBOL(xlink_pcie_reset_device);
drivers/misc/xlink-pcie/local_host/Makefile +1 -0
index 65df94c7e860..16bb1e7345ac 100644
@@ -3,3 +3,4 @@ mxlk_ep-objs := epf.o
 mxlk_ep-objs += dma.o
 mxlk_ep-objs += core.o
 mxlk_ep-objs += ../common/util.o
+mxlk_ep-objs += ../common/interface.o
drivers/misc/xlink-pcie/remote_host/Makefile +1 -0
index e8074dbb1161..088e121ad46e 100644
@@ -3,3 +3,4 @@ mxlk-objs := main.o
 mxlk-objs += pci.o
 mxlk-objs += core.o
 mxlk-objs += ../common/util.o
+mxlk-objs += ../common/interface.o
Signature · 1 line
2.17.1
#23 lore raw

PATCH 15/22 xlink-ipc: Add xlink ipc device tree bindings

In reply to [email protected]

From: Seamus Kelly <[email protected]>

Add device tree bindings for the xLink IPC driver which enables xLink to control and communicate with the VPU IP present on the Intel Keem Bay SoC.

---
 .../misc/intel,keembay-xlink-ipc.yaml         | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/intel,keembay-xlink-ipc.yaml
Documentation/devicetree/bindings/misc/intel,keembay-xlink-ipc.yaml new file +49 -0
new file mode 100644
index 000000000000..699e43c4cd40
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (c) Intel Corporation. All rights reserved.
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/misc/intel,keembay-xlink-ipc.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Intel Keem Bay xlink IPC
+
+maintainers:
+  - Kelly Seamus <[email protected]>
+
+description: |
+  The Keem Bay xlink IPC driver enables the communication/control sub-system
+  for internal IPC communications within the Intel Keem Bay SoC.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+        - const: intel,keembay-xlink-ipc
+
+  memory-region:
+    items:
+      - description: reference to the CSS xlink IPC reserved memory region.
+      - description: reference to the MSS xlink IPC reserved memory region.
+
+  intel,keembay-vpu-ipc-id:
+    $ref: "/schemas/types.yaml#/definitions/uint32"
+    description: The numeric ID identifying the VPU within the xLink stack.
+
+  intel,keembay-vpu-ipc-name:
+    $ref: "/schemas/types.yaml#/definitions/string"
+    description: User-friendly name for the VPU within the xLink stack.
+
+  intel,keembay-vpu-ipc:
+    $ref: "/schemas/types.yaml#/definitions/phandle"
+    description: reference to the corresponding intel,keembay-vpu-ipc node.
+
+examples:
+  - |
+    xlink-ipc {
+        compatible = "intel,keembay-xlink-ipc";
+        memory-region = <&css_xlink_reserved>,
+                        <&mss_xlink_reserved>;
+        intel,keembay-vpu-ipc-id = <0x0>;
+        intel,keembay-vpu-ipc-name = "vpu-slice-0";
+        intel,keembay-vpu-ipc = <&vpuipc>;
+    };
Signature · 1 line
2.17.1
#5 lore raw

PATCH 5/22 keembay-vpu-ipc: Add Keem Bay VPU IPC module

In reply to [email protected]

From: Paul Murphy <[email protected]>

Intel Keem Bay SoC contains a Vision Processing Unit (VPU) to enable machine vision and other applications.

Enable Linux to control the VPU processor and provides an interface to the Keem Bay IPC for communicating with the VPU firmware.

Specifically the driver provides the following functionality to other kernel components:
- Starting (including loading the VPU firmware) / Stopping / Rebooting
the VPU.
- Getting notifications of VPU events (e.g., WDT events).
- Communicating with the VPU via the Keem Bay IPC mechanism.

In addition to the above, the driver also exposes SoC information (like stepping, device ID, etc.) to user-space via sysfs. Specifically, the following sysfs files are provided:
- /sys/firmware/keembay-vpu-ipc/device_id
- /sys/firmware/keembay-vpu-ipc/feature_exclusion
- /sys/firmware/keembay-vpu-ipc/hardware_id
- /sys/firmware/keembay-vpu-ipc/sku
- /sys/firmware/keembay-vpu-ipc/stepping

---
 MAINTAINERS                               |    9 +
 drivers/soc/intel/Kconfig                 |   15 +
 drivers/soc/intel/Makefile                |    3 +-
 drivers/soc/intel/keembay-vpu-ipc.c       | 2036 +++++++++++++++++++++
 include/linux/soc/intel/keembay-vpu-ipc.h |   62 +
 5 files changed, 2124 insertions(+), 1 deletion(-)
 create mode 100644 drivers/soc/intel/keembay-vpu-ipc.c
 create mode 100644 include/linux/soc/intel/keembay-vpu-ipc.h
MAINTAINERS +9 -0
index 64475ba4ea9d..f95cef927d19 100644
@@ -8963,6 +8963,15 @@ F:	Documentation/devicetree/bindings/soc/intel/intel,keembay-ipc.yaml
 F:	drivers/soc/intel/keembay-ipc.c
 F:	include/linux/soc/intel/keembay-ipc.h
 
+INTEL KEEM BAY VPU IPC DRIVER
+M:	Paul J Murphy <[email protected]>
+M:	Daniele Alessandrelli <[email protected]>
+M:	Mark Gross <[email protected]>
+S:	Maintained
+F:	Documentation/devicetree/bindings/soc/intel/intel,keembay-vpu-ipc.yaml
+F:	drivers/soc/intel/keembay-vpu-ipc.c
+F:	include/linux/soc/intel/keembay-vpu-ipc.h
+
 INTEL MANAGEMENT ENGINE (mei)
 M:	Tomas Winkler <[email protected]>
 L:	[email protected]
drivers/soc/intel/Kconfig +15 -0
index 1f5c05b97649..83ce8c4a7851 100644
@@ -14,4 +14,19 @@ config KEEMBAY_IPC
 
 	  Select this if you are compiling the Kernel for an Intel SoC that
 	  includes the Intel Vision Processing Unit (VPU) such as Keem Bay.
+
+config KEEMBAY_VPU_IPC
+	tristate "Intel Keem Bay VPU IPC Driver"
+	depends on KEEMBAY_IPC
+	depends on HAVE_ARM_SMCCC
+	help
+	  This option enables support for loading and communicating with
+	  the firmware on the Vision Processing Unit (VPU) of the Keem Bay
+	  SoC. The driver depends on the Keem Bay IPC driver to do
+	  communication, and it depends on secure world monitor software to
+	  do the control of the VPU state.
+
+	  Select this if you are compiling the Kernel for an Intel SoC that
+	  includes the Intel Vision Processing Unit (VPU) such as Keem Bay.
+
 endmenu
drivers/soc/intel/Makefile +2 -1
index ecf0246e7822..363a81848843 100644
@@ -1,4 +1,5 @@
 #
 # Makefile for Keem Bay IPC Linux driver
 #
-obj-$(CONFIG_KEEMBAY_IPC) += keembay-ipc.o
+obj-$(CONFIG_KEEMBAY_IPC)	+= keembay-ipc.o
+obj-$(CONFIG_KEEMBAY_VPU_IPC)	+= keembay-vpu-ipc.o
drivers/soc/intel/keembay-vpu-ipc.c new file +2036 -0

2,036 lines not on this page · raw message

include/linux/soc/intel/keembay-vpu-ipc.h new file +62 -0

62 lines not on this page · raw message

Signature · 1 line
2.17.1
#30 lore raw

PATCH 22/22 xlink-core: factorize xlink_ioctl function by creating sub-functions for each ioctl command

In reply to [email protected]

From: Seamus Kelly <[email protected]>

Refactor the too large IOCTL function to call helper functions.

Cc Arnd Bergmann <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
---
 drivers/misc/xlink-core/Makefile      |   2 +-
 drivers/misc/xlink-core/xlink-core.c  | 625 ++++++--------------------
 drivers/misc/xlink-core/xlink-core.h  |  24 +
 drivers/misc/xlink-core/xlink-defs.h  |   2 +-
 drivers/misc/xlink-core/xlink-ioctl.c | 584 ++++++++++++++++++++++++
 drivers/misc/xlink-core/xlink-ioctl.h |  36 ++
 6 files changed, 773 insertions(+), 500 deletions(-)
 create mode 100644 drivers/misc/xlink-core/xlink-core.h
 create mode 100644 drivers/misc/xlink-core/xlink-ioctl.c
 create mode 100644 drivers/misc/xlink-core/xlink-ioctl.h
drivers/misc/xlink-core/Makefile +1 -1
index 6e604c0b8962..2f64703301d6 100644
@@ -2,4 +2,4 @@
 # Makefile for KeemBay xlink Linux driver
 #
 obj-$(CONFIG_XLINK_CORE) += xlink.o
-xlink-objs += xlink-core.o xlink-multiplexer.o xlink-dispatcher.o xlink-platform.o
+xlink-objs += xlink-core.o xlink-multiplexer.o xlink-dispatcher.o xlink-platform.o xlink-ioctl.o
drivers/misc/xlink-core/xlink-core.c +127 -498

764 lines not on this page · raw message

drivers/misc/xlink-core/xlink-core.h new file +24 -0
new file mode 100644
index 000000000000..c3d100a75c44
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * xlink core header file.
+ *
+ * Copyright (C) 2018-2019 Intel Corporation
+ *
+ */
+
+#ifndef XLINK_CORE_H_
+#define XLINK_CORE_H_
+#include "xlink-defs.h"
+
+#define NUM_REG_EVENTS 4
+
+enum xlink_error xlink_write_data_user(struct xlink_handle *handle,
+				       u16 chan, u8 const *pmessage,
+				       u32 size);
+enum xlink_error xlink_register_device_event_user(struct xlink_handle *handle,
+						  u32 *event_list, u32 num_events,
+						  xlink_device_event_cb event_notif_fn);
+enum xlink_error xlink_write_volatile_user(struct xlink_handle *handle,
+					   u16 chan, u8 const *message,
+					   u32 size);
+#endif /* XLINK_CORE_H_ */
drivers/misc/xlink-core/xlink-defs.h +1 -1
index df686e5185c5..81aa3bfffcd3 100644
@@ -35,7 +35,7 @@
 #define CONTROL_CHANNEL_TIMEOUT_MS	0U	// wait indefinitely
 #define SIGXLNK				44	// signal XLink uses for callback signalling
 
-#define UNUSED(x) (void)(x)
+#define UNUSED(x) ((void)(x))
 
 // the end of the IPC channel range (starting at zero)
 #define XLINK_IPC_MAX_CHANNELS	1024
drivers/misc/xlink-core/xlink-ioctl.c new file +584 -0

584 lines not on this page · raw message

drivers/misc/xlink-core/xlink-ioctl.h new file +36 -0
new file mode 100644
index 000000000000..7818b676d488
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * xlink ioctl header files.
+ *
+ * Copyright (C) 2018-2019 Intel Corporation
+ *
+ */
+
+#ifndef XLINK_IOCTL_H_
+#define XLINK_IOCTL_H_
+
+int ioctl_connect(unsigned long arg);
+int ioctl_open_channel(unsigned long arg);
+int ioctl_read_data(unsigned long arg);
+int ioctl_read_to_buffer(unsigned long arg);
+int ioctl_write_data(unsigned long arg);
+int ioctl_write_control_data(unsigned long arg);
+int ioctl_write_volatile_data(unsigned long arg);
+int ioctl_release_data(unsigned long arg);
+int ioctl_close_channel(unsigned long arg);
+int ioctl_start_vpu(unsigned long arg);
+int ioctl_stop_vpu(void);
+int ioctl_disconnect(unsigned long arg);
+int ioctl_get_device_name(unsigned long arg);
+int ioctl_get_device_list(unsigned long arg);
+int ioctl_get_device_status(unsigned long arg);
+int ioctl_boot_device(unsigned long arg);
+int ioctl_reset_device(unsigned long arg);
+int ioctl_get_device_mode(unsigned long arg);
+int ioctl_set_device_mode(unsigned long arg);
+int ioctl_register_device_event(unsigned long arg);
+int ioctl_unregister_device_event(unsigned long arg);
+int ioctl_data_ready_callback(unsigned long arg);
+int ioctl_data_consumed_callback(unsigned long arg);
+
+#endif /* XLINK_IOCTL_H_ */
Signature · 1 line
2.17.1
#27 lore raw

PATCH 19/22 xlink-core: Enable xlink protocol over pcie

In reply to [email protected]

From: Seamus Kelly <[email protected]>

Enable host system access to the VPU over the xlink protocol over PCIe by enabling channel multiplexing and dispatching. This allows for remote host communication channels across pcie links.

add dispatcher
update multiplexer to utilise dispatcher

xlink-core: Patch set 2

Add xlink-dispatcher
creates tx and rx threads
enables queueing of messages for transmission and on reception

Update multiplexer to utilise dispatcher:
handle multiplexing channels over single interface link e.g. PCIe process messages received by dispatcher
pass messages created by API calls to dispatcher for transmission

Cc Arnd Bergmann <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
---
 drivers/misc/xlink-core/Makefile            |   2 +-
 drivers/misc/xlink-core/xlink-core.c        |  38 +-
 drivers/misc/xlink-core/xlink-dispatcher.c  | 441 +++++++++++++++++
 drivers/misc/xlink-core/xlink-dispatcher.h  |  26 +
 drivers/misc/xlink-core/xlink-multiplexer.c | 498 +++++++++++++++++++-
 5 files changed, 1001 insertions(+), 4 deletions(-)
 create mode 100644 drivers/misc/xlink-core/xlink-dispatcher.c
 create mode 100644 drivers/misc/xlink-core/xlink-dispatcher.h
drivers/misc/xlink-core/Makefile +1 -1
index 6b708340dbfe..6e604c0b8962 100644
@@ -2,4 +2,4 @@
 # Makefile for KeemBay xlink Linux driver
 #
 obj-$(CONFIG_XLINK_CORE) += xlink.o
-xlink-objs += xlink-core.o xlink-multiplexer.o xlink-platform.o
+xlink-objs += xlink-core.o xlink-multiplexer.o xlink-dispatcher.o xlink-platform.o
drivers/misc/xlink-core/xlink-core.c +36 -2
index 3813208ffa95..e7d5f68a5ba1 100644
@@ -20,6 +20,7 @@
 #endif
 
 #include "xlink-defs.h"
+#include "xlink-dispatcher.h"
 #include "xlink-multiplexer.h"
 #include "xlink-platform.h"
 
@@ -159,6 +160,12 @@ static int kmb_xlink_probe(struct platform_device *pdev)
 		goto r_multiplexer;
 	}
 
+	// initialize dispatcher
+	rc = xlink_dispatcher_init(xlink_dev->pdev);
+	if (rc != X_LINK_SUCCESS) {
+		pr_err("Dispatcher initialization failed\n");
+		goto r_dispatcher;
+	}
 	// initialize xlink data structure
 	xlink_dev->nmb_connected_links = 0;
 	mutex_init(&xlink_dev->lock);
@@ -176,7 +183,7 @@ static int kmb_xlink_probe(struct platform_device *pdev)
 	/*Allocating Major number*/
 	if ((alloc_chrdev_region(&xdev, 0, 1, "xlinkdev")) < 0) {
 		dev_info(&pdev->dev, "Cannot allocate major number\n");
-		goto r_multiplexer;
+		goto r_dispatcher;
 	}
 	dev_info(&pdev->dev, "Major = %d Minor = %d\n", MAJOR(xdev),
 		 MINOR(xdev));
@@ -213,6 +220,8 @@ static int kmb_xlink_probe(struct platform_device *pdev)
 	class_destroy(dev_class);
 r_class:
 	unregister_chrdev_region(xdev, 1);
+r_dispatcher:
+	xlink_dispatcher_destroy();
 r_multiplexer:
 	xlink_multiplexer_destroy();
 	return -1;
@@ -228,6 +237,10 @@ static int kmb_xlink_remove(struct platform_device *pdev)
 	rc = xlink_multiplexer_destroy();
 	if (rc != X_LINK_SUCCESS)
 		pr_err("Multiplexer destroy failed\n");
+	// stop dispatchers and destroy
+	rc = xlink_dispatcher_destroy();
+	if (rc != X_LINK_SUCCESS)
+		pr_err("Dispatcher destroy failed\n");
 
 	mutex_unlock(&xlink->lock);
 	mutex_destroy(&xlink->lock);
@@ -436,6 +449,14 @@ enum xlink_error xlink_connect(struct xlink_handle *handle)
 		link->handle = *handle;
 		xlink->nmb_connected_links++;
 		kref_init(&link->refcount);
+		if (interface != IPC_INTERFACE) {
+			// start dispatcher
+			rc = xlink_dispatcher_start(link->id, &link->handle);
+			if (rc) {
+				pr_err("dispatcher start failed\n");
+				goto r_cleanup;
+			}
+		}
 		// initialize multiplexer connection
 		rc = xlink_multiplexer_connect(link->id);
 		if (rc) {
@@ -629,7 +650,8 @@ static enum xlink_error xlink_write_data_user(struct xlink_handle *handle,
 }
 
 static enum xlink_error xlink_write_volatile_user(struct xlink_handle *handle,
-						  u16 chan, u8 const *message, u32 size)
+						  u16 chan, u8 const *message,
+						  u32 size)
 {
 	enum xlink_error rc = 0;
 
@@ -781,6 +803,7 @@ EXPORT_SYMBOL(xlink_release_data);
 enum xlink_error xlink_disconnect(struct xlink_handle *handle)
 {
 	struct xlink_link *link;
+	int interface = NULL_INTERFACE;
 	enum xlink_error rc = X_LINK_ERROR;
 
 	if (!xlink || !handle)
@@ -793,6 +816,17 @@ enum xlink_error xlink_disconnect(struct xlink_handle *handle)
 	// decrement refcount, if count is 0 lock mutex and disconnect
 	if (kref_put_mutex(&link->refcount, release_after_kref_put,
 			   &xlink->lock)) {
+		// stop dispatcher
+		interface = get_interface_from_sw_device_id(link->handle.sw_device_id);
+		if (interface != IPC_INTERFACE) {
+			// stop dispatcher
+			rc = xlink_dispatcher_stop(link->id);
+			if (rc != X_LINK_SUCCESS) {
+				pr_err("dispatcher stop failed\n");
+				mutex_unlock(&xlink->lock);
+				return X_LINK_ERROR;
+			}
+		}
 		// deinitialize multiplexer connection
 		rc = xlink_multiplexer_disconnect(link->id);
 		if (rc) {
drivers/misc/xlink-core/xlink-dispatcher.c new file +441 -0

441 lines not on this page · raw message

drivers/misc/xlink-core/xlink-dispatcher.h new file +26 -0
new file mode 100644
index 000000000000..d1458e7a4ab7
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * xlink Dispatcher.
+ *
+ * Copyright (C) 2018-2019 Intel Corporation
+ *
+ */
+#ifndef __XLINK_DISPATCHER_H
+#define __XLINK_DISPATCHER_H
+
+#include "xlink-defs.h"
+
+enum xlink_error xlink_dispatcher_init(void *dev);
+
+enum xlink_error xlink_dispatcher_start(int id, struct xlink_handle *handle);
+
+enum xlink_error xlink_dispatcher_event_add(enum xlink_event_origin origin,
+					    struct xlink_event *event);
+
+enum xlink_error xlink_dispatcher_stop(int id);
+
+enum xlink_error xlink_dispatcher_destroy(void);
+
+enum xlink_error xlink_dispatcher_ipc_passthru_event_add(struct xlink_event *event);
+
+#endif /* __XLINK_DISPATCHER_H */
drivers/misc/xlink-core/xlink-multiplexer.c +497 -1

539 lines not on this page · raw message

Signature · 1 line
2.17.1
#25 lore raw

PATCH 17/22 xlink-core: Add xlink core device tree bindings

In reply to [email protected]

From: Seamus Kelly <[email protected]>

Add device tree bindings for keembay-xlink.

---
 .../bindings/misc/intel,keembay-xlink.yaml    | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/intel,keembay-xlink.yaml
Documentation/devicetree/bindings/misc/intel,keembay-xlink.yaml new file +27 -0
new file mode 100644
index 000000000000..89c34018fa04
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (c) Intel Corporation. All rights reserved.
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/misc/intel,keembay-xlink.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Intel Keem Bay xlink
+
+maintainers:
+  - Seamus Kelly <[email protected]>
+
+description: |
+  The Keem Bay xlink driver enables the communication/control sub-system
+  for internal and external communications to the Intel Keem Bay SoC.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+        - const: intel,keembay-xlink
+
+examples:
+  - |
+    xlink {
+        compatible = "intel,keembay-xlink";
+    };
Signature · 1 line
2.17.1
#26 lore raw

PATCH 18/22 xlink-core: Add xlink core driver xLink

In reply to [email protected]

From: Seamus Kelly <[email protected]>

Add xLink driver, which provides an abstracted control and communication subsystem based on channel identification.
It is intended to support VPU technology both at SoC level as well as at IP level, over multiple interfaces. This initial patch enables local host user mode to open/close/read/write via IOCTLs.

Specifically the driver enables application/process to:

* Access a common xLink API across all interfaces from both kernel and user space.
* Call typical APIs types (open, close, read, write) that you would associate with a communication interface.
* Call other APIs that are related to other functions that the device can perform e.g. boot, reset get/set device mode. Device mode refers to the power load of the VPU and an API can be used to read and control it.
* Use multiple commnication channels that the driver manages from one interface to another, providing routing of data through these multiple channels across a single physical interface.

xLink: Add xLink Core device tree bindings

Add device tree bindings for the xLink Core driver which enables xLink to control and communicate with the VPU IP present on the Intel Keem Bay SoC.

Cc Jonathan Corbet <[email protected]>
Cc Derek Kiernan <[email protected]>
Cc Dragan Cvetic <[email protected]>
Cc Arnd Bergmann <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
---
 Documentation/vpu/index.rst                 |   1 +
 Documentation/vpu/xlink-core.rst            |  80 ++
 MAINTAINERS                                 |  12 +
 drivers/misc/Kconfig                        |   1 +
 drivers/misc/Makefile                       |   1 +
 drivers/misc/xlink-core/Kconfig             |  33 +
 drivers/misc/xlink-core/Makefile            |   5 +
 drivers/misc/xlink-core/xlink-core.c        | 870 ++++++++++++++++++++
 drivers/misc/xlink-core/xlink-defs.h        | 175 ++++
 drivers/misc/xlink-core/xlink-multiplexer.c | 534 ++++++++++++
 drivers/misc/xlink-core/xlink-multiplexer.h |  35 +
 drivers/misc/xlink-core/xlink-platform.c    | 160 ++++
 drivers/misc/xlink-core/xlink-platform.h    |  65 ++
 include/linux/xlink.h                       | 108 +++
 include/uapi/misc/xlink_uapi.h              | 145 ++++
 15 files changed, 2225 insertions(+)
 create mode 100644 Documentation/vpu/xlink-core.rst
 create mode 100644 drivers/misc/xlink-core/Kconfig
 create mode 100644 drivers/misc/xlink-core/Makefile
 create mode 100644 drivers/misc/xlink-core/xlink-core.c
 create mode 100644 drivers/misc/xlink-core/xlink-defs.h
 create mode 100644 drivers/misc/xlink-core/xlink-multiplexer.c
 create mode 100644 drivers/misc/xlink-core/xlink-multiplexer.h
 create mode 100644 drivers/misc/xlink-core/xlink-platform.c
 create mode 100644 drivers/misc/xlink-core/xlink-platform.h
 create mode 100644 include/linux/xlink.h
 create mode 100644 include/uapi/misc/xlink_uapi.h
Documentation/vpu/index.rst +1 -0
index 49c78bb65b83..cd4272e089ec 100644
@@ -16,3 +16,4 @@ This documentation contains information for the Intel VPU stack.
    vpu-stack-overview
    xlink-pcie
    xlink-ipc
+   xlink-core
Documentation/vpu/xlink-core.rst new file +80 -0

80 lines not on this page · raw message

MAINTAINERS +12 -0
index ebc2cce7251f..0d49622aa1a6 100644
@@ -1952,6 +1952,12 @@ F:	Documentation/devicetree/bindings/arm/intel,keembay.yaml
 F:	arch/arm64/boot/dts/intel/keembay-evm.dts
 F:	arch/arm64/boot/dts/intel/keembay-soc.dtsi
 
+ARM/INTEL XLINK CORE SUPPORT
+M:	Seamus Kelly <[email protected]>
+M:	Mark Gross <[email protected]>
+S:	Maintained
+F:	drivers/misc/xlink-core/
+
 ARM/INTEL XLINK IPC SUPPORT
 M:	Seamus Kelly <[email protected]>
 M:	Mark Gross <[email protected]>
@@ -1964,6 +1970,12 @@ M:	Mark Gross <[email protected]>
 S:	Maintained
 F:	drivers/misc/xlink-pcie/
 
+ARM/INTEL TSENS SUPPORT
+M:	Udhayakumar C <[email protected]>
+S:	Maintained
+F:	drivers/misc/hddl_device/
+F:	drivers/misc/intel_tsens/
+
 ARM/INTEL RESEARCH IMOTE/STARGATE 2 MACHINE SUPPORT
 M:	Jonathan Cameron <[email protected]>
 L:	[email protected] (moderated for non-subscribers)
drivers/misc/Kconfig +1 -0
index 1f81ea915b95..09ae65e98681 100644
@@ -483,4 +483,5 @@ source "drivers/misc/habanalabs/Kconfig"
 source "drivers/misc/uacce/Kconfig"
 source "drivers/misc/xlink-pcie/Kconfig"
 source "drivers/misc/xlink-ipc/Kconfig"
+source "drivers/misc/xlink-core/Kconfig"
 endmenu
drivers/misc/Makefile +1 -0
index b51495a2f1e0..f3a6eb03bae9 100644
@@ -59,3 +59,4 @@ obj-$(CONFIG_XILINX_SDFEC)	+= xilinx_sdfec.o
 obj-$(CONFIG_HISI_HIKEY_USB)	+= hisi_hikey_usb.o
 obj-y                           += xlink-pcie/
 obj-$(CONFIG_XLINK_IPC)		+= xlink-ipc/
+obj-$(CONFIG_XLINK_CORE)	+= xlink-core/
drivers/misc/xlink-core/Kconfig new file +33 -0
new file mode 100644
index 000000000000..3ae7dc01007f
@@ -0,0 +1,33 @@
+config XLINK_CORE
+	tristate "Support for XLINK CORE"
+	depends on ((XLINK_PCIE_RH_DRIVER || XBAY_XLINK_PCIE_RH_DRIVER) || (XLINK_LOCAL_HOST && (XLINK_PCIE_LH_DRIVER || XBAY_XLINK_PCIE_RH_DRIVER)))
+	help
+	  XLINK CORE enables the communication/control Sub-System.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called xlink.ko.
+
+config XLINK_LOCAL_HOST
+	tristate "Support for XLINK LOCAL HOST"
+	depends on XLINK_IPC
+	help
+	  XLINK LOCAL HOST enables local host functionality for
+	  the communication/control Sub-System.
+
+	  Enable this config when building the kernel for the Inel Vision
+	  Processing Unit (VPU) Local Host core.
+
+	  If building for a Remote Host kernel, say N.
+
+config XLINK_PSS
+	tristate "Support for XLINK PSS"
+	depends on XLINK_LOCAL_HOST
+	help
+	  XLINK PSS enables the communication/control Sub-System on a PSS platform.
+
+	  Enable this config when building the kernel for the Intel Vision
+	  Processing Unit (VPU) in a simulated env.
+
+	  If building for a VPU silicon, say N.
drivers/misc/xlink-core/Makefile new file +5 -0
new file mode 100644
index 000000000000..6b708340dbfe
@@ -0,0 +1,5 @@
+#
+# Makefile for KeemBay xlink Linux driver
+#
+obj-$(CONFIG_XLINK_CORE) += xlink.o
+xlink-objs += xlink-core.o xlink-multiplexer.o xlink-platform.o
drivers/misc/xlink-core/xlink-core.c new file +870 -0

870 lines not on this page · raw message

drivers/misc/xlink-core/xlink-defs.h new file +175 -0

175 lines not on this page · raw message

drivers/misc/xlink-core/xlink-multiplexer.c new file +534 -0

534 lines not on this page · raw message

drivers/misc/xlink-core/xlink-multiplexer.h new file +35 -0
new file mode 100644
index 000000000000..c978e5683b45
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * xlink Multiplexer.
+ *
+ * Copyright (C) 2018-2019 Intel Corporation
+ *
+ */
+#ifndef __XLINK_MULTIPLEXER_H
+#define __XLINK_MULTIPLEXER_H
+
+#include "xlink-defs.h"
+
+enum xlink_error xlink_multiplexer_init(void *dev);
+
+enum xlink_error xlink_multiplexer_connect(u32 link_id);
+
+enum xlink_error xlink_multiplexer_disconnect(u32 link_id);
+
+enum xlink_error xlink_multiplexer_destroy(void);
+
+enum xlink_error xlink_multiplexer_tx(struct xlink_event *event,
+				      int *event_queued);
+
+enum xlink_error xlink_multiplexer_rx(struct xlink_event *event);
+
+enum xlink_error xlink_passthrough(struct xlink_event *event);
+
+void *find_allocated_buffer(dma_addr_t paddr);
+
+int unregister_allocated_buffer(void *buf, dma_addr_t paddr);
+
+int core_release_packet_from_channel(u32 link_id, uint16_t chan,
+				     uint8_t * const addr);
+
+#endif /* __XLINK_MULTIPLEXER_H */
drivers/misc/xlink-core/xlink-platform.c new file +160 -0

160 lines not on this page · raw message

drivers/misc/xlink-core/xlink-platform.h new file +65 -0

65 lines not on this page · raw message

include/linux/xlink.h new file +108 -0

108 lines not on this page · raw message

include/uapi/misc/xlink_uapi.h new file +145 -0

145 lines not on this page · raw message

Signature · 1 line
2.17.1
#29 lore raw

PATCH 21/22 xlink-core: add async channel and events

In reply to [email protected]

From: Seamus Kelly <[email protected]>

Enable asynchronous channel and event communication.

Add APIs:
data ready callback:
The xLink Data Ready Callback function is used to register a callback function that is invoked when data is ready to be read from a channel
data consumed callback:
The xLink Data Consumed Callback function is used to register a callback function that is invoked when data is consumed by the peer node on a channel
Add event notification handling including APIs:
register device event:
The xLink Register Device Event function is used to register a callback for notification of certain system events. Currently XLink supports 4 such events [0-3] whose meaning is system dependent. Registering for an event means that the callback will be called when the event occurs with 2 parameters the sw_device_id of the device that triggered the event and the event number [0-3]
unregister device event
The xLink Unregister Device Event function is used to unregister events that have previously been registered by register device event API

Cc Arnd Bergmann <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
---
 drivers/misc/xlink-core/xlink-core.c        | 422 +++++++++++++++++++-
 drivers/misc/xlink-core/xlink-defs.h        |   4 +
 drivers/misc/xlink-core/xlink-dispatcher.c  |  53 ++-
 drivers/misc/xlink-core/xlink-multiplexer.c | 176 +++++---
 drivers/misc/xlink-core/xlink-platform.c    |  27 ++
 include/linux/xlink.h                       |  15 +-
 6 files changed, 609 insertions(+), 88 deletions(-)
drivers/misc/xlink-core/xlink-core.c +414 -8
index a600068840d3..63f65def8aa9 100644
@@ -62,6 +62,16 @@ static enum xlink_error xlink_write_volatile_user(struct xlink_handle *handle,
 static enum xlink_error do_xlink_write_volatile(struct xlink_handle *handle,
 						u16 chan, u8 const *message,
 						u32 size, u32 user_flag);
+static enum xlink_error xlink_register_device_event_user(struct xlink_handle *handle,
+							 u32 *event_list,
+							 u32 num_events,
+							 xlink_device_event_cb event_notif_fn);
+static enum xlink_error do_xlink_register_device_event(struct xlink_handle *handle,
+						       u32 *event_list,
+						       u32 num_events,
+						       xlink_device_event_cb event_notif_fn,
+						       u32 user_flag);
+static struct mutex dev_event_lock;
 
 static const struct file_operations fops = {
 		.owner		= THIS_MODULE,
@@ -74,14 +84,81 @@ struct xlink_link {
 	struct kref refcount;
 };
 
+struct xlink_attr {
+	unsigned long value;
+	u32 sw_dev_id;
+};
+
 struct keembay_xlink_dev {
 	struct platform_device *pdev;
 	struct xlink_link links[XLINK_MAX_CONNECTIONS];
 	u32 nmb_connected_links;
 	struct mutex lock;  // protect access to xlink_dev
+	struct xlink_attr eventx[4];
+};
+
+struct event_info {
+	struct list_head list;
+	u32 sw_device_id;
+	u32 event_type;
+	u32 user_flag;
+	xlink_device_event_cb event_notif_fn;
 };
 
 static u8 volbuf[XLINK_MAX_BUF_SIZE]; // buffer for volatile transactions
+#define NUM_REG_EVENTS 4
+
+// sysfs attribute functions
+
+static ssize_t event0_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct keembay_xlink_dev *xlink_dev = dev_get_drvdata(dev);
+	struct xlink_attr *a = &xlink_dev->eventx[0];
+
+	return scnprintf(buf, PAGE_SIZE, "0x%x 0x%lx\n", a->sw_dev_id, a->value);
+}
+
+static ssize_t event1_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct keembay_xlink_dev *xlink_dev = dev_get_drvdata(dev);
+	struct xlink_attr *a = &xlink_dev->eventx[1];
+
+	return scnprintf(buf, PAGE_SIZE, "0x%x 0x%lx\n", a->sw_dev_id, a->value);
+}
+
+static ssize_t event2_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct keembay_xlink_dev *xlink_dev = dev_get_drvdata(dev);
+	struct xlink_attr *a = &xlink_dev->eventx[2];
+
+	return scnprintf(buf, PAGE_SIZE, "0x%x 0x%lx\n", a->sw_dev_id, a->value);
+}
+
+static ssize_t event3_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct keembay_xlink_dev *xlink_dev = dev_get_drvdata(dev);
+	struct xlink_attr *a = &xlink_dev->eventx[3];
+
+	return scnprintf(buf, PAGE_SIZE, "0x%x 0x%lx\n", a->sw_dev_id, a->value);
+}
+
+static DEVICE_ATTR_RO(event0);
+static DEVICE_ATTR_RO(event1);
+static DEVICE_ATTR_RO(event2);
+static DEVICE_ATTR_RO(event3);
+static struct attribute *xlink_sysfs_entries[] = {
+	&dev_attr_event0.attr,
+	&dev_attr_event1.attr,
+	&dev_attr_event2.attr,
+	&dev_attr_event3.attr,
+	NULL,
+};
+
+static const struct attribute_group xlink_sysfs_group = {
+	.attrs = xlink_sysfs_entries,
+};
+
+static struct event_info ev_info;
 
 /*
  * global variable pointing to our xlink device.
@@ -215,7 +292,14 @@ static int kmb_xlink_probe(struct platform_device *pdev)
 		dev_info(&pdev->dev, "Cannot add the device to the system\n");
 		goto r_class;
 	}
+	INIT_LIST_HEAD(&ev_info.list);
 
+	rc = devm_device_add_group(&pdev->dev, &xlink_sysfs_group);
+	if (rc) {
+		dev_err(&pdev->dev, "failed to create sysfs entries: %d\n", rc);
+		return rc;
+	}
+	mutex_init(&dev_event_lock);
 	return 0;
 
 r_device:
@@ -239,7 +323,6 @@ static int kmb_xlink_remove(struct platform_device *pdev)
 	rc = xlink_multiplexer_destroy();
 	if (rc != X_LINK_SUCCESS)
 		pr_err("Multiplexer destroy failed\n");
-	// stop dispatchers and destroy
 	rc = xlink_dispatcher_destroy();
 	if (rc != X_LINK_SUCCESS)
 		pr_err("Dispatcher destroy failed\n");
@@ -270,19 +353,23 @@ static long xlink_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	struct xlinkconnect		con	= {0};
 	struct xlinkrelease		rel	= {0};
 	struct xlinkstartvpu		startvpu = {0};
+	struct xlinkcallback		cb	= {0};
 	struct xlinkgetdevicename	devn	= {0};
 	struct xlinkgetdevicelist	devl	= {0};
 	struct xlinkgetdevicestatus	devs	= {0};
 	struct xlinkbootdevice		boot	= {0};
 	struct xlinkresetdevice		res	= {0};
 	struct xlinkdevmode		devm	= {0};
+	struct xlinkregdevevent		regdevevent = {0};
 	u32 sw_device_id_list[XLINK_MAX_DEVICE_LIST_SIZE];
 	char name[XLINK_MAX_DEVICE_NAME_SIZE];
 	int interface = NULL_INTERFACE;
 	u32 device_status = 0;
 	u32 num_devices = 0;
 	u32 device_mode = 0;
+	u32 num_events = 0;
 	char filename[64];
+	u32 *ev_list;
 	u8 reladdr;
 	u8 *rdaddr;
 	u32 size;
@@ -318,6 +405,30 @@ static long xlink_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		if (copy_to_user((void __user *)op.return_code, (void *)&rc, sizeof(rc)))
 			return -EFAULT;
 		break;
+	case XL_DATA_READY_CALLBACK:
+		if (copy_from_user(&cb, (void __user *)arg,
+				   sizeof(struct xlinkcallback)))
+			return -EFAULT;
+		if (copy_from_user(&devh, (void __user *)cb.handle,
+				   sizeof(struct xlink_handle)))
+			return -EFAULT;
+		CHANNEL_SET_USER_BIT(cb.chan); // set MSbit for user space call
+		rc = xlink_data_available_event(&devh, cb.chan, cb.callback);
+		if (copy_to_user((void __user *)cb.return_code, (void *)&rc, sizeof(rc)))
+			return -EFAULT;
+		break;
+	case XL_DATA_CONSUMED_CALLBACK:
+		if (copy_from_user(&cb, (void __user *)arg,
+				   sizeof(struct xlinkcallback)))
+			return -EFAULT;
+		if (copy_from_user(&devh, (void __user *)cb.handle,
+				   sizeof(struct xlink_handle)))
+			return -EFAULT;
+		CHANNEL_SET_USER_BIT(cb.chan); // set MSbit for user space call
+		rc = xlink_data_consumed_event(&devh, cb.chan, cb.callback);
+		if (copy_to_user((void __user *)cb.return_code, (void *)&rc, sizeof(rc)))
+			return -EFAULT;
+		break;
 	case XL_READ_DATA:
 		if (copy_from_user(&rd, (void __user *)arg,
 				   sizeof(struct xlinkreaddata)))
@@ -598,6 +709,61 @@ static long xlink_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		if (copy_to_user((void __user *)devm.return_code, (void *)&rc, sizeof(rc)))
 			return -EFAULT;
 		break;
+	case XL_REGISTER_DEV_EVENT:
+		if (copy_from_user(&regdevevent, (void __user *)arg,
+				   sizeof(struct xlinkregdevevent)))
+			return -EFAULT;
+		if (copy_from_user(&devh, (void __user *)regdevevent.handle,
+				   sizeof(struct xlink_handle)))
+			return -EFAULT;
+		num_events = regdevevent.num_events;
+		if (num_events > 0 && num_events <= NUM_REG_EVENTS) {
+			ev_list = kzalloc((num_events * sizeof(u32)), GFP_KERNEL);
+			if (ev_list) {
+				if (copy_from_user(ev_list,
+						   (void __user *)regdevevent.event_list,
+						   (num_events * sizeof(u32)))) {
+					kfree(ev_list);
+					return -EFAULT;
+				}
+				rc = xlink_register_device_event_user(&devh,
+								      ev_list,
+								      num_events,
+								      NULL);
+				kfree(ev_list);
+			} else {
+				rc = X_LINK_ERROR;
+			}
+		} else {
+			rc = X_LINK_ERROR;
+		}
+		if (copy_to_user((void __user *)regdevevent.return_code, (void *)&rc, sizeof(rc)))
+			return -EFAULT;
+		break;
+	case XL_UNREGISTER_DEV_EVENT:
+		if (copy_from_user(&regdevevent, (void __user *)arg,
+				   sizeof(struct xlinkregdevevent)))
+			return -EFAULT;
+		if (copy_from_user(&devh, (void __user *)regdevevent.handle,
+				   sizeof(struct xlink_handle)))
+			return -EFAULT;
+		num_events = regdevevent.num_events;
+		if (num_events <= NUM_REG_EVENTS) {
+			ev_list = kzalloc((num_events * sizeof(u32)), GFP_KERNEL);
+			if (copy_from_user(ev_list,
+					   (void __user *)regdevevent.event_list,
+					   (num_events * sizeof(u32)))) {
+				kfree(ev_list);
+				return -EFAULT;
+			}
+			rc = xlink_unregister_device_event(&devh, ev_list, num_events);
+			kfree(ev_list);
+		} else {
+			rc = X_LINK_ERROR;
+		}
+		if (copy_to_user((void __user *)regdevevent.return_code, (void *)&rc, sizeof(rc)))
+			return -EFAULT;
+		break;
 	}
 	if (rc)
 		return -EIO;
@@ -671,14 +837,12 @@ enum xlink_error xlink_connect(struct xlink_handle *handle)
 		xlink->nmb_connected_links++;
 		kref_init(&link->refcount);
 		if (interface != IPC_INTERFACE) {
-			// start dispatcher
 			rc = xlink_dispatcher_start(link->id, &link->handle);
 			if (rc) {
 				pr_err("dispatcher start failed\n");
 				goto r_cleanup;
 			}
 		}
-		// initialize multiplexer connection
 		rc = xlink_multiplexer_connect(link->id);
 		if (rc) {
 			pr_err("multiplexer connect failed\n");
@@ -689,7 +853,6 @@ enum xlink_error xlink_connect(struct xlink_handle *handle)
 			link->handle.dev_type,
 			xlink->nmb_connected_links);
 	} else {
-		// already connected
 		pr_info("dev 0x%x ALREADY connected - dev_type %d\n",
 			link->handle.sw_device_id,
 			link->handle.dev_type);
@@ -697,7 +860,6 @@ enum xlink_error xlink_connect(struct xlink_handle *handle)
 		*handle = link->handle;
 	}
 	mutex_unlock(&xlink->lock);
-	// TODO: implement ping
 	return X_LINK_SUCCESS;
 
 r_cleanup:
@@ -707,6 +869,78 @@ enum xlink_error xlink_connect(struct xlink_handle *handle)
 }
 EXPORT_SYMBOL(xlink_connect);
 
+enum xlink_error xlink_data_available_event(struct xlink_handle *handle,
+					    u16 chan,
+					    xlink_event data_available_event)
+{
+	struct xlink_event *event;
+	struct xlink_link *link;
+	enum xlink_error rc;
+	int event_queued = 0;
+	char origin = 'K';
+
+	if (!xlink || !handle)
+		return X_LINK_ERROR;
+
+	if (CHANNEL_USER_BIT_IS_SET(chan))
+		origin  = 'U';     // function called from user space
+	CHANNEL_CLEAR_USER_BIT(chan);  // restore proper channel value
+
+	link = get_link_by_sw_device_id(handle->sw_device_id);
+	if (!link)
+		return X_LINK_ERROR;
+	event = xlink_create_event(link->id, XLINK_DATA_READY_CALLBACK_REQ,
+				   &link->handle, chan, 0, 0);
+	if (!event)
+		return X_LINK_ERROR;
+	event->data = data_available_event;
+	event->callback_origin = origin;
+	if (!data_available_event)
+		event->calling_pid = NULL; // disable callbacks on this channel
+	else
+		event->calling_pid = current;
+	rc = xlink_multiplexer_tx(event, &event_queued);
+	if (!event_queued)
+		xlink_destroy_event(event);
+	return rc;
+}
+EXPORT_SYMBOL(xlink_data_available_event);
+enum xlink_error xlink_data_consumed_event(struct xlink_handle *handle,
+					   u16 chan,
+					   xlink_event data_consumed_event)
+{
+	struct xlink_event *event;
+	struct xlink_link *link;
+	enum xlink_error rc;
+	int event_queued = 0;
+	char origin = 'K';
+
+	if (!xlink || !handle)
+		return X_LINK_ERROR;
+
+	if (CHANNEL_USER_BIT_IS_SET(chan))
+		origin  = 'U';     // function called from user space
+	CHANNEL_CLEAR_USER_BIT(chan);  // restore proper channel value
+
+	link = get_link_by_sw_device_id(handle->sw_device_id);
+	if (!link)
+		return X_LINK_ERROR;
+	event = xlink_create_event(link->id, XLINK_DATA_CONSUMED_CALLBACK_REQ,
+				   &link->handle, chan, 0, 0);
+	if (!event)
+		return X_LINK_ERROR;
+	event->data = data_consumed_event;
+	event->callback_origin = origin;
+	if (!data_consumed_event)
+		event->calling_pid = NULL; // disable callbacks on this channel
+	else
+		event->calling_pid = current;
+	rc = xlink_multiplexer_tx(event, &event_queued);
+	if (!event_queued)
+		xlink_destroy_event(event);
+	return rc;
+}
+EXPORT_SYMBOL(xlink_data_consumed_event);
 enum xlink_error xlink_open_channel(struct xlink_handle *handle,
 				    u16 chan, enum xlink_opmode mode,
 				    u32 data_size, u32 timeout)
@@ -1051,8 +1285,8 @@ EXPORT_SYMBOL(xlink_release_data);
 enum xlink_error xlink_disconnect(struct xlink_handle *handle)
 {
 	struct xlink_link *link;
-	int interface = NULL_INTERFACE;
-	enum xlink_error rc = X_LINK_ERROR;
+	int interface;
+	enum xlink_error rc = 0;
 
 	if (!xlink || !handle)
 		return X_LINK_ERROR;
@@ -1061,7 +1295,6 @@ enum xlink_error xlink_disconnect(struct xlink_handle *handle)
 	if (!link)
 		return X_LINK_ERROR;
 
-	// decrement refcount, if count is 0 lock mutex and disconnect
 	if (kref_put_mutex(&link->refcount, release_after_kref_put,
 			   &xlink->lock)) {
 		// stop dispatcher
@@ -1240,6 +1473,179 @@ enum xlink_error xlink_get_device_mode(struct xlink_handle *handle,
 	return rc;
 }
 EXPORT_SYMBOL(xlink_get_device_mode);
+
+static int xlink_device_event_handler(u32 sw_device_id, u32 event_type)
+{
+	struct event_info *events = NULL;
+	xlink_device_event_cb event_cb;
+	bool found = false;
+	char event_attr[7];
+
+	mutex_lock(&dev_event_lock);
+	// find sw_device_id, event_type in list
+	list_for_each_entry(events, &ev_info.list, list) {
+		if (events) {
+			if (events->sw_device_id == sw_device_id &&
+			    events->event_type == event_type) {
+				event_cb = events->event_notif_fn;
+				found = true;
+				break;
+			}
+		}
+	}
+	if (found) {
+		if (events->user_flag) {
+			xlink->eventx[events->event_type].value = events->event_type;
+			xlink->eventx[events->event_type].sw_dev_id = sw_device_id;
+			sprintf(event_attr, "event%d", events->event_type);
+			sysfs_notify(&xlink->pdev->dev.kobj, NULL, event_attr);
+		} else {
+			if (event_cb) {
+				event_cb(sw_device_id, event_type);
+			} else {
+				pr_info("No callback found for sw_device_id : 0x%x event type %d\n",
+					sw_device_id, event_type);
+				mutex_unlock(&dev_event_lock);
+				return X_LINK_ERROR;
+			}
+		}
+		pr_info("sysfs_notify event %d swdev_id %xs\n",
+			events->event_type, sw_device_id);
+	}
+	mutex_unlock(&dev_event_lock);
+return X_LINK_SUCCESS;
+}
+
+static bool event_registered(u32 sw_dev_id, u32 event)
+{
+	struct event_info *events = NULL;
+
+	list_for_each_entry(events, &ev_info.list, list) {
+		if (events) {
+			if (events->sw_device_id == sw_dev_id &&
+			    events->event_type == event) {
+				return true;
+			}
+		}
+	}
+return false;
+}
+
+static enum xlink_error xlink_register_device_event_user(struct xlink_handle *handle,
+							 u32 *event_list, u32 num_events,
+							 xlink_device_event_cb event_notif_fn)
+{
+	enum xlink_error rc;
+
+	rc = do_xlink_register_device_event(handle, event_list, num_events,
+					    event_notif_fn, 1);
+	return rc;
+}
+
+enum xlink_error xlink_register_device_event(struct xlink_handle *handle,
+					     u32 *event_list, u32 num_events,
+					     xlink_device_event_cb event_notif_fn)
+{
+	enum xlink_error rc;
+
+	rc = do_xlink_register_device_event(handle, event_list, num_events,
+					    event_notif_fn, 0);
+	return rc;
+}
+EXPORT_SYMBOL(xlink_register_device_event);
+
+static enum xlink_error do_xlink_register_device_event(struct xlink_handle *handle,
+						       u32 *event_list,
+						       u32 num_events,
+						       xlink_device_event_cb event_notif_fn,
+						       u32 user_flag)
+{
+	struct event_info *events;
+	u32 interface;
+	u32 event;
+	int i;
+
+	if (num_events < 0 || num_events >= NUM_REG_EVENTS)
+		return X_LINK_ERROR;
+	for (i = 0; i < num_events; i++) {
+		events = kzalloc(sizeof(*events), GFP_KERNEL);
+		if (!events)
+			return X_LINK_ERROR;
+		event = *event_list;
+		events->sw_device_id = handle->sw_device_id;
+		events->event_notif_fn = event_notif_fn;
+		events->event_type = *event_list++;
+		events->user_flag = user_flag;
+		if (user_flag) {
+			/* only add to list once if userspace */
+			/* xlink userspace handles multi process callbacks */
+			if (event_registered(handle->sw_device_id, event)) {
+				pr_info("xlink-core: Event 0x%x - %d already registered\n",
+					handle->sw_device_id, event);
+				kfree(events);
+				continue;
+			}
+		}
+		pr_info("xlink-core:Events: sw_device_id 0x%x event %d fn %p user_flag %d\n",
+			events->sw_device_id, events->event_type,
+			events->event_notif_fn, events->user_flag);
+		list_add_tail(&events->list, &ev_info.list);
+	}
+	interface = get_interface_from_sw_device_id(handle->sw_device_id);
+	if (interface == NULL_INTERFACE)
+		return X_LINK_ERROR;
+	xlink_platform_register_for_events(interface, handle->sw_device_id,
+					   xlink_device_event_handler);
+	return X_LINK_SUCCESS;
+}
+
+enum xlink_error xlink_unregister_device_event(struct xlink_handle *handle,
+					       u32 *event_list,
+					       u32 num_events)
+{
+	struct event_info *events = NULL;
+	u32 interface;
+	int found = 0;
+	int count = 0;
+	int i;
+
+	if (num_events < 0 || num_events >= NUM_REG_EVENTS)
+		return X_LINK_ERROR;
+	for (i = 0; i < num_events; i++) {
+		list_for_each_entry(events, &ev_info.list, list) {
+			if (events->sw_device_id == handle->sw_device_id &&
+			    events->event_type == event_list[i]) {
+				found = 1;
+				break;
+			}
+		}
+		if (!events || !found)
+			return X_LINK_ERROR;
+		pr_info("removing event %d for sw_device_id 0x%x\n",
+			events->event_type, events->sw_device_id);
+		list_del(&events->list);
+		kfree(events);
+	}
+	// check if any events left for this sw_device_id
+	// are still registered ( in list )
+	list_for_each_entry(events, &ev_info.list, list) {
+		if (events) {
+			if (events->sw_device_id == handle->sw_device_id) {
+				count++;
+				break;
+			}
+		}
+	}
+	if (count == 0) {
+		interface = get_interface_from_sw_device_id(handle->sw_device_id);
+		if (interface == NULL_INTERFACE)
+			return X_LINK_ERROR;
+		xlink_platform_unregister_for_events(interface, handle->sw_device_id);
+	}
+	return X_LINK_SUCCESS;
+}
+EXPORT_SYMBOL(xlink_unregister_device_event);
+
 /* Device tree driver match. */
 static const struct of_device_id kmb_xlink_of_match[] = {
 	{
drivers/misc/xlink-core/xlink-defs.h +4 -0
index 8985f6631175..df686e5185c5 100644
@@ -102,6 +102,8 @@ enum xlink_event_type {
 	XLINK_CLOSE_CHANNEL_REQ,
 	XLINK_PING_REQ,
 	XLINK_WRITE_CONTROL_REQ,
+	XLINK_DATA_READY_CALLBACK_REQ,
+	XLINK_DATA_CONSUMED_CALLBACK_REQ,
 	XLINK_REQ_LAST,
 	// response events
 	XLINK_WRITE_RESP = 0x10,
@@ -113,6 +115,8 @@ enum xlink_event_type {
 	XLINK_CLOSE_CHANNEL_RESP,
 	XLINK_PING_RESP,
 	XLINK_WRITE_CONTROL_RESP,
+	XLINK_DATA_READY_CALLBACK_RESP,
+	XLINK_DATA_CONSUMED_CALLBACK_RESP,
 	XLINK_RESP_LAST,
 };
 
drivers/misc/xlink-core/xlink-dispatcher.c +24 -29

148 lines not on this page · raw message

drivers/misc/xlink-core/xlink-multiplexer.c +127 -49

257 lines not on this page · raw message

drivers/misc/xlink-core/xlink-platform.c +27 -0
index 56eb8da28a5f..b0076cb3671d 100644
@@ -56,6 +56,11 @@ static inline int xlink_ipc_close_channel(u32 sw_device_id,
 					  u32 channel)
 { return -1; }
 
+static inline int xlink_ipc_register_for_events(u32 sw_device_id,
+						int (*callback)(u32 sw_device_id, u32 event))
+{ return -1; }
+static inline int xlink_ipc_unregister_for_events(u32 sw_device_id)
+{ return -1; }
 #endif /* CONFIG_XLINK_LOCAL_HOST */
 
 /*
@@ -95,6 +100,13 @@ static int (*open_chan_fcts[NMB_OF_INTERFACES])(u32, u32) = {
 
 static int (*close_chan_fcts[NMB_OF_INTERFACES])(u32, u32) = {
 		xlink_ipc_close_channel, NULL, NULL, NULL};
+static int (*register_for_events_fcts[NMB_OF_INTERFACES])(u32,
+						   int (*callback)(u32 sw_device_id, u32 event)) = {
+								   xlink_ipc_register_for_events,
+								   xlink_pcie_register_device_event,
+								   NULL, NULL};
+static int (*unregister_for_events_fcts[NMB_OF_INTERFACES])(u32) = {
+		xlink_ipc_unregister_for_events, xlink_pcie_unregister_device_event, NULL, NULL};
 
 /*
  * xlink low-level driver interface
@@ -207,6 +219,21 @@ int xlink_platform_close_channel(u32 interface, u32 sw_device_id,
 	return close_chan_fcts[interface](sw_device_id, channel);
 }
 
+int xlink_platform_register_for_events(u32 interface, u32 sw_device_id,
+				       xlink_device_event_cb event_notif_fn)
+{
+	if (interface >= NMB_OF_INTERFACES || !register_for_events_fcts[interface])
+		return -1;
+	return register_for_events_fcts[interface](sw_device_id, event_notif_fn);
+}
+
+int xlink_platform_unregister_for_events(u32 interface, u32 sw_device_id)
+{
+	if (interface >= NMB_OF_INTERFACES || !unregister_for_events_fcts[interface])
+		return -1;
+	return unregister_for_events_fcts[interface](sw_device_id);
+}
+
 void *xlink_platform_allocate(struct device *dev, dma_addr_t *handle,
 			      u32 size, u32 alignment,
 			      enum xlink_memory_region region)
include/linux/xlink.h +13 -2
index b00dbc719530..ac196ff85469 100644
@@ -70,6 +70,12 @@ enum xlink_error xlink_open_channel(struct xlink_handle *handle,
 				    u16 chan, enum xlink_opmode mode,
 				    u32 data_size, u32 timeout);
 
+enum xlink_error xlink_data_available_event(struct xlink_handle *handle,
+					    u16 chan,
+					    xlink_event data_available_event);
+enum xlink_error xlink_data_consumed_event(struct xlink_handle *handle,
+					   u16 chan,
+					   xlink_event data_consumed_event);
 enum xlink_error xlink_close_channel(struct xlink_handle *handle, u16 chan);
 
 enum xlink_error xlink_write_data(struct xlink_handle *handle,
@@ -113,9 +119,14 @@ enum xlink_error xlink_set_device_mode(struct xlink_handle *handle,
 enum xlink_error xlink_get_device_mode(struct xlink_handle *handle,
 				       enum xlink_device_power_mode *power_mode);
 
-enum xlink_error xlink_start_vpu(char *filename); /* depreciated */
+enum xlink_error xlink_register_device_event(struct xlink_handle *handle,
+					     u32 *event_list, u32 num_events,
+					     xlink_device_event_cb event_notif_fn);
+enum xlink_error xlink_unregister_device_event(struct xlink_handle *handle,
+					       u32 *event_list, u32 num_events);
+enum xlink_error xlink_start_vpu(char *filename); /* deprecated */
 
-enum xlink_error xlink_stop_vpu(void); /* depreciated */
+enum xlink_error xlink_stop_vpu(void); /* deprecated */
 
 /* API functions to be implemented
  *
Signature · 1 line
2.17.1
#8 lore raw

Re: [PATCH 07/22] misc: xlink-pcie: lh: Add PCIe EPF driver for Local Host

In reply to [email protected]
Quoted 11 lines · On Mon, Nov 30, 2020 at 03:06:52PM -0800, [email protected] wrote:

From: Srikanth Thokala <[email protected]>

Add PCIe EPF driver for local host (lh) to configure BAR's and other HW resources. Underlying PCIe HW controller is a Synopsys DWC PCIe core.

Cc Derek Kiernan <[email protected]>
Cc Dragan Cvetic <[email protected]>
Cc Arnd Bergmann <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>

<snip>

Again, you sent this twice? And it never got to lore.kernel.org nor the mailing lists?

And I can't see a 00/XX email anywhere explaining this, and I didn't get the whole series?

Something is really wrong on your end with your email client configuration, please fix that up and send this so that we can actually see it all, and know what the heck we are supposed to be reviewing...

thanks,

greg k-h

#31 lore raw
In reply to [email protected]
Quoted 22 lines · On Mon, Nov 30, 2020 at 03:06:45PM -0800, [email protected] wrote:

From: mark gross <[email protected]>

The Intel Vision Processing Unit (VPU) is an IP block that is showing up for the first time as part of the Keem Bay SOC. Keem Bay is a quad core A53 Arm SOC. It is designed to be used as a stand alone SOC as well as in an PCIe Vision Processing accelerator add in card.

This part 1 of the patches make up the base or core of the stack needed to enable both use cases for the VPU.

Part 2 includes 11 more patches that depend on part 1. Those should be ready in a couple of weeks or less.

I am trying something a bit new with this sequence where I've been working with the driver developers as a "pre-maintainer" reviewing and enforcing the kernel expectations as I understand them. Its taken a couple of months to get this code to the point I feel its ready for public posting. My goal is to make sure it meets expectations for quality and compliance with kernel expectations and there will be mostly technical / design issues to talk about.

Thanks for looking at these and providing feedback.

Quoted 8 lines

--mark
p.s. I have had a problem my MTA configuration between mutt and git send-email where I was using msmpt to send from mutt (because 15+ years ago its the first way I got to work and never changed) while my worstation MTA that git send-email uses was un-configured resulting in my return-path naming my workstion withing the firewall. I suck at email administration.

I appologies for the multiple copies.

Ah, here's the full set of patches...

But, you didn't cc: everyone on them, some of us just got a partial set of patches, why?

still confused,

greg k-h

#17 lore raw

Re: [PATCH 09/22] misc: xlink-pcie: lh: Add core communication logic

In reply to [email protected]
Quoted 11 lines · On Mon, Nov 30, 2020 at 03:06:54PM -0800, [email protected] wrote:
drivers/misc/xlink-pcie/local_host/core.c new file +11 -0
+static int rx_pool_size = SZ_32M;
+module_param(rx_pool_size, int, 0664);
+MODULE_PARM_DESC(rx_pool_size, "receiving pool size (default 32 MiB)");
+
+static int tx_pool_size = SZ_32M;
+module_param(tx_pool_size, int, 0664);
+MODULE_PARM_DESC(tx_pool_size, "transmitting pool size (default 32 MiB)");
+
+static int fragment_size = XPCIE_FRAGMENT_SIZE;
+module_param(fragment_size, int, 0664);
+MODULE_PARM_DESC(fragment_size, "transfer descriptor size (default 128 KiB)");

drivers/misc/xlink-pcie/local_host/core.c line 38

Quoted 10 lines
drivers/misc/xlink-pcie/local_host/core.c new file +10 -0
+
+static bool tx_pool_coherent = true;
+module_param(tx_pool_coherent, bool, 0664);
+MODULE_PARM_DESC(tx_pool_coherent,
+		 "transmitting pool using coherent memory (default true)");
+
+static bool rx_pool_coherent;
+module_param(rx_pool_coherent, bool, 0664);
+MODULE_PARM_DESC(rx_pool_coherent,
+		 "receiving pool using coherent memory (default false)");

This is not the 1990's anymore, please never use module parameters for new drivers as they do not work well (i.e. they do not work at all on a individual device basis.)

Make this all "just work" so that userspace does not have to "tune" anything. But if you really must allow configuration like this, then use configfs, as that's what it is there for.

thanks,

greg k-h

#13 lore raw

Re: [PATCH 07/22] misc: xlink-pcie: lh: Add PCIe EPF driver for Local Host

In reply to [email protected]

drivers/misc/xlink-pcie/local_host/xpcie.h line 36

Quoted 13 lines · On Mon, Nov 30, 2020 at 03:06:52PM -0800, [email protected] wrote:
drivers/misc/xlink-pcie/local_host/xpcie.h new file +13 -0
+#define XPCIE_VERSION_MAJOR 0
+#define XPCIE_VERSION_MINOR 5
+#define XPCIE_VERSION_BUILD 0
+#define _TOSTR(X) #X
+#define _VERSION(A, B, C) _TOSTR(A) "." _TOSTR(B) "." _TOSTR(C)
+#define XPCIE_DRIVER_VERSION \
+	_VERSION(XPCIE_VERSION_MAJOR, XPCIE_VERSION_MINOR, XPCIE_VERSION_BUILD)
+
+struct xpcie_version {
+	u8 major;
+	u8 minor;
+	u16 build;
+} __packed;

Now that the driver will be in the tree, there is no need for this structure or these fields, right? It will just be the version of the kernel. Otherwise something like this will never be correct, given stable kernel releases and enterprise kernel releases, and loads of other messy backported trees. Just stick to the kernel release number please, that's the only sane thing.

thanks,

greg k-h

author
#9 lore raw

Re: [PATCH 07/22] misc: xlink-pcie: lh: Add PCIe EPF driver for Local Host

In reply to Greg Kroah-Hartman
Quoted 13 lines · Greg Kroah-Hartman
Quoted 11 lines · On Mon, Nov 30, 2020 at 03:06:52PM -0800, [email protected] wrote:

From: Srikanth Thokala <[email protected]>

Add PCIe EPF driver for local host (lh) to configure BAR's and other HW resources. Underlying PCIe HW controller is a Synopsys DWC PCIe core.

Cc Derek Kiernan <[email protected]>
Cc Dragan Cvetic <[email protected]>
Cc Arnd Bergmann <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
Quoted 4 lines

<snip>

Again, you sent this twice? And it never got to lore.kernel.org nor the mailing lists?

In my excitement of sorting out my MTA misconfiguration work around I actually hit entry without including the magic fix "[email protected]" in my git send-email command line.

Quoted 3 lines

And I can't see a 00/XX email anywhere explaining this, and I didn't get the whole series?

https://lore.kernel.org/lkml/[email protected]/

Did I mess up on who all should get the 00/xx email?

Quoted 4 lines

Something is really wrong on your end with your email client configuration, please fix that up and send this so that we can actually see it all, and know what the heck we are supposed to be reviewing...

Yes, I think I have it fixed, or worked around now.

sorry,

--mark

#10 lore raw

Re: [PATCH 07/22] misc: xlink-pcie: lh: Add PCIe EPF driver for Local Host

Quoted 22 lines · mark gross
Quoted 13 lines · Greg Kroah-Hartman
Quoted 11 lines · On Mon, Nov 30, 2020 at 03:06:52PM -0800, [email protected] wrote:

From: Srikanth Thokala <[email protected]>

Add PCIe EPF driver for local host (lh) to configure BAR's and other HW resources. Underlying PCIe HW controller is a Synopsys DWC PCIe core.

Cc Derek Kiernan <[email protected]>
Cc Dragan Cvetic <[email protected]>
Cc Arnd Bergmann <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
Quoted 4 lines

<snip>

Again, you sent this twice? And it never got to lore.kernel.org nor the mailing lists?

In my excitement of sorting out my MTA misconfiguration work around I actually hit entry without including the magic fix "[email protected]" in my git send-email command line.

Quoted 1 line
Quoted 5 lines
Quoted 2 lines

And I can't see a 00/XX email anywhere explaining this, and I didn't get the whole series?

https://lore.kernel.org/lkml/[email protected]/

Did I mess up on who all should get the 00/xx email?

Yes, you need to include the people that you want to review the individual patches, otherwise we have no idea :(

thanks,

greg k-h

author
#32 lore raw
In reply to Greg KH
Quoted 30 lines · Greg KH
Quoted 29 lines · On Mon, Nov 30, 2020 at 03:06:45PM -0800, [email protected] wrote:

From: mark gross <[email protected]>

The Intel Vision Processing Unit (VPU) is an IP block that is showing up for the first time as part of the Keem Bay SOC. Keem Bay is a quad core A53 Arm SOC. It is designed to be used as a stand alone SOC as well as in an PCIe Vision Processing accelerator add in card.

This part 1 of the patches make up the base or core of the stack needed to enable both use cases for the VPU.

Part 2 includes 11 more patches that depend on part 1. Those should be ready in a couple of weeks or less.

I am trying something a bit new with this sequence where I've been working with the driver developers as a "pre-maintainer" reviewing and enforcing the kernel expectations as I understand them. Its taken a couple of months to get this code to the point I feel its ready for public posting. My goal is to make sure it meets expectations for quality and compliance with kernel expectations and there will be mostly technical / design issues to talk about.

Thanks for looking at these and providing feedback.

--mark
p.s. I have had a problem my MTA configuration between mutt and git send-email where I was using msmpt to send from mutt (because 15+ years ago its the first way I got to work and never changed) while my worstation MTA that git send-email uses was un-configured resulting in my return-path naming my workstion withing the firewall. I suck at email administration.

Quoted 6 lines
Quoted 1 line

I appologies for the multiple copies.

Ah, here's the full set of patches...

But, you didn't cc: everyone on them, some of us just got a partial set of patches, why?

Because I thought ccing everyone on all the changes was not what was expected. Does the DT guy want to see all the non-DT changes?

this is my first time sending a big patch set that crosses subsystems like this. I'm not sure what the preferd way to do things so I used get_maintainer.pl on each patch to add thime in the cc: tags just above the signed off's.

Should I have simply concatinated the list of mainttainers and CC them all on all the patches?

Quoted 2 lines

still confused,

its my fault.

--mark

#12 lore raw

RE: [PATCH 07/22] misc: xlink-pcie: lh: Add PCIe EPF driver for Local Host

In reply to mark gross

Hi Mark,

You should remove me and Derek Kiernan from CC list, we don't belong to this list.

Dragan

Quoted 47 lines

-----Original Message-----
From: mark gross <[email protected]>
Sent: Tuesday 1 December 2020 17:46
To: Greg Kroah-Hartman <[email protected]>
Cc: [email protected]; [email protected]; [email protected]; [email protected]; Srikanth Thokala <[email protected]>; Derek Kiernan <[email protected]>; Dragan Cvetic <[email protected]>; Arnd Bergmann <[email protected]>
Subject: Re: [PATCH 07/22] misc: xlink-pcie: lh: Add PCIe EPF driver for Local Host

Quoted 13 lines · Greg Kroah-Hartman
Quoted 11 lines · On Mon, Nov 30, 2020 at 03:06:52PM -0800, [email protected] wrote:

From: Srikanth Thokala <[email protected]>

Add PCIe EPF driver for local host (lh) to configure BAR's and other HW resources. Underlying PCIe HW controller is a Synopsys DWC PCIe core.

Cc Derek Kiernan <[email protected]>
Cc Dragan Cvetic <[email protected]>
Cc Arnd Bergmann <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
Quoted 4 lines

<snip>

Again, you sent this twice? And it never got to lore.kernel.org nor the mailing lists?

In my excitement of sorting out my MTA misconfiguration work around I actually hit entry without including the magic fix "[email protected]" in my git send-email command line.

Quoted 3 lines

And I can't see a 00/XX email anywhere explaining this, and I didn't get the whole series?

https://lore.kernel.org/lkml/[email protected]/

Did I mess up on who all should get the 00/xx email?

Quoted 4 lines

Something is really wrong on your end with your email client configuration, please fix that up and send this so that we can actually see it all, and know what the heck we are supposed to be reviewing...

Yes, I think I have it fixed, or worked around now.

sorry,

--mark

author
#11 lore raw

Re: [PATCH 07/22] misc: xlink-pcie: lh: Add PCIe EPF driver for Local Host

In reply to Greg Kroah-Hartman
Quoted 23 lines · Greg Kroah-Hartman
Quoted 22 lines · mark gross
Quoted 13 lines · Greg Kroah-Hartman
Quoted 11 lines · On Mon, Nov 30, 2020 at 03:06:52PM -0800, [email protected] wrote:

From: Srikanth Thokala <[email protected]>

Add PCIe EPF driver for local host (lh) to configure BAR's and other HW resources. Underlying PCIe HW controller is a Synopsys DWC PCIe core.

Cc Derek Kiernan <[email protected]>
Cc Dragan Cvetic <[email protected]>
Cc Arnd Bergmann <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
Quoted 4 lines

<snip>

Again, you sent this twice? And it never got to lore.kernel.org nor the mailing lists?

In my excitement of sorting out my MTA misconfiguration work around I actually hit entry without including the magic fix "[email protected]" in my git send-email command line.

Quoted 1 line
Quoted 9 lines
Quoted 5 lines
Quoted 2 lines

And I can't see a 00/XX email anywhere explaining this, and I didn't get the whole series?

https://lore.kernel.org/lkml/[email protected]/

Did I mess up on who all should get the 00/xx email?

Yes, you need to include the people that you want to review the individual patches, otherwise we have no idea :(

Ok, I will reset and try again. I appoligize for this false start. I'll resend after I trim the CC list based on Dragon's feedback.

--mark

#14 lore raw

RE: [PATCH 07/22] misc: xlink-pcie: lh: Add PCIe EPF driver for Local Host

In reply to Greg Kroah-Hartman

Hi Greg,

Quoted 20 lines

-----Original Message-----
From: Greg Kroah-Hartman <[email protected]>
Sent: Tuesday, December 1, 2020 3:48 PM
To: [email protected]
Cc: [email protected]; [email protected]; Gretzinger, Adam R <[email protected]>; Thokala, Srikanth <[email protected]>; Derek Kiernan <[email protected]>; Dragan Cvetic <[email protected]>; Arnd Bergmann <[email protected]>
Subject: Re: [PATCH 07/22] misc: xlink-pcie: lh: Add PCIe EPF driver for Local Host

drivers/misc/xlink-pcie/local_host/xpcie.h

Quoted 7 lines · On Mon, Nov 30, 2020 at 03:06:52PM -0800, [email protected] wrote:
drivers/misc/xlink-pcie/local_host/xpcie.h new file +7 -0
+#define XPCIE_VERSION_MAJOR 0
+#define XPCIE_VERSION_MINOR 5
+#define XPCIE_VERSION_BUILD 0
+#define _TOSTR(X) #X
+#define _VERSION(A, B, C) _TOSTR(A) "." _TOSTR(B) "." _TOSTR(C)
+#define XPCIE_DRIVER_VERSION \
+	_VERSION(XPCIE_VERSION_MAJOR, XPCIE_VERSION_MINOR,

XPCIE_VERSION_BUILD)

Quoted 14 lines

drivers/misc/xlink-pcie/local_host/xpcie.h line 36

Quoted 6 lines
drivers/misc/xlink-pcie/local_host/xpcie.h new file +6 -0
+
+struct xpcie_version {
+	u8 major;
+	u8 minor;
+	u16 build;
+} __packed;

Now that the driver will be in the tree, there is no need for this structure or these fields, right? It will just be the version of the kernel. Otherwise something like this will never be correct, given stable kernel releases and enterprise kernel releases, and loads of other messy backported trees. Just stick to the kernel release number please, that's the only sane thing.

Sure, I agree. I will fix it in my v2.

thanks!
Srikanth

Quoted 3 lines

thanks,

greg k-h