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

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

#ifdef CONFIG_ARM_ARCH_TIMER
#include <asm/arch_timer.h>
#endif

#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/firmware.h>
#include <linux/iopoll.h>
#include <linux/iosys-map.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>

#include <drm/drm_drv.h>
#include <drm/drm_managed.h>

#include "panthor_device.h"
#include "panthor_fw.h"
#include "panthor_gem.h"
#include "panthor_gpu.h"
#include "panthor_mmu.h"
#include "panthor_regs.h"
#include "panthor_sched.h"

#define CSF_FW_NAME

#define PING_INTERVAL_MS
#define PROGRESS_TIMEOUT_CYCLES
#define PROGRESS_TIMEOUT_SCALE_SHIFT
#define IDLE_HYSTERESIS_US
#define PWROFF_HYSTERESIS_US

/**
 * struct panthor_fw_binary_hdr - Firmware binary header.
 */
struct panthor_fw_binary_hdr {};

/**
 * enum panthor_fw_binary_entry_type - Firmware binary entry type
 */
enum panthor_fw_binary_entry_type {};

#define CSF_FW_BINARY_ENTRY_TYPE(ehdr)
#define CSF_FW_BINARY_ENTRY_SIZE(ehdr)
#define CSF_FW_BINARY_ENTRY_UPDATE
#define CSF_FW_BINARY_ENTRY_OPTIONAL

#define CSF_FW_BINARY_IFACE_ENTRY_RD_RD
#define CSF_FW_BINARY_IFACE_ENTRY_RD_WR
#define CSF_FW_BINARY_IFACE_ENTRY_RD_EX
#define CSF_FW_BINARY_IFACE_ENTRY_RD_CACHE_MODE_NONE
#define CSF_FW_BINARY_IFACE_ENTRY_RD_CACHE_MODE_CACHED
#define CSF_FW_BINARY_IFACE_ENTRY_RD_CACHE_MODE_UNCACHED_COHERENT
#define CSF_FW_BINARY_IFACE_ENTRY_RD_CACHE_MODE_CACHED_COHERENT
#define CSF_FW_BINARY_IFACE_ENTRY_RD_CACHE_MODE_MASK
#define CSF_FW_BINARY_IFACE_ENTRY_RD_PROT
#define CSF_FW_BINARY_IFACE_ENTRY_RD_SHARED
#define CSF_FW_BINARY_IFACE_ENTRY_RD_ZERO

#define CSF_FW_BINARY_IFACE_ENTRY_RD_SUPPORTED_FLAGS

/**
 * struct panthor_fw_binary_section_entry_hdr - Describes a section of FW binary
 */
struct panthor_fw_binary_section_entry_hdr {};

/**
 * struct panthor_fw_binary_iter - Firmware binary iterator
 *
 * Used to parse a firmware binary.
 */
struct panthor_fw_binary_iter {};

/**
 * struct panthor_fw_section - FW section
 */
struct panthor_fw_section {};

#define CSF_MCU_SHARED_REGION_START
#define CSF_MCU_SHARED_REGION_SIZE

#define MIN_CS_PER_CSG
#define MIN_CSGS
#define MAX_CSG_PRIO

#define CSF_IFACE_VERSION(major, minor, patch)
#define CSF_IFACE_VERSION_MAJOR(v)
#define CSF_IFACE_VERSION_MINOR(v)
#define CSF_IFACE_VERSION_PATCH(v)

#define CSF_GROUP_CONTROL_OFFSET
#define CSF_STREAM_CONTROL_OFFSET
#define CSF_UNPRESERVED_REG_COUNT

/**
 * struct panthor_fw_iface - FW interfaces
 */
struct panthor_fw_iface {};

/**
 * struct panthor_fw - Firmware management
 */
struct panthor_fw {};

struct panthor_vm *panthor_fw_vm(struct panthor_device *ptdev)
{}

/**
 * panthor_fw_get_glb_iface() - Get the global interface
 * @ptdev: Device.
 *
 * Return: The global interface.
 */
struct panthor_fw_global_iface *
panthor_fw_get_glb_iface(struct panthor_device *ptdev)
{}

/**
 * panthor_fw_get_csg_iface() - Get a command stream group slot interface
 * @ptdev: Device.
 * @csg_slot: Index of the command stream group slot.
 *
 * Return: The command stream group slot interface.
 */
struct panthor_fw_csg_iface *
panthor_fw_get_csg_iface(struct panthor_device *ptdev, u32 csg_slot)
{}

/**
 * panthor_fw_get_cs_iface() - Get a command stream slot interface
 * @ptdev: Device.
 * @csg_slot: Index of the command stream group slot.
 * @cs_slot: Index of the command stream slot.
 *
 * Return: The command stream slot interface.
 */
struct panthor_fw_cs_iface *
panthor_fw_get_cs_iface(struct panthor_device *ptdev, u32 csg_slot, u32 cs_slot)
{}

/**
 * panthor_fw_conv_timeout() - Convert a timeout into a cycle-count
 * @ptdev: Device.
 * @timeout_us: Timeout expressed in micro-seconds.
 *
 * The FW has two timer sources: the GPU counter or arch-timer. We need
 * to express timeouts in term of number of cycles and specify which
 * timer source should be used.
 *
 * Return: A value suitable for timeout fields in the global interface.
 */
static u32 panthor_fw_conv_timeout(struct panthor_device *ptdev, u32 timeout_us)
{}

static int panthor_fw_binary_iter_read(struct panthor_device *ptdev,
				       struct panthor_fw_binary_iter *iter,
				       void *out, size_t size)
{}

static int panthor_fw_binary_sub_iter_init(struct panthor_device *ptdev,
					   struct panthor_fw_binary_iter *iter,
					   struct panthor_fw_binary_iter *sub_iter,
					   size_t size)
{}

static void panthor_fw_init_section_mem(struct panthor_device *ptdev,
					struct panthor_fw_section *section)
{}

/**
 * panthor_fw_alloc_queue_iface_mem() - Allocate a ring-buffer interfaces.
 * @ptdev: Device.
 * @input: Pointer holding the input interface on success.
 * Should be ignored on failure.
 * @output: Pointer holding the output interface on success.
 * Should be ignored on failure.
 * @input_fw_va: Pointer holding the input interface FW VA on success.
 * Should be ignored on failure.
 * @output_fw_va: Pointer holding the output interface FW VA on success.
 * Should be ignored on failure.
 *
 * Allocates panthor_fw_ringbuf_{input,out}_iface interfaces. The input
 * interface is at offset 0, and the output interface at offset 4096.
 *
 * Return: A valid pointer in case of success, an ERR_PTR() otherwise.
 */
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)
{}

/**
 * panthor_fw_alloc_suspend_buf_mem() - Allocate a suspend buffer for a command stream group.
 * @ptdev: Device.
 * @size: Size of the suspend buffer.
 *
 * Return: A valid pointer in case of success, an ERR_PTR() otherwise.
 */
struct panthor_kernel_bo *
panthor_fw_alloc_suspend_buf_mem(struct panthor_device *ptdev, size_t size)
{}

static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
					 const struct firmware *fw,
					 struct panthor_fw_binary_iter *iter,
					 u32 ehdr)
{}

static void
panthor_reload_fw_sections(struct panthor_device *ptdev, bool full_reload)
{}

static int panthor_fw_load_entry(struct panthor_device *ptdev,
				 const struct firmware *fw,
				 struct panthor_fw_binary_iter *iter)
{}

static int panthor_fw_load(struct panthor_device *ptdev)
{}

/**
 * iface_fw_to_cpu_addr() - Turn an MCU address into a CPU address
 * @ptdev: Device.
 * @mcu_va: MCU address.
 *
 * Return: NULL if the address is not part of the shared section, non-NULL otherwise.
 */
static void *iface_fw_to_cpu_addr(struct panthor_device *ptdev, u32 mcu_va)
{}

static int panthor_init_cs_iface(struct panthor_device *ptdev,
				 unsigned int csg_idx, unsigned int cs_idx)
{}

static bool compare_csg(const struct panthor_fw_csg_control_iface *a,
			const struct panthor_fw_csg_control_iface *b)
{}

static int panthor_init_csg_iface(struct panthor_device *ptdev,
				  unsigned int csg_idx)
{}

static u32 panthor_get_instr_features(struct panthor_device *ptdev)
{}

static int panthor_fw_init_ifaces(struct panthor_device *ptdev)
{}

static void panthor_fw_init_global_iface(struct panthor_device *ptdev)
{}

static void panthor_job_irq_handler(struct panthor_device *ptdev, u32 status)
{}
PANTHOR_IRQ_HANDLER(job, JOB, panthor_job_irq_handler);

static int panthor_fw_start(struct panthor_device *ptdev)
{}

static void panthor_fw_stop(struct panthor_device *ptdev)
{}

/**
 * panthor_fw_pre_reset() - Call before a reset.
 * @ptdev: Device.
 * @on_hang: true if the reset was triggered on a GPU hang.
 *
 * If the reset is not triggered on a hang, we try to gracefully halt the
 * MCU, so we can do a fast-reset when panthor_fw_post_reset() is called.
 */
void panthor_fw_pre_reset(struct panthor_device *ptdev, bool on_hang)
{}

/**
 * panthor_fw_post_reset() - Call after a reset.
 * @ptdev: Device.
 *
 * Start the FW. If this is not a fast reset, all FW sections are reloaded to
 * make sure we can recover from a memory corruption.
 */
int panthor_fw_post_reset(struct panthor_device *ptdev)
{}

/**
 * panthor_fw_unplug() - Called when the device is unplugged.
 * @ptdev: Device.
 *
 * This function must make sure all pending operations are flushed before
 * will release device resources, thus preventing any interaction with
 * the HW.
 *
 * If there is still FW-related work running after this function returns,
 * they must use drm_dev_{enter,exit}() and skip any HW access when
 * drm_dev_enter() returns false.
 */
void panthor_fw_unplug(struct panthor_device *ptdev)
{}

/**
 * panthor_fw_wait_acks() - Wait for requests to be acknowledged by the FW.
 * @req_ptr: Pointer to the req register.
 * @ack_ptr: Pointer to the ack register.
 * @wq: Wait queue to use for the sleeping wait.
 * @req_mask: Mask of requests to wait for.
 * @acked: Pointer to field that's updated with the acked requests.
 * If the function returns 0, *acked == req_mask.
 * @timeout_ms: Timeout expressed in milliseconds.
 *
 * Return: 0 on success, -ETIMEDOUT otherwise.
 */
static int panthor_fw_wait_acks(const u32 *req_ptr, const u32 *ack_ptr,
				wait_queue_head_t *wq,
				u32 req_mask, u32 *acked,
				u32 timeout_ms)
{}

/**
 * panthor_fw_glb_wait_acks() - Wait for global requests to be acknowledged.
 * @ptdev: Device.
 * @req_mask: Mask of requests to wait for.
 * @acked: Pointer to field that's updated with the acked requests.
 * If the function returns 0, *acked == req_mask.
 * @timeout_ms: Timeout expressed in milliseconds.
 *
 * Return: 0 on success, -ETIMEDOUT otherwise.
 */
int panthor_fw_glb_wait_acks(struct panthor_device *ptdev,
			     u32 req_mask, u32 *acked,
			     u32 timeout_ms)
{}

/**
 * panthor_fw_csg_wait_acks() - Wait for command stream group requests to be acknowledged.
 * @ptdev: Device.
 * @csg_slot: CSG slot ID.
 * @req_mask: Mask of requests to wait for.
 * @acked: Pointer to field that's updated with the acked requests.
 * If the function returns 0, *acked == req_mask.
 * @timeout_ms: Timeout expressed in milliseconds.
 *
 * Return: 0 on success, -ETIMEDOUT otherwise.
 */
int panthor_fw_csg_wait_acks(struct panthor_device *ptdev, u32 csg_slot,
			     u32 req_mask, u32 *acked, u32 timeout_ms)
{}

/**
 * panthor_fw_ring_csg_doorbells() - Ring command stream group doorbells.
 * @ptdev: Device.
 * @csg_mask: Bitmask encoding the command stream group doorbells to ring.
 *
 * This function is toggling bits in the doorbell_req and ringing the
 * global doorbell. It doesn't require a user doorbell to be attached to
 * the group.
 */
void panthor_fw_ring_csg_doorbells(struct panthor_device *ptdev, u32 csg_mask)
{}

static void panthor_fw_ping_work(struct work_struct *work)
{}

/**
 * panthor_fw_init() - Initialize FW related data.
 * @ptdev: Device.
 *
 * Return: 0 on success, a negative error code otherwise.
 */
int panthor_fw_init(struct panthor_device *ptdev)
{}

MODULE_FIRMWARE();