Commit fb583a21 authored by Dikshita Agarwal's avatar Dikshita Agarwal Committed by Hans Verkuil
Browse files

media: iris: introduce host firmware interface with necessary hooks



The Host firmware interface (HFI) is a well defined set of interfaces
for the communication between the host driver and the firmware. The
commands and responses are exchanged in form of packets. One or multiple
packets are grouped under the packet header. Each packet has a packet
type which describes the specific HFI and the payload, which holds the
corresponding value for that HFI.

Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS 13 9345)
Reviewed-by: default avatarStefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: default avatarDikshita Agarwal <quic_dikshita@quicinc.com>
Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
parent abf5bac6
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
iris-objs += iris_core.o \
             iris_firmware.o \
             iris_hfi_common.o \
             iris_hfi_gen1_command.o \
             iris_hfi_gen1_response.o \
             iris_hfi_gen2_command.o \
             iris_hfi_gen2_packet.o \
             iris_hfi_gen2_response.o \
             iris_hfi_queue.o \
             iris_platform_sm8550.o \
             iris_probe.o \
+23 −1
Original line number Diff line number Diff line
@@ -17,6 +17,24 @@ void iris_core_deinit(struct iris_core *core)
	mutex_unlock(&core->lock);
}

static int iris_wait_for_system_response(struct iris_core *core)
{
	u32 hw_response_timeout_val = core->iris_platform_data->hw_response_timeout;
	int ret;

	if (core->state == IRIS_CORE_ERROR)
		return -EIO;

	ret = wait_for_completion_timeout(&core->core_init_done,
					  msecs_to_jiffies(hw_response_timeout_val));
	if (!ret) {
		core->state = IRIS_CORE_ERROR;
		return -ETIMEDOUT;
	}

	return 0;
}

int iris_core_init(struct iris_core *core)
{
	int ret;
@@ -44,9 +62,13 @@ int iris_core_init(struct iris_core *core)
	if (ret)
		goto error_unload_fw;

	ret = iris_hfi_core_init(core);
	if (ret)
		goto error_unload_fw;

	mutex_unlock(&core->lock);

	return 0;
	return iris_wait_for_system_response(core);

error_unload_fw:
	iris_fw_unload(core);
+20 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/types.h>
#include <media/v4l2-device.h>

#include "iris_hfi_common.h"
#include "iris_hfi_queue.h"
#include "iris_platform_common.h"
#include "iris_state.h"
@@ -19,6 +20,9 @@ struct icc_info {
	u32			bw_max_kbps;
};

#define IRIS_FW_VERSION_LENGTH		128
#define IFACEQ_CORE_PKT_SIZE		(1024 * 4)

/**
 * struct iris_core - holds core parameters valid for all instances
 *
@@ -45,6 +49,14 @@ struct icc_info {
 * @message_queue: shared interface queue to receive responses from firmware
 * @debug_queue: shared interface queue to receive debug info from firmware
 * @lock: a lock for this strucure
 * @response_packet: a pointer to response packet from fw to driver
 * @header_id: id of packet header
 * @packet_id: id of packet
 * @hfi_ops: iris hfi command ops
 * @hfi_response_ops: iris hfi response ops
 * @core_init_done: structure of signal completion for system response
 * @intr_status: interrupt status
 * @sys_error_handler: a delayed work for handling system fatal error
 */

struct iris_core {
@@ -71,6 +83,14 @@ struct iris_core {
	struct iris_iface_q_info		message_queue;
	struct iris_iface_q_info		debug_queue;
	struct mutex				lock; /* lock for core related operations */
	u8					*response_packet;
	u32					header_id;
	u32					packet_id;
	const struct iris_hfi_command_ops	*hfi_ops;
	const struct iris_hfi_response_ops	*hfi_response_ops;
	struct completion			core_init_done;
	u32					intr_status;
	struct delayed_work			sys_error_handler;
};

int iris_core_init(struct iris_core *core);
+50 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#include "iris_core.h"
#include "iris_hfi_common.h"
#include "iris_vpu_common.h"

int iris_hfi_core_init(struct iris_core *core)
{
	const struct iris_hfi_command_ops *hfi_ops = core->hfi_ops;
	int ret;

	ret = hfi_ops->sys_init(core);
	if (ret)
		return ret;

	ret = hfi_ops->sys_image_version(core);
	if (ret)
		return ret;

	return hfi_ops->sys_interframe_powercollapse(core);
}

irqreturn_t iris_hfi_isr(int irq, void *data)
{
	disable_irq_nosync(irq);

	return IRQ_WAKE_THREAD;
}

irqreturn_t iris_hfi_isr_handler(int irq, void *data)
{
	struct iris_core *core = data;

	if (!core)
		return IRQ_NONE;

	mutex_lock(&core->lock);
	iris_vpu_clear_interrupt(core);
	mutex_unlock(&core->lock);

	core->hfi_response_ops->hfi_response_handler(core);

	if (!iris_vpu_watchdog(core, core->intr_status))
		enable_irq(irq);

	return IRQ_HANDLED;
}
+60 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#ifndef __IRIS_HFI_COMMON_H__
#define __IRIS_HFI_COMMON_H__

#include <linux/types.h>
#include <media/v4l2-device.h>

struct iris_core;

enum hfi_packet_port_type {
	HFI_PORT_NONE		= 0x00000000,
	HFI_PORT_BITSTREAM	= 0x00000001,
	HFI_PORT_RAW		= 0x00000002,
};

enum hfi_packet_payload_info {
	HFI_PAYLOAD_NONE	= 0x00000000,
	HFI_PAYLOAD_U32		= 0x00000001,
	HFI_PAYLOAD_S32		= 0x00000002,
	HFI_PAYLOAD_U64		= 0x00000003,
	HFI_PAYLOAD_S64		= 0x00000004,
	HFI_PAYLOAD_STRUCTURE	= 0x00000005,
	HFI_PAYLOAD_BLOB	= 0x00000006,
	HFI_PAYLOAD_STRING	= 0x00000007,
	HFI_PAYLOAD_Q16		= 0x00000008,
	HFI_PAYLOAD_U32_ENUM	= 0x00000009,
	HFI_PAYLOAD_32_PACKED	= 0x0000000a,
	HFI_PAYLOAD_U32_ARRAY	= 0x0000000b,
	HFI_PAYLOAD_S32_ARRAY	= 0x0000000c,
	HFI_PAYLOAD_64_PACKED	= 0x0000000d,
};

enum hfi_packet_host_flags {
	HFI_HOST_FLAGS_NONE			= 0x00000000,
	HFI_HOST_FLAGS_INTR_REQUIRED		= 0x00000001,
	HFI_HOST_FLAGS_RESPONSE_REQUIRED	= 0x00000002,
	HFI_HOST_FLAGS_NON_DISCARDABLE		= 0x00000004,
	HFI_HOST_FLAGS_GET_PROPERTY		= 0x00000008,
};

struct iris_hfi_command_ops {
	int (*sys_init)(struct iris_core *core);
	int (*sys_image_version)(struct iris_core *core);
	int (*sys_interframe_powercollapse)(struct iris_core *core);
};

struct iris_hfi_response_ops {
	void (*hfi_response_handler)(struct iris_core *core);
};

int iris_hfi_core_init(struct iris_core *core);

irqreturn_t iris_hfi_isr(int irq, void *data);
irqreturn_t iris_hfi_isr_handler(int irq, void *data);

#endif
Loading