@@ -1,7 +1,11 @@
-iris-objs += ../hfi_queue.o
+iris-objs += ../hfi_queue.o ../firmware.o
iris-objs += iris_probe.o \
- resources.o \
- iris_state.o
+ iris_state.o \
+ iris_core.o \
+ iris_state.o \
+ iris_helpers.o \
+ iris_hfi.o \
+ resources.o
obj-$(CONFIG_VIDEO_QCOM_IRIS) += iris.o
new file mode 100644
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "iris_core.h"
+#include "iris_helpers.h"
+#include "iris_hfi.h"
+#include "iris_state.h"
+
+static int iris_core_deinit_locked(struct iris_core *core)
+{
+ int ret;
+
+ ret = check_core_lock(core);
+ if (ret)
+ return ret;
+
+ if (core->state == IRIS_CORE_DEINIT)
+ return 0;
+
+ iris_hfi_core_deinit(core);
+
+ iris_change_core_state(core, IRIS_CORE_DEINIT);
+
+ return ret;
+}
+
+int iris_core_deinit(struct iris_core *core)
+{
+ int ret;
+
+ mutex_lock(&core->lock);
+ ret = iris_core_deinit_locked(core);
+ mutex_unlock(&core->lock);
+
+ return ret;
+}
+
+int iris_core_init(struct iris_core *core)
+{
+ int ret = 0;
+
+ mutex_lock(&core->lock);
+ if (core_in_valid_state(core)) {
+ goto unlock;
+ } else if (core->state == IRIS_CORE_ERROR) {
+ ret = -EINVAL;
+ goto unlock;
+ }
+
+ if (iris_change_core_state(core, IRIS_CORE_INIT_WAIT)) {
+ iris_change_core_state(core, IRIS_CORE_ERROR);
+ ret = -EINVAL;
+ goto unlock;
+ }
+
+ ret = iris_hfi_core_init(core);
+ if (ret) {
+ iris_change_core_state(core, IRIS_CORE_ERROR);
+ dev_err(core->dev, "%s: core init failed\n", __func__);
+ iris_core_deinit_locked(core);
+ goto unlock;
+ }
+
+unlock:
+ mutex_unlock(&core->lock);
+
+ return ret;
+}
@@ -11,6 +11,7 @@
#include "../hfi_queue.h"
#include "iris_state.h"
+#include "resources.h"
/**
* struct iris_core - holds core parameters valid for all instances
@@ -36,6 +37,8 @@
* @message_queue: shared interface queue to receive responses from firmware
* @debug_queue: shared interface queue to receive debug info from firmware
* @sfr: SFR register memory
+ * @lock: a lock for this strucure
+ * @use_tz: a flag that suggests presence of trustzone
*/
struct iris_core {
@@ -60,6 +63,11 @@ struct iris_core {
struct iface_q_info message_queue;
struct iface_q_info debug_queue;
struct mem_desc sfr;
+ struct mutex lock; /* lock for core structure */
+ unsigned int use_tz;
};
+int iris_core_init(struct iris_core *core);
+int iris_core_deinit(struct iris_core *core);
+
#endif
new file mode 100644
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "iris_helpers.h"
+
+int check_core_lock(struct iris_core *core)
+{
+ bool fatal = !mutex_is_locked(&core->lock);
+
+ WARN_ON(fatal);
+
+ return fatal ? -EINVAL : 0;
+}
new file mode 100644
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_HELPERS_H_
+#define _IRIS_HELPERS_H_
+
+#include "iris_core.h"
+
+int check_core_lock(struct iris_core *core);
+
+#endif
new file mode 100644
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "../firmware.h"
+#include "iris_helpers.h"
+#include "iris_hfi.h"
+
+#define CP_START 0
+#define CP_SIZE 0x25800000
+#define CP_NONPIXEL_START 0x01000000
+#define CP_NONPIXEL_SIZE 0x24800000
+
+#define FW_NAME "vpu30_4v.mbn"
+#define IRIS_PAS_ID 9
+
+int iris_hfi_core_init(struct iris_core *core)
+{
+ phys_addr_t mem_phys = 0;
+ size_t mem_size = 0;
+ int ret;
+
+ ret = check_core_lock(core);
+ if (ret)
+ return ret;
+
+ ret = hfi_queue_init(core->dev, &core->iface_q_table, &core->sfr,
+ &core->command_queue, &core->message_queue,
+ &core->debug_queue, core);
+ if (ret)
+ goto error;
+
+ core->use_tz = use_tz(core->dev);
+ if (!core->use_tz)
+ goto error;
+
+ ret = load_fw(core->dev, FW_NAME, &mem_phys, &mem_size,
+ IRIS_PAS_ID, core->use_tz);
+ if (ret)
+ goto error;
+
+ ret = auth_reset_fw(IRIS_PAS_ID);
+ if (ret)
+ goto error;
+
+ ret = protect_secure_region(CP_START, CP_SIZE, CP_NONPIXEL_START,
+ CP_NONPIXEL_SIZE, IRIS_PAS_ID);
+
+ return ret;
+
+error:
+ dev_err(core->dev, "%s(): failed with ret %d\n", __func__, ret);
+
+ return ret;
+}
+
+int iris_hfi_core_deinit(struct iris_core *core)
+{
+ int ret;
+
+ ret = check_core_lock(core);
+ if (ret)
+ return ret;
+
+ if (core->state == IRIS_CORE_DEINIT)
+ return 0;
+
+ unload_fw(IRIS_PAS_ID);
+
+ return ret;
+}
new file mode 100644
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_HFI_H_
+#define _IRIS_HFI_H_
+
+#include "iris_core.h"
+
+int iris_hfi_core_init(struct iris_core *core);
+int iris_hfi_core_deinit(struct iris_core *core);
+
+#endif
@@ -51,6 +51,7 @@ static void iris_remove(struct platform_device *pdev)
if (!core)
return;
+ iris_core_deinit(core);
hfi_queue_deinit(core->dev, &core->iface_q_table, &core->sfr,
&core->command_queue, &core->message_queue,
&core->debug_queue);
@@ -58,6 +59,9 @@ static void iris_remove(struct platform_device *pdev)
video_unregister_device(core->vdev_dec);
v4l2_device_unregister(&core->v4l2_dev);
+
+ mutex_destroy(&core->lock);
+ core->state = IRIS_CORE_DEINIT;
}
static int iris_probe(struct platform_device *pdev)
@@ -72,6 +76,9 @@ static int iris_probe(struct platform_device *pdev)
return -ENOMEM;
core->dev = dev;
+ core->state = IRIS_CORE_DEINIT;
+ mutex_init(&core->lock);
+
core->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(core->reg_base))
return PTR_ERR(core->reg_base);
@@ -120,10 +127,20 @@ static int iris_probe(struct platform_device *pdev)
goto err_vdev_unreg;
}
+ ret = iris_core_init(core);
+ if (ret) {
+ dev_err_probe(core->dev, ret, "%s: core init failed\n", __func__);
+ goto err_queue_deinit;
+ }
+
return ret;
+err_queue_deinit:
+ hfi_queue_deinit(core->dev, &core->iface_q_table, &core->sfr,
+ &core->command_queue, &core->message_queue,
+ &core->debug_queue);
err_vdev_unreg:
- iris_unregister_video_device(core);
+ video_unregister_device(core->vdev_dec);
err_v4l2_unreg:
v4l2_device_unregister(&core->v4l2_dev);
@@ -4,6 +4,7 @@
*/
#include "iris_core.h"
+#include "iris_helpers.h"
#include "iris_state.h"
#define IRIS_STATE(name)[IRIS_CORE_##name] = "CORE_"#name
@@ -52,6 +53,12 @@ static bool iris_allow_core_state_change(struct iris_core *core,
int iris_change_core_state(struct iris_core *core,
enum iris_core_state request_state)
{
+ int ret;
+
+ ret = check_core_lock(core);
+ if (ret)
+ return ret;
+
if (core->state == request_state)
return 0;
@@ -60,5 +67,5 @@ int iris_change_core_state(struct iris_core *core,
core->state = request_state;
- return 0;
+ return ret;
}
Load/unload firmware in memory via mdt loader. Firmware loading is part of core initialization and unloading is part of core de-initialization. This also changes the core states accordingly. Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com> --- drivers/media/platform/qcom/vcodec/iris/Makefile | 10 ++- .../media/platform/qcom/vcodec/iris/iris_core.c | 70 +++++++++++++++++++++ .../media/platform/qcom/vcodec/iris/iris_core.h | 8 +++ .../media/platform/qcom/vcodec/iris/iris_helpers.c | 15 +++++ .../media/platform/qcom/vcodec/iris/iris_helpers.h | 13 ++++ drivers/media/platform/qcom/vcodec/iris/iris_hfi.c | 72 ++++++++++++++++++++++ drivers/media/platform/qcom/vcodec/iris/iris_hfi.h | 14 +++++ .../media/platform/qcom/vcodec/iris/iris_probe.c | 19 +++++- .../media/platform/qcom/vcodec/iris/iris_state.c | 9 ++- 9 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 drivers/media/platform/qcom/vcodec/iris/iris_core.c create mode 100644 drivers/media/platform/qcom/vcodec/iris/iris_helpers.c create mode 100644 drivers/media/platform/qcom/vcodec/iris/iris_helpers.h create mode 100644 drivers/media/platform/qcom/vcodec/iris/iris_hfi.c create mode 100644 drivers/media/platform/qcom/vcodec/iris/iris_hfi.h