This series is the AFFINE image processing accelerator driver for Toshiba's ARM SoC, Visconti[0]. This provides DT binding documentation, device driver, MAINTAINER files.
Best regards, Yuji
[0]: https://toshiba.semicon-storage.com/ap-en/semiconductor/product/image-recogn...
Yuji Ishikawa (4): dt-bindings: soc: visconti: Add Toshiba Visconti AFFINE image processing accelerator bindings soc: visconti: Add Toshiba Visconti image processing accelerator common source soc: visconti: Add Toshiba Visconti AFFINE image processing accelerator MAINTAINERS: Add entries for Toshiba Visconti AFFINE image processing accelerator
.../soc/visconti/toshiba,visconti-affine.yaml | 53 ++ MAINTAINERS | 2 + drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/visconti/Kconfig | 7 + drivers/soc/visconti/Makefile | 8 + drivers/soc/visconti/affine/Makefile | 6 + drivers/soc/visconti/affine/affine.c | 451 ++++++++++++++++++ drivers/soc/visconti/affine/hwd_affine.c | 207 ++++++++ drivers/soc/visconti/affine/hwd_affine.h | 83 ++++ drivers/soc/visconti/affine/hwd_affine_reg.h | 45 ++ drivers/soc/visconti/ipa_common.c | 55 +++ drivers/soc/visconti/ipa_common.h | 19 + drivers/soc/visconti/uapi/affine.h | 87 ++++ drivers/soc/visconti/uapi/ipa.h | 87 ++++ 15 files changed, 1112 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/visconti/toshiba,visconti-affine.yaml create mode 100644 drivers/soc/visconti/Kconfig create mode 100644 drivers/soc/visconti/Makefile create mode 100644 drivers/soc/visconti/affine/Makefile create mode 100644 drivers/soc/visconti/affine/affine.c create mode 100644 drivers/soc/visconti/affine/hwd_affine.c create mode 100644 drivers/soc/visconti/affine/hwd_affine.h create mode 100644 drivers/soc/visconti/affine/hwd_affine_reg.h create mode 100644 drivers/soc/visconti/ipa_common.c create mode 100644 drivers/soc/visconti/ipa_common.h create mode 100644 drivers/soc/visconti/uapi/affine.h create mode 100644 drivers/soc/visconti/uapi/ipa.h
Signed-off-by: Yuji Ishikawa yuji2.ishikawa@toshiba.co.jp Reviewed-by: Nobuhiro Iwamatsu nobuhiro1.iwamatsu@toshiba.co.jp --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS index dd36acc87..231b2c6f9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2796,12 +2796,14 @@ F: Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml F: Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml F: Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml F: Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml +F: Documentation/devicetree/bindings/soc/visconti/ F: Documentation/devicetree/bindings/watchdog/toshiba,visconti-wdt.yaml F: arch/arm64/boot/dts/toshiba/ F: drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c F: drivers/gpio/gpio-visconti.c F: drivers/pci/controller/dwc/pcie-visconti.c F: drivers/pinctrl/visconti/ +F: drivers/soc/visconti/ F: drivers/watchdog/visconti_wdt.c N: visconti
Adds the Device Tree binding documentation that allows to describe the AFFINE image processing accelerator found in Toshiba Visconti SoCs.
Signed-off-by: Yuji Ishikawa yuji2.ishikawa@toshiba.co.jp Reviewed-by: Nobuhiro Iwamatsu nobuhiro1.iwamatsu@toshiba.co.jp --- .../soc/visconti/toshiba,visconti-affine.yaml | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/visconti/toshiba,visconti-affine.yaml
diff --git a/Documentation/devicetree/bindings/soc/visconti/toshiba,visconti-affine.yaml b/Documentation/devicetree/bindings/soc/visconti/toshiba,visconti-affine.yaml new file mode 100644 index 000000000..a446e1c4f --- /dev/null +++ b/Documentation/devicetree/bindings/soc/visconti/toshiba,visconti-affine.yaml @@ -0,0 +1,53 @@ +# SPDX-LIcense-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/visconti/toshiba,visconti-affine.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Toshiba Visconti AFFINE image processing accelerator + +maintainers: + - Nobuhiro Iwamatsu nobuhiro1.iwamatsu@toshiba.co.jp + +description: | + Toshiba Visconti AFFINE image processing accelerator provides affine transform, lens undistortion and LUT transform. + Visconti5 have up to 2 AFFINE units. + +properties: + compatible: + items: + - const: toshiba,visconti-affine + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + index: + enum: [0, 1] + +required: + - compatible + - reg + - interrupts + - index + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + + soc { + #address-cells = <2>; + #size-cells = <2>; + affine0: affine@14000000 { + compatible = "toshiba,visconti-affine"; + reg = <0 0x14000000 0 0x8000>; + interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>; + index = <0>; + status = "disabled"; + }; + };
Adds common operations for image processing accelerator drivers including dma-buf control and ioctl definitiion
Signed-off-by: Yuji Ishikawa yuji2.ishikawa@toshiba.co.jp Reviewed-by: Nobuhiro Iwamatsu nobuhiro1.iwamatsu@toshiba.co.jp --- drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/visconti/Kconfig | 1 + drivers/soc/visconti/Makefile | 6 +++ drivers/soc/visconti/ipa_common.c | 55 +++++++++++++++++++ drivers/soc/visconti/ipa_common.h | 19 +++++++ drivers/soc/visconti/uapi/ipa.h | 87 +++++++++++++++++++++++++++++++ 7 files changed, 170 insertions(+) create mode 100644 drivers/soc/visconti/Kconfig create mode 100644 drivers/soc/visconti/Makefile create mode 100644 drivers/soc/visconti/ipa_common.c create mode 100644 drivers/soc/visconti/ipa_common.h create mode 100644 drivers/soc/visconti/uapi/ipa.h
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index e8a30c4c5..c99139aa8 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -22,6 +22,7 @@ source "drivers/soc/tegra/Kconfig" source "drivers/soc/ti/Kconfig" source "drivers/soc/ux500/Kconfig" source "drivers/soc/versatile/Kconfig" +source "drivers/soc/visconti/Kconfig" source "drivers/soc/xilinx/Kconfig"
endmenu diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index a05e9fbcd..455b993c2 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -28,4 +28,5 @@ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-y += ti/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_PLAT_VERSATILE) += versatile/ +obj-$(CONFIG_ARCH_VISCONTI) += visconti/ obj-y += xilinx/ diff --git a/drivers/soc/visconti/Kconfig b/drivers/soc/visconti/Kconfig new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/drivers/soc/visconti/Kconfig @@ -0,0 +1 @@ + diff --git a/drivers/soc/visconti/Makefile b/drivers/soc/visconti/Makefile new file mode 100644 index 000000000..8d710da08 --- /dev/null +++ b/drivers/soc/visconti/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for the Visconti specific device drivers. +# + +obj-y += ipa_common.o diff --git a/drivers/soc/visconti/ipa_common.c b/drivers/soc/visconti/ipa_common.c new file mode 100644 index 000000000..6345f33c5 --- /dev/null +++ b/drivers/soc/visconti/ipa_common.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Toshiba Visconti Image Processing Accelerator Support + * + * (C) Copyright 2022 TOSHIBA CORPORATION + * (C) Copyright 2022 Toshiba Electronic Devices & Storage Corporation + */ + +#include "ipa_common.h" + +int ipa_attach_dmabuf(struct device *dev, int fd, struct dma_buf_attachment **a, + struct sg_table **s, dma_addr_t *addr, enum dma_data_direction dma_dir) +{ + struct dma_buf_attachment *attachment; + struct dma_buf *dmabuf; + struct sg_table *sgt; + int ret; + + dmabuf = dma_buf_get(fd); + if (IS_ERR(dmabuf)) { + dev_err(dev, "Invalid dmabuf FD\n"); + return PTR_ERR(dmabuf); + } + attachment = dma_buf_attach(dmabuf, dev); + + if (IS_ERR(attachment)) { + dev_err(dev, "Failed to attach dmabuf\n"); + ret = PTR_ERR(attachment); + goto err_put; + } + sgt = dma_buf_map_attachment(attachment, dma_dir); + if (IS_ERR(sgt)) { + dev_err(dev, "Failed to get dmabufs sg_table\n"); + ret = PTR_ERR(sgt); + goto err_detach; + } + if (sgt->nents != 1) { + dev_err(dev, "Sparse DMA region is unsupported\n"); + ret = -EINVAL; + goto err_unmap; + } + + *addr = sg_dma_address(sgt->sgl); + *a = attachment; + *s = sgt; + + return 0; + +err_unmap: + dma_buf_unmap_attachment(attachment, sgt, dma_dir); +err_detach: + dma_buf_detach(dmabuf, attachment); +err_put: + dma_buf_put(dmabuf); + return ret; +} diff --git a/drivers/soc/visconti/ipa_common.h b/drivers/soc/visconti/ipa_common.h new file mode 100644 index 000000000..2c3b64837 --- /dev/null +++ b/drivers/soc/visconti/ipa_common.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Toshiba Visconti Image Processing Accelerator Support + * + * (C) Copyright 2022 TOSHIBA CORPORATION + * (C) Copyright 2022 Toshiba Electronic Devices & Storage Corporation + */ + +#include <linux/dma-mapping.h> +#include <linux/dma-buf.h> + +#define COHERENT_ADDRESS_BIT (0x400000000ULL) +#define IPA_POLL_EVENT_NONE (0) +#define IPA_POLL_EVENT_DONE (1) +#define IPA_POLL_EVENT_ERROR (2) +#define IPA_WAKEUP_RETRY_DELAY (300 * 1000) /*usec*/ + +extern int ipa_attach_dmabuf(struct device *dev, int fd, struct dma_buf_attachment **a, + struct sg_table **s, dma_addr_t *addr, + enum dma_data_direction dma_dir); diff --git a/drivers/soc/visconti/uapi/ipa.h b/drivers/soc/visconti/uapi/ipa.h new file mode 100644 index 000000000..f3a066648 --- /dev/null +++ b/drivers/soc/visconti/uapi/ipa.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * (C) Copyright 2020 Toshiba Electronic Devices & Storage Corporation + */ + +#ifndef _UAPI_LINUX_IPA_H +#define _UAPI_LINUX_IPA_H + +/** + * enum drv_ipa_state - state of Visconti IPA driver + * + * @DRV_IPA_STATE_IDLE: driver is idle + * @DRV_IPA_STATE_BUSY: device is busy + */ +enum drv_ipa_state { DRV_IPA_STATE_IDLE = 0, DRV_IPA_STATE_BUSY }; + +/** + * enum drv_ipa_buffer_direction - usage of buffer + * + * @DRV_IPA_DIR_BIDIRECTION: cpu writes/reads data + * @DRV_IPA_DIR_TO_DEVICE: cpu writes data + * @DRV_IPA_DIR_FROM_DEVICE: cpu reads data + * @DRV_IPA_DIR_NONE: cpu not access or non-coherent + */ +enum drv_ipa_buffer_direction { + DRV_IPA_DIR_BIDIRECTION = 0, + DRV_IPA_DIR_TO_DEVICE, + DRV_IPA_DIR_FROM_DEVICE, + DRV_IPA_DIR_NONE +}; + +/** + * struct drv_ipa_buffer_info - buffer information for Visconti IPA drivers + * + * @fd: file descriptor of Ion allocated heap + * @coherent: allocated via coherent bus or not + * @direction: buffer direction (to/from device) + * + * note: When the Ion heap is allocated wit ION_FLAG_CACHED, + * &struct drv_ipa_buffer_info.coherent should be true. + * Else, it should be false. + */ +struct drv_ipa_buffer_info { + uint32_t fd; + bool coherent; + enum drv_ipa_buffer_direction direction; +}; + +/** + * struct drv_ipa_addr - address structure for Visconti IPA drivers + * + * @buffer_index: array index of &struct drv_ipa_buffer_info + * @offset: offset from the top of Ion heap + */ +struct drv_ipa_addr { + uint32_t buffer_index : 4; + uint32_t offset : 28; +}; + +#define IPA_BUFFER_INDEX_MAX (16) +#define IPA_INVALID_ADDR \ + { \ + .buffer_index = 0xfu, .offset = 0xfffffffu \ + } + +static inline struct drv_ipa_addr drv_ipa_invalid_addr(void) +{ + struct drv_ipa_addr invalid_addr = IPA_INVALID_ADDR; + return invalid_addr; +} + +static inline bool drv_ipa_is_invalid_addr(struct drv_ipa_addr addr) +{ + struct drv_ipa_addr invalid_addr = IPA_INVALID_ADDR; + + if ((addr.buffer_index == invalid_addr.buffer_index) && + (addr.offset == invalid_addr.offset)) { + return true; + } + return false; +} + +#define IOC_IPA_MAGIC 'I' +#define IOC_IPA_START _IO(IOC_IPA_MAGIC, 0) +#define IOC_IPA_GET_STATUS _IO(IOC_IPA_MAGIC, 1) + +#endif /* _UAPI_LINUX_IPA_H */
Adds support to AFFINE image processing accelerator on Toshiba Visconti ARM SoCs. This accelerator supoorts affine transform, lens undistortion and LUT transform.
Signed-off-by: Yuji Ishikawa yuji2.ishikawa@toshiba.co.jp Reviewed-by: Nobuhiro Iwamatsu nobuhiro1.iwamatsu@toshiba.co.jp --- drivers/soc/visconti/Kconfig | 6 + drivers/soc/visconti/Makefile | 2 + drivers/soc/visconti/affine/Makefile | 6 + drivers/soc/visconti/affine/affine.c | 451 +++++++++++++++++++ drivers/soc/visconti/affine/hwd_affine.c | 207 +++++++++ drivers/soc/visconti/affine/hwd_affine.h | 83 ++++ drivers/soc/visconti/affine/hwd_affine_reg.h | 45 ++ drivers/soc/visconti/uapi/affine.h | 87 ++++ 8 files changed, 887 insertions(+) create mode 100644 drivers/soc/visconti/affine/Makefile create mode 100644 drivers/soc/visconti/affine/affine.c create mode 100644 drivers/soc/visconti/affine/hwd_affine.c create mode 100644 drivers/soc/visconti/affine/hwd_affine.h create mode 100644 drivers/soc/visconti/affine/hwd_affine_reg.h create mode 100644 drivers/soc/visconti/uapi/affine.h
diff --git a/drivers/soc/visconti/Kconfig b/drivers/soc/visconti/Kconfig index 8b1378917..01583d407 100644 --- a/drivers/soc/visconti/Kconfig +++ b/drivers/soc/visconti/Kconfig @@ -1 +1,7 @@ +if ARCH_VISCONTI + +config VISCONTI_AFFINE + bool "Visconti Affine driver" + +endif
diff --git a/drivers/soc/visconti/Makefile b/drivers/soc/visconti/Makefile index 8d710da08..b25a726c3 100644 --- a/drivers/soc/visconti/Makefile +++ b/drivers/soc/visconti/Makefile @@ -4,3 +4,5 @@ #
obj-y += ipa_common.o + +obj-$(CONFIG_VISCONTI_AFFINE) += affine/ diff --git a/drivers/soc/visconti/affine/Makefile b/drivers/soc/visconti/affine/Makefile new file mode 100644 index 000000000..82f83b2d6 --- /dev/null +++ b/drivers/soc/visconti/affine/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for the Visconti AFFINE driver +# + +obj-y += affine.o hwd_affine.o diff --git a/drivers/soc/visconti/affine/affine.c b/drivers/soc/visconti/affine/affine.c new file mode 100644 index 000000000..3b31e41c8 --- /dev/null +++ b/drivers/soc/visconti/affine/affine.c @@ -0,0 +1,451 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Toshiba Visconti Affine Accelerator Support + * + * (C) Copyright 2022 TOSHIBA CORPORATION + * (C) Copyright 2022 Toshiba Electronic Devices & Storage Corporation + */ + +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/iommu.h> +#include <linux/kernel.h> +#include <linux/miscdevice.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/poll.h> +#include <linux/wait.h> + +#include "hwd_affine.h" +#include "../ipa_common.h" +#include "../uapi/affine.h" + +struct affine_priv { + struct device *dev; + struct miscdevice miscdev; + struct mutex lock; + void __iomem *regs; + int irq; + wait_queue_head_t waitq; + enum drv_ipa_state status; + unsigned int hwd_event; + unsigned int poll_event; + int id; + char name[16]; + bool dma_coherent; + struct hwd_affine_status hwd_status; + + struct dma_buf_attachment *dba[DRV_AFFINE_BUFFER_INDEX_MAX]; + struct sg_table *sgt[DRV_AFFINE_BUFFER_INDEX_MAX]; + enum dma_data_direction dma_dir[DRV_AFFINE_BUFFER_INDEX_MAX]; + unsigned int dma_count; + + dma_addr_t buffer_iova[DRV_AFFINE_BUFFER_INDEX_MAX]; +}; + +static uint32_t affine_ipa_addr_to_iova(struct affine_priv *priv, struct drv_ipa_addr addr) +{ + uint32_t iova = 0; + + if ((addr.buffer_index < priv->dma_count) && + (addr.offset < priv->dba[addr.buffer_index]->dmabuf->size)) + iova = priv->buffer_iova[addr.buffer_index] + addr.offset; + return iova; +} + +static int affine_attach_dma_buf(struct affine_priv *priv, unsigned int buffer_index, + struct drv_ipa_buffer_info *buffer_info) +{ + int ret = 0; + dma_addr_t addr; + + if (buffer_index >= DRV_AFFINE_BUFFER_INDEX_MAX) { + dev_err(priv->dev, "Buffer index invalid: index=%d\n", buffer_index); + return -EINVAL; + } + + switch (buffer_info[buffer_index].direction) { + case DRV_IPA_DIR_NONE: + priv->dma_dir[priv->dma_count] = DMA_NONE; + break; + case DRV_IPA_DIR_TO_DEVICE: + priv->dma_dir[priv->dma_count] = DMA_TO_DEVICE; + break; + case DRV_IPA_DIR_FROM_DEVICE: + priv->dma_dir[priv->dma_count] = DMA_FROM_DEVICE; + break; + case DRV_IPA_DIR_BIDIRECTION: + priv->dma_dir[priv->dma_count] = DMA_BIDIRECTIONAL; + break; + default: + dev_err(priv->dev, "DMA direction invalid: index=%d dir=%d\n", buffer_index, + buffer_info[buffer_index].direction); + return -EINVAL; + } + + if (buffer_info[buffer_index].coherent == false) { + priv->dev->dma_coherent = false; + if (priv->dma_coherent == true) + priv->dma_dir[priv->dma_count] = DMA_NONE; + } + + ret = ipa_attach_dmabuf(priv->dev, buffer_info[buffer_index].fd, + &priv->dba[priv->dma_count], &priv->sgt[priv->dma_count], &addr, + priv->dma_dir[priv->dma_count]); + if (ret == 0) { + priv->dma_count++; + priv->buffer_iova[buffer_index] = addr; + } + + priv->dev->dma_coherent = priv->dma_coherent; + + return ret; +} + +static void affine_detach_dma_buf(struct affine_priv *priv) +{ + struct dma_buf *dmabuf; + int i; + + for (i = 0; i < priv->dma_count; i++) { + dmabuf = priv->dba[i]->dmabuf; + dma_buf_unmap_attachment(priv->dba[i], priv->sgt[i], priv->dma_dir[i]); + dma_buf_detach(dmabuf, priv->dba[i]); + dma_buf_put(dmabuf); + } +} + +static irqreturn_t affine_irq(int irq, void *dev_id) +{ + struct affine_priv *priv = dev_id; + + priv->hwd_event = hwd_AFFINE_irq_handler(priv->id); + + disable_irq_nosync(priv->irq); + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t affine_irq_thread(int irq, void *dev_id) +{ + struct affine_priv *priv = dev_id; + unsigned long delay = 1; + + mutex_lock(&priv->lock); + affine_detach_dma_buf(priv); + + hwd_AFFINE_get_status(priv->id, &priv->hwd_status); + + priv->status = DRV_IPA_STATE_IDLE; + + /* status should be updated before poll_event so that + * when poll() returns, user context must observe state as idle + */ + smp_wmb(); + + if (priv->hwd_event == HWD_AFFINE_EVENT_DONE) + priv->poll_event = IPA_POLL_EVENT_DONE; + else + priv->poll_event = IPA_POLL_EVENT_ERROR; + + /* General barrier to avoid re-ordering of priv->poll_event=N and + * waitqueue_active() + */ + smp_mb(); + + /* Threads going to sleep in poll() can miss wakeup, when wakeup is done + * between event check in ipa_poll() and sleeping. Wakeup repeatedly. + */ + while (waitqueue_active(&priv->waitq)) { + wake_up_interruptible(&priv->waitq); + + WARN_ON(delay > IPA_WAKEUP_RETRY_DELAY); + usleep_range(delay, delay + 1); + delay += delay; + } + + mutex_unlock(&priv->lock); + + return IRQ_HANDLED; +} + +static void affine_start(struct affine_priv *priv, struct hwd_affine_descriptor *desc) +{ + hwd_AFFINE_start(priv->id, desc); +} + +static int affine_ioctl_start(struct affine_priv *priv, unsigned long arg) +{ + struct hwd_affine_descriptor hwd_desc; + struct drv_affine_descriptor desc; + int ret = 0; + int i; + + ret = mutex_lock_interruptible(&priv->lock); + if (ret) + return ret; + + if (priv->status == DRV_IPA_STATE_BUSY) { + dev_dbg(priv->dev, "busy: %d\n", priv->status); + ret = -EBUSY; + goto err1; + } + + if (copy_from_user(&desc, (void __user *)arg, sizeof(struct drv_affine_descriptor))) { + dev_err(priv->dev, "Descriptor memory access error\n"); + ret = -EFAULT; + goto err1; + } + + if (DRV_AFFINE_BIT_CONFIG_DESC_FINAL != + (desc.config_done & DRV_AFFINE_BIT_CONFIG_DESC_FINAL)) { + dev_err(priv->dev, "Descriptor configuration not complete\n"); + ret = -EINVAL; + goto err1; + } + + priv->dma_count = 0; + + /* setup buffer */ + for (i = 0; i < desc.buffer_info_num; i++) { + ret = affine_attach_dma_buf(priv, i, desc.buffer_info); + if (ret) { + dev_err(priv->dev, "dma buf attach error: index=%d\n", i); + goto err2; + } + dev_dbg(priv->dev, "@buffer[%d]@: fd=%d %s iova=%llx\n", i, desc.buffer_info[i].fd, + (desc.buffer_info[i].coherent == true) ? "coherent" : "non-coherent", + (uint64_t)priv->buffer_iova[i]); + } + + memcpy(&hwd_desc, &desc, sizeof(struct hwd_affine_descriptor)); + + hwd_desc.src_addr = affine_ipa_addr_to_iova(priv, desc.src_addr); + if (hwd_desc.src_addr == 0) { + dev_err(priv->dev, "IPA address to iova conversion error: src_addr %s: %d\n", + __func__, __LINE__); + ret = -EINVAL; + goto err2; + } + + hwd_desc.dst_addr = affine_ipa_addr_to_iova(priv, desc.dst_addr); + if (hwd_desc.dst_addr == 0) { + dev_err(priv->dev, "IPA address to iova conversion error: dst_addr %s: %d\n", + __func__, __LINE__); + ret = -EINVAL; + goto err2; + } + + hwd_desc.tbl_addr = 0; + if (desc.tbl_ptch != 0) { + hwd_desc.tbl_addr = affine_ipa_addr_to_iova(priv, desc.tbl_addr); + if (hwd_desc.tbl_addr == 0) { + dev_err(priv->dev, + "IPA address to iova conversion error: tbl_addr %s: %d\n", __func__, + __LINE__); + ret = -EINVAL; + goto err2; + } + } + + dev_dbg(priv->dev, "src: 0x%x\n", hwd_desc.src_addr); + dev_dbg(priv->dev, "dst: 0x%x\n", hwd_desc.dst_addr); + dev_dbg(priv->dev, "tbl: 0x%x\n", hwd_desc.tbl_addr); + + affine_start(priv, &hwd_desc); + + priv->poll_event = IPA_POLL_EVENT_NONE; + priv->hwd_event = 0; + priv->status = DRV_IPA_STATE_BUSY; + /* Barrier to prevent affine_irq() from setting priv->hwd_event + * before it is reset above + */ + smp_wmb(); + enable_irq(priv->irq); + + mutex_unlock(&priv->lock); + + return ret; + +err2: + affine_detach_dma_buf(priv); +err1: + mutex_unlock(&priv->lock); + return ret; +} + +static int affine_ioctl_get_status(struct affine_priv *priv, unsigned long arg) +{ + struct drv_affine_status status; + struct hwd_affine_status hwd_status; + int ret = 0; + + ret = mutex_lock_interruptible(&priv->lock); + if (ret) + return ret; + + if (priv->status == DRV_IPA_STATE_BUSY) + hwd_AFFINE_get_status(priv->id, &hwd_status); + else + hwd_status = priv->hwd_status; + + status.state = priv->status; + mutex_unlock(&priv->lock); + + status.comp_lack_data = hwd_status.comp_lack_data; + status.comp_over_coordinate = hwd_status.comp_over_coordinate; + status.comp_over_data = hwd_status.comp_over_data; + status.comp_size = hwd_status.comp_size; + status.comp_syntax_error = hwd_status.comp_syntax_error; + if (copy_to_user((void __user *)arg, &status, sizeof(struct drv_affine_status))) { + dev_err(priv->dev, "status memory access error\n"); + ret = -EFAULT; + } + + return ret; +} + +static long affine_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) +{ + struct affine_priv *priv = container_of(fp->private_data, struct affine_priv, miscdev); + int ret = 0; + + switch (cmd) { + case IOC_IPA_START: + ret = affine_ioctl_start(priv, arg); + break; + case IOC_IPA_GET_STATUS: + ret = affine_ioctl_get_status(priv, arg); + break; + default: + ret = -ENOIOCTLCMD; + break; + } + + return ret; +} + +static __poll_t affine_poll(struct file *fp, poll_table *wait) +{ + struct affine_priv *priv = container_of(fp->private_data, struct affine_priv, miscdev); + __poll_t mask = 0; + unsigned int poll_event; + + poll_wait(fp, &priv->waitq, wait); + + /* Barrier to avoid re-ordering of poll_wait() and event load + * Read barrier here and release barrier in poll_wait() together will + * prevent re-ordering + */ + smp_rmb(); + poll_event = priv->poll_event; + if (poll_event != IPA_POLL_EVENT_NONE) { + if (poll_event == IPA_POLL_EVENT_DONE) + mask = EPOLLIN | EPOLLRDNORM; + else + mask = EPOLLERR; + } + return mask; +} + +static const struct file_operations affine_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = affine_ioctl, + .poll = affine_poll, +}; + +static int affine_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct affine_priv *priv; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + mutex_init(&priv->lock); + + /* update DMA mask */ + priv->dma_coherent = dev->dma_coherent; + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36)); + if (ret) + return ret; + + priv->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->regs)) + return PTR_ERR(priv->regs); + + priv->irq = platform_get_irq(pdev, 0); + if (priv->irq < 0) { + dev_err(dev, "failed to acquire irq resource\n"); + return -ENOENT; + } + ret = devm_request_threaded_irq(dev, priv->irq, affine_irq, affine_irq_thread, 0, "affine", + priv); + if (ret) { + dev_err(dev, "irq request failed\n"); + return ret; + } + disable_irq(priv->irq); + + ret = of_property_read_u32(dev->of_node, "index", &priv->id); + if (ret) { + dev_err(dev, "failed to acquire irq resource\n"); + return ret; + } + + hwd_AFFINE_initialize(priv->id, priv->regs); + + snprintf(priv->name, sizeof(priv->name), "affine%d", priv->id); + priv->miscdev.minor = MISC_DYNAMIC_MINOR; + priv->miscdev.name = priv->name; + priv->miscdev.fops = &affine_fops; + ret = misc_register(&priv->miscdev); + if (ret) { + dev_err(dev, "misc registration failed\n"); + hwd_AFFINE_uninitialize(priv->id); + return ret; + } + + priv->dev = dev; + platform_set_drvdata(pdev, priv); + + init_waitqueue_head(&priv->waitq); + + priv->status = DRV_IPA_STATE_IDLE; + return 0; +} + +static int affine_remove(struct platform_device *pdev) +{ + struct affine_priv *priv = platform_get_drvdata(pdev); + + misc_deregister(&priv->miscdev); + hwd_AFFINE_uninitialize(priv->id); + return 0; +} + +static const struct of_device_id affine_of_match[] = { + { + .compatible = "toshiba,visconti-affine", + }, + {}, +}; +MODULE_DEVICE_TABLE(platform, affine_of_match); + +static struct platform_driver affine_driver = { + .probe = affine_probe, + .remove = affine_remove, + .driver = { + .name = "visconti_affine", + .of_match_table = of_match_ptr(affine_of_match), + }, +}; +module_platform_driver(affine_driver); + +MODULE_AUTHOR("Yuji Ishikawa yuji2.ishikawa@toshiba.co.jp"); +MODULE_DESCRIPTION("Toshiba Visconti affine driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/soc/visconti/affine/hwd_affine.c b/drivers/soc/visconti/affine/hwd_affine.c new file mode 100644 index 000000000..3f077d904 --- /dev/null +++ b/drivers/soc/visconti/affine/hwd_affine.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Toshiba Visconti Affine Accelerator Support + * + * (C) Copyright 2022 TOSHIBA CORPORATION + * (C) Copyright 2022 Toshiba Electronic Devices & Storage Corporation + */ + +#include <linux/delay.h> +#include <linux/io.h> + +#include "hwd_affine.h" +#include "hwd_affine_reg.h" + +#define HWD_AFFINE_CLEAR_BITS GENMASK(15, 0) +#define HWD_AFFINE_INTMASK_NORMAL (0x04100) + +#define HWD_AFFINE_INT_END BIT(0) +#define HWD_AFFINE_INT_TCOMP_ERR0 BIT(16) +#define HWD_AFFINE_INT_TCOMP_ERR1 BIT(17) +#define HWD_AFFINE_INT_TCOMP_ERR2 BIT(18) +#define HWD_AFFINE_INT_TCOMP_ERR3 BIT(19) +#define HWD_AFFINE_INT_TCOMP_SIZE BIT(20) + +#define HWD_AFFINE_HWD_MASK_ADDR GENMASK(31, 0) + +#define HWD_AFFINE_START_CMD BIT(0) + +/** + * struct hwd_affine_resources - HWD driver internal resource structure + */ +struct hwd_affine_resources { + struct hwd_affine_reg *reg; + struct hwd_affine_status status; +}; + +/* HWD driver internal resource */ +static struct hwd_affine_resources hwd_AFFINE_resources[HWD_AFFINE_DEVICE_MAX] = {}; + +/** + * hwd_AFFINE_initialize() - Initialize AFFINE device + * + * @module_id: @ref hwd_affine_device "id" of the h/w module + * @vaddr: register base virtual address + */ +void hwd_AFFINE_initialize(uint32_t module_id, void *vaddr) +{ + struct hwd_affine_resources *res = &hwd_AFFINE_resources[module_id]; + + /* Initialize the device */ + res->reg = (struct hwd_affine_reg *)vaddr; +} + +/** + * hwd_AFFINE_uninitialize() - Uninitialize AFFINE device + * + * @module_id: @ref hwd_affine_device "id" of the h/w module + */ +void hwd_AFFINE_uninitialize(uint32_t module_id) +{ + struct hwd_affine_resources *res = &hwd_AFFINE_resources[module_id]; + + /* Deinitialize the device */ + res->reg = NULL; +} + +#define NUM_AFFINE_PARAMS 6 +#define NUM_HOMO_PARAMS 3 +#define NUM_DISTORT_PARAMS 12 + +/** + * hwd_AFFINE_start() - Start AFFINE device + * + * @module_id: @ref hwd_affine_device "id" of the h/w module + * @desc: Pointer to AFFINE descriptor structure + */ +void hwd_AFFINE_start(uint32_t module_id, const struct hwd_affine_descriptor *desc) +{ + struct hwd_affine_resources *res = &hwd_AFFINE_resources[module_id]; + struct hwd_affine_reg *reg; + int i; + + reg = res->reg; + + /* Initialize status */ + res->status.comp_syntax_error = 0; + res->status.comp_over_coordinate = 0; + res->status.comp_over_data = 0; + res->status.comp_lack_data = 0; + res->status.comp_size = 0; + + /* Clear interrupt status */ + writel(HWD_AFFINE_CLEAR_BITS, &(reg->statc)); + + /* Reset T_RST bit, C_RST bit, and O_RST bits*/ + writel(desc->ctrl, &(reg->ctrl)); + readl(&(reg->ctrl)); + + writel(desc->src_size, &(reg->src_size)); + writel((uint32_t)(desc->src_addr & HWD_AFFINE_HWD_MASK_ADDR), &(reg->src_addr)); + writel(desc->dst_bgn, &(reg->dst_bgn)); + writel(desc->dst_size, &(reg->dst_size)); + writel((uint32_t)(desc->dst_addr & HWD_AFFINE_HWD_MASK_ADDR), &(reg->dst_addr)); + writel(desc->l_ptch, &(reg->l_ptch)); + + for (i = 0; i < NUM_AFFINE_PARAMS; i++) + writel(desc->affine_param[i], &(reg->affine_param[i])); + + for (i = 0; i < NUM_HOMO_PARAMS; i++) + writel(desc->homo_param[i], &(reg->homo_param[i])); + + /* AFFINE Table */ + writel((uint32_t)(desc->tbl_addr & HWD_AFFINE_HWD_MASK_ADDR), &(reg->tbl_addr)); + writel(desc->tbl_ptch, &(reg->tbl_ptch)); + writel(desc->tbl_comp_size, &(reg->tbl_comp_size)); + + for (i = 0; i < NUM_DISTORT_PARAMS; i++) + writel(desc->dist_param[i], &(reg->dist_param[i])); + + writel(HWD_AFFINE_INTMASK_NORMAL, &(reg->intm)); + + writel(desc->mode, &(reg->mode)); + writel(desc->mode2, &(reg->mode2)); + writel(desc->adj_p, &(reg->adj_p)); + + /* Data Sync */ + dsb(st); + + /* Kick AFFINE */ + writel(HWD_AFFINE_START_CMD, &(reg->ctrl)); +} + +/** + * hwd_AFFINE_irq_handler() - HWD AFFINE interrupt handler + * + * @module_id: @ref hwd_affine_device "id" of the h/w module + * Return: HWD_AFFINE_EVENT_DONE Bit field saying HW processing is completed + * Return: HWD_AFFINE_EVENT_SYNTAX_ERROR Bit field saying HW Table Syntax error + * Return: HWD_AFFINE_EVENT_OVER_COORD Bit field saying HW Table decoding coordinate error + * Return: HWD_AFFINE_EVENT_OVER_DATA Bit field saying HW Table over compressed data error + * Return: HWD_AFFINE_EVENT_LACK_DATA Bit field saying HW Table compressed data insufficient error + * Return: HWD_AFFINE_EVENT_SIZE_ERROR Bit field saying HW Table smaller than the size actual size of compressed data + */ +uint32_t hwd_AFFINE_irq_handler(uint32_t module_id) +{ + uint32_t event = 0; + struct hwd_affine_resources *res = &hwd_AFFINE_resources[module_id]; + struct hwd_affine_reg *reg; + uint32_t IntCause; + + reg = res->reg; + + /* Read the interrupt causes */ + IntCause = readl(&(reg->statc)); + + /* Clear the interrupt causes */ + writel(IntCause, &(reg->statc)); + + /* Check Execution End */ + if (IntCause & HWD_AFFINE_INT_END) + event |= HWD_AFFINE_EVENT_DONE; + + if (IntCause & HWD_AFFINE_INT_TCOMP_ERR0) { + /* Syntax error */ + res->status.comp_syntax_error = 1; + event |= HWD_AFFINE_EVENT_SYNTAX_ERROR; + } + + if (IntCause & HWD_AFFINE_INT_TCOMP_ERR1) { + /* Decoding coordinate error */ + res->status.comp_over_coordinate = 1; + event |= HWD_AFFINE_EVENT_OVER_COORD; + } + + if (IntCause & HWD_AFFINE_INT_TCOMP_ERR2) { + /* Over compressed data error */ + res->status.comp_over_data = 1; + event |= HWD_AFFINE_EVENT_OVER_DATA; + } + + if (IntCause & HWD_AFFINE_INT_TCOMP_ERR3) { + /* Compressed data insufficient error */ + res->status.comp_lack_data = 1; + event |= HWD_AFFINE_EVENT_LACK_DATA; + } + + if (IntCause & HWD_AFFINE_INT_TCOMP_SIZE) { + /* Smaller than the actual size of compressed data */ + res->status.comp_size = 1; + event |= HWD_AFFINE_EVENT_SIZE_ERROR; + } + + return event; +} + +/** + * hwd_AFFINE_get_status() - HWD AFFINE Get Status + * + * @module_id: @ref hwd_affine_device "id" of the h/w module + * @status: Pointer to status structure + * Return: RETURN_OK operation completed successfully + */ +void hwd_AFFINE_get_status(uint32_t module_id, struct hwd_affine_status *status) +{ + const struct hwd_affine_resources *res = &hwd_AFFINE_resources[module_id]; + + *status = res->status; +} diff --git a/drivers/soc/visconti/affine/hwd_affine.h b/drivers/soc/visconti/affine/hwd_affine.h new file mode 100644 index 000000000..91f17dca5 --- /dev/null +++ b/drivers/soc/visconti/affine/hwd_affine.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Toshiba Visconti Affine Accelerator Support + * + * (C) Copyright 2022 TOSHIBA CORPORATION + * (C) Copyright 2022 Toshiba Electronic Devices & Storage Corporation + */ + +#ifndef HWD_AFFINE_H +#define HWD_AFFINE_H + +/** + * enum hwd_affine_device_id - AFFINE HWD Device ID + */ +enum hwd_affine_device_id { + HWD_AFFINE_DEVICE_0 = 0, + HWD_AFFINE_DEVICE_1 = 1, + HWD_AFFINE_DEVICE_MAX = 2, +}; + +/* hwd_AFFINE_event_flags - Macro for Affine driver events */ +#define HWD_AFFINE_EVENT_DONE BIT(0) +#define HWD_AFFINE_EVENT_SYNTAX_ERROR BIT(1) +#define HWD_AFFINE_EVENT_OVER_COORD BIT(2) +#define HWD_AFFINE_EVENT_OVER_DATA BIT(3) +#define HWD_AFFINE_EVENT_LACK_DATA BIT(4) +#define HWD_AFFINE_EVENT_SIZE_ERROR BIT(5) +#define HWD_AFFINE_EVENT_MAX BIT(6) + +/* hwd_AFFINE_param_num_flags Macro for Affine parameter number */ +#define HWD_AFFINE_AFFINE_PARAM_NUM (6U) +#define HWD_AFFINE_UNDIST_PARAM_NUM (12U) +#define HWD_AFFINE_HOMO_PARAM_NUM (3U) +#define HWD_AFFINE_TEMP_UNDIST_PARAM_NUM (10U) + +/** + * struct hwd_affine_status - HWD Affine status + * @comp_size: Setting size is smaller than actual size + * @comp_lack_data: Compressed table is lacking enough data for processing + * @comp_over_data: Compressed table is exceeding the limit of data that can be processed + * @comp_over_coordinate: Number of coordinates in compressed table data exceeded the limit + * @comp_syntax_error: Syntax error of compressed table has occurred + * @reserved: Padding + */ +struct hwd_affine_status { + uint32_t comp_size : 1; + uint32_t comp_lack_data : 1; + uint32_t comp_over_data : 1; + uint32_t comp_over_coordinate : 1; + uint32_t comp_syntax_error : 1; + uint32_t reserved : 27; +}; + +/** + * struct hwd_affine_descriptor - HWD AFFINE Descriptor + */ +struct hwd_affine_descriptor { + uint32_t ctrl; + uint32_t mode2; + uint32_t mode; + uint32_t adj_p; + uint32_t src_size; + uint32_t src_addr; + uint32_t dst_bgn; + uint32_t dst_size; + uint32_t dst_addr; + uint32_t l_ptch; + uint32_t tbl_addr; + uint32_t tbl_ptch; + uint32_t affine_param[HWD_AFFINE_AFFINE_PARAM_NUM]; + uint32_t dist_param[HWD_AFFINE_UNDIST_PARAM_NUM]; + uint32_t homo_param[HWD_AFFINE_HOMO_PARAM_NUM]; + uint32_t tbl_comp_size; + float temp_dist_p[HWD_AFFINE_TEMP_UNDIST_PARAM_NUM]; + uint16_t config_done; +}; + +void hwd_AFFINE_initialize(uint32_t module_id, void *vaddr); +void hwd_AFFINE_uninitialize(uint32_t module_id); +void hwd_AFFINE_start(uint32_t module_id, const struct hwd_affine_descriptor *desc); +uint32_t hwd_AFFINE_irq_handler(uint32_t module_id); +void hwd_AFFINE_get_status(uint32_t module_id, struct hwd_affine_status *status); + +#endif /* HWD_AFFINE_H */ diff --git a/drivers/soc/visconti/affine/hwd_affine_reg.h b/drivers/soc/visconti/affine/hwd_affine_reg.h new file mode 100644 index 000000000..998c442aa --- /dev/null +++ b/drivers/soc/visconti/affine/hwd_affine_reg.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Toshiba Visconti Affine Accelerator Support + * + * (C) Copyright 2022 TOSHIBA CORPORATION + * (C) Copyright 2022 Toshiba Electronic Devices & Storage Corporation + */ + +#ifndef HWD_AFFINE_REG_H +#define HWD_AFFINE_REG_H + +/* hwd_AFFINE_params_num_flags - Macro for Affine parameter number */ +#define HWD_AFFINE_AFFINE_PARAMS_NUM (6) +#define HWD_AFFINE_UNDIST_PARAMS_NUM (12) +#define HWD_AFFINE_HOMO_PARAMS_NUM (3) +#define HWD_AFFINE_RESERVED (472) + +/** + * struct hwd_affine_reg - Structure of Affine register descriptor + */ +struct hwd_affine_reg { + uint32_t ctrl; + uint32_t reserved0[2]; + uint32_t mode2; + uint32_t mode; + uint32_t adj_p; + uint32_t intm; + uint32_t statc; + uint32_t out_lpos; + uint32_t src_size; + uint32_t src_addr; + uint32_t dst_bgn; + uint32_t dst_size; + uint32_t dst_addr; + uint32_t l_ptch; + uint32_t tbl_addr; + uint32_t tbl_ptch; + uint32_t affine_param[HWD_AFFINE_AFFINE_PARAMS_NUM]; + uint32_t dist_param[HWD_AFFINE_UNDIST_PARAMS_NUM]; + uint32_t reserved1; + uint32_t homo_param[HWD_AFFINE_HOMO_PARAMS_NUM]; + uint32_t tbl_comp_size; + uint32_t reserved2[HWD_AFFINE_RESERVED]; +}; + +#endif /* HWD_AFFINE_REG_H */ diff --git a/drivers/soc/visconti/uapi/affine.h b/drivers/soc/visconti/uapi/affine.h new file mode 100644 index 000000000..539261483 --- /dev/null +++ b/drivers/soc/visconti/uapi/affine.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * (C) Copyright 2020 Toshiba Electronic Devices & Storage Corporation + */ + +#ifndef _UAPI_LINUX_AFIINE_H +#define _UAPI_LINUX_AFIINE_H + +#include <linux/ioctl.h> +#include <linux/types.h> +#include "ipa.h" + +#define DRV_AFFINE_BIT_CONFIG_DESC_FINAL (0x8000U) +#define DRV_AFFINE_BUFFER_INDEX_MAX (3) + +#define DRV_AFFINE_AFFINE_PARAM_NUM (6U) +#define DRV_AFFINE_UNDIST_PARAM_NUM (12U) +#define DRV_AFFINE_HOMO_PARAM_NUM (3U) +#define DRV_AFFINE_TEMP_UNDIST_PARAM_NUM (10U) + +/** + * struct drv_affine_status - AFFINE IPA status for IOC_IPA_GET_STATUS + * @state: State of driver + * @comp_size: Setting size is smaller than actual size + * @comp_lack_data: Compressed table is lacking enough data for processing + * @comp_over_data: Compressed table is exceeding the limit of data that can be processed + * @comp_over_coordinate: Number of coordinates in compressed table data exceeded the limit + * @comp_syntax_error: Syntax error of compressed table has occurred + * @reserved: Padding + */ +struct drv_affine_status { + enum drv_ipa_state state; + uint32_t comp_size : 1; + uint32_t comp_lack_data : 1; + uint32_t comp_over_data : 1; + uint32_t comp_over_coordinate : 1; + uint32_t comp_syntax_error : 1; + uint32_t reserved : 27; +}; + +/** + * struct drv_affine_descriptor - AFFINE IPA descriptor for IOC_IPA_START + * @ctrl: Operation control of AFFINE + * @mode2: Operation mode for the AFFINE execution + * @mode: Operation mode for the AFFINE execution + * @adj_p: Output Pixel Value Adjustment + * @src_size: Input image size + * @src_addr: Start address of input image + * @dst_bgn: Start coordinate of the output rectangle area + * @dst_size: Size of the output rectangle area + * @dst_addr: Address of the output rectangle area + * @l_ptch: Line pitch of both the input image and output rectangle area + * @tbl_addr: Start address of the table used in the table conversion mode. + * @tbl_ptch: Line pitch of the table used in the table conversion mode + * @affine_param: Parameters for Affine transformation + * @dist_param: Parameters for Distortion correction + * @homo_param: Parameters Homography transformation + * @tbl_comp_size: Table compression size + * @temp_dist_p: Temporary buffer to hold distortion input parameters + * @config_done: Flags of called configuration + * @buffer_info: Table of buffer information + * @buffer_info_num: Number of buffer_info + */ +struct drv_affine_descriptor { + uint32_t ctrl; + uint32_t mode2; + uint32_t mode; + uint32_t adj_p; + uint32_t src_size; + struct drv_ipa_addr src_addr; + uint32_t dst_bgn; + uint32_t dst_size; + struct drv_ipa_addr dst_addr; + uint32_t l_ptch; + struct drv_ipa_addr tbl_addr; + uint32_t tbl_ptch; + uint32_t affine_param[DRV_AFFINE_AFFINE_PARAM_NUM]; + uint32_t dist_param[DRV_AFFINE_UNDIST_PARAM_NUM]; + uint32_t homo_param[DRV_AFFINE_HOMO_PARAM_NUM]; + uint32_t tbl_comp_size; + float temp_dist_p[DRV_AFFINE_TEMP_UNDIST_PARAM_NUM]; + uint16_t config_done; + struct drv_ipa_buffer_info buffer_info[DRV_AFFINE_BUFFER_INDEX_MAX]; + int32_t buffer_info_num; +}; + +#endif /* _UAPI_LINUX_AFIINE_H */
Hi,
I withdraw this series of patches. I'm going to submit updated version after applying checkpatch.pl with strict option.
Best regards, Yuji
-----Original Message----- From: Yuji Ishikawa yuji2.ishikawa@toshiba.co.jp Sent: Tuesday, April 19, 2022 4:20 PM To: iwamatsu nobuhiro(岩松 信洋 □SWC◯ACT) nobuhiro1.iwamatsu@toshiba.co.jp; Sumit Semwal sumit.semwal@linaro.org; Christian König christian.koenig@amd.com Cc: linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org; linux-media@vger.kernel.org; dri-devel@lists.freedesktop.org; linaro-mm-sig@lists.linaro.org; ishikawa yuji(石川 悠司 ○RDC□AITC○ EA開) yuji2.ishikawa@toshiba.co.jp Subject: [PATCH 0/4] Add Toshiba Visconti AFFINE image processing accelerator driver
This series is the AFFINE image processing accelerator driver for Toshiba's ARM SoC, Visconti[0]. This provides DT binding documentation, device driver, MAINTAINER files.
Best regards, Yuji
ecognition-processors-visconti.html
Yuji Ishikawa (4): dt-bindings: soc: visconti: Add Toshiba Visconti AFFINE image processing accelerator bindings soc: visconti: Add Toshiba Visconti image processing accelerator common source soc: visconti: Add Toshiba Visconti AFFINE image processing accelerator MAINTAINERS: Add entries for Toshiba Visconti AFFINE image processing accelerator
.../soc/visconti/toshiba,visconti-affine.yaml | 53 ++ MAINTAINERS | 2 + drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/visconti/Kconfig | 7 + drivers/soc/visconti/Makefile | 8 + drivers/soc/visconti/affine/Makefile | 6 + drivers/soc/visconti/affine/affine.c | 451 ++++++++++++++++++ drivers/soc/visconti/affine/hwd_affine.c | 207 ++++++++ drivers/soc/visconti/affine/hwd_affine.h | 83 ++++ drivers/soc/visconti/affine/hwd_affine_reg.h | 45 ++ drivers/soc/visconti/ipa_common.c | 55 +++ drivers/soc/visconti/ipa_common.h | 19 + drivers/soc/visconti/uapi/affine.h | 87 ++++ drivers/soc/visconti/uapi/ipa.h | 87 ++++ 15 files changed, 1112 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/visconti/toshiba,visconti-affine.yaml create mode 100644 drivers/soc/visconti/Kconfig create mode 100644 drivers/soc/visconti/Makefile create mode 100644 drivers/soc/visconti/affine/Makefile create mode 100644 drivers/soc/visconti/affine/affine.c create mode 100644 drivers/soc/visconti/affine/hwd_affine.c create mode 100644 drivers/soc/visconti/affine/hwd_affine.h create mode 100644 drivers/soc/visconti/affine/hwd_affine_reg.h create mode 100644 drivers/soc/visconti/ipa_common.c create mode 100644 drivers/soc/visconti/ipa_common.h create mode 100644 drivers/soc/visconti/uapi/affine.h create mode 100644 drivers/soc/visconti/uapi/ipa.h
-- 2.17.1
linaro-mm-sig@lists.linaro.org