1 /* SPDX-License-Identifier: GPL-2.0-only OR MIT */
2 /* Copyright (c) 2023 Imagination Technologies Ltd. */
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>
14 #include "pvr_device.h"
15 #include "pvr_rogue_fwif_shared.h"
17 /* Forward declaration from pvr_free_list.h. */
20 /* Forward declaration from pvr_gem.h. */
24 * struct pvr_hwrt_data - structure representing HWRT data
26 struct pvr_hwrt_data
{
27 /** @fw_obj: FW object representing the FW-side structure. */
28 struct pvr_fw_object
*fw_obj
;
30 /** @data: Local copy of FW-side structure. */
31 struct rogue_fwif_hwrtdata data
;
33 /** @freelist_node: List node connecting this HWRT to the local freelist. */
34 struct list_head freelist_node
;
37 * @srtc_obj: FW object representing shadow render target cache.
39 * Only valid if @max_rts > 1.
41 struct pvr_fw_object
*srtc_obj
;
44 * @raa_obj: FW object representing renders accumulation array.
46 * Only valid if @max_rts > 1.
48 struct pvr_fw_object
*raa_obj
;
50 /** @hwrt_dataset: Back pointer to owning HWRT dataset. */
51 struct pvr_hwrt_dataset
*hwrt_dataset
;
55 * struct pvr_hwrt_dataset - structure representing a HWRT data set.
57 struct pvr_hwrt_dataset
{
58 /** @ref_count: Reference count of object. */
59 struct kref ref_count
;
61 /** @pvr_dev: Pointer to device that owns this object. */
62 struct pvr_device
*pvr_dev
;
64 /** @common_fw_obj: FW object representing common FW-side structure. */
65 struct pvr_fw_object
*common_fw_obj
;
67 /** @common: Common HWRT data. */
68 struct rogue_fwif_hwrtdata_common common
;
70 /** @data: HWRT data structures belonging to this set. */
71 struct pvr_hwrt_data data
[ROGUE_FWIF_NUM_RTDATAS
];
73 /** @free_lists: Free lists used by HWRT data set. */
74 struct pvr_free_list
*free_lists
[ROGUE_FWIF_NUM_RTDATA_FREELISTS
];
76 /** @max_rts: Maximum render targets for this HWRT data set. */
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
);
85 pvr_destroy_hwrt_datasets_for_file(struct pvr_file
*pvr_file
);
88 * pvr_hwrt_dataset_lookup() - Lookup HWRT dataset pointer from handle
89 * @pvr_file: Pointer to pvr_file structure.
90 * @handle: Object handle.
92 * Takes reference on dataset object. Call pvr_hwrt_dataset_put() to release.
95 * * The requested object on success, or
96 * * %NULL on failure (object does not exist in list, or is not a HWRT
99 static __always_inline
struct pvr_hwrt_dataset
*
100 pvr_hwrt_dataset_lookup(struct pvr_file
*pvr_file
, u32 handle
)
102 struct pvr_hwrt_dataset
*hwrt
;
104 xa_lock(&pvr_file
->hwrt_handles
);
105 hwrt
= xa_load(&pvr_file
->hwrt_handles
, handle
);
108 kref_get(&hwrt
->ref_count
);
110 xa_unlock(&pvr_file
->hwrt_handles
);
116 pvr_hwrt_dataset_put(struct pvr_hwrt_dataset
*hwrt
);
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.
124 * Takes reference on dataset object. Call pvr_hwrt_data_put() to release.
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)
131 static __always_inline
struct pvr_hwrt_data
*
132 pvr_hwrt_data_lookup(struct pvr_file
*pvr_file
, u32 handle
, u32 index
)
134 struct pvr_hwrt_dataset
*hwrt_dataset
= pvr_hwrt_dataset_lookup(pvr_file
, handle
);
137 if (index
< ARRAY_SIZE(hwrt_dataset
->data
))
138 return &hwrt_dataset
->data
[index
];
140 pvr_hwrt_dataset_put(hwrt_dataset
);
147 * pvr_hwrt_data_put() - Release reference on HWRT data
148 * @hwrt: Pointer to HWRT data to release reference on
150 static __always_inline
void
151 pvr_hwrt_data_put(struct pvr_hwrt_data
*hwrt
)
154 pvr_hwrt_dataset_put(hwrt
->hwrt_dataset
);
157 static __always_inline
struct pvr_hwrt_data
*
158 pvr_hwrt_data_get(struct pvr_hwrt_data
*hwrt
)
161 kref_get(&hwrt
->hwrt_dataset
->ref_count
);
166 #endif /* PVR_HWRT_H */