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. */ 18struct pvr_free_list; 19 20/* Forward declaration from pvr_gem.h. */ 21struct pvr_fw_object; 22 23/** 24 * struct pvr_hwrt_data - structure representing HWRT data 25 */ 26struct 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 */ 57struct 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 80struct pvr_hwrt_dataset * 81pvr_hwrt_dataset_create(struct pvr_file *pvr_file, 82 struct drm_pvr_ioctl_create_hwrt_dataset_args *args); 83 84void 85pvr_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 */ 99static __always_inline struct pvr_hwrt_dataset * 100pvr_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 115void 116pvr_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 */ 131static __always_inline struct pvr_hwrt_data * 132pvr_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 */ 150static __always_inline void 151pvr_hwrt_data_put(struct pvr_hwrt_data *hwrt) 152{ 153 if (hwrt) 154 pvr_hwrt_dataset_put(hwrt->hwrt_dataset); 155} 156 157static __always_inline struct pvr_hwrt_data * 158pvr_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