lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1702899149-21321-13-git-send-email-quic_dikshita@quicinc.com>
Date: Mon, 18 Dec 2023 17:02:07 +0530
From: Dikshita Agarwal <quic_dikshita@...cinc.com>
To: linux-media@...r.kernel.org, linux-kernel@...r.kernel.org,
        stanimir.k.varbanov@...il.com, quic_vgarodia@...cinc.com,
        agross@...nel.org, andersson@...nel.org, konrad.dybcio@...aro.org,
        mchehab@...nel.org, bryan.odonoghue@...aro.org
Cc: linux-arm-msm@...r.kernel.org, quic_abhinavk@...cinc.com,
        Dikshita Agarwal <quic_dikshita@...cinc.com>
Subject: [PATCH v2 12/34] media: iris: add video processing unit(VPU) specific register handling

Registers are defined differently for different VPUs.
Define ops for VPU specific handling to accommodate
different VPUs. Implement boot sequence of firmware and interrupt
programming.

Signed-off-by: Dikshita Agarwal <quic_dikshita@...cinc.com>
---
 drivers/media/platform/qcom/vcodec/iris/Makefile   |   4 +-
 .../media/platform/qcom/vcodec/iris/iris_core.h    |   3 +
 drivers/media/platform/qcom/vcodec/iris/iris_hfi.c |   7 +
 .../media/platform/qcom/vcodec/iris/iris_probe.c   |   7 +
 .../media/platform/qcom/vcodec/iris/vpu_common.c   |  71 +++++++++
 .../media/platform/qcom/vcodec/iris/vpu_common.h   |  32 ++++
 .../media/platform/qcom/vcodec/iris/vpu_iris3.c    | 166 +++++++++++++++++++++
 .../media/platform/qcom/vcodec/iris/vpu_iris3.h    |  13 ++
 8 files changed, 302 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/platform/qcom/vcodec/iris/vpu_common.c
 create mode 100644 drivers/media/platform/qcom/vcodec/iris/vpu_common.h
 create mode 100644 drivers/media/platform/qcom/vcodec/iris/vpu_iris3.c
 create mode 100644 drivers/media/platform/qcom/vcodec/iris/vpu_iris3.h

diff --git a/drivers/media/platform/qcom/vcodec/iris/Makefile b/drivers/media/platform/qcom/vcodec/iris/Makefile
index a2d5d74..90241b5 100644
--- a/drivers/media/platform/qcom/vcodec/iris/Makefile
+++ b/drivers/media/platform/qcom/vcodec/iris/Makefile
@@ -7,6 +7,8 @@ iris-objs += iris_probe.o \
              iris_helpers.o \
              iris_hfi.o \
              iris_hfi_packet.o \
-             resources.o
+             resources.o \
+             vpu_common.o \
+             vpu_iris3.o
 
 obj-$(CONFIG_VIDEO_QCOM_IRIS) += iris.o
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_core.h b/drivers/media/platform/qcom/vcodec/iris/iris_core.h
index de0cfef..64678fd 100644
--- a/drivers/media/platform/qcom/vcodec/iris/iris_core.h
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_core.h
@@ -12,6 +12,7 @@
 #include "../hfi_queue.h"
 #include "iris_state.h"
 #include "resources.h"
+#include "vpu_common.h"
 
 /**
  * struct iris_core - holds core parameters valid for all instances
@@ -44,6 +45,7 @@
  * @sys_init_id: id of sys init packet
  * @header_id: id of packet header
  * @packet_id: id of packet
+ * @vpu_ops: a pointer to vpu ops
  */
 
 struct iris_core {
@@ -75,6 +77,7 @@ struct iris_core {
 	u32					sys_init_id;
 	u32					header_id;
 	u32					packet_id;
+	const struct vpu_ops			*vpu_ops;
 };
 
 int iris_core_init(struct iris_core *core);
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_hfi.c b/drivers/media/platform/qcom/vcodec/iris/iris_hfi.c
index fe16448..7b3cbbc 100644
--- a/drivers/media/platform/qcom/vcodec/iris/iris_hfi.c
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_hfi.c
@@ -8,6 +8,7 @@
 #include "iris_helpers.h"
 #include "iris_hfi.h"
 #include "iris_hfi_packet.h"
+#include "vpu_common.h"
 
 static int iris_hfi_queue_cmd_write(struct iris_core *core, void *pkt)
 {
@@ -33,6 +34,8 @@ static int iris_hfi_queue_cmd_write(struct iris_core *core, void *pkt)
 	packet_size = header->size;
 
 	if (!write_queue(q_info, pkt, packet_size, &rx_req)) {
+		call_vpu_op(core, raise_interrupt, core);
+	} else {
 		dev_err(core->dev, "queue full\n");
 		return -ENODATA;
 	}
@@ -108,6 +111,10 @@ int iris_hfi_core_init(struct iris_core *core)
 	if (ret)
 		goto error;
 
+	ret = call_vpu_op(core, boot_firmware, core);
+	if (ret)
+		goto error;
+
 	ret = sys_init(core);
 	if (ret)
 		goto error;
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_probe.c b/drivers/media/platform/qcom/vcodec/iris/iris_probe.c
index 570c64e..773481f 100644
--- a/drivers/media/platform/qcom/vcodec/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_probe.c
@@ -92,6 +92,13 @@ static int iris_probe(struct platform_device *pdev)
 	if (core->irq < 0)
 		return core->irq;
 
+	ret = init_vpu(core);
+	if (ret) {
+		dev_err_probe(core->dev, ret,
+			      "%s: init vpu failed with %d\n", __func__, ret);
+		return ret;
+	}
+
 	ret = init_resources(core);
 	if (ret) {
 		dev_err_probe(core->dev, ret,
diff --git a/drivers/media/platform/qcom/vcodec/iris/vpu_common.c b/drivers/media/platform/qcom/vcodec/iris/vpu_common.c
new file mode 100644
index 0000000..3282510
--- /dev/null
+++ b/drivers/media/platform/qcom/vcodec/iris/vpu_common.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "vpu_iris3.h"
+#include "iris_core.h"
+#include "iris_helpers.h"
+#include "vpu_common.h"
+
+int write_register(struct iris_core *core, u32 reg, u32 value)
+{
+	void __iomem *base_addr;
+	int ret;
+
+	ret = check_core_lock(core);
+	if (ret)
+		return ret;
+
+	base_addr = core->reg_base;
+	base_addr += reg;
+	writel_relaxed(value, base_addr);
+
+	/* Make sure value is written into the register */
+	wmb();
+
+	return ret;
+}
+
+int read_register(struct iris_core *core, u32 reg, u32 *value)
+{
+	void __iomem *base_addr;
+
+	base_addr = core->reg_base;
+
+	*value = readl_relaxed(base_addr + reg);
+
+	/* Make sure value is read correctly from the register */
+	rmb();
+
+	return 0;
+}
+
+static const struct compat_handle compat_handle[] = {
+	{
+		.compat                  = "qcom,sm8550-iris",
+		.init                    = init_iris3,
+	},
+};
+
+int init_vpu(struct iris_core *core)
+{
+	struct device *dev = NULL;
+	int i, ret = 0;
+
+	dev = core->dev;
+
+	for (i = 0; i < ARRAY_SIZE(compat_handle); i++) {
+		if (of_device_is_compatible(dev->of_node, compat_handle[i].compat)) {
+			ret = compat_handle[i].init(core);
+			if (ret)
+				return ret;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(compat_handle))
+		return -EINVAL;
+
+	return ret;
+}
diff --git a/drivers/media/platform/qcom/vcodec/iris/vpu_common.h b/drivers/media/platform/qcom/vcodec/iris/vpu_common.h
new file mode 100644
index 0000000..790496a
--- /dev/null
+++ b/drivers/media/platform/qcom/vcodec/iris/vpu_common.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _VPU_COMMON_H_
+#define _VPU_COMMON_H_
+
+#include <linux/types.h>
+
+struct iris_core;
+
+#define call_vpu_op(d, op, ...)			\
+	(((d) && (d)->vpu_ops && (d)->vpu_ops->op) ? \
+	((d)->vpu_ops->op(__VA_ARGS__)) : 0)
+
+struct compat_handle {
+	const char *compat;
+	int (*init)(struct iris_core *core);
+};
+
+struct vpu_ops {
+	int (*boot_firmware)(struct iris_core *core);
+	int (*raise_interrupt)(struct iris_core *core);
+};
+
+int init_vpu(struct iris_core *core);
+
+int write_register(struct iris_core *core, u32 reg, u32 value);
+int read_register(struct iris_core *core, u32 reg, u32 *value);
+
+#endif
diff --git a/drivers/media/platform/qcom/vcodec/iris/vpu_iris3.c b/drivers/media/platform/qcom/vcodec/iris/vpu_iris3.c
new file mode 100644
index 0000000..95bf223
--- /dev/null
+++ b/drivers/media/platform/qcom/vcodec/iris/vpu_iris3.c
@@ -0,0 +1,166 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/delay.h>
+
+#include "vpu_iris3.h"
+
+#define VIDEO_ARCH_LX 1
+
+#define CPU_BASE_OFFS_IRIS3     0x000A0000
+
+#define CPU_CS_BASE_OFFS_IRIS3      (CPU_BASE_OFFS_IRIS3)
+#define CPU_IC_BASE_OFFS_IRIS3      (CPU_BASE_OFFS_IRIS3)
+
+#define CPU_CS_VCICMDARG0_IRIS3     (CPU_CS_BASE_OFFS_IRIS3 + 0x24)
+#define CPU_CS_VCICMDARG1_IRIS3     (CPU_CS_BASE_OFFS_IRIS3 + 0x28)
+
+/* HFI_CTRL_INIT */
+#define CPU_CS_SCIACMD_IRIS3        (CPU_CS_BASE_OFFS_IRIS3 + 0x48)
+
+/* HFI_CTRL_STATUS */
+#define CPU_CS_SCIACMDARG0_IRIS3    (CPU_CS_BASE_OFFS_IRIS3 + 0x4C)
+#define CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_IRIS3     0x40000000
+
+#define CPU_CS_H2XSOFTINTEN_IRIS3   (CPU_CS_BASE_OFFS_IRIS3 + 0x148)
+
+#define CPU_CS_X2RPMH_IRIS3         (CPU_CS_BASE_OFFS_IRIS3 + 0x168)
+
+/* UC_REGION_ADDR */
+#define CPU_CS_SCIBARG1_IRIS3       (CPU_CS_BASE_OFFS_IRIS3 + 0x64)
+
+/* UC_REGION_ADDR */
+#define CPU_CS_SCIBARG2_IRIS3       (CPU_CS_BASE_OFFS_IRIS3 + 0x68)
+
+/* HFI_QTBL_INFO */
+#define CPU_CS_SCIACMDARG1_IRIS3    (CPU_CS_BASE_OFFS_IRIS3 + 0x50)
+
+/* HFI_QTBL_ADDR */
+#define CPU_CS_SCIACMDARG2_IRIS3    (CPU_CS_BASE_OFFS_IRIS3 + 0x54)
+
+/* SFR_ADDR */
+#define CPU_CS_SCIBCMD_IRIS3        (CPU_CS_BASE_OFFS_IRIS3 + 0x5C)
+
+#define UC_REGION_ADDR_IRIS3        CPU_CS_SCIBARG1_IRIS3
+#define UC_REGION_SIZE_IRIS3	    CPU_CS_SCIBARG2_IRIS3
+
+#define QTBL_INFO_IRIS3             CPU_CS_SCIACMDARG1_IRIS3
+#define QTBL_ADDR_IRIS3             CPU_CS_SCIACMDARG2_IRIS3
+
+#define SFR_ADDR_IRIS3              CPU_CS_SCIBCMD_IRIS3
+
+#define CTRL_INIT_IRIS3             CPU_CS_SCIACMD_IRIS3
+
+#define CTRL_STATUS_IRIS3           CPU_CS_SCIACMDARG0_IRIS3
+#define CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS3	0xfe
+#define CTRL_ERROR_STATUS__M_IRIS3 \
+		CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS3
+
+#define CPU_IC_SOFTINT_IRIS3        (CPU_IC_BASE_OFFS_IRIS3 + 0x150)
+#define CPU_IC_SOFTINT_H2A_SHFT_IRIS3	0x0
+
+static int setup_ucregion_memory_map_iris3(struct iris_core *core)
+{
+	int ret;
+	u32 value;
+
+	value = (u32)core->iface_q_table.device_addr;
+	ret = write_register(core, UC_REGION_ADDR_IRIS3, value);
+	if (ret)
+		return ret;
+
+	value = SHARED_QSIZE;
+	ret = write_register(core, UC_REGION_SIZE_IRIS3, value);
+	if (ret)
+		return ret;
+
+	value = (u32)core->iface_q_table.device_addr;
+	ret = write_register(core, QTBL_ADDR_IRIS3, value);
+	if (ret)
+		return ret;
+
+	ret = write_register(core, QTBL_INFO_IRIS3, 0x01);
+	if (ret)
+		return ret;
+
+	value = (u32)((u64)core->iface_q_table.kernel_vaddr);
+	ret = write_register(core, CPU_CS_VCICMDARG0_IRIS3, value);
+	if (ret)
+		return ret;
+
+	value = (u32)((u64)core->iface_q_table.kernel_vaddr >> 32);
+	ret = write_register(core, CPU_CS_VCICMDARG1_IRIS3, value);
+	if (ret)
+		return ret;
+
+	if (core->sfr.device_addr) {
+		value = (u32)core->sfr.device_addr + VIDEO_ARCH_LX;
+		ret = write_register(core, SFR_ADDR_IRIS3, value);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static int boot_firmware_iris3(struct iris_core *core)
+{
+	u32 ctrl_init = 0, ctrl_status = 0, count = 0, max_tries = 1000;
+	int ret;
+
+	ret = setup_ucregion_memory_map_iris3(core);
+	if (ret)
+		return ret;
+
+	ctrl_init = BIT(0);
+
+	ret = write_register(core, CTRL_INIT_IRIS3, ctrl_init);
+	if (ret)
+		return ret;
+
+	while (!ctrl_status && count < max_tries) {
+		ret = read_register(core, CTRL_STATUS_IRIS3, &ctrl_status);
+		if (ret)
+			return ret;
+
+		if ((ctrl_status & CTRL_ERROR_STATUS__M_IRIS3) == 0x4) {
+			dev_err(core->dev, "invalid setting for UC_REGION\n");
+			break;
+		}
+
+		usleep_range(50, 100);
+		count++;
+	}
+
+	if (count >= max_tries) {
+		dev_err(core->dev, "Error booting up vidc firmware\n");
+		return -ETIME;
+	}
+
+	ret = write_register(core, CPU_CS_H2XSOFTINTEN_IRIS3, 0x1);
+	if (ret)
+		return ret;
+
+	ret = write_register(core, CPU_CS_X2RPMH_IRIS3, 0x0);
+
+	return ret;
+}
+
+static int raise_interrupt_iris3(struct iris_core *core)
+{
+	return write_register(core, CPU_IC_SOFTINT_IRIS3, 1 << CPU_IC_SOFTINT_H2A_SHFT_IRIS3);
+}
+
+static const struct vpu_ops iris3_ops = {
+	.boot_firmware = boot_firmware_iris3,
+	.raise_interrupt = raise_interrupt_iris3,
+};
+
+int init_iris3(struct iris_core *core)
+{
+	core->vpu_ops = &iris3_ops;
+
+	return 0;
+}
diff --git a/drivers/media/platform/qcom/vcodec/iris/vpu_iris3.h b/drivers/media/platform/qcom/vcodec/iris/vpu_iris3.h
new file mode 100644
index 0000000..1424a5f
--- /dev/null
+++ b/drivers/media/platform/qcom/vcodec/iris/vpu_iris3.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _VPU_IRIS3_H_
+#define _VPU_IRIS3_H_
+
+#include "iris_core.h"
+
+int init_iris3(struct iris_core *core);
+
+#endif
-- 
2.7.4


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ