brintos

brintos / linux-shallow public Read only

0
0
Text · 14.0 KiB · 22448ab Raw
504 lines · c
1/* SPDX-License-Identifier: GPL-2.0 or MIT */2/* Copyright 2023 Collabora ltd. */3 4#ifndef __PANTHOR_MCU_H__5#define __PANTHOR_MCU_H__6 7#include <linux/types.h>8 9struct panthor_device;10struct panthor_kernel_bo;11 12#define MAX_CSGS				3113#define MAX_CS_PER_CSG                          3214 15struct panthor_fw_ringbuf_input_iface {16	u64 insert;17	u64 extract;18};19 20struct panthor_fw_ringbuf_output_iface {21	u64 extract;22	u32 active;23};24 25struct panthor_fw_cs_control_iface {26#define CS_FEATURES_WORK_REGS(x)		(((x) & GENMASK(7, 0)) + 1)27#define CS_FEATURES_SCOREBOARDS(x)		(((x) & GENMASK(15, 8)) >> 8)28#define CS_FEATURES_COMPUTE			BIT(16)29#define CS_FEATURES_FRAGMENT			BIT(17)30#define CS_FEATURES_TILER			BIT(18)31	u32 features;32	u32 input_va;33	u32 output_va;34};35 36struct panthor_fw_cs_input_iface {37#define CS_STATE_MASK				GENMASK(2, 0)38#define CS_STATE_STOP				039#define CS_STATE_START				140#define CS_EXTRACT_EVENT			BIT(4)41#define CS_IDLE_SYNC_WAIT			BIT(8)42#define CS_IDLE_PROTM_PENDING			BIT(9)43#define CS_IDLE_EMPTY				BIT(10)44#define CS_IDLE_RESOURCE_REQ			BIT(11)45#define CS_TILER_OOM				BIT(26)46#define CS_PROTM_PENDING			BIT(27)47#define CS_FATAL				BIT(30)48#define CS_FAULT				BIT(31)49#define CS_REQ_MASK				(CS_STATE_MASK | \50						 CS_EXTRACT_EVENT | \51						 CS_IDLE_SYNC_WAIT | \52						 CS_IDLE_PROTM_PENDING | \53						 CS_IDLE_EMPTY | \54						 CS_IDLE_RESOURCE_REQ)55#define CS_EVT_MASK				(CS_TILER_OOM | \56						 CS_PROTM_PENDING | \57						 CS_FATAL | \58						 CS_FAULT)59	u32 req;60 61#define CS_CONFIG_PRIORITY(x)			((x) & GENMASK(3, 0))62#define CS_CONFIG_DOORBELL(x)			(((x) << 8) & GENMASK(15, 8))63	u32 config;64	u32 reserved1;65	u32 ack_irq_mask;66	u64 ringbuf_base;67	u32 ringbuf_size;68	u32 reserved2;69	u64 heap_start;70	u64 heap_end;71	u64 ringbuf_input;72	u64 ringbuf_output;73	u32 instr_config;74	u32 instrbuf_size;75	u64 instrbuf_base;76	u64 instrbuf_offset_ptr;77};78 79struct panthor_fw_cs_output_iface {80	u32 ack;81	u32 reserved1[15];82	u64 status_cmd_ptr;83 84#define CS_STATUS_WAIT_SB_MASK			GENMASK(15, 0)85#define CS_STATUS_WAIT_SB_SRC_MASK		GENMASK(19, 16)86#define CS_STATUS_WAIT_SB_SRC_NONE		(0 << 16)87#define CS_STATUS_WAIT_SB_SRC_WAIT		(8 << 16)88#define CS_STATUS_WAIT_SYNC_COND_LE		(0 << 24)89#define CS_STATUS_WAIT_SYNC_COND_GT		(1 << 24)90#define CS_STATUS_WAIT_SYNC_COND_MASK		GENMASK(27, 24)91#define CS_STATUS_WAIT_PROGRESS			BIT(28)92#define CS_STATUS_WAIT_PROTM			BIT(29)93#define CS_STATUS_WAIT_SYNC_64B			BIT(30)94#define CS_STATUS_WAIT_SYNC			BIT(31)95	u32 status_wait;96	u32 status_req_resource;97	u64 status_wait_sync_ptr;98	u32 status_wait_sync_value;99	u32 status_scoreboards;100 101#define CS_STATUS_BLOCKED_REASON_UNBLOCKED	0102#define CS_STATUS_BLOCKED_REASON_SB_WAIT	1103#define CS_STATUS_BLOCKED_REASON_PROGRESS_WAIT	2104#define CS_STATUS_BLOCKED_REASON_SYNC_WAIT	3105#define CS_STATUS_BLOCKED_REASON_DEFERRED	5106#define CS_STATUS_BLOCKED_REASON_RES		6107#define CS_STATUS_BLOCKED_REASON_FLUSH		7108#define CS_STATUS_BLOCKED_REASON_MASK		GENMASK(3, 0)109	u32 status_blocked_reason;110	u32 status_wait_sync_value_hi;111	u32 reserved2[6];112 113#define CS_EXCEPTION_TYPE(x)			((x) & GENMASK(7, 0))114#define CS_EXCEPTION_DATA(x)			(((x) >> 8) & GENMASK(23, 0))115	u32 fault;116	u32 fatal;117	u64 fault_info;118	u64 fatal_info;119	u32 reserved3[10];120	u32 heap_vt_start;121	u32 heap_vt_end;122	u32 reserved4;123	u32 heap_frag_end;124	u64 heap_address;125};126 127struct panthor_fw_csg_control_iface {128	u32 features;129	u32 input_va;130	u32 output_va;131	u32 suspend_size;132	u32 protm_suspend_size;133	u32 stream_num;134	u32 stream_stride;135};136 137struct panthor_fw_csg_input_iface {138#define CSG_STATE_MASK				GENMASK(2, 0)139#define CSG_STATE_TERMINATE			0140#define CSG_STATE_START				1141#define CSG_STATE_SUSPEND			2142#define CSG_STATE_RESUME			3143#define CSG_ENDPOINT_CONFIG			BIT(4)144#define CSG_STATUS_UPDATE			BIT(5)145#define CSG_SYNC_UPDATE				BIT(28)146#define CSG_IDLE				BIT(29)147#define CSG_DOORBELL				BIT(30)148#define CSG_PROGRESS_TIMER_EVENT		BIT(31)149#define CSG_REQ_MASK				(CSG_STATE_MASK | \150						 CSG_ENDPOINT_CONFIG | \151						 CSG_STATUS_UPDATE)152#define CSG_EVT_MASK				(CSG_SYNC_UPDATE | \153						 CSG_IDLE | \154						 CSG_PROGRESS_TIMER_EVENT)155	u32 req;156	u32 ack_irq_mask;157 158	u32 doorbell_req;159	u32 cs_irq_ack;160	u32 reserved1[4];161	u64 allow_compute;162	u64 allow_fragment;163	u32 allow_other;164 165#define CSG_EP_REQ_COMPUTE(x)			((x) & GENMASK(7, 0))166#define CSG_EP_REQ_FRAGMENT(x)			(((x) << 8) & GENMASK(15, 8))167#define CSG_EP_REQ_TILER(x)			(((x) << 16) & GENMASK(19, 16))168#define CSG_EP_REQ_EXCL_COMPUTE			BIT(20)169#define CSG_EP_REQ_EXCL_FRAGMENT		BIT(21)170#define CSG_EP_REQ_PRIORITY(x)			(((x) << 28) & GENMASK(31, 28))171#define CSG_EP_REQ_PRIORITY_MASK		GENMASK(31, 28)172	u32 endpoint_req;173	u32 reserved2[2];174	u64 suspend_buf;175	u64 protm_suspend_buf;176	u32 config;177	u32 iter_trace_config;178};179 180struct panthor_fw_csg_output_iface {181	u32 ack;182	u32 reserved1;183	u32 doorbell_ack;184	u32 cs_irq_req;185	u32 status_endpoint_current;186	u32 status_endpoint_req;187 188#define CSG_STATUS_STATE_IS_IDLE		BIT(0)189	u32 status_state;190	u32 resource_dep;191};192 193struct panthor_fw_global_control_iface {194	u32 version;195	u32 features;196	u32 input_va;197	u32 output_va;198	u32 group_num;199	u32 group_stride;200	u32 perfcnt_size;201	u32 instr_features;202};203 204struct panthor_fw_global_input_iface {205#define GLB_HALT				BIT(0)206#define GLB_CFG_PROGRESS_TIMER			BIT(1)207#define GLB_CFG_ALLOC_EN			BIT(2)208#define GLB_CFG_POWEROFF_TIMER			BIT(3)209#define GLB_PROTM_ENTER				BIT(4)210#define GLB_PERFCNT_EN				BIT(5)211#define GLB_PERFCNT_SAMPLE			BIT(6)212#define GLB_COUNTER_EN				BIT(7)213#define GLB_PING				BIT(8)214#define GLB_FWCFG_UPDATE			BIT(9)215#define GLB_IDLE_EN				BIT(10)216#define GLB_SLEEP				BIT(12)217#define GLB_INACTIVE_COMPUTE			BIT(20)218#define GLB_INACTIVE_FRAGMENT			BIT(21)219#define GLB_INACTIVE_TILER			BIT(22)220#define GLB_PROTM_EXIT				BIT(23)221#define GLB_PERFCNT_THRESHOLD			BIT(24)222#define GLB_PERFCNT_OVERFLOW			BIT(25)223#define GLB_IDLE				BIT(26)224#define GLB_DBG_CSF				BIT(30)225#define GLB_DBG_HOST				BIT(31)226#define GLB_REQ_MASK				GENMASK(10, 0)227#define GLB_EVT_MASK				GENMASK(26, 20)228	u32 req;229	u32 ack_irq_mask;230	u32 doorbell_req;231	u32 reserved1;232	u32 progress_timer;233 234#define GLB_TIMER_VAL(x)			((x) & GENMASK(30, 0))235#define GLB_TIMER_SOURCE_GPU_COUNTER		BIT(31)236	u32 poweroff_timer;237	u64 core_en_mask;238	u32 reserved2;239	u32 perfcnt_as;240	u64 perfcnt_base;241	u32 perfcnt_extract;242	u32 reserved3[3];243	u32 perfcnt_config;244	u32 perfcnt_csg_select;245	u32 perfcnt_fw_enable;246	u32 perfcnt_csg_enable;247	u32 perfcnt_csf_enable;248	u32 perfcnt_shader_enable;249	u32 perfcnt_tiler_enable;250	u32 perfcnt_mmu_l2_enable;251	u32 reserved4[8];252	u32 idle_timer;253};254 255enum panthor_fw_halt_status {256	PANTHOR_FW_HALT_OK = 0,257	PANTHOR_FW_HALT_ON_PANIC = 0x4e,258	PANTHOR_FW_HALT_ON_WATCHDOG_EXPIRATION = 0x4f,259};260 261struct panthor_fw_global_output_iface {262	u32 ack;263	u32 reserved1;264	u32 doorbell_ack;265	u32 reserved2;266	u32 halt_status;267	u32 perfcnt_status;268	u32 perfcnt_insert;269};270 271/**272 * struct panthor_fw_cs_iface - Firmware command stream slot interface273 */274struct panthor_fw_cs_iface {275	/**276	 * @lock: Lock protecting access to the panthor_fw_cs_input_iface::req277	 * field.278	 *279	 * Needed so we can update the req field concurrently from the interrupt280	 * handler and the scheduler logic.281	 *282	 * TODO: Ideally we'd want to use a cmpxchg() to update the req, but FW283	 * interface sections are mapped uncached/write-combined right now, and284	 * using cmpxchg() on such mappings leads to SError faults. Revisit when285	 * we have 'SHARED' GPU mappings hooked up.286	 */287	spinlock_t lock;288 289	/**290	 * @control: Command stream slot control interface.291	 *292	 * Used to expose command stream slot properties.293	 *294	 * This interface is read-only.295	 */296	struct panthor_fw_cs_control_iface *control;297 298	/**299	 * @input: Command stream slot input interface.300	 *301	 * Used for host updates/events.302	 */303	struct panthor_fw_cs_input_iface *input;304 305	/**306	 * @output: Command stream slot output interface.307	 *308	 * Used for FW updates/events.309	 *310	 * This interface is read-only.311	 */312	const struct panthor_fw_cs_output_iface *output;313};314 315/**316 * struct panthor_fw_csg_iface - Firmware command stream group slot interface317 */318struct panthor_fw_csg_iface {319	/**320	 * @lock: Lock protecting access to the panthor_fw_csg_input_iface::req321	 * field.322	 *323	 * Needed so we can update the req field concurrently from the interrupt324	 * handler and the scheduler logic.325	 *326	 * TODO: Ideally we'd want to use a cmpxchg() to update the req, but FW327	 * interface sections are mapped uncached/write-combined right now, and328	 * using cmpxchg() on such mappings leads to SError faults. Revisit when329	 * we have 'SHARED' GPU mappings hooked up.330	 */331	spinlock_t lock;332 333	/**334	 * @control: Command stream group slot control interface.335	 *336	 * Used to expose command stream group slot properties.337	 *338	 * This interface is read-only.339	 */340	const struct panthor_fw_csg_control_iface *control;341 342	/**343	 * @input: Command stream slot input interface.344	 *345	 * Used for host updates/events.346	 */347	struct panthor_fw_csg_input_iface *input;348 349	/**350	 * @output: Command stream group slot output interface.351	 *352	 * Used for FW updates/events.353	 *354	 * This interface is read-only.355	 */356	const struct panthor_fw_csg_output_iface *output;357};358 359/**360 * struct panthor_fw_global_iface - Firmware global interface361 */362struct panthor_fw_global_iface {363	/**364	 * @lock: Lock protecting access to the panthor_fw_global_input_iface::req365	 * field.366	 *367	 * Needed so we can update the req field concurrently from the interrupt368	 * handler and the scheduler/FW management logic.369	 *370	 * TODO: Ideally we'd want to use a cmpxchg() to update the req, but FW371	 * interface sections are mapped uncached/write-combined right now, and372	 * using cmpxchg() on such mappings leads to SError faults. Revisit when373	 * we have 'SHARED' GPU mappings hooked up.374	 */375	spinlock_t lock;376 377	/**378	 * @control: Command stream group slot control interface.379	 *380	 * Used to expose global FW properties.381	 *382	 * This interface is read-only.383	 */384	const struct panthor_fw_global_control_iface *control;385 386	/**387	 * @input: Global input interface.388	 *389	 * Used for host updates/events.390	 */391	struct panthor_fw_global_input_iface *input;392 393	/**394	 * @output: Global output interface.395	 *396	 * Used for FW updates/events.397	 *398	 * This interface is read-only.399	 */400	const struct panthor_fw_global_output_iface *output;401};402 403/**404 * panthor_fw_toggle_reqs() - Toggle acknowledge bits to send an event to the FW405 * @__iface: The interface to operate on.406 * @__in_reg: Name of the register to update in the input section of the interface.407 * @__out_reg: Name of the register to take as a reference in the output section of the408 * interface.409 * @__mask: Mask to apply to the update.410 *411 * The Host -> FW event/message passing was designed to be lockless, with each side of412 * the channel having its writeable section. Events are signaled as a difference between413 * the host and FW side in the req/ack registers (when a bit differs, there's an event414 * pending, when they are the same, nothing needs attention).415 *416 * This helper allows one to update the req register based on the current value of the417 * ack register managed by the FW. Toggling a specific bit will flag an event. In order418 * for events to be re-evaluated, the interface doorbell needs to be rung.419 *420 * Concurrent accesses to the same req register is covered.421 *422 * Anything requiring atomic updates to multiple registers requires a dedicated lock.423 */424#define panthor_fw_toggle_reqs(__iface, __in_reg, __out_reg, __mask) \425	do { \426		u32 __cur_val, __new_val, __out_val; \427		spin_lock(&(__iface)->lock); \428		__cur_val = READ_ONCE((__iface)->input->__in_reg); \429		__out_val = READ_ONCE((__iface)->output->__out_reg); \430		__new_val = ((__out_val ^ (__mask)) & (__mask)) | (__cur_val & ~(__mask)); \431		WRITE_ONCE((__iface)->input->__in_reg, __new_val); \432		spin_unlock(&(__iface)->lock); \433	} while (0)434 435/**436 * panthor_fw_update_reqs() - Update bits to reflect a configuration change437 * @__iface: The interface to operate on.438 * @__in_reg: Name of the register to update in the input section of the interface.439 * @__val: Value to set.440 * @__mask: Mask to apply to the update.441 *442 * Some configuration get passed through req registers that are also used to443 * send events to the FW. Those req registers being updated from the interrupt444 * handler, they require special helpers to update the configuration part as well.445 *446 * Concurrent accesses to the same req register is covered.447 *448 * Anything requiring atomic updates to multiple registers requires a dedicated lock.449 */450#define panthor_fw_update_reqs(__iface, __in_reg, __val, __mask) \451	do { \452		u32 __cur_val, __new_val; \453		spin_lock(&(__iface)->lock); \454		__cur_val = READ_ONCE((__iface)->input->__in_reg); \455		__new_val = (__cur_val & ~(__mask)) | ((__val) & (__mask)); \456		WRITE_ONCE((__iface)->input->__in_reg, __new_val); \457		spin_unlock(&(__iface)->lock); \458	} while (0)459 460struct panthor_fw_global_iface *461panthor_fw_get_glb_iface(struct panthor_device *ptdev);462 463struct panthor_fw_csg_iface *464panthor_fw_get_csg_iface(struct panthor_device *ptdev, u32 csg_slot);465 466struct panthor_fw_cs_iface *467panthor_fw_get_cs_iface(struct panthor_device *ptdev, u32 csg_slot, u32 cs_slot);468 469int panthor_fw_csg_wait_acks(struct panthor_device *ptdev, u32 csg_id, u32 req_mask,470			     u32 *acked, u32 timeout_ms);471 472int panthor_fw_glb_wait_acks(struct panthor_device *ptdev, u32 req_mask, u32 *acked,473			     u32 timeout_ms);474 475void panthor_fw_ring_csg_doorbells(struct panthor_device *ptdev, u32 csg_slot);476 477struct panthor_kernel_bo *478panthor_fw_alloc_queue_iface_mem(struct panthor_device *ptdev,479				 struct panthor_fw_ringbuf_input_iface **input,480				 const struct panthor_fw_ringbuf_output_iface **output,481				 u32 *input_fw_va, u32 *output_fw_va);482struct panthor_kernel_bo *483panthor_fw_alloc_suspend_buf_mem(struct panthor_device *ptdev, size_t size);484 485struct panthor_vm *panthor_fw_vm(struct panthor_device *ptdev);486 487void panthor_fw_pre_reset(struct panthor_device *ptdev, bool on_hang);488int panthor_fw_post_reset(struct panthor_device *ptdev);489 490static inline void panthor_fw_suspend(struct panthor_device *ptdev)491{492	panthor_fw_pre_reset(ptdev, false);493}494 495static inline int panthor_fw_resume(struct panthor_device *ptdev)496{497	return panthor_fw_post_reset(ptdev);498}499 500int panthor_fw_init(struct panthor_device *ptdev);501void panthor_fw_unplug(struct panthor_device *ptdev);502 503#endif504