brintos

brintos / linux-shallow public Read only

0
0
Text · 14.1 KiB · b7966bd Raw
510 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only OR MIT */2/* Copyright (c) 2023 Imagination Technologies Ltd. */3 4#ifndef PVR_FW_H5#define PVR_FW_H6 7#include "pvr_fw_info.h"8#include "pvr_fw_trace.h"9#include "pvr_gem.h"10 11#include <drm/drm_mm.h>12 13#include <linux/types.h>14 15/* Forward declarations from "pvr_device.h". */16struct pvr_device;17struct pvr_file;18 19/* Forward declaration from "pvr_vm.h". */20struct pvr_vm_context;21 22#define ROGUE_FWIF_FWCCB_NUMCMDS_LOG2 523 24#define ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT 725 26/**27 * struct pvr_fw_object - container for firmware memory allocations28 */29struct pvr_fw_object {30	/** @ref_count: FW object reference counter. */31	struct kref ref_count;32 33	/** @gem: GEM object backing the FW object. */34	struct pvr_gem_object *gem;35 36	/**37	 * @fw_mm_node: Node representing mapping in FW address space. @pvr_obj->lock must38	 *              be held when writing.39	 */40	struct drm_mm_node fw_mm_node;41 42	/**43	 * @fw_addr_offset: Virtual address offset of firmware mapping. Only44	 *                  valid if @flags has %PVR_GEM_OBJECT_FLAGS_FW_MAPPED45	 *                  set.46	 */47	u32 fw_addr_offset;48 49	/**50	 * @init: Initialisation callback. Will be called on object creation and FW hard reset.51	 *        Object will have been zeroed before this is called.52	 */53	void (*init)(void *cpu_ptr, void *priv);54 55	/** @init_priv: Private data for initialisation callback. */56	void *init_priv;57 58	/** @node: Node for firmware object list. */59	struct list_head node;60};61 62/**63 * struct pvr_fw_defs - FW processor function table and static definitions64 */65struct pvr_fw_defs {66	/**67	 * @init:68	 *69	 * FW processor specific initialisation.70	 * @pvr_dev: Target PowerVR device.71	 *72	 * This function must call pvr_fw_heap_calculate() to initialise the firmware heap for this73	 * FW processor.74	 *75	 * This function is mandatory.76	 *77	 * Returns:78	 *  * 0 on success, or79	 *  * Any appropriate error on failure.80	 */81	int (*init)(struct pvr_device *pvr_dev);82 83	/**84	 * @fini:85	 *86	 * FW processor specific finalisation.87	 * @pvr_dev: Target PowerVR device.88	 *89	 * This function is optional.90	 */91	void (*fini)(struct pvr_device *pvr_dev);92 93	/**94	 * @fw_process:95	 *96	 * Load and process firmware image.97	 * @pvr_dev: Target PowerVR device.98	 * @fw: Pointer to firmware image.99	 * @fw_code_ptr: Pointer to firmware code section.100	 * @fw_data_ptr: Pointer to firmware data section.101	 * @fw_core_code_ptr: Pointer to firmware core code section. May be %NULL.102	 * @fw_core_data_ptr: Pointer to firmware core data section. May be %NULL.103	 * @core_code_alloc_size: Total allocation size of core code section.104	 *105	 * This function is mandatory.106	 *107	 * Returns:108	 *  * 0 on success, or109	 *  * Any appropriate error on failure.110	 */111	int (*fw_process)(struct pvr_device *pvr_dev, const u8 *fw,112			  u8 *fw_code_ptr, u8 *fw_data_ptr, u8 *fw_core_code_ptr,113			  u8 *fw_core_data_ptr, u32 core_code_alloc_size);114 115	/**116	 * @vm_map:117	 *118	 * Map FW object into FW processor address space.119	 * @pvr_dev: Target PowerVR device.120	 * @fw_obj: FW object to map.121	 *122	 * This function is mandatory.123	 *124	 * Returns:125	 *  * 0 on success, or126	 *  * Any appropriate error on failure.127	 */128	int (*vm_map)(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj);129 130	/**131	 * @vm_unmap:132	 *133	 * Unmap FW object from FW processor address space.134	 * @pvr_dev: Target PowerVR device.135	 * @fw_obj: FW object to map.136	 *137	 * This function is mandatory.138	 */139	void (*vm_unmap)(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj);140 141	/**142	 * @get_fw_addr_with_offset:143	 *144	 * Called to get address of object in firmware address space, with offset.145	 * @fw_obj: Pointer to object.146	 * @offset: Desired offset from start of object.147	 *148	 * This function is mandatory.149	 *150	 * Returns:151	 *  * Address in firmware address space.152	 */153	u32 (*get_fw_addr_with_offset)(struct pvr_fw_object *fw_obj, u32 offset);154 155	/**156	 * @wrapper_init:157	 *158	 * Called to initialise FW wrapper.159	 * @pvr_dev: Target PowerVR device.160	 *161	 * This function is mandatory.162	 *163	 * Returns:164	 *  * 0 on success.165	 *  * Any appropriate error on failure.166	 */167	int (*wrapper_init)(struct pvr_device *pvr_dev);168 169	/**170	 * @has_fixed_data_addr:171	 *172	 * Called to check if firmware fixed data must be loaded at the address given by the173	 * firmware layout table.174	 *175	 * This function is mandatory.176	 *177	 * Returns:178	 *  * %true if firmware fixed data must be loaded at the address given by the firmware179	 *    layout table.180	 *  * %false otherwise.181	 */182	bool (*has_fixed_data_addr)(void);183 184	/**185	 * @irq: FW Interrupt information.186	 *187	 * Those are processor dependent, and should be initialized by the188	 * processor backend in pvr_fw_funcs::init().189	 */190	struct {191		/** @enable_reg: FW interrupt enable register. */192		u32 enable_reg;193 194		/** @status_reg: FW interrupt status register. */195		u32 status_reg;196 197		/**198		 * @clear_reg: FW interrupt clear register.199		 *200		 * If @status_reg == @clear_reg, we clear by write a bit to zero,201		 * otherwise we clear by writing a bit to one.202		 */203		u32 clear_reg;204 205		/** @event_mask: Bitmask of events to listen for. */206		u32 event_mask;207 208		/** @clear_mask: Value to write to the clear_reg in order to clear FW IRQs. */209		u32 clear_mask;210	} irq;211};212 213/**214 * struct pvr_fw_mem - FW memory allocations215 */216struct pvr_fw_mem {217	/** @code_obj: Object representing firmware code. */218	struct pvr_fw_object *code_obj;219 220	/** @data_obj: Object representing firmware data. */221	struct pvr_fw_object *data_obj;222 223	/**224	 * @core_code_obj: Object representing firmware core code. May be225	 *                 %NULL if firmware does not contain this section.226	 */227	struct pvr_fw_object *core_code_obj;228 229	/**230	 * @core_data_obj: Object representing firmware core data. May be231	 *                 %NULL if firmware does not contain this section.232	 */233	struct pvr_fw_object *core_data_obj;234 235	/** @code: Driver-side copy of firmware code. */236	u8 *code;237 238	/** @data: Driver-side copy of firmware data. */239	u8 *data;240 241	/**242	 * @core_code: Driver-side copy of firmware core code. May be %NULL if firmware does not243	 *             contain this section.244	 */245	u8 *core_code;246 247	/**248	 * @core_data: Driver-side copy of firmware core data. May be %NULL if firmware does not249	 *             contain this section.250	 */251	u8 *core_data;252 253	/** @code_alloc_size: Allocation size of firmware code section. */254	u32 code_alloc_size;255 256	/** @data_alloc_size: Allocation size of firmware data section. */257	u32 data_alloc_size;258 259	/** @core_code_alloc_size: Allocation size of firmware core code section. */260	u32 core_code_alloc_size;261 262	/** @core_data_alloc_size: Allocation size of firmware core data section. */263	u32 core_data_alloc_size;264 265	/**266	 * @fwif_connection_ctl_obj: Object representing FWIF connection control267	 *                           structure.268	 */269	struct pvr_fw_object *fwif_connection_ctl_obj;270 271	/** @osinit_obj: Object representing FW OSINIT structure. */272	struct pvr_fw_object *osinit_obj;273 274	/** @sysinit_obj: Object representing FW SYSINIT structure. */275	struct pvr_fw_object *sysinit_obj;276 277	/** @osdata_obj: Object representing FW OSDATA structure. */278	struct pvr_fw_object *osdata_obj;279 280	/** @hwrinfobuf_obj: Object representing FW hwrinfobuf structure. */281	struct pvr_fw_object *hwrinfobuf_obj;282 283	/** @sysdata_obj: Object representing FW SYSDATA structure. */284	struct pvr_fw_object *sysdata_obj;285 286	/** @power_sync_obj: Object representing power sync state. */287	struct pvr_fw_object *power_sync_obj;288 289	/** @fault_page_obj: Object representing FW fault page. */290	struct pvr_fw_object *fault_page_obj;291 292	/** @gpu_util_fwcb_obj: Object representing FW GPU utilisation control structure. */293	struct pvr_fw_object *gpu_util_fwcb_obj;294 295	/** @runtime_cfg_obj: Object representing FW runtime config structure. */296	struct pvr_fw_object *runtime_cfg_obj;297 298	/** @mmucache_sync_obj: Object used as the sync parameter in an MMU cache operation. */299	struct pvr_fw_object *mmucache_sync_obj;300};301 302struct pvr_fw_device {303	/** @firmware: Handle to the firmware loaded into the device. */304	const struct firmware *firmware;305 306	/** @header: Pointer to firmware header. */307	const struct pvr_fw_info_header *header;308 309	/** @layout_entries: Pointer to firmware layout. */310	const struct pvr_fw_layout_entry *layout_entries;311 312	/** @mem: Structure containing objects representing firmware memory allocations. */313	struct pvr_fw_mem mem;314 315	/** @booted: %true if the firmware has been booted, %false otherwise. */316	bool booted;317 318	/**319	 * @processor_type: FW processor type for this device. Must be one of320	 *                  %PVR_FW_PROCESSOR_TYPE_*.321	 */322	u16 processor_type;323 324	/** @funcs: Function table for the FW processor used by this device. */325	const struct pvr_fw_defs *defs;326 327	/** @processor_data: Pointer to data specific to FW processor. */328	union {329		/** @mips_data: Pointer to MIPS-specific data. */330		struct pvr_fw_mips_data *mips_data;331	} processor_data;332 333	/** @fw_heap_info: Firmware heap information. */334	struct {335		/** @gpu_addr: Base address of firmware heap in GPU address space. */336		u64 gpu_addr;337 338		/** @size: Size of main area of heap. */339		u32 size;340 341		/** @offset_mask: Mask for offsets within FW heap. */342		u32 offset_mask;343 344		/** @raw_size: Raw size of heap, including reserved areas. */345		u32 raw_size;346 347		/** @log2_size: Log2 of raw size of heap. */348		u32 log2_size;349 350		/** @config_offset: Offset of config area within heap. */351		u32 config_offset;352 353		/** @reserved_size: Size of reserved area in heap. */354		u32 reserved_size;355	} fw_heap_info;356 357	/** @fw_mm: Firmware address space allocator. */358	struct drm_mm fw_mm;359 360	/** @fw_mm_lock: Lock protecting access to &fw_mm. */361	spinlock_t fw_mm_lock;362 363	/** @fw_mm_base: Base address of address space managed by @fw_mm. */364	u64 fw_mm_base;365 366	/**367	 * @fwif_connection_ctl: Pointer to CPU mapping of FWIF connection368	 *                       control structure.369	 */370	struct rogue_fwif_connection_ctl *fwif_connection_ctl;371 372	/** @fwif_sysinit: Pointer to CPU mapping of FW SYSINIT structure. */373	struct rogue_fwif_sysinit *fwif_sysinit;374 375	/** @fwif_sysdata: Pointer to CPU mapping of FW SYSDATA structure. */376	struct rogue_fwif_sysdata *fwif_sysdata;377 378	/** @fwif_osinit: Pointer to CPU mapping of FW OSINIT structure. */379	struct rogue_fwif_osinit *fwif_osinit;380 381	/** @fwif_osdata: Pointer to CPU mapping of FW OSDATA structure. */382	struct rogue_fwif_osdata *fwif_osdata;383 384	/** @power_sync: Pointer to CPU mapping of power sync state. */385	u32 *power_sync;386 387	/** @hwrinfobuf: Pointer to CPU mapping of FW HWR info buffer. */388	struct rogue_fwif_hwrinfobuf *hwrinfobuf;389 390	/** @fw_trace: Device firmware trace buffer state. */391	struct pvr_fw_trace fw_trace;392 393	/** @fw_objs: Structure tracking FW objects. */394	struct {395		/** @list: Head of FW object list. */396		struct list_head list;397 398		/** @lock: Lock protecting access to FW object list. */399		struct mutex lock;400	} fw_objs;401};402 403#define pvr_fw_irq_read_reg(pvr_dev, name) \404	pvr_cr_read32((pvr_dev), (pvr_dev)->fw_dev.defs->irq.name ## _reg)405 406#define pvr_fw_irq_write_reg(pvr_dev, name, value) \407	pvr_cr_write32((pvr_dev), (pvr_dev)->fw_dev.defs->irq.name ## _reg, value)408 409#define pvr_fw_irq_pending(pvr_dev) \410	(pvr_fw_irq_read_reg(pvr_dev, status) & (pvr_dev)->fw_dev.defs->irq.event_mask)411 412#define pvr_fw_irq_clear(pvr_dev) \413	pvr_fw_irq_write_reg(pvr_dev, clear, (pvr_dev)->fw_dev.defs->irq.clear_mask)414 415#define pvr_fw_irq_enable(pvr_dev) \416	pvr_fw_irq_write_reg(pvr_dev, enable, (pvr_dev)->fw_dev.defs->irq.event_mask)417 418#define pvr_fw_irq_disable(pvr_dev) \419	pvr_fw_irq_write_reg(pvr_dev, enable, 0)420 421extern const struct pvr_fw_defs pvr_fw_defs_meta;422extern const struct pvr_fw_defs pvr_fw_defs_mips;423 424int pvr_fw_validate_init_device_info(struct pvr_device *pvr_dev);425int pvr_fw_init(struct pvr_device *pvr_dev);426void pvr_fw_fini(struct pvr_device *pvr_dev);427 428int pvr_wait_for_fw_boot(struct pvr_device *pvr_dev);429 430int431pvr_fw_hard_reset(struct pvr_device *pvr_dev);432 433void pvr_fw_mts_schedule(struct pvr_device *pvr_dev, u32 val);434 435void436pvr_fw_heap_info_init(struct pvr_device *pvr_dev, u32 log2_size, u32 reserved_size);437 438const struct pvr_fw_layout_entry *439pvr_fw_find_layout_entry(struct pvr_device *pvr_dev, enum pvr_fw_section_id id);440int441pvr_fw_find_mmu_segment(struct pvr_device *pvr_dev, u32 addr, u32 size, void *fw_code_ptr,442			void *fw_data_ptr, void *fw_core_code_ptr, void *fw_core_data_ptr,443			void **host_addr_out);444 445int446pvr_fw_structure_cleanup(struct pvr_device *pvr_dev, u32 type, struct pvr_fw_object *fw_obj,447			 u32 offset);448 449int pvr_fw_object_create(struct pvr_device *pvr_dev, size_t size, u64 flags,450			 void (*init)(void *cpu_ptr, void *priv), void *init_priv,451			 struct pvr_fw_object **pvr_obj_out);452 453void *pvr_fw_object_create_and_map(struct pvr_device *pvr_dev, size_t size, u64 flags,454				   void (*init)(void *cpu_ptr, void *priv),455				   void *init_priv, struct pvr_fw_object **pvr_obj_out);456 457void *458pvr_fw_object_create_and_map_offset(struct pvr_device *pvr_dev, u32 dev_offset, size_t size,459				    u64 flags, void (*init)(void *cpu_ptr, void *priv),460				    void *init_priv, struct pvr_fw_object **pvr_obj_out);461 462static __always_inline void *463pvr_fw_object_vmap(struct pvr_fw_object *fw_obj)464{465	return pvr_gem_object_vmap(fw_obj->gem);466}467 468static __always_inline void469pvr_fw_object_vunmap(struct pvr_fw_object *fw_obj)470{471	pvr_gem_object_vunmap(fw_obj->gem);472}473 474void pvr_fw_object_destroy(struct pvr_fw_object *fw_obj);475 476static __always_inline void477pvr_fw_object_unmap_and_destroy(struct pvr_fw_object *fw_obj)478{479	pvr_fw_object_vunmap(fw_obj);480	pvr_fw_object_destroy(fw_obj);481}482 483/**484 * pvr_fw_object_get_dma_addr() - Get DMA address for given offset in firmware485 * object.486 * @fw_obj: Pointer to object to lookup address in.487 * @offset: Offset within object to lookup address at.488 * @dma_addr_out: Pointer to location to store DMA address.489 *490 * Returns:491 *  * 0 on success, or492 *  * -%EINVAL if object is not currently backed, or if @offset is out of valid493 *    range for this object.494 */495static __always_inline int496pvr_fw_object_get_dma_addr(struct pvr_fw_object *fw_obj, u32 offset, dma_addr_t *dma_addr_out)497{498	return pvr_gem_get_dma_addr(fw_obj->gem, offset, dma_addr_out);499}500 501void pvr_fw_object_get_fw_addr_offset(struct pvr_fw_object *fw_obj, u32 offset, u32 *fw_addr_out);502 503static __always_inline void504pvr_fw_object_get_fw_addr(struct pvr_fw_object *fw_obj, u32 *fw_addr_out)505{506	pvr_fw_object_get_fw_addr_offset(fw_obj, 0, fw_addr_out);507}508 509#endif /* PVR_FW_H */510