]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - drivers/media/pci/intel/ipu6/ipu6se-fw-resources.c
c0413fbddef6132dbb64ef36fb473e99e7d60045
[mirror_ubuntu-jammy-kernel.git] / drivers / media / pci / intel / ipu6 / ipu6se-fw-resources.c
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2015 - 2019 Intel Corporation
3
4 #include <linux/err.h>
5 #include <linux/string.h>
6
7 #include "ipu-psys.h"
8 #include "ipu-fw-psys.h"
9 #include "ipu6se-platform-resources.h"
10
11 /* resources table */
12
13 /*
14 * Cell types by cell IDs
15 */
16 /* resources table */
17
18 /*
19 * Cell types by cell IDs
20 */
21 const u8 ipu6se_fw_psys_cell_types[IPU6SE_FW_PSYS_N_CELL_ID] = {
22 IPU6SE_FW_PSYS_SP_CTRL_TYPE_ID,
23 IPU6SE_FW_PSYS_ACC_ISA_TYPE_ID, /* IPU6SE_FW_PSYS_ISA_ICA_ID */
24 IPU6SE_FW_PSYS_ACC_ISA_TYPE_ID, /* IPU6SE_FW_PSYS_ISA_LSC_ID */
25 IPU6SE_FW_PSYS_ACC_ISA_TYPE_ID, /* IPU6SE_FW_PSYS_ISA_DPC_ID */
26 IPU6SE_FW_PSYS_ACC_ISA_TYPE_ID, /* IPU6SE_FW_PSYS_ISA_B2B_ID */
27 IPU6SE_FW_PSYS_ACC_ISA_TYPE_ID, /* IPU6SE_FW_PSYS_ISA_BNLM_ID */
28 IPU6SE_FW_PSYS_ACC_ISA_TYPE_ID, /* IPU6SE_FW_PSYS_ISA_DM_ID */
29 IPU6SE_FW_PSYS_ACC_ISA_TYPE_ID, /* IPU6SE_FW_PSYS_ISA_R2I_SIE_ID */
30 IPU6SE_FW_PSYS_ACC_ISA_TYPE_ID, /* IPU6SE_FW_PSYS_ISA_R2I_DS_A_ID */
31 IPU6SE_FW_PSYS_ACC_ISA_TYPE_ID, /* IPU6SE_FW_PSYS_ISA_R2I_DS_B_ID */
32 IPU6SE_FW_PSYS_ACC_ISA_TYPE_ID, /* IPU6SE_FW_PSYS_ISA_AWB_ID */
33 IPU6SE_FW_PSYS_ACC_ISA_TYPE_ID, /* IPU6SE_FW_PSYS_ISA_AE_ID */
34 IPU6SE_FW_PSYS_ACC_ISA_TYPE_ID, /* IPU6SE_FW_PSYS_ISA_AF_ID*/
35 IPU6SE_FW_PSYS_ACC_ISA_TYPE_ID /* PAF */
36 };
37
38 const u16 ipu6se_fw_num_dev_channels[IPU6SE_FW_PSYS_N_DEV_CHN_ID] = {
39 IPU6SE_FW_PSYS_DEV_CHN_DMA_EXT0_MAX_SIZE,
40 IPU6SE_FW_PSYS_DEV_CHN_DMA_EXT1_READ_MAX_SIZE,
41 IPU6SE_FW_PSYS_DEV_CHN_DMA_EXT1_WRITE_MAX_SIZE,
42 IPU6SE_FW_PSYS_DEV_CHN_DMA_ISA_MAX_SIZE,
43 };
44
45 const u16 ipu6se_fw_psys_mem_size[IPU6SE_FW_PSYS_N_MEM_ID] = {
46 IPU6SE_FW_PSYS_TRANSFER_VMEM0_MAX_SIZE,
47 IPU6SE_FW_PSYS_LB_VMEM_MAX_SIZE,
48 IPU6SE_FW_PSYS_DMEM0_MAX_SIZE,
49 IPU6SE_FW_PSYS_DMEM1_MAX_SIZE
50 };
51
52 const u16 ipu6se_fw_psys_dfms[IPU6SE_FW_PSYS_N_DEV_DFM_ID] = {
53 IPU6SE_FW_PSYS_DEV_DFM_ISL_FULL_PORT_ID_MAX_SIZE,
54 IPU6SE_FW_PSYS_DEV_DFM_ISL_EMPTY_PORT_ID_MAX_SIZE
55 };
56
57 const u8
58 ipu6se_fw_psys_c_mem[IPU6SE_FW_PSYS_N_CELL_ID][IPU6SE_FW_PSYS_N_MEM_TYPE_ID] = {
59 { /* IPU6SE_FW_PSYS_SP0_ID */
60 IPU6SE_FW_PSYS_N_MEM_ID,
61 IPU6SE_FW_PSYS_N_MEM_ID,
62 IPU6SE_FW_PSYS_DMEM0_ID,
63 IPU6SE_FW_PSYS_N_MEM_ID,
64 IPU6SE_FW_PSYS_N_MEM_ID,
65 IPU6SE_FW_PSYS_N_MEM_ID,
66 },
67 { /* IPU6SE_FW_PSYS_ISA_ICA_ID */
68 IPU6SE_FW_PSYS_TRANSFER_VMEM0_ID,
69 IPU6SE_FW_PSYS_LB_VMEM_ID,
70 IPU6SE_FW_PSYS_N_MEM_ID,
71 IPU6SE_FW_PSYS_N_MEM_ID,
72 IPU6SE_FW_PSYS_N_MEM_ID,
73 IPU6SE_FW_PSYS_N_MEM_ID,
74 },
75 { /* IPU6SE_FW_PSYS_ISA_LSC_ID */
76 IPU6SE_FW_PSYS_TRANSFER_VMEM0_ID,
77 IPU6SE_FW_PSYS_LB_VMEM_ID,
78 IPU6SE_FW_PSYS_N_MEM_ID,
79 IPU6SE_FW_PSYS_N_MEM_ID,
80 IPU6SE_FW_PSYS_N_MEM_ID,
81 IPU6SE_FW_PSYS_N_MEM_ID,
82 },
83 { /* IPU6SE_FW_PSYS_ISA_DPC_ID */
84 IPU6SE_FW_PSYS_TRANSFER_VMEM0_ID,
85 IPU6SE_FW_PSYS_LB_VMEM_ID,
86 IPU6SE_FW_PSYS_N_MEM_ID,
87 IPU6SE_FW_PSYS_N_MEM_ID,
88 IPU6SE_FW_PSYS_N_MEM_ID,
89 IPU6SE_FW_PSYS_N_MEM_ID,
90 },
91 { /* IPU6SE_FW_PSYS_ISA_B2B_ID */
92 IPU6SE_FW_PSYS_TRANSFER_VMEM0_ID,
93 IPU6SE_FW_PSYS_LB_VMEM_ID,
94 IPU6SE_FW_PSYS_N_MEM_ID,
95 IPU6SE_FW_PSYS_N_MEM_ID,
96 IPU6SE_FW_PSYS_N_MEM_ID,
97 IPU6SE_FW_PSYS_N_MEM_ID,
98 },
99
100 { /* IPU6SE_FW_PSYS_ISA_BNLM_ID */
101 IPU6SE_FW_PSYS_TRANSFER_VMEM0_ID,
102 IPU6SE_FW_PSYS_LB_VMEM_ID,
103 IPU6SE_FW_PSYS_N_MEM_ID,
104 IPU6SE_FW_PSYS_N_MEM_ID,
105 IPU6SE_FW_PSYS_N_MEM_ID,
106 IPU6SE_FW_PSYS_N_MEM_ID,
107 },
108 { /* IPU6SE_FW_PSYS_ISA_DM_ID */
109 IPU6SE_FW_PSYS_TRANSFER_VMEM0_ID,
110 IPU6SE_FW_PSYS_LB_VMEM_ID,
111 IPU6SE_FW_PSYS_N_MEM_ID,
112 IPU6SE_FW_PSYS_N_MEM_ID,
113 IPU6SE_FW_PSYS_N_MEM_ID,
114 IPU6SE_FW_PSYS_N_MEM_ID,
115 },
116 { /* IPU6SE_FW_PSYS_ISA_R2I_SIE_ID */
117 IPU6SE_FW_PSYS_TRANSFER_VMEM0_ID,
118 IPU6SE_FW_PSYS_LB_VMEM_ID,
119 IPU6SE_FW_PSYS_N_MEM_ID,
120 IPU6SE_FW_PSYS_N_MEM_ID,
121 IPU6SE_FW_PSYS_N_MEM_ID,
122 IPU6SE_FW_PSYS_N_MEM_ID,
123 },
124 { /* IPU6SE_FW_PSYS_ISA_R2I_DS_A_ID */
125 IPU6SE_FW_PSYS_TRANSFER_VMEM0_ID,
126 IPU6SE_FW_PSYS_LB_VMEM_ID,
127 IPU6SE_FW_PSYS_N_MEM_ID,
128 IPU6SE_FW_PSYS_N_MEM_ID,
129 IPU6SE_FW_PSYS_N_MEM_ID,
130 IPU6SE_FW_PSYS_N_MEM_ID,
131 },
132 { /* IPU6SE_FW_PSYS_ISA_R2I_DS_B_ID */
133 IPU6SE_FW_PSYS_TRANSFER_VMEM0_ID,
134 IPU6SE_FW_PSYS_LB_VMEM_ID,
135 IPU6SE_FW_PSYS_N_MEM_ID,
136 IPU6SE_FW_PSYS_N_MEM_ID,
137 IPU6SE_FW_PSYS_N_MEM_ID,
138 IPU6SE_FW_PSYS_N_MEM_ID,
139 },
140 { /* IPU6SE_FW_PSYS_ISA_AWB_ID */
141 IPU6SE_FW_PSYS_TRANSFER_VMEM0_ID,
142 IPU6SE_FW_PSYS_LB_VMEM_ID,
143 IPU6SE_FW_PSYS_N_MEM_ID,
144 IPU6SE_FW_PSYS_N_MEM_ID,
145 IPU6SE_FW_PSYS_N_MEM_ID,
146 IPU6SE_FW_PSYS_N_MEM_ID,
147 },
148 { /* IPU6SE_FW_PSYS_ISA_AE_ID */
149 IPU6SE_FW_PSYS_TRANSFER_VMEM0_ID,
150 IPU6SE_FW_PSYS_LB_VMEM_ID,
151 IPU6SE_FW_PSYS_N_MEM_ID,
152 IPU6SE_FW_PSYS_N_MEM_ID,
153 IPU6SE_FW_PSYS_N_MEM_ID,
154 IPU6SE_FW_PSYS_N_MEM_ID,
155 },
156 { /* IPU6SE_FW_PSYS_ISA_AF_ID */
157 IPU6SE_FW_PSYS_TRANSFER_VMEM0_ID,
158 IPU6SE_FW_PSYS_LB_VMEM_ID,
159 IPU6SE_FW_PSYS_N_MEM_ID,
160 IPU6SE_FW_PSYS_N_MEM_ID,
161 IPU6SE_FW_PSYS_N_MEM_ID,
162 IPU6SE_FW_PSYS_N_MEM_ID,
163 },
164 { /* IPU6SE_FW_PSYS_ISA_PAF_ID */
165 IPU6SE_FW_PSYS_TRANSFER_VMEM0_ID,
166 IPU6SE_FW_PSYS_LB_VMEM_ID,
167 IPU6SE_FW_PSYS_N_MEM_ID,
168 IPU6SE_FW_PSYS_N_MEM_ID,
169 IPU6SE_FW_PSYS_N_MEM_ID,
170 IPU6SE_FW_PSYS_N_MEM_ID,
171 }
172 };
173
174 static const struct ipu_fw_resource_definitions ipu6se_defs = {
175 .cells = ipu6se_fw_psys_cell_types,
176 .num_cells = IPU6SE_FW_PSYS_N_CELL_ID,
177 .num_cells_type = IPU6SE_FW_PSYS_N_CELL_TYPE_ID,
178
179 .dev_channels = ipu6se_fw_num_dev_channels,
180 .num_dev_channels = IPU6SE_FW_PSYS_N_DEV_CHN_ID,
181
182 .num_ext_mem_types = IPU6SE_FW_PSYS_N_DATA_MEM_TYPE_ID,
183 .num_ext_mem_ids = IPU6SE_FW_PSYS_N_MEM_ID,
184 .ext_mem_ids = ipu6se_fw_psys_mem_size,
185
186 .num_dfm_ids = IPU6SE_FW_PSYS_N_DEV_DFM_ID,
187
188 .dfms = ipu6se_fw_psys_dfms,
189
190 .cell_mem_row = IPU6SE_FW_PSYS_N_MEM_TYPE_ID,
191 .cell_mem = &ipu6se_fw_psys_c_mem[0][0],
192 };
193
194 const struct ipu_fw_resource_definitions *ipu6se_res_defs = &ipu6se_defs;
195
196 int ipu6se_fw_psys_set_proc_dev_chn(struct ipu_fw_psys_process *ptr, u16 offset,
197 u16 value)
198 {
199 struct ipu6se_fw_psys_process_ext *pm_ext;
200 u8 ps_ext_offset;
201
202 ps_ext_offset = ptr->process_extension_offset;
203 if (!ps_ext_offset)
204 return -EINVAL;
205
206 pm_ext = (struct ipu6se_fw_psys_process_ext *)((u8 *)ptr +
207 ps_ext_offset);
208
209 pm_ext->dev_chn_offset[offset] = value;
210
211 return 0;
212 }
213
214 int ipu6se_fw_psys_set_proc_dfm_bitmap(struct ipu_fw_psys_process *ptr,
215 u16 id, u32 bitmap,
216 u32 active_bitmap)
217 {
218 struct ipu6se_fw_psys_process_ext *pm_ext;
219 u8 ps_ext_offset;
220
221 ps_ext_offset = ptr->process_extension_offset;
222 if (!ps_ext_offset)
223 return -EINVAL;
224
225 pm_ext = (struct ipu6se_fw_psys_process_ext *)((u8 *)ptr +
226 ps_ext_offset);
227
228 pm_ext->dfm_port_bitmap[id] = bitmap;
229 pm_ext->dfm_active_port_bitmap[id] = active_bitmap;
230
231 return 0;
232 }
233
234 int ipu6se_fw_psys_set_process_ext_mem(struct ipu_fw_psys_process *ptr,
235 u16 type_id, u16 mem_id, u16 offset)
236 {
237 struct ipu6se_fw_psys_process_ext *pm_ext;
238 u8 ps_ext_offset;
239
240 ps_ext_offset = ptr->process_extension_offset;
241 if (!ps_ext_offset)
242 return -EINVAL;
243
244 pm_ext = (struct ipu6se_fw_psys_process_ext *)((u8 *)ptr +
245 ps_ext_offset);
246
247 pm_ext->ext_mem_offset[type_id] = offset;
248 pm_ext->ext_mem_id[type_id] = mem_id;
249
250 return 0;
251 }
252
253 static struct ipu_fw_psys_program_manifest *
254 get_program_manifest(const struct ipu_fw_psys_program_group_manifest *manifest,
255 const unsigned int program_index)
256 {
257 struct ipu_fw_psys_program_manifest *prg_manifest_base;
258 u8 *program_manifest = NULL;
259 u8 program_count;
260 unsigned int i;
261
262 program_count = manifest->program_count;
263
264 prg_manifest_base = (struct ipu_fw_psys_program_manifest *)
265 ((char *)manifest + manifest->program_manifest_offset);
266 if (program_index < program_count) {
267 program_manifest = (u8 *)prg_manifest_base;
268 for (i = 0; i < program_index; i++)
269 program_manifest +=
270 ((struct ipu_fw_psys_program_manifest *)
271 program_manifest)->size;
272 }
273
274 return (struct ipu_fw_psys_program_manifest *)program_manifest;
275 }
276
277 int ipu6se_fw_psys_get_program_manifest_by_process(
278 struct ipu_fw_generic_program_manifest *gen_pm,
279 const struct ipu_fw_psys_program_group_manifest *pg_manifest,
280 struct ipu_fw_psys_process *process)
281 {
282 u32 program_id = process->program_idx;
283 struct ipu_fw_psys_program_manifest *pm;
284 struct ipu6se_fw_psys_program_manifest_ext *pm_ext;
285
286 pm = get_program_manifest(pg_manifest, program_id);
287
288 if (!pm)
289 return -ENOENT;
290
291 if (pm->program_extension_offset) {
292 pm_ext = (struct ipu6se_fw_psys_program_manifest_ext *)
293 ((u8 *)pm + pm->program_extension_offset);
294
295 gen_pm->dev_chn_size = pm_ext->dev_chn_size;
296 gen_pm->dev_chn_offset = pm_ext->dev_chn_offset;
297 gen_pm->ext_mem_size = pm_ext->ext_mem_size;
298 gen_pm->ext_mem_offset = (u16 *)pm_ext->ext_mem_offset;
299 gen_pm->is_dfm_relocatable = pm_ext->is_dfm_relocatable;
300 gen_pm->dfm_port_bitmap = pm_ext->dfm_port_bitmap;
301 gen_pm->dfm_active_port_bitmap =
302 pm_ext->dfm_active_port_bitmap;
303 }
304
305 memcpy(gen_pm->cells, pm->cells, sizeof(pm->cells));
306 gen_pm->cell_id = pm->cells[0];
307 gen_pm->cell_type_id = pm->cell_type_id;
308
309 return 0;
310 }
311
312 void ipu6se_fw_psys_pg_dump(struct ipu_psys *psys,
313 struct ipu_psys_kcmd *kcmd, const char *note)
314 {
315 struct ipu_fw_psys_process_group *pg = kcmd->kpg->pg;
316 u32 pgid = pg->ID;
317 u8 processes = pg->process_count;
318 u16 *process_offset_table = (u16 *)((char *)pg + pg->processes_offset);
319 unsigned int p, chn, mem, mem_id;
320
321 dev_dbg(&psys->adev->dev, "%s %s pgid %i has %i processes:\n",
322 __func__, note, pgid, processes);
323
324 for (p = 0; p < processes; p++) {
325 struct ipu_fw_psys_process *process =
326 (struct ipu_fw_psys_process *)
327 ((char *)pg + process_offset_table[p]);
328 struct ipu6se_fw_psys_process_ext *pm_ext =
329 (struct ipu6se_fw_psys_process_ext *)((u8 *)process
330 + process->process_extension_offset);
331 dev_dbg(&psys->adev->dev, "\t process %i size=%u",
332 p, process->size);
333 if (!process->process_extension_offset)
334 continue;
335
336 for (mem = 0; mem < IPU6SE_FW_PSYS_N_DATA_MEM_TYPE_ID;
337 mem++) {
338 mem_id = pm_ext->ext_mem_id[mem];
339 if (mem_id != IPU6SE_FW_PSYS_N_MEM_ID)
340 dev_dbg(&psys->adev->dev,
341 "\t mem type %u id %d offset=0x%x",
342 mem, mem_id,
343 pm_ext->ext_mem_offset[mem]);
344 }
345 for (chn = 0; chn < IPU6SE_FW_PSYS_N_DEV_CHN_ID; chn++) {
346 if (pm_ext->dev_chn_offset[chn] != (u16)(-1))
347 dev_dbg(&psys->adev->dev,
348 "\t dev_chn[%u]=0x%x\n",
349 chn, pm_ext->dev_chn_offset[chn]);
350 }
351 }
352 }