1 /* SPDX-License-Identifier: GPL-2.0-only OR MIT */ 2 /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 4 #ifndef PVR_HWRT_H 5 #define PVR_HWRT_H 6 7 #include <linux/compiler_attributes.h> 8 #include <linux/kref.h> 9 #include <linux/list.h> 10 #include <linux/types.h> 11 #include <linux/xarray.h> 12 #include <uapi/drm/pvr_drm.h> 13 14 #include "pvr_device.h" 15 #include "pvr_rogue_fwif_shared.h" 16 17 /* Forward declaration from pvr_free_list.h. */ 18 struct pvr_free_list; 19 20 /* Forward declaration from pvr_gem.h. */ 21 struct pvr_fw_object; 22 23 /** 24 * struct pvr_hwrt_data - structure representing HWRT data 25 */ 26 struct pvr_hwrt_data { 27 /** @fw_obj: FW object representing the FW-side structure. */ 28 struct pvr_fw_object *fw_obj; 29 30 /** @data: Local copy of FW-side structure. */ 31 struct rogue_fwif_hwrtdata data; 32 33 /** @freelist_node: List node connecting this HWRT to the local freelist. */ 34 struct list_head freelist_node; 35 36 /** 37 * @srtc_obj: FW object representing shadow render target cache. 38 * 39 * Only valid if @max_rts > 1. 40 */ 41 struct pvr_fw_object *srtc_obj; 42 43 /** 44 * @raa_obj: FW object representing renders accumulation array. 45 * 46 * Only valid if @max_rts > 1. 47 */ 48 struct pvr_fw_object *raa_obj; 49 50 /** @hwrt_dataset: Back pointer to owning HWRT dataset. */ 51 struct pvr_hwrt_dataset *hwrt_dataset; 52 }; 53 54 /** 55 * struct pvr_hwrt_dataset - structure representing a HWRT data set. 56 */ 57 struct pvr_hwrt_dataset { 58 /** @ref_count: Reference count of object. */ 59 struct kref ref_count; 60 61 /** @pvr_dev: Pointer to device that owns this object. */ 62 struct pvr_device *pvr_dev; 63 64 /** @common_fw_obj: FW object representing common FW-side structure. */ 65 struct pvr_fw_object *common_fw_obj; 66 67 /** @common: Common HWRT data. */ 68 struct rogue_fwif_hwrtdata_common common; 69 70 /** @data: HWRT data structures belonging to this set. */ 71 struct pvr_hwrt_data data[ROGUE_FWIF_NUM_RTDATAS]; 72 73 /** @free_lists: Free lists used by HWRT data set. */ 74 struct pvr_free_list *free_lists[ROGUE_FWIF_NUM_RTDATA_FREELISTS]; 75 76 /** @max_rts: Maximum render targets for this HWRT data set. */ 77 u16 max_rts; 78 }; 79 80 struct pvr_hwrt_dataset * 81 pvr_hwrt_dataset_create(struct pvr_file *pvr_file, 82 struct drm_pvr_ioctl_create_hwrt_dataset_args *args); 83 84 void 85 pvr_destroy_hwrt_datasets_for_file(struct pvr_file *pvr_file); 86 87 /** 88 * pvr_hwrt_dataset_lookup() - Lookup HWRT dataset pointer from handle 89 * @pvr_file: Pointer to pvr_file structure. 90 * @handle: Object handle. 91 * 92 * Takes reference on dataset object. Call pvr_hwrt_dataset_put() to release. 93 * 94 * Returns: 95 * * The requested object on success, or 96 * * %NULL on failure (object does not exist in list, or is not a HWRT 97 * dataset) 98 */ 99 static __always_inline struct pvr_hwrt_dataset * 100 pvr_hwrt_dataset_lookup(struct pvr_file *pvr_file, u32 handle) 101 { 102 struct pvr_hwrt_dataset *hwrt; 103 104 xa_lock(&pvr_file->hwrt_handles); 105 hwrt = xa_load(&pvr_file->hwrt_handles, handle); 106 107 if (hwrt) 108 kref_get(&hwrt->ref_count); 109 110 xa_unlock(&pvr_file->hwrt_handles); 111 112 return hwrt; 113 } 114 115 void 116 pvr_hwrt_dataset_put(struct pvr_hwrt_dataset *hwrt); 117 118 /** 119 * pvr_hwrt_data_lookup() - Lookup HWRT data pointer from handle and index 120 * @pvr_file: Pointer to pvr_file structure. 121 * @handle: Object handle. 122 * @index: Index of RT data within dataset. 123 * 124 * Takes reference on dataset object. Call pvr_hwrt_data_put() to release. 125 * 126 * Returns: 127 * * The requested object on success, or 128 * * %NULL on failure (object does not exist in list, or is not a HWRT 129 * dataset, or index is out of range) 130 */ 131 static __always_inline struct pvr_hwrt_data * 132 pvr_hwrt_data_lookup(struct pvr_file *pvr_file, u32 handle, u32 index) 133 { 134 struct pvr_hwrt_dataset *hwrt_dataset = pvr_hwrt_dataset_lookup(pvr_file, handle); 135 136 if (hwrt_dataset) { 137 if (index < ARRAY_SIZE(hwrt_dataset->data)) 138 return &hwrt_dataset->data[index]; 139 140 pvr_hwrt_dataset_put(hwrt_dataset); 141 } 142 143 return NULL; 144 } 145 146 /** 147 * pvr_hwrt_data_put() - Release reference on HWRT data 148 * @hwrt: Pointer to HWRT data to release reference on 149 */ 150 static __always_inline void 151 pvr_hwrt_data_put(struct pvr_hwrt_data *hwrt) 152 { 153 if (hwrt) 154 pvr_hwrt_dataset_put(hwrt->hwrt_dataset); 155 } 156 157 static __always_inline struct pvr_hwrt_data * 158 pvr_hwrt_data_get(struct pvr_hwrt_data *hwrt) 159 { 160 if (hwrt) 161 kref_get(&hwrt->hwrt_dataset->ref_count); 162 163 return hwrt; 164 } 165 166 #endif /* PVR_HWRT_H */ 167