linux/drivers/gpu/drm/panthor/panthor_fw.h

/* SPDX-License-Identifier: GPL-2.0 or MIT */
/* Copyright 2023 Collabora ltd. */

#ifndef __PANTHOR_MCU_H__
#define __PANTHOR_MCU_H__

#include <linux/types.h>

struct panthor_device;
struct panthor_kernel_bo;

#define MAX_CSGS
#define MAX_CS_PER_CSG

struct panthor_fw_ringbuf_input_iface {};

struct panthor_fw_ringbuf_output_iface {};

struct panthor_fw_cs_control_iface {};

struct panthor_fw_cs_input_iface {};

struct panthor_fw_cs_output_iface {};

struct panthor_fw_csg_control_iface {};

struct panthor_fw_csg_input_iface {};

struct panthor_fw_csg_output_iface {};

struct panthor_fw_global_control_iface {};

struct panthor_fw_global_input_iface {};

enum panthor_fw_halt_status {};

struct panthor_fw_global_output_iface {};

/**
 * struct panthor_fw_cs_iface - Firmware command stream slot interface
 */
struct panthor_fw_cs_iface {};

/**
 * struct panthor_fw_csg_iface - Firmware command stream group slot interface
 */
struct panthor_fw_csg_iface {};

/**
 * struct panthor_fw_global_iface - Firmware global interface
 */
struct panthor_fw_global_iface {};

/**
 * panthor_fw_toggle_reqs() - Toggle acknowledge bits to send an event to the FW
 * @__iface: The interface to operate on.
 * @__in_reg: Name of the register to update in the input section of the interface.
 * @__out_reg: Name of the register to take as a reference in the output section of the
 * interface.
 * @__mask: Mask to apply to the update.
 *
 * The Host -> FW event/message passing was designed to be lockless, with each side of
 * the channel having its writeable section. Events are signaled as a difference between
 * the host and FW side in the req/ack registers (when a bit differs, there's an event
 * pending, when they are the same, nothing needs attention).
 *
 * This helper allows one to update the req register based on the current value of the
 * ack register managed by the FW. Toggling a specific bit will flag an event. In order
 * for events to be re-evaluated, the interface doorbell needs to be rung.
 *
 * Concurrent accesses to the same req register is covered.
 *
 * Anything requiring atomic updates to multiple registers requires a dedicated lock.
 */
#define panthor_fw_toggle_reqs(__iface, __in_reg, __out_reg, __mask)

/**
 * panthor_fw_update_reqs() - Update bits to reflect a configuration change
 * @__iface: The interface to operate on.
 * @__in_reg: Name of the register to update in the input section of the interface.
 * @__val: Value to set.
 * @__mask: Mask to apply to the update.
 *
 * Some configuration get passed through req registers that are also used to
 * send events to the FW. Those req registers being updated from the interrupt
 * handler, they require special helpers to update the configuration part as well.
 *
 * Concurrent accesses to the same req register is covered.
 *
 * Anything requiring atomic updates to multiple registers requires a dedicated lock.
 */
#define panthor_fw_update_reqs(__iface, __in_reg, __val, __mask)

struct panthor_fw_global_iface *
panthor_fw_get_glb_iface(struct panthor_device *ptdev);

struct panthor_fw_csg_iface *
panthor_fw_get_csg_iface(struct panthor_device *ptdev, u32 csg_slot);

struct panthor_fw_cs_iface *
panthor_fw_get_cs_iface(struct panthor_device *ptdev, u32 csg_slot, u32 cs_slot);

int panthor_fw_csg_wait_acks(struct panthor_device *ptdev, u32 csg_id, u32 req_mask,
			     u32 *acked, u32 timeout_ms);

int panthor_fw_glb_wait_acks(struct panthor_device *ptdev, u32 req_mask, u32 *acked,
			     u32 timeout_ms);

void panthor_fw_ring_csg_doorbells(struct panthor_device *ptdev, u32 csg_slot);

struct panthor_kernel_bo *
panthor_fw_alloc_queue_iface_mem(struct panthor_device *ptdev,
				 struct panthor_fw_ringbuf_input_iface **input,
				 const struct panthor_fw_ringbuf_output_iface **output,
				 u32 *input_fw_va, u32 *output_fw_va);
struct panthor_kernel_bo *
panthor_fw_alloc_suspend_buf_mem(struct panthor_device *ptdev, size_t size);

struct panthor_vm *panthor_fw_vm(struct panthor_device *ptdev);

void panthor_fw_pre_reset(struct panthor_device *ptdev, bool on_hang);
int panthor_fw_post_reset(struct panthor_device *ptdev);

static inline void panthor_fw_suspend(struct panthor_device *ptdev)
{}

static inline int panthor_fw_resume(struct panthor_device *ptdev)
{}

int panthor_fw_init(struct panthor_device *ptdev);
void panthor_fw_unplug(struct panthor_device *ptdev);

#endif