1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2022 Imagination Technologies Ltd.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
5bf215546Sopenharmony_ci * of this software and associated documentation files (the "Software"), to deal
6bf215546Sopenharmony_ci * in the Software without restriction, including without limitation the rights
7bf215546Sopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8bf215546Sopenharmony_ci * copies of the Software, and to permit persons to whom the Software is
9bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18bf215546Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21bf215546Sopenharmony_ci * SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci/* This file is based on rgxdefs.h and should only contain function-like macros
25bf215546Sopenharmony_ci * and inline functions. Any object-like macros should instead appear in
26bf215546Sopenharmony_ci * rogue_hw_defs.h.
27bf215546Sopenharmony_ci */
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#ifndef ROGUE_HW_UTILS_H
30bf215546Sopenharmony_ci#define ROGUE_HW_UTILS_H
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci#include <stdint.h>
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci#include "pvr_types.h"
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_ci#define __pvr_address_type pvr_dev_addr_t
37bf215546Sopenharmony_ci#define __pvr_get_address(pvr_dev_addr) (pvr_dev_addr).addr
38bf215546Sopenharmony_ci/* clang-format off */
39bf215546Sopenharmony_ci#define __pvr_make_address(addr_u64) PVR_DEV_ADDR(addr_u64)
40bf215546Sopenharmony_ci/* clang-format on */
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci#include "csbgen/rogue_cdm.h"
43bf215546Sopenharmony_ci#include "csbgen/rogue_lls.h"
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ci#undef __pvr_make_address
46bf215546Sopenharmony_ci#undef __pvr_get_address
47bf215546Sopenharmony_ci#undef __pvr_address_type
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci#include "rogue_hw_defs.h"
50bf215546Sopenharmony_ci#include "pvr_device_info.h"
51bf215546Sopenharmony_ci#include "util/compiler.h"
52bf215546Sopenharmony_ci#include "util/macros.h"
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_cistatic inline void
55bf215546Sopenharmony_cirogue_get_isp_samples_per_tile_xy(const struct pvr_device_info *dev_info,
56bf215546Sopenharmony_ci                                  uint32_t samples,
57bf215546Sopenharmony_ci                                  uint32_t *const x_out,
58bf215546Sopenharmony_ci                                  uint32_t *const y_out)
59bf215546Sopenharmony_ci{
60bf215546Sopenharmony_ci   const uint32_t tile_size_x =
61bf215546Sopenharmony_ci      PVR_GET_FEATURE_VALUE(dev_info, tile_size_x, 0U);
62bf215546Sopenharmony_ci   const uint32_t tile_size_y =
63bf215546Sopenharmony_ci      PVR_GET_FEATURE_VALUE(dev_info, tile_size_y, 0U);
64bf215546Sopenharmony_ci   const uint32_t samples_per_pixel =
65bf215546Sopenharmony_ci      PVR_GET_FEATURE_VALUE(dev_info, isp_samples_per_pixel, 0U);
66bf215546Sopenharmony_ci
67bf215546Sopenharmony_ci#if !defined(NDEBUG)
68bf215546Sopenharmony_ci   switch (samples_per_pixel) {
69bf215546Sopenharmony_ci   case 1:
70bf215546Sopenharmony_ci   case 2:
71bf215546Sopenharmony_ci   case 4:
72bf215546Sopenharmony_ci      break;
73bf215546Sopenharmony_ci   default:
74bf215546Sopenharmony_ci      assert(!"Unsupported ISP samples per pixel");
75bf215546Sopenharmony_ci   }
76bf215546Sopenharmony_ci#endif
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_ci   *x_out = tile_size_x;
79bf215546Sopenharmony_ci   *y_out = tile_size_y;
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ci   switch (samples) {
82bf215546Sopenharmony_ci   case 1:
83bf215546Sopenharmony_ci      break;
84bf215546Sopenharmony_ci   case 2:
85bf215546Sopenharmony_ci      if (samples_per_pixel == 2 || samples_per_pixel == 4)
86bf215546Sopenharmony_ci         *y_out *= 2;
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ci      break;
89bf215546Sopenharmony_ci   case 4:
90bf215546Sopenharmony_ci      if (samples_per_pixel == 2 || samples_per_pixel == 4)
91bf215546Sopenharmony_ci         *x_out *= 2;
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci      if (samples_per_pixel == 2)
94bf215546Sopenharmony_ci         *y_out *= 2;
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ci      break;
97bf215546Sopenharmony_ci   case 8:
98bf215546Sopenharmony_ci      *y_out *= 2;
99bf215546Sopenharmony_ci      break;
100bf215546Sopenharmony_ci   default:
101bf215546Sopenharmony_ci      assert(!"Unsupported number of samples");
102bf215546Sopenharmony_ci   }
103bf215546Sopenharmony_ci}
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_cistatic inline uint64_t
106bf215546Sopenharmony_cirogue_get_min_free_list_size(const struct pvr_device_info *dev_info)
107bf215546Sopenharmony_ci{
108bf215546Sopenharmony_ci   uint64_t min_num_pages;
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_ci   if (PVR_HAS_FEATURE(dev_info, roguexe)) {
111bf215546Sopenharmony_ci      if (PVR_HAS_QUIRK(dev_info, 66011))
112bf215546Sopenharmony_ci         min_num_pages = 40U;
113bf215546Sopenharmony_ci      else
114bf215546Sopenharmony_ci         min_num_pages = 25U;
115bf215546Sopenharmony_ci   } else {
116bf215546Sopenharmony_ci      min_num_pages = 50U;
117bf215546Sopenharmony_ci   }
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_ci   return min_num_pages << ROGUE_BIF_PM_PHYSICAL_PAGE_SHIFT;
120bf215546Sopenharmony_ci}
121bf215546Sopenharmony_ci
122bf215546Sopenharmony_cistatic inline uint32_t
123bf215546Sopenharmony_cirogue_get_max_num_vdm_pds_tasks(const struct pvr_device_info *dev_info)
124bf215546Sopenharmony_ci{
125bf215546Sopenharmony_ci   /* Default value based on the minimum value found in all existing cores. */
126bf215546Sopenharmony_ci   uint32_t max_usc_tasks = PVR_GET_FEATURE_VALUE(dev_info, max_usc_tasks, 24U);
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci   /* FIXME: Where does the 9 come from? */
129bf215546Sopenharmony_ci   return max_usc_tasks - 9;
130bf215546Sopenharmony_ci}
131bf215546Sopenharmony_ci
132bf215546Sopenharmony_cistatic inline uint32_t
133bf215546Sopenharmony_cirogue_get_max_output_regs_per_pixel(const struct pvr_device_info *dev_info)
134bf215546Sopenharmony_ci{
135bf215546Sopenharmony_ci   if (PVR_HAS_FEATURE(dev_info, eight_output_registers))
136bf215546Sopenharmony_ci      return 8U;
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci   return 4U;
139bf215546Sopenharmony_ci}
140bf215546Sopenharmony_ci
141bf215546Sopenharmony_cistatic inline void
142bf215546Sopenharmony_cirogue_get_num_macrotiles_xy(const struct pvr_device_info *dev_info,
143bf215546Sopenharmony_ci                            uint32_t *const x_out,
144bf215546Sopenharmony_ci                            uint32_t *const y_out)
145bf215546Sopenharmony_ci{
146bf215546Sopenharmony_ci   uint32_t version;
147bf215546Sopenharmony_ci
148bf215546Sopenharmony_ci   if (PVR_FEATURE_VALUE(dev_info, simple_parameter_format_version, &version))
149bf215546Sopenharmony_ci      version = 0;
150bf215546Sopenharmony_ci
151bf215546Sopenharmony_ci   if (!PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format) ||
152bf215546Sopenharmony_ci       version == 2) {
153bf215546Sopenharmony_ci      *x_out = 4;
154bf215546Sopenharmony_ci      *y_out = 4;
155bf215546Sopenharmony_ci   } else {
156bf215546Sopenharmony_ci      *x_out = 1;
157bf215546Sopenharmony_ci      *y_out = 1;
158bf215546Sopenharmony_ci   }
159bf215546Sopenharmony_ci}
160bf215546Sopenharmony_ci
161bf215546Sopenharmony_cistatic inline uint32_t
162bf215546Sopenharmony_cirogue_get_macrotile_array_size(const struct pvr_device_info *dev_info)
163bf215546Sopenharmony_ci{
164bf215546Sopenharmony_ci   uint32_t num_macrotiles_x;
165bf215546Sopenharmony_ci   uint32_t num_macrotiles_y;
166bf215546Sopenharmony_ci
167bf215546Sopenharmony_ci   if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format))
168bf215546Sopenharmony_ci      return 0;
169bf215546Sopenharmony_ci
170bf215546Sopenharmony_ci   rogue_get_num_macrotiles_xy(dev_info, &num_macrotiles_x, &num_macrotiles_y);
171bf215546Sopenharmony_ci
172bf215546Sopenharmony_ci   return num_macrotiles_x * num_macrotiles_y * 8U;
173bf215546Sopenharmony_ci}
174bf215546Sopenharmony_ci
175bf215546Sopenharmony_ci/* Region header size in bytes. */
176bf215546Sopenharmony_cistatic inline uint32_t
177bf215546Sopenharmony_cirogue_get_region_header_size(const struct pvr_device_info *dev_info)
178bf215546Sopenharmony_ci{
179bf215546Sopenharmony_ci   uint32_t version;
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_ci   if (PVR_FEATURE_VALUE(dev_info, simple_parameter_format_version, &version))
182bf215546Sopenharmony_ci      version = 0;
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_ci   if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format) &&
185bf215546Sopenharmony_ci       version == 2) {
186bf215546Sopenharmony_ci      return 6;
187bf215546Sopenharmony_ci   }
188bf215546Sopenharmony_ci
189bf215546Sopenharmony_ci   return 5;
190bf215546Sopenharmony_ci}
191bf215546Sopenharmony_ci
192bf215546Sopenharmony_cistatic inline uint32_t
193bf215546Sopenharmony_cirogue_get_render_size_max(const struct pvr_device_info *dev_info)
194bf215546Sopenharmony_ci{
195bf215546Sopenharmony_ci   if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format))
196bf215546Sopenharmony_ci      if (!PVR_HAS_FEATURE(dev_info, screen_size8K))
197bf215546Sopenharmony_ci         return 4096U;
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ci   return 8192U;
200bf215546Sopenharmony_ci}
201bf215546Sopenharmony_ci
202bf215546Sopenharmony_ci#define rogue_get_render_size_max_x(dev_info) \
203bf215546Sopenharmony_ci   rogue_get_render_size_max(dev_info)
204bf215546Sopenharmony_ci
205bf215546Sopenharmony_ci#define rogue_get_render_size_max_y(dev_info) \
206bf215546Sopenharmony_ci   rogue_get_render_size_max(dev_info)
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_cistatic inline uint32_t
209bf215546Sopenharmony_cirogue_get_slc_cache_line_size(const struct pvr_device_info *dev_info)
210bf215546Sopenharmony_ci{
211bf215546Sopenharmony_ci   return PVR_GET_FEATURE_VALUE(dev_info, slc_cache_line_size_bits, 8U) / 8U;
212bf215546Sopenharmony_ci}
213bf215546Sopenharmony_ci
214bf215546Sopenharmony_cistatic inline uint32_t pvr_get_max_user_vertex_output_components(
215bf215546Sopenharmony_ci   const struct pvr_device_info *dev_info)
216bf215546Sopenharmony_ci{
217bf215546Sopenharmony_ci   const uint32_t uvs_pba_entries =
218bf215546Sopenharmony_ci      PVR_GET_FEATURE_VALUE(dev_info, uvs_pba_entries, 0U);
219bf215546Sopenharmony_ci   const uint32_t uvs_banks = PVR_GET_FEATURE_VALUE(dev_info, uvs_banks, 0U);
220bf215546Sopenharmony_ci
221bf215546Sopenharmony_ci   if (uvs_banks <= 8U && uvs_pba_entries == 160U)
222bf215546Sopenharmony_ci      return 64U;
223bf215546Sopenharmony_ci
224bf215546Sopenharmony_ci   return 128U;
225bf215546Sopenharmony_ci}
226bf215546Sopenharmony_ci
227bf215546Sopenharmony_cistatic inline uint32_t
228bf215546Sopenharmony_cirogue_max_compute_shared_registers(const struct pvr_device_info *dev_info)
229bf215546Sopenharmony_ci{
230bf215546Sopenharmony_ci   if (PVR_HAS_FEATURE(dev_info, compute))
231bf215546Sopenharmony_ci      return 2U * 1024U;
232bf215546Sopenharmony_ci
233bf215546Sopenharmony_ci   return 0U;
234bf215546Sopenharmony_ci}
235bf215546Sopenharmony_ci
236bf215546Sopenharmony_cistatic inline uint32_t
237bf215546Sopenharmony_cirogue_get_cdm_context_resume_buffer_size(const struct pvr_device_info *dev_info)
238bf215546Sopenharmony_ci{
239bf215546Sopenharmony_ci   if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support)) {
240bf215546Sopenharmony_ci      const uint32_t max_num_cores =
241bf215546Sopenharmony_ci         PVR_GET_FEATURE_VALUE(dev_info, xpu_max_slaves, 0U) + 1U;
242bf215546Sopenharmony_ci      const uint32_t cache_line_size = rogue_get_slc_cache_line_size(dev_info);
243bf215546Sopenharmony_ci      const uint32_t cdm_context_resume_buffer_stride =
244bf215546Sopenharmony_ci         ALIGN_POT(ROGUE_LLS_CDM_CONTEXT_RESUME_BUFFER_SIZE, cache_line_size);
245bf215546Sopenharmony_ci
246bf215546Sopenharmony_ci      return cdm_context_resume_buffer_stride * max_num_cores;
247bf215546Sopenharmony_ci   }
248bf215546Sopenharmony_ci
249bf215546Sopenharmony_ci   return ROGUE_LLS_CDM_CONTEXT_RESUME_BUFFER_SIZE;
250bf215546Sopenharmony_ci}
251bf215546Sopenharmony_ci
252bf215546Sopenharmony_cistatic inline uint32_t rogue_get_cdm_context_resume_buffer_alignment(
253bf215546Sopenharmony_ci   const struct pvr_device_info *dev_info)
254bf215546Sopenharmony_ci{
255bf215546Sopenharmony_ci   if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support))
256bf215546Sopenharmony_ci      return rogue_get_slc_cache_line_size(dev_info);
257bf215546Sopenharmony_ci
258bf215546Sopenharmony_ci   return ROGUE_LLS_CDM_CONTEXT_RESUME_BUFFER_ALIGNMENT;
259bf215546Sopenharmony_ci}
260bf215546Sopenharmony_ci
261bf215546Sopenharmony_cistatic inline uint32_t
262bf215546Sopenharmony_cirogue_get_compute_max_work_group_size(const struct pvr_device_info *dev_info)
263bf215546Sopenharmony_ci{
264bf215546Sopenharmony_ci   /* The number of tasks which can be executed per USC - Limited to 16U by the
265bf215546Sopenharmony_ci    * CDM.
266bf215546Sopenharmony_ci    */
267bf215546Sopenharmony_ci   const uint32_t max_tasks_per_usc = 16U;
268bf215546Sopenharmony_ci
269bf215546Sopenharmony_ci   if (!PVR_HAS_ERN(dev_info, 35421)) {
270bf215546Sopenharmony_ci      /* Barriers on work-groups > 32 instances aren't supported. */
271bf215546Sopenharmony_ci      return ROGUE_MAX_INSTANCES_PER_TASK;
272bf215546Sopenharmony_ci   }
273bf215546Sopenharmony_ci
274bf215546Sopenharmony_ci   return ROGUE_MAX_INSTANCES_PER_TASK * max_tasks_per_usc;
275bf215546Sopenharmony_ci}
276bf215546Sopenharmony_ci
277bf215546Sopenharmony_ci#endif /* ROGUE_HW_UTILS_H */
278