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 struct rogue_fwif_hwrtdata_common common; 68 69 /** @data: HWRT data structures belonging to this set. */ 70 struct pvr_hwrt_data data[ROGUE_FWIF_NUM_RTDATAS]; 71 72 /** @free_lists: Free lists used by HWRT data set. */ 73 struct pvr_free_list *free_lists[ROGUE_FWIF_NUM_RTDATA_FREELISTS]; 74 75 /** @max_rts: Maximum render targets for this HWRT data set. */ 76 u16 max_rts; 77 }; 78 79 struct pvr_hwrt_dataset * 80 pvr_hwrt_dataset_create(struct pvr_file *pvr_file, 81 struct drm_pvr_ioctl_create_hwrt_dataset_args *args); 82 83 void 84 pvr_destroy_hwrt_datasets_for_file(struct pvr_file *pvr_file); 85 86 /** 87 * pvr_hwrt_dataset_lookup() - Lookup HWRT dataset pointer from handle 88 * @pvr_file: Pointer to pvr_file structure. 89 * @handle: Object handle. 90 * 91 * Takes reference on dataset object. Call pvr_hwrt_dataset_put() to release. 92 * 93 * Returns: 94 * * The requested object on success, or 95 * * %NULL on failure (object does not exist in list, or is not a HWRT 96 * dataset) 97 */ 98 static __always_inline struct pvr_hwrt_dataset * 99 pvr_hwrt_dataset_lookup(struct pvr_file *pvr_file, u32 handle) 100 { 101 struct pvr_hwrt_dataset *hwrt; 102 103 xa_lock(&pvr_file->hwrt_handles); 104 hwrt = xa_load(&pvr_file->hwrt_handles, handle); 105 106 if (hwrt) 107 kref_get(&hwrt->ref_count); 108 109 xa_unlock(&pvr_file->hwrt_handles); 110 111 return hwrt; 112 } 113 114 void 115 pvr_hwrt_dataset_put(struct pvr_hwrt_dataset *hwrt); 116 117 /** 118 * pvr_hwrt_data_lookup() - Lookup HWRT data pointer from handle and index 119 * @pvr_file: Pointer to pvr_file structure. 120 * @handle: Object handle. 121 * @index: Index of RT data within dataset. 122 * 123 * Takes reference on dataset object. Call pvr_hwrt_data_put() to release. 124 * 125 * Returns: 126 * * The requested object on success, or 127 * * %NULL on failure (object does not exist in list, or is not a HWRT 128 * dataset, or index is out of range) 129 */ 130 static __always_inline struct pvr_hwrt_data * 131 pvr_hwrt_data_lookup(struct pvr_file *pvr_file, u32 handle, u32 index) 132 { 133 struct pvr_hwrt_dataset *hwrt_dataset = pvr_hwrt_dataset_lookup(pvr_file, handle); 134 135 if (hwrt_dataset) { 136 if (index < ARRAY_SIZE(hwrt_dataset->data)) 137 return &hwrt_dataset->data[index]; 138 139 pvr_hwrt_dataset_put(hwrt_dataset); 140 } 141 142 return NULL; 143 } 144 145 /** 146 * pvr_hwrt_data_put() - Release reference on HWRT data 147 * @hwrt: Pointer to HWRT data to release reference on 148 */ 149 static __always_inline void 150 pvr_hwrt_data_put(struct pvr_hwrt_data *hwrt) 151 { 152 if (hwrt) 153 pvr_hwrt_dataset_put(hwrt->hwrt_dataset); 154 } 155 156 static __always_inline struct pvr_hwrt_data * 157 pvr_hwrt_data_get(struct pvr_hwrt_data *hwrt) 158 { 159 if (hwrt) 160 kref_get(&hwrt->hwrt_dataset->ref_count); 161 162 return hwrt; 163 } 164 165 #endif /* PVR_HWRT_H */ 166