1 // SPDX-License-Identifier: GPL-2.0
3 * Support for Intel Camera Imaging ISP subsystem.
4 * Copyright (c) 2015, Intel Corporation.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 #include "sh_css_sp.h"
20 #if !defined(HAS_NO_INPUT_FORMATTER)
21 #include "input_formatter.h"
24 #include "dma.h" /* N_DMA_CHANNEL_ID */
26 #include "ia_css_buffer.h"
27 #include "ia_css_binary.h"
28 #include "sh_css_hrt.h"
29 #include "sh_css_defs.h"
30 #include "sh_css_internal.h"
31 #include "ia_css_control.h"
32 #include "ia_css_debug.h"
33 #include "ia_css_debug_pipe.h"
34 #include "ia_css_event_public.h"
35 #include "ia_css_mmu.h"
36 #include "ia_css_stream.h"
37 #include "ia_css_isp_param.h"
38 #include "sh_css_params.h"
39 #include "sh_css_legacy.h"
40 #include "ia_css_frame_comm.h"
41 #if !defined(HAS_NO_INPUT_SYSTEM)
42 #include "ia_css_isys.h"
45 #include "gdc_device.h" /* HRT_GDC_N */
47 /*#include "sp.h"*/ /* host2sp_enqueue_frame_data() */
50 #include "assert_support.h"
51 #include "platform_support.h" /* hrt_sleep() */
53 #include "sw_event_global.h" /* Event IDs.*/
54 #include "ia_css_event.h"
55 #include "mmu_device.h"
56 #include "ia_css_spctrl.h"
59 #define offsetof(T, x) ((unsigned int)&(((T *)0)->x))
62 #define IA_CSS_INCLUDE_CONFIGURATIONS
63 #include "ia_css_isp_configs.h"
64 #define IA_CSS_INCLUDE_STATES
65 #include "ia_css_isp_states.h"
67 #include "isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.h"
69 struct sh_css_sp_group sh_css_sp_group;
70 struct sh_css_sp_stage sh_css_sp_stage;
71 struct sh_css_isp_stage sh_css_isp_stage;
72 static struct sh_css_sp_output sh_css_sp_output;
73 static struct sh_css_sp_per_frame_data per_frame_data;
75 /* true if SP supports frame loop and host2sp_commands */
76 /* For the moment there is only code that sets this bool to true */
77 /* TODO: add code that sets this bool to false */
78 static bool sp_running;
81 set_output_frame_buffer(const struct ia_css_frame *frame,
85 sh_css_copy_buffer_attr_to_spbuffer(struct ia_css_buffer_sp *dest_buf,
86 const enum sh_css_queue_id queue_id,
87 const ia_css_ptr xmem_addr,
88 const enum ia_css_buffer_type buf_type);
91 initialize_frame_buffer_attribute(struct ia_css_buffer_sp *buf_attr);
94 initialize_stage_frames(struct ia_css_frames_sp *frames);
96 /* This data is stored every frame */
98 store_sp_group_data(void)
100 per_frame_data.sp_group_addr = sh_css_store_sp_group_to_ddr();
104 copy_isp_stage_to_sp_stage(void)
106 /* [WW07.5]type casting will cause potential issues */
107 sh_css_sp_stage.num_stripes = (uint8_t)
108 sh_css_isp_stage.binary_info.iterator.num_stripes;
109 sh_css_sp_stage.row_stripes_height = (uint16_t)
110 sh_css_isp_stage.binary_info.iterator.row_stripes_height;
111 sh_css_sp_stage.row_stripes_overlap_lines = (uint16_t)
112 sh_css_isp_stage.binary_info.iterator.row_stripes_overlap_lines;
113 sh_css_sp_stage.top_cropping = (uint16_t)
114 sh_css_isp_stage.binary_info.pipeline.top_cropping;
115 /* moved to sh_css_sp_init_stage
116 sh_css_sp_stage.enable.vf_output =
117 sh_css_isp_stage.binary_info.enable.vf_veceven ||
118 sh_css_isp_stage.binary_info.num_output_pins > 1;
120 sh_css_sp_stage.enable.sdis = sh_css_isp_stage.binary_info.enable.dis;
121 sh_css_sp_stage.enable.s3a = sh_css_isp_stage.binary_info.enable.s3a;
125 store_sp_stage_data(enum ia_css_pipe_id id, unsigned int pipe_num,
128 unsigned int thread_id;
130 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
131 copy_isp_stage_to_sp_stage();
132 if (id != IA_CSS_PIPE_ID_COPY)
133 sh_css_sp_stage.isp_stage_addr =
134 sh_css_store_isp_stage_to_ddr(pipe_num, stage);
135 sh_css_sp_group.pipe[thread_id].sp_stage_addr[stage] =
136 sh_css_store_sp_stage_to_ddr(pipe_num, stage);
138 /* Clear for next frame */
139 sh_css_sp_stage.program_input_circuit = false;
143 store_sp_per_frame_data(const struct ia_css_fw_info *fw)
145 unsigned int HIVE_ADDR_sp_per_frame_data = 0;
150 case ia_css_sp_firmware:
151 HIVE_ADDR_sp_per_frame_data = fw->info.sp.per_frame_data;
153 case ia_css_acc_firmware:
154 HIVE_ADDR_sp_per_frame_data = fw->info.acc.per_frame_data;
156 case ia_css_isp_firmware:
160 sp_dmem_store(SP0_ID,
161 (unsigned int)sp_address_of(sp_per_frame_data),
163 sizeof(per_frame_data));
167 sh_css_store_sp_per_frame_data(enum ia_css_pipe_id pipe_id,
168 unsigned int pipe_num,
169 const struct ia_css_fw_info *sp_fw)
172 sp_fw = &sh_css_sp_fw;
174 store_sp_stage_data(pipe_id, pipe_num, 0);
175 store_sp_group_data();
176 store_sp_per_frame_data(sp_fw);
179 #if SP_DEBUG != SP_DEBUG_NONE
182 sh_css_sp_get_debug_state(struct sh_css_sp_debug_state *state)
184 const struct ia_css_fw_info *fw = &sh_css_sp_fw;
185 unsigned int HIVE_ADDR_sp_output = fw->info.sp.output;
187 unsigned int offset = (unsigned int)offsetof(struct sh_css_sp_output,
188 debug) / sizeof(int);
192 (void)HIVE_ADDR_sp_output; /* To get rid of warning in CRUN */
193 for (i = 0; i < sizeof(*state) / sizeof(int); i++)
194 ((unsigned *)state)[i] = load_sp_array_uint(sp_output, i + offset);
200 sh_css_sp_start_binary_copy(unsigned int pipe_num,
201 struct ia_css_frame *out_frame,
202 unsigned int two_ppc)
204 enum ia_css_pipe_id pipe_id;
205 unsigned int thread_id;
206 struct sh_css_sp_pipeline *pipe;
210 pipe_id = IA_CSS_PIPE_ID_CAPTURE;
211 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
212 pipe = &sh_css_sp_group.pipe[thread_id];
214 pipe->copy.bin.bytes_available = out_frame->data_bytes;
215 pipe->num_stages = 1;
216 pipe->pipe_id = pipe_id;
217 pipe->pipe_num = pipe_num;
218 pipe->thread_id = thread_id;
219 pipe->pipe_config = 0x0; /* No parameters */
220 pipe->pipe_qos_config = QOS_INVALID;
222 if (pipe->inout_port_config == 0) {
223 SH_CSS_PIPE_PORT_CONFIG_SET(pipe->inout_port_config,
224 (uint8_t)SH_CSS_PORT_INPUT,
225 (uint8_t)SH_CSS_HOST_TYPE, 1);
226 SH_CSS_PIPE_PORT_CONFIG_SET(pipe->inout_port_config,
227 (uint8_t)SH_CSS_PORT_OUTPUT,
228 (uint8_t)SH_CSS_HOST_TYPE, 1);
230 IA_CSS_LOG("pipe_id %d port_config %08x",
231 pipe->pipe_id, pipe->inout_port_config);
233 #if !defined(HAS_NO_INPUT_FORMATTER)
234 sh_css_sp_group.config.input_formatter.isp_2ppc = (uint8_t)two_ppc;
239 sh_css_sp_stage.num = stage_num;
240 sh_css_sp_stage.stage_type = SH_CSS_SP_STAGE_TYPE;
241 sh_css_sp_stage.func =
242 (unsigned int)IA_CSS_PIPELINE_BIN_COPY;
244 set_output_frame_buffer(out_frame, 0);
246 /* sp_bin_copy_init on the SP does not deal with dynamica/static yet */
247 /* For now always update the dynamic data from out frames. */
248 sh_css_store_sp_per_frame_data(pipe_id, pipe_num, &sh_css_sp_fw);
252 sh_css_sp_start_raw_copy(struct ia_css_frame *out_frame,
253 unsigned int pipe_num,
254 unsigned int two_ppc,
255 unsigned int max_input_width,
256 enum sh_css_pipe_config_override pipe_conf_override,
257 unsigned int if_config_index)
259 enum ia_css_pipe_id pipe_id;
260 unsigned int thread_id;
262 struct sh_css_sp_pipeline *pipe;
268 * Clear sh_css_sp_stage for easy debugging.
269 * program_input_circuit must be saved as it is set outside
272 u8 program_input_circuit;
274 program_input_circuit = sh_css_sp_stage.program_input_circuit;
275 memset(&sh_css_sp_stage, 0, sizeof(sh_css_sp_stage));
276 sh_css_sp_stage.program_input_circuit = program_input_circuit;
279 pipe_id = IA_CSS_PIPE_ID_COPY;
280 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
281 pipe = &sh_css_sp_group.pipe[thread_id];
283 pipe->copy.raw.height = out_frame->info.res.height;
284 pipe->copy.raw.width = out_frame->info.res.width;
285 pipe->copy.raw.padded_width = out_frame->info.padded_width;
286 pipe->copy.raw.raw_bit_depth = out_frame->info.raw_bit_depth;
287 pipe->copy.raw.max_input_width = max_input_width;
288 pipe->num_stages = 1;
289 pipe->pipe_id = pipe_id;
290 /* TODO: next indicates from which queues parameters need to be
291 sampled, needs checking/improvement */
292 if (pipe_conf_override == SH_CSS_PIPE_CONFIG_OVRD_NO_OVRD)
294 (SH_CSS_PIPE_CONFIG_SAMPLE_PARAMS << thread_id);
296 pipe->pipe_config = pipe_conf_override;
298 pipe->pipe_qos_config = QOS_INVALID;
300 if (pipe->inout_port_config == 0) {
301 SH_CSS_PIPE_PORT_CONFIG_SET(pipe->inout_port_config,
302 (uint8_t)SH_CSS_PORT_INPUT,
303 (uint8_t)SH_CSS_HOST_TYPE, 1);
304 SH_CSS_PIPE_PORT_CONFIG_SET(pipe->inout_port_config,
305 (uint8_t)SH_CSS_PORT_OUTPUT,
306 (uint8_t)SH_CSS_HOST_TYPE, 1);
308 IA_CSS_LOG("pipe_id %d port_config %08x",
309 pipe->pipe_id, pipe->inout_port_config);
311 #if !defined(HAS_NO_INPUT_FORMATTER)
312 sh_css_sp_group.config.input_formatter.isp_2ppc = (uint8_t)two_ppc;
317 sh_css_sp_stage.num = stage_num;
318 sh_css_sp_stage.xmem_bin_addr = 0x0;
319 sh_css_sp_stage.stage_type = SH_CSS_SP_STAGE_TYPE;
320 sh_css_sp_stage.func = (unsigned int)IA_CSS_PIPELINE_RAW_COPY;
321 sh_css_sp_stage.if_config_index = (uint8_t)if_config_index;
322 set_output_frame_buffer(out_frame, 0);
324 ia_css_debug_pipe_graph_dump_sp_raw_copy(out_frame);
328 sh_css_sp_start_isys_copy(struct ia_css_frame *out_frame,
329 unsigned int pipe_num, unsigned int max_input_width,
330 unsigned int if_config_index)
332 enum ia_css_pipe_id pipe_id;
333 unsigned int thread_id;
335 struct sh_css_sp_pipeline *pipe;
336 #if defined SH_CSS_ENABLE_METADATA
337 enum sh_css_queue_id queue_id;
344 * Clear sh_css_sp_stage for easy debugging.
345 * program_input_circuit must be saved as it is set outside
348 u8 program_input_circuit;
350 program_input_circuit = sh_css_sp_stage.program_input_circuit;
351 memset(&sh_css_sp_stage, 0, sizeof(sh_css_sp_stage));
352 sh_css_sp_stage.program_input_circuit = program_input_circuit;
355 pipe_id = IA_CSS_PIPE_ID_COPY;
356 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
357 pipe = &sh_css_sp_group.pipe[thread_id];
359 pipe->copy.raw.height = out_frame->info.res.height;
360 pipe->copy.raw.width = out_frame->info.res.width;
361 pipe->copy.raw.padded_width = out_frame->info.padded_width;
362 pipe->copy.raw.raw_bit_depth = out_frame->info.raw_bit_depth;
363 pipe->copy.raw.max_input_width = max_input_width;
364 pipe->num_stages = 1;
365 pipe->pipe_id = pipe_id;
366 pipe->pipe_config = 0x0; /* No parameters */
367 pipe->pipe_qos_config = QOS_INVALID;
369 initialize_stage_frames(&sh_css_sp_stage.frames);
370 sh_css_sp_stage.num = stage_num;
371 sh_css_sp_stage.xmem_bin_addr = 0x0;
372 sh_css_sp_stage.stage_type = SH_CSS_SP_STAGE_TYPE;
373 sh_css_sp_stage.func = (unsigned int)IA_CSS_PIPELINE_ISYS_COPY;
374 sh_css_sp_stage.if_config_index = (uint8_t)if_config_index;
376 set_output_frame_buffer(out_frame, 0);
378 #if defined SH_CSS_ENABLE_METADATA
379 if (pipe->metadata.height > 0) {
380 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_METADATA, thread_id,
382 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage.frames.metadata_buf,
383 queue_id, mmgr_EXCEPTION,
384 IA_CSS_BUFFER_TYPE_METADATA);
388 ia_css_debug_pipe_graph_dump_sp_raw_copy(out_frame);
392 sh_css_sp_get_binary_copy_size(void)
394 const struct ia_css_fw_info *fw = &sh_css_sp_fw;
395 unsigned int HIVE_ADDR_sp_output = fw->info.sp.output;
396 unsigned int offset = (unsigned int)offsetof(struct sh_css_sp_output,
397 bin_copy_bytes_copied) / sizeof(int);
398 (void)HIVE_ADDR_sp_output; /* To get rid of warning in CRUN */
399 return load_sp_array_uint(sp_output, offset);
403 sh_css_sp_get_sw_interrupt_value(unsigned int irq)
405 const struct ia_css_fw_info *fw = &sh_css_sp_fw;
406 unsigned int HIVE_ADDR_sp_output = fw->info.sp.output;
407 unsigned int offset = (unsigned int)offsetof(struct sh_css_sp_output,
410 (void)HIVE_ADDR_sp_output; /* To get rid of warning in CRUN */
411 return load_sp_array_uint(sp_output, offset + irq);
415 sh_css_copy_buffer_attr_to_spbuffer(struct ia_css_buffer_sp *dest_buf,
416 const enum sh_css_queue_id queue_id,
417 const ia_css_ptr xmem_addr,
418 const enum ia_css_buffer_type buf_type)
420 assert(buf_type < IA_CSS_NUM_BUFFER_TYPE);
421 if (queue_id > SH_CSS_INVALID_QUEUE_ID) {
423 * value >=0 indicates that function init_frame_pointers()
424 * should use the dynamic data address
426 assert(queue_id < SH_CSS_MAX_NUM_QUEUES);
428 /* Klocwork assumes assert can be disabled;
429 Since we can get there with any type, and it does not
430 know that frame_in->dynamic_data_index can only be set
431 for one of the types in the assert) it has to assume we
432 can get here for any type. however this could lead to an
433 out of bounds reference when indexing buf_type about 10
434 lines below. In order to satisfy KW an additional if
435 has been added. This one will always yield true.
437 if ((queue_id < SH_CSS_MAX_NUM_QUEUES)) {
438 dest_buf->buf_src.queue_id = queue_id;
441 assert(xmem_addr != mmgr_EXCEPTION);
442 dest_buf->buf_src.xmem_addr = xmem_addr;
444 dest_buf->buf_type = buf_type;
448 sh_css_copy_frame_to_spframe(struct ia_css_frame_sp *sp_frame_out,
449 const struct ia_css_frame *frame_in)
453 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
454 "sh_css_copy_frame_to_spframe():\n");
456 sh_css_copy_buffer_attr_to_spbuffer(&sp_frame_out->buf_attr,
457 frame_in->dynamic_queue_id,
461 ia_css_frame_info_to_frame_sp_info(&sp_frame_out->info, &frame_in->info);
463 switch (frame_in->info.format) {
464 case IA_CSS_FRAME_FORMAT_RAW_PACKED:
465 case IA_CSS_FRAME_FORMAT_RAW:
466 sp_frame_out->planes.raw.offset = frame_in->planes.raw.offset;
468 case IA_CSS_FRAME_FORMAT_RGB565:
469 case IA_CSS_FRAME_FORMAT_RGBA888:
470 sp_frame_out->planes.rgb.offset = frame_in->planes.rgb.offset;
472 case IA_CSS_FRAME_FORMAT_PLANAR_RGB888:
473 sp_frame_out->planes.planar_rgb.r.offset =
474 frame_in->planes.planar_rgb.r.offset;
475 sp_frame_out->planes.planar_rgb.g.offset =
476 frame_in->planes.planar_rgb.g.offset;
477 sp_frame_out->planes.planar_rgb.b.offset =
478 frame_in->planes.planar_rgb.b.offset;
480 case IA_CSS_FRAME_FORMAT_YUYV:
481 case IA_CSS_FRAME_FORMAT_UYVY:
482 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_8:
483 case IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8:
484 case IA_CSS_FRAME_FORMAT_YUV_LINE:
485 sp_frame_out->planes.yuyv.offset = frame_in->planes.yuyv.offset;
487 case IA_CSS_FRAME_FORMAT_NV11:
488 case IA_CSS_FRAME_FORMAT_NV12:
489 case IA_CSS_FRAME_FORMAT_NV12_16:
490 case IA_CSS_FRAME_FORMAT_NV12_TILEY:
491 case IA_CSS_FRAME_FORMAT_NV21:
492 case IA_CSS_FRAME_FORMAT_NV16:
493 case IA_CSS_FRAME_FORMAT_NV61:
494 sp_frame_out->planes.nv.y.offset =
495 frame_in->planes.nv.y.offset;
496 sp_frame_out->planes.nv.uv.offset =
497 frame_in->planes.nv.uv.offset;
499 case IA_CSS_FRAME_FORMAT_YUV420:
500 case IA_CSS_FRAME_FORMAT_YUV422:
501 case IA_CSS_FRAME_FORMAT_YUV444:
502 case IA_CSS_FRAME_FORMAT_YUV420_16:
503 case IA_CSS_FRAME_FORMAT_YUV422_16:
504 case IA_CSS_FRAME_FORMAT_YV12:
505 case IA_CSS_FRAME_FORMAT_YV16:
506 sp_frame_out->planes.yuv.y.offset =
507 frame_in->planes.yuv.y.offset;
508 sp_frame_out->planes.yuv.u.offset =
509 frame_in->planes.yuv.u.offset;
510 sp_frame_out->planes.yuv.v.offset =
511 frame_in->planes.yuv.v.offset;
513 case IA_CSS_FRAME_FORMAT_QPLANE6:
514 sp_frame_out->planes.plane6.r.offset =
515 frame_in->planes.plane6.r.offset;
516 sp_frame_out->planes.plane6.r_at_b.offset =
517 frame_in->planes.plane6.r_at_b.offset;
518 sp_frame_out->planes.plane6.gr.offset =
519 frame_in->planes.plane6.gr.offset;
520 sp_frame_out->planes.plane6.gb.offset =
521 frame_in->planes.plane6.gb.offset;
522 sp_frame_out->planes.plane6.b.offset =
523 frame_in->planes.plane6.b.offset;
524 sp_frame_out->planes.plane6.b_at_r.offset =
525 frame_in->planes.plane6.b_at_r.offset;
527 case IA_CSS_FRAME_FORMAT_BINARY_8:
528 sp_frame_out->planes.binary.data.offset =
529 frame_in->planes.binary.data.offset;
532 /* This should not happen, but in case it does,
535 memset(&sp_frame_out->planes, 0, sizeof(sp_frame_out->planes));
541 set_input_frame_buffer(const struct ia_css_frame *frame) {
545 switch (frame->info.format)
547 case IA_CSS_FRAME_FORMAT_QPLANE6:
548 case IA_CSS_FRAME_FORMAT_YUV420_16:
549 case IA_CSS_FRAME_FORMAT_RAW_PACKED:
550 case IA_CSS_FRAME_FORMAT_RAW:
551 case IA_CSS_FRAME_FORMAT_YUV420:
552 case IA_CSS_FRAME_FORMAT_YUYV:
553 case IA_CSS_FRAME_FORMAT_YUV_LINE:
554 case IA_CSS_FRAME_FORMAT_NV12:
555 case IA_CSS_FRAME_FORMAT_NV12_16:
556 case IA_CSS_FRAME_FORMAT_NV12_TILEY:
557 case IA_CSS_FRAME_FORMAT_NV21:
558 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_8:
559 case IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8:
560 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_10:
565 sh_css_copy_frame_to_spframe(&sh_css_sp_stage.frames.in, frame);
571 set_output_frame_buffer(const struct ia_css_frame *frame,
576 switch (frame->info.format)
578 case IA_CSS_FRAME_FORMAT_YUV420:
579 case IA_CSS_FRAME_FORMAT_YUV422:
580 case IA_CSS_FRAME_FORMAT_YUV444:
581 case IA_CSS_FRAME_FORMAT_YV12:
582 case IA_CSS_FRAME_FORMAT_YV16:
583 case IA_CSS_FRAME_FORMAT_YUV420_16:
584 case IA_CSS_FRAME_FORMAT_YUV422_16:
585 case IA_CSS_FRAME_FORMAT_NV11:
586 case IA_CSS_FRAME_FORMAT_NV12:
587 case IA_CSS_FRAME_FORMAT_NV12_16:
588 case IA_CSS_FRAME_FORMAT_NV12_TILEY:
589 case IA_CSS_FRAME_FORMAT_NV16:
590 case IA_CSS_FRAME_FORMAT_NV21:
591 case IA_CSS_FRAME_FORMAT_NV61:
592 case IA_CSS_FRAME_FORMAT_YUYV:
593 case IA_CSS_FRAME_FORMAT_UYVY:
594 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_8:
595 case IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8:
596 case IA_CSS_FRAME_FORMAT_YUV_LINE:
597 case IA_CSS_FRAME_FORMAT_RGB565:
598 case IA_CSS_FRAME_FORMAT_RGBA888:
599 case IA_CSS_FRAME_FORMAT_PLANAR_RGB888:
600 case IA_CSS_FRAME_FORMAT_RAW:
601 case IA_CSS_FRAME_FORMAT_RAW_PACKED:
602 case IA_CSS_FRAME_FORMAT_QPLANE6:
603 case IA_CSS_FRAME_FORMAT_BINARY_8:
608 sh_css_copy_frame_to_spframe(&sh_css_sp_stage.frames.out[idx], frame);
613 set_view_finder_buffer(const struct ia_css_frame *frame) {
617 switch (frame->info.format)
619 /* the dual output pin */
620 case IA_CSS_FRAME_FORMAT_NV12:
621 case IA_CSS_FRAME_FORMAT_NV12_16:
622 case IA_CSS_FRAME_FORMAT_NV21:
623 case IA_CSS_FRAME_FORMAT_YUYV:
624 case IA_CSS_FRAME_FORMAT_UYVY:
625 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_8:
626 case IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8:
627 case IA_CSS_FRAME_FORMAT_YUV420:
628 case IA_CSS_FRAME_FORMAT_YV12:
629 case IA_CSS_FRAME_FORMAT_NV12_TILEY:
632 case IA_CSS_FRAME_FORMAT_YUV_LINE:
638 sh_css_copy_frame_to_spframe(&sh_css_sp_stage.frames.out_vf, frame);
642 #if !defined(HAS_NO_INPUT_FORMATTER)
643 void sh_css_sp_set_if_configs(
644 const input_formatter_cfg_t *config_a,
645 const input_formatter_cfg_t *config_b,
646 const uint8_t if_config_index
649 assert(if_config_index < SH_CSS_MAX_IF_CONFIGS);
652 sh_css_sp_group.config.input_formatter.set[if_config_index].config_a =
654 sh_css_sp_group.config.input_formatter.a_changed = true;
657 sh_css_sp_group.config.input_formatter.set[if_config_index].config_b =
659 sh_css_sp_group.config.input_formatter.b_changed = true;
666 #if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2)
668 sh_css_sp_program_input_circuit(int fmt_type,
670 enum ia_css_input_mode input_mode)
672 sh_css_sp_group.config.input_circuit.no_side_band = false;
673 sh_css_sp_group.config.input_circuit.fmt_type = fmt_type;
674 sh_css_sp_group.config.input_circuit.ch_id = ch_id;
675 sh_css_sp_group.config.input_circuit.input_mode = input_mode;
677 * The SP group is only loaded at SP boot time and is read once
678 * change flags as "input_circuit_cfg_changed" must be reset on the SP
680 sh_css_sp_group.config.input_circuit_cfg_changed = true;
681 sh_css_sp_stage.program_input_circuit = true;
685 #if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2)
687 sh_css_sp_configure_sync_gen(int width, int height,
691 sh_css_sp_group.config.sync_gen.width = width;
692 sh_css_sp_group.config.sync_gen.height = height;
693 sh_css_sp_group.config.sync_gen.hblank_cycles = hblank_cycles;
694 sh_css_sp_group.config.sync_gen.vblank_cycles = vblank_cycles;
698 sh_css_sp_configure_tpg(int x_mask,
704 sh_css_sp_group.config.tpg.x_mask = x_mask;
705 sh_css_sp_group.config.tpg.y_mask = y_mask;
706 sh_css_sp_group.config.tpg.x_delta = x_delta;
707 sh_css_sp_group.config.tpg.y_delta = y_delta;
708 sh_css_sp_group.config.tpg.xy_mask = xy_mask;
712 sh_css_sp_configure_prbs(int seed)
714 sh_css_sp_group.config.prbs.seed = seed;
719 sh_css_sp_configure_enable_raw_pool_locking(bool lock_all)
721 sh_css_sp_group.config.enable_raw_pool_locking = true;
722 sh_css_sp_group.config.lock_all = lock_all;
726 sh_css_sp_enable_isys_event_queue(bool enable)
728 #if !defined(HAS_NO_INPUT_SYSTEM)
729 sh_css_sp_group.config.enable_isys_event_queue = enable;
736 sh_css_sp_set_disable_continuous_viewfinder(bool flag)
738 sh_css_sp_group.config.disable_cont_vf = flag;
742 sh_css_sp_write_frame_pointers(const struct sh_css_binary_args *args) {
749 err = set_input_frame_buffer(args->in_frame);
750 if (!err && args->out_vf_frame)
751 err = set_view_finder_buffer(args->out_vf_frame);
752 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
754 if (!err && args->out_frame[i])
755 err = set_output_frame_buffer(args->out_frame[i], i);
758 /* we don't pass this error back to the upper layer, so we add a assert here
759 because we actually hit the error here but it still works by accident... */
760 if (err) assert(false);
765 sh_css_sp_init_group(bool two_ppc,
766 enum atomisp_input_format input_format,
768 uint8_t if_config_index)
770 #if !defined(HAS_NO_INPUT_FORMATTER)
771 sh_css_sp_group.config.input_formatter.isp_2ppc = two_ppc;
776 sh_css_sp_group.config.no_isp_sync = (uint8_t)no_isp_sync;
777 /* decide whether the frame is processed online or offline */
778 if (if_config_index == SH_CSS_IF_CONFIG_NOT_NEEDED) return;
779 #if !defined(HAS_NO_INPUT_FORMATTER)
780 assert(if_config_index < SH_CSS_MAX_IF_CONFIGS);
781 sh_css_sp_group.config.input_formatter.set[if_config_index].stream_format =
789 sh_css_stage_write_binary_info(struct ia_css_binary_info *info)
792 sh_css_isp_stage.binary_info = *info;
796 copy_isp_mem_if_to_ddr(struct ia_css_binary *binary) {
799 err = ia_css_isp_param_copy_isp_mem_if_to_ddr(
802 IA_CSS_PARAM_CLASS_CONFIG);
805 err = ia_css_isp_param_copy_isp_mem_if_to_ddr(
808 IA_CSS_PARAM_CLASS_STATE);
815 is_sp_stage(struct ia_css_pipeline_stage *stage)
818 return stage->sp_func != IA_CSS_PIPELINE_NO_FUNC;
822 configure_isp_from_args(
823 const struct sh_css_sp_pipeline *pipeline,
824 const struct ia_css_binary *binary,
825 const struct sh_css_binary_args *args,
827 bool deinterleaved) {
828 ia_css_fpn_configure(binary, &binary->in_frame_info);
829 ia_css_crop_configure(binary, &args->delay_frames[0]->info);
830 ia_css_qplane_configure(pipeline, binary, &binary->in_frame_info);
831 ia_css_output0_configure(binary, &args->out_frame[0]->info);
832 ia_css_output1_configure(binary, &args->out_vf_frame->info);
833 ia_css_copy_output_configure(binary, args->copy_output);
834 ia_css_output0_configure(binary, &args->out_frame[0]->info);
836 ia_css_sc_configure(binary, pipeline->shading.internal_frame_origin_x_bqs_on_sctbl,
837 pipeline->shading.internal_frame_origin_y_bqs_on_sctbl);
839 ia_css_iterator_configure(binary, &args->in_frame->info);
840 ia_css_dvs_configure(binary, &args->out_frame[0]->info);
841 ia_css_output_configure(binary, &args->out_frame[0]->info);
842 ia_css_raw_configure(pipeline, binary, &args->in_frame->info, &binary->in_frame_info, two_ppc, deinterleaved);
845 * FIXME: args->delay_frames can be NULL here
847 * Somehow, the driver at the Intel Atom Yocto tree doesn't seem to
848 * suffer from the same issue.
850 * Anyway, the function below should now handle a NULL delay_frames
851 * without crashing, but the pipeline should likely be built without
852 * adding it at the first place (or there are a hidden bug somewhere)
854 ia_css_ref_configure(binary, args->delay_frames, pipeline->dvs_frame_delay);
855 ia_css_tnr_configure(binary, args->tnr_frames);
856 ia_css_bayer_io_config(binary, args);
861 initialize_isp_states(const struct ia_css_binary *binary)
865 if (!binary->info->mem_offsets.offsets.state)
867 for (i = 0; i < IA_CSS_NUM_STATE_IDS; i++) {
868 ia_css_kernel_init_state[i](binary);
873 initialize_frame_buffer_attribute(struct ia_css_buffer_sp *buf_attr)
875 buf_attr->buf_src.queue_id = SH_CSS_INVALID_QUEUE_ID;
876 buf_attr->buf_type = IA_CSS_BUFFER_TYPE_INVALID;
880 initialize_stage_frames(struct ia_css_frames_sp *frames)
884 initialize_frame_buffer_attribute(&frames->in.buf_attr);
885 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) {
886 initialize_frame_buffer_attribute(&frames->out[i].buf_attr);
888 initialize_frame_buffer_attribute(&frames->out_vf.buf_attr);
889 initialize_frame_buffer_attribute(&frames->s3a_buf);
890 initialize_frame_buffer_attribute(&frames->dvs_buf);
891 #if defined SH_CSS_ENABLE_METADATA
892 initialize_frame_buffer_attribute(&frames->metadata_buf);
897 sh_css_sp_init_stage(struct ia_css_binary *binary,
898 const char *binary_name,
899 const struct ia_css_blob_info *blob_info,
900 const struct sh_css_binary_args *args,
901 unsigned int pipe_num,
904 const struct ia_css_isp_param_css_segments *isp_mem_if,
905 unsigned int if_config_index,
907 const struct ia_css_binary_xinfo *xinfo;
908 const struct ia_css_binary_info *info;
911 struct ia_css_pipe *pipe = NULL;
912 unsigned int thread_id;
913 enum sh_css_queue_id queue_id;
914 bool continuous = sh_css_continuous_is_enabled((uint8_t)pipe_num);
921 xinfo = binary->info;
925 * Clear sh_css_sp_stage for easy debugging.
926 * program_input_circuit must be saved as it is set outside
929 u8 program_input_circuit;
931 program_input_circuit = sh_css_sp_stage.program_input_circuit;
932 memset(&sh_css_sp_stage, 0, sizeof(sh_css_sp_stage));
933 sh_css_sp_stage.program_input_circuit = (uint8_t)program_input_circuit;
936 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
940 sh_css_sp_group.pipe[thread_id].sp_stage_addr[stage] = mmgr_NULL;
944 #if defined(USE_INPUT_SYSTEM_VERSION_2401)
946 sh_css_sp_stage.deinterleaved = 0;
948 sh_css_sp_stage.deinterleaved = ((stage == 0) && continuous);
951 initialize_stage_frames(&sh_css_sp_stage.frames);
953 * TODO: Make the Host dynamically determine
956 sh_css_sp_stage.stage_type = SH_CSS_ISP_STAGE_TYPE;
957 sh_css_sp_stage.num = (uint8_t)stage;
958 sh_css_sp_stage.isp_online = (uint8_t)binary->online;
959 sh_css_sp_stage.isp_copy_vf = (uint8_t)args->copy_vf;
960 sh_css_sp_stage.isp_copy_output = (uint8_t)args->copy_output;
961 sh_css_sp_stage.enable.vf_output = (args->out_vf_frame != NULL);
963 /* Copy the frame infos first, to be overwritten by the frames,
964 if these are present.
966 sh_css_sp_stage.frames.effective_in_res.width = binary->effective_in_frame_res.width;
967 sh_css_sp_stage.frames.effective_in_res.height = binary->effective_in_frame_res.height;
969 ia_css_frame_info_to_frame_sp_info(&sh_css_sp_stage.frames.in.info,
970 &binary->in_frame_info);
971 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
973 ia_css_frame_info_to_frame_sp_info(&sh_css_sp_stage.frames.out[i].info,
974 &binary->out_frame_info[i]);
976 ia_css_frame_info_to_frame_sp_info(&sh_css_sp_stage.frames.internal_frame_info,
977 &binary->internal_frame_info);
978 sh_css_sp_stage.dvs_envelope.width = binary->dvs_envelope.width;
979 sh_css_sp_stage.dvs_envelope.height = binary->dvs_envelope.height;
980 sh_css_sp_stage.isp_pipe_version = (uint8_t)info->pipeline.isp_pipe_version;
981 sh_css_sp_stage.isp_deci_log_factor = (uint8_t)binary->deci_factor_log2;
982 sh_css_sp_stage.isp_vf_downscale_bits = (uint8_t)binary->vf_downscale_log2;
984 sh_css_sp_stage.if_config_index = (uint8_t)if_config_index;
986 sh_css_sp_stage.sp_enable_xnr = (uint8_t)xnr;
987 sh_css_sp_stage.xmem_bin_addr = xinfo->xmem_addr;
988 sh_css_sp_stage.xmem_map_addr = sh_css_params_ddr_address_map();
989 sh_css_isp_stage.blob_info = *blob_info;
990 sh_css_stage_write_binary_info((struct ia_css_binary_info *)info);
992 /* Make sure binary name is smaller than allowed string size */
993 assert(strlen(binary_name) < SH_CSS_MAX_BINARY_NAME - 1);
994 strscpy(sh_css_isp_stage.binary_name, binary_name, SH_CSS_MAX_BINARY_NAME);
995 sh_css_isp_stage.mem_initializers = *isp_mem_if;
998 * Even when a stage does not need uds and does not params,
999 * ia_css_uds_sp_scale_params() seems to be called (needs
1000 * further investigation). This function can not deal with
1004 err = sh_css_sp_write_frame_pointers(args);
1005 /* TODO: move it to a better place */
1006 if (binary->info->sp.enable.s3a)
1008 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_3A_STATISTICS, thread_id,
1010 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage.frames.s3a_buf, queue_id,
1012 IA_CSS_BUFFER_TYPE_3A_STATISTICS);
1014 if (binary->info->sp.enable.dis)
1016 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_DIS_STATISTICS, thread_id,
1018 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage.frames.dvs_buf, queue_id,
1020 IA_CSS_BUFFER_TYPE_DIS_STATISTICS);
1022 #if defined SH_CSS_ENABLE_METADATA
1023 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_METADATA, thread_id, &queue_id);
1024 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage.frames.metadata_buf, queue_id, mmgr_EXCEPTION, IA_CSS_BUFFER_TYPE_METADATA);
1029 #ifdef USE_INPUT_SYSTEM_VERSION_2401
1031 pipe = find_pipe_by_num(sh_css_sp_group.pipe[thread_id].pipe_num);
1036 ia_css_get_crop_offsets(pipe, &args->in_frame->info);
1038 ia_css_get_crop_offsets(pipe, &binary->in_frame_info);
1041 (void)pipe; /*avoid build warning*/
1044 err = configure_isp_from_args(&sh_css_sp_group.pipe[thread_id],
1045 binary, args, two_ppc, sh_css_sp_stage.deinterleaved);
1049 initialize_isp_states(binary);
1051 /* we do this only for preview pipe because in fill_binary_info function
1052 * we assign vf_out res to out res, but for ISP internal processing, we need
1053 * the original out res. for video pipe, it has two output pins --- out and
1054 * vf_out, so it can keep these two resolutions already. */
1055 if (binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_PREVIEW &&
1056 (binary->vf_downscale_log2 > 0))
1058 /* TODO: Remove this after preview output decimation is fixed
1059 * by configuring out&vf info fiels properly */
1060 sh_css_sp_stage.frames.out[0].info.padded_width
1061 <<= binary->vf_downscale_log2;
1062 sh_css_sp_stage.frames.out[0].info.res.width
1063 <<= binary->vf_downscale_log2;
1064 sh_css_sp_stage.frames.out[0].info.res.height
1065 <<= binary->vf_downscale_log2;
1067 err = copy_isp_mem_if_to_ddr(binary);
1075 sp_init_stage(struct ia_css_pipeline_stage *stage,
1076 unsigned int pipe_num,
1078 unsigned int if_config_index,
1080 struct ia_css_binary *binary;
1081 const struct ia_css_fw_info *firmware;
1082 const struct sh_css_binary_args *args;
1083 unsigned int stage_num;
1085 * Initialiser required because of the "else" path below.
1086 * Is this a valid path ?
1088 const char *binary_name = "";
1089 const struct ia_css_binary_xinfo *info = NULL;
1090 /* note: the var below is made static as it is quite large;
1091 if it is not static it ends up on the stack which could
1092 cause issues for drivers
1094 static struct ia_css_binary tmp_binary;
1095 const struct ia_css_blob_info *blob_info = NULL;
1096 struct ia_css_isp_param_css_segments isp_mem_if;
1097 /* LA: should be ia_css_data, should not contain host pointer.
1098 However, CSS/DDR pointer is not available yet.
1099 Hack is to store it in params->ddr_ptrs and then copy it late in the SP just before vmem init.
1100 TODO: Call this after CSS/DDR allocation and store that pointer.
1101 Best is to allocate it at stage creation time together with host pointer.
1102 Remove vmem from params.
1104 struct ia_css_isp_param_css_segments *mem_if = &isp_mem_if;
1110 binary = stage->binary;
1111 firmware = stage->firmware;
1112 args = &stage->args;
1113 stage_num = stage->stage_num;
1117 info = binary->info;
1118 binary_name = (const char *)(info->blob->name);
1119 blob_info = &info->blob->header.blob;
1120 ia_css_init_memory_interface(mem_if, &binary->mem_params, &binary->css_params);
1121 } else if (firmware)
1123 const struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS] = {NULL};
1125 if (args->out_frame[0])
1126 out_infos[0] = &args->out_frame[0]->info;
1127 info = &firmware->info.isp;
1128 ia_css_binary_fill_info(info, false, false,
1129 ATOMISP_INPUT_FORMAT_RAW_10,
1130 args->in_frame ? &args->in_frame->info : NULL,
1133 args->out_vf_frame ? &args->out_vf_frame->info
1138 binary = &tmp_binary;
1139 binary->info = info;
1140 binary_name = IA_CSS_EXT_ISP_PROG_NAME(firmware);
1141 blob_info = &firmware->blob;
1142 mem_if = (struct ia_css_isp_param_css_segments *)&firmware->mem_initializers;
1146 assert(stage->sp_func != IA_CSS_PIPELINE_NO_FUNC);
1147 /* binary and blob_info are now NULL.
1148 These will be passed to sh_css_sp_init_stage
1149 and dereferenced there, so passing a NULL
1150 pointer is no good. return an error */
1154 err = sh_css_sp_init_stage(binary,
1155 (const char *)binary_name,
1168 sp_init_sp_stage(struct ia_css_pipeline_stage *stage,
1169 unsigned int pipe_num,
1171 enum sh_css_pipe_config_override copy_ovrd,
1172 unsigned int if_config_index)
1174 const struct sh_css_binary_args *args = &stage->args;
1177 switch (stage->sp_func) {
1178 case IA_CSS_PIPELINE_RAW_COPY:
1179 sh_css_sp_start_raw_copy(args->out_frame[0],
1181 stage->max_input_width,
1182 copy_ovrd, if_config_index);
1184 case IA_CSS_PIPELINE_BIN_COPY:
1185 assert(false); /* TBI */
1187 case IA_CSS_PIPELINE_ISYS_COPY:
1188 sh_css_sp_start_isys_copy(args->out_frame[0],
1189 pipe_num, stage->max_input_width, if_config_index);
1191 case IA_CSS_PIPELINE_NO_FUNC:
1198 sh_css_sp_init_pipeline(struct ia_css_pipeline *me,
1199 enum ia_css_pipe_id id,
1205 unsigned int required_bds_factor,
1206 enum sh_css_pipe_config_override copy_ovrd,
1207 enum ia_css_input_mode input_mode,
1208 const struct ia_css_metadata_config *md_config,
1209 const struct ia_css_metadata_info *md_info,
1210 #if !defined(HAS_NO_INPUT_SYSTEM)
1211 const enum mipi_port_id port_id,
1213 const struct ia_css_coordinate
1214 *internal_frame_origin_bqs_on_sctbl, /* Origin of internal frame
1215 positioned on shading table at shading correction in ISP. */
1216 const struct ia_css_isp_parameters *params
1218 /* Get first stage */
1219 struct ia_css_pipeline_stage *stage = NULL;
1220 struct ia_css_binary *first_binary = NULL;
1221 struct ia_css_pipe *pipe = NULL;
1224 enum ia_css_pipe_id pipe_id = id;
1225 unsigned int thread_id;
1226 u8 if_config_index, tmp_if_config_index;
1230 #if !defined(HAS_NO_INPUT_SYSTEM)
1233 first_binary = me->stages->binary;
1235 if (input_mode == IA_CSS_INPUT_MODE_SENSOR ||
1236 input_mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
1238 assert(port_id < N_MIPI_PORT_ID);
1239 if (port_id >= N_MIPI_PORT_ID) /* should not happen but KW does not know */
1240 return; /* we should be able to return an error */
1241 if_config_index = (uint8_t)(port_id - MIPI_PORT0_ID);
1242 } else if (input_mode == IA_CSS_INPUT_MODE_MEMORY)
1244 if_config_index = SH_CSS_IF_CONFIG_NOT_NEEDED;
1247 if_config_index = 0x0;
1251 if_config_index = SH_CSS_IF_CONFIG_NOT_NEEDED;
1254 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
1255 memset(&sh_css_sp_group.pipe[thread_id], 0, sizeof(struct sh_css_sp_pipeline));
1258 for (stage = me->stages, num = 0; stage; stage = stage->next, num++)
1260 stage->stage_num = num;
1261 ia_css_debug_pipe_graph_dump_stage(stage, id);
1263 me->num_stages = num;
1267 /* Init pipeline data */
1268 sh_css_sp_init_group(two_ppc, first_binary->input_format,
1269 offline, if_config_index);
1270 } /* if (first_binary != NULL) */
1272 #if defined(USE_INPUT_SYSTEM_VERSION_2401) || defined(USE_INPUT_SYSTEM_VERSION_2)
1273 /* Signal the host immediately after start for SP_ISYS_COPY only */
1274 if ((me->num_stages == 1) && me->stages &&
1275 (me->stages->sp_func == IA_CSS_PIPELINE_ISYS_COPY))
1276 sh_css_sp_group.config.no_isp_sync = true;
1279 /* Init stage data */
1280 sh_css_init_host2sp_frame_data();
1282 sh_css_sp_group.pipe[thread_id].num_stages = 0;
1283 sh_css_sp_group.pipe[thread_id].pipe_id = pipe_id;
1284 sh_css_sp_group.pipe[thread_id].thread_id = thread_id;
1285 sh_css_sp_group.pipe[thread_id].pipe_num = pipe_num;
1286 sh_css_sp_group.pipe[thread_id].num_execs = me->num_execs;
1287 sh_css_sp_group.pipe[thread_id].pipe_qos_config = me->pipe_qos_config;
1288 sh_css_sp_group.pipe[thread_id].required_bds_factor = required_bds_factor;
1289 #if !defined(HAS_NO_INPUT_SYSTEM)
1290 sh_css_sp_group.pipe[thread_id].input_system_mode
1291 = (uint32_t)input_mode;
1292 sh_css_sp_group.pipe[thread_id].port_id = port_id;
1294 sh_css_sp_group.pipe[thread_id].dvs_frame_delay = (uint32_t)me->dvs_frame_delay;
1296 /* TODO: next indicates from which queues parameters need to be
1297 sampled, needs checking/improvement */
1298 if (ia_css_pipeline_uses_params(me))
1300 sh_css_sp_group.pipe[thread_id].pipe_config =
1301 SH_CSS_PIPE_CONFIG_SAMPLE_PARAMS << thread_id;
1304 /* For continuous use-cases, SP copy is responsible for sampling the
1307 sh_css_sp_group.pipe[thread_id].pipe_config = 0;
1309 sh_css_sp_group.pipe[thread_id].inout_port_config = me->inout_port_config;
1311 pipe = find_pipe_by_num(pipe_num);
1317 sh_css_sp_group.pipe[thread_id].scaler_pp_lut = sh_css_pipe_get_pp_gdc_lut(pipe);
1319 #if defined(SH_CSS_ENABLE_METADATA)
1320 if (md_info && md_info->size > 0)
1322 sh_css_sp_group.pipe[thread_id].metadata.width = md_info->resolution.width;
1323 sh_css_sp_group.pipe[thread_id].metadata.height = md_info->resolution.height;
1324 sh_css_sp_group.pipe[thread_id].metadata.stride = md_info->stride;
1325 sh_css_sp_group.pipe[thread_id].metadata.size = md_info->size;
1326 ia_css_isys_convert_stream_format_to_mipi_format(
1327 md_config->data_type, MIPI_PREDICTOR_NONE,
1328 &sh_css_sp_group.pipe[thread_id].metadata.format);
1335 #if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
1336 sh_css_sp_group.pipe[thread_id].output_frame_queue_id = (uint32_t)SH_CSS_INVALID_QUEUE_ID;
1337 if (pipe_id != IA_CSS_PIPE_ID_COPY)
1339 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, thread_id,
1340 (enum sh_css_queue_id *)(
1341 &sh_css_sp_group.pipe[thread_id].output_frame_queue_id));
1346 /* For the shading correction type 1 (the legacy shading table conversion in css is not used),
1347 * the parameters are passed to the isp for the shading table centering.
1349 if (internal_frame_origin_bqs_on_sctbl &&
1350 params && params->shading_settings.enable_shading_table_conversion == 0)
1352 sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_x_bqs_on_sctbl
1353 = (uint32_t)internal_frame_origin_bqs_on_sctbl->x;
1354 sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_y_bqs_on_sctbl
1355 = (uint32_t)internal_frame_origin_bqs_on_sctbl->y;
1358 sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_x_bqs_on_sctbl =
1360 sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_y_bqs_on_sctbl =
1365 IA_CSS_LOG("pipe_id %d port_config %08x",
1366 pipe_id, sh_css_sp_group.pipe[thread_id].inout_port_config);
1368 for (stage = me->stages, num = 0; stage; stage = stage->next, num++)
1370 sh_css_sp_group.pipe[thread_id].num_stages++;
1371 if (is_sp_stage(stage)) {
1372 sp_init_sp_stage(stage, pipe_num, two_ppc,
1373 copy_ovrd, if_config_index);
1375 if ((stage->stage_num != 0) ||
1376 SH_CSS_PIPE_PORT_CONFIG_IS_CONTINUOUS(me->inout_port_config))
1377 tmp_if_config_index = SH_CSS_IF_CONFIG_NOT_NEEDED;
1379 tmp_if_config_index = if_config_index;
1380 sp_init_stage(stage, pipe_num,
1381 xnr, tmp_if_config_index, two_ppc);
1384 store_sp_stage_data(pipe_id, pipe_num, num);
1386 sh_css_sp_group.pipe[thread_id].pipe_config |= (uint32_t)
1387 (me->acquire_isp_each_stage << IA_CSS_ACQUIRE_ISP_POS);
1388 store_sp_group_data();
1392 sh_css_sp_uninit_pipeline(unsigned int pipe_num)
1394 unsigned int thread_id;
1396 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
1397 /*memset(&sh_css_sp_group.pipe[thread_id], 0, sizeof(struct sh_css_sp_pipeline));*/
1398 sh_css_sp_group.pipe[thread_id].num_stages = 0;
1401 bool sh_css_write_host2sp_command(enum host2sp_commands host2sp_command)
1403 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1404 unsigned int offset = (unsigned int)offsetof(struct host_sp_communication,
1407 enum host2sp_commands last_cmd = host2sp_cmd_error;
1408 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1410 /* Previous command must be handled by SP (by design) */
1411 last_cmd = load_sp_array_uint(host_sp_com, offset);
1412 if (last_cmd != host2sp_cmd_ready)
1413 IA_CSS_ERROR("last host command not handled by SP(%d)", last_cmd);
1415 store_sp_array_uint(host_sp_com, offset, host2sp_command);
1417 return (last_cmd == host2sp_cmd_ready);
1420 enum host2sp_commands
1421 sh_css_read_host2sp_command(void) {
1422 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1423 unsigned int offset = (unsigned int)offsetof(struct host_sp_communication, host2sp_command)
1425 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1426 return (enum host2sp_commands)load_sp_array_uint(host_sp_com, offset);
1430 * Frame data is no longer part of the sp_stage structure but part of a
1431 * separate structure. The aim is to make the sp_data struct static
1432 * (it defines a pipeline) and that the dynamic (per frame) data is stored
1435 * This function must be called first every where were you start constructing
1436 * a new pipeline by defining one or more stages with use of variable
1437 * sh_css_sp_stage. Even the special cases like accelerator and copy_frame
1438 * These have a pipeline of just 1 stage.
1441 sh_css_init_host2sp_frame_data(void)
1444 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1446 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1448 * rvanimme: don't clean it to save static frame info line ref_in
1449 * ref_out, and tnr_frames. Once this static data is in a
1450 * separate data struct, this may be enable (but still, there is
1456 * @brief Update the offline frame information in host_sp_communication.
1457 * Refer to "sh_css_sp.h" for more details.
1460 sh_css_update_host2sp_offline_frame(
1461 unsigned int frame_num,
1462 struct ia_css_frame *frame,
1463 struct ia_css_metadata *metadata)
1465 unsigned int HIVE_ADDR_host_sp_com;
1466 unsigned int offset;
1468 assert(frame_num < NUM_CONTINUOUS_FRAMES);
1470 /* Write new frame data into SP DMEM */
1471 HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1472 offset = (unsigned int)offsetof(struct host_sp_communication,
1473 host2sp_offline_frames)
1475 offset += frame_num;
1476 store_sp_array_uint(host_sp_com, offset, frame ? frame->data : 0);
1478 /* Write metadata buffer into SP DMEM */
1479 offset = (unsigned int)offsetof(struct host_sp_communication,
1480 host2sp_offline_metadata)
1482 offset += frame_num;
1483 store_sp_array_uint(host_sp_com, offset, metadata ? metadata->address : 0);
1486 #if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
1488 * @brief Update the mipi frame information in host_sp_communication.
1489 * Refer to "sh_css_sp.h" for more details.
1492 sh_css_update_host2sp_mipi_frame(
1493 unsigned int frame_num,
1494 struct ia_css_frame *frame)
1496 unsigned int HIVE_ADDR_host_sp_com;
1497 unsigned int offset;
1499 /* MIPI buffers are dedicated to port, so now there are more of them. */
1500 assert(frame_num < (N_CSI_PORTS * NUM_MIPI_FRAMES_PER_STREAM));
1502 /* Write new frame data into SP DMEM */
1503 HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1504 offset = (unsigned int)offsetof(struct host_sp_communication,
1505 host2sp_mipi_frames)
1507 offset += frame_num;
1509 store_sp_array_uint(host_sp_com, offset,
1510 frame ? frame->data : 0);
1514 * @brief Update the mipi metadata information in host_sp_communication.
1515 * Refer to "sh_css_sp.h" for more details.
1518 sh_css_update_host2sp_mipi_metadata(
1519 unsigned int frame_num,
1520 struct ia_css_metadata *metadata)
1522 unsigned int HIVE_ADDR_host_sp_com;
1525 /* MIPI buffers are dedicated to port, so now there are more of them. */
1526 assert(frame_num < (N_CSI_PORTS * NUM_MIPI_FRAMES_PER_STREAM));
1528 /* Write new frame data into SP DMEM */
1529 HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1530 o = offsetof(struct host_sp_communication, host2sp_mipi_metadata)
1533 store_sp_array_uint(host_sp_com, o,
1534 metadata ? metadata->address : 0);
1538 sh_css_update_host2sp_num_mipi_frames(unsigned int num_frames)
1540 unsigned int HIVE_ADDR_host_sp_com;
1541 unsigned int offset;
1543 /* Write new frame data into SP DMEM */
1544 HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1545 offset = (unsigned int)offsetof(struct host_sp_communication,
1546 host2sp_num_mipi_frames)
1549 store_sp_array_uint(host_sp_com, offset, num_frames);
1554 sh_css_update_host2sp_cont_num_raw_frames(unsigned int num_frames,
1557 const struct ia_css_fw_info *fw;
1558 unsigned int HIVE_ADDR_host_sp_com;
1559 unsigned int extra_num_frames, avail_num_frames;
1560 unsigned int offset, offset_extra;
1562 /* Write new frame data into SP DMEM */
1564 HIVE_ADDR_host_sp_com = fw->info.sp.host_sp_com;
1566 offset = (unsigned int)offsetof(struct host_sp_communication,
1567 host2sp_cont_avail_num_raw_frames)
1569 avail_num_frames = load_sp_array_uint(host_sp_com, offset);
1570 extra_num_frames = num_frames - avail_num_frames;
1571 offset_extra = (unsigned int)offsetof(struct host_sp_communication,
1572 host2sp_cont_extra_num_raw_frames)
1574 store_sp_array_uint(host_sp_com, offset_extra, extra_num_frames);
1576 offset = (unsigned int)offsetof(struct host_sp_communication,
1577 host2sp_cont_target_num_raw_frames)
1580 store_sp_array_uint(host_sp_com, offset, num_frames);
1584 sh_css_event_init_irq_mask(void)
1587 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1588 unsigned int offset;
1589 struct sh_css_event_irq_mask event_irq_mask_init;
1591 event_irq_mask_init.or_mask = IA_CSS_EVENT_TYPE_ALL;
1592 event_irq_mask_init.and_mask = IA_CSS_EVENT_TYPE_NONE;
1593 (void)HIVE_ADDR_host_sp_com; /* Suppress warnings in CRUN */
1595 assert(sizeof(event_irq_mask_init) % HRT_BUS_BYTES == 0);
1596 for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++) {
1597 offset = (unsigned int)offsetof(struct host_sp_communication,
1598 host2sp_event_irq_mask[i]);
1599 assert(offset % HRT_BUS_BYTES == 0);
1600 sp_dmem_store(SP0_ID,
1601 (unsigned int)sp_address_of(host_sp_com) + offset,
1602 &event_irq_mask_init, sizeof(event_irq_mask_init));
1607 ia_css_pipe_set_irq_mask(struct ia_css_pipe *pipe,
1608 unsigned int or_mask,
1609 unsigned int and_mask) {
1610 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1611 unsigned int offset;
1612 struct sh_css_event_irq_mask event_irq_mask;
1613 unsigned int pipe_num;
1617 assert(IA_CSS_PIPE_ID_NUM == NR_OF_PIPELINES);
1618 /* Linux kernel does not have UINT16_MAX
1619 * Therefore decided to comment out these 2 asserts for Linux
1620 * Alternatives that were not chosen:
1621 * - add a conditional #define for UINT16_MAX
1622 * - compare with (uint16_t)~0 or 0xffff
1623 * - different assert for Linux and Windows
1626 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1628 IA_CSS_LOG("or_mask=%x, and_mask=%x", or_mask, and_mask);
1629 event_irq_mask.or_mask = (uint16_t)or_mask;
1630 event_irq_mask.and_mask = (uint16_t)and_mask;
1632 pipe_num = ia_css_pipe_get_pipe_num(pipe);
1633 if (pipe_num >= IA_CSS_PIPE_ID_NUM)
1635 offset = (unsigned int)offsetof(struct host_sp_communication,
1636 host2sp_event_irq_mask[pipe_num]);
1637 assert(offset % HRT_BUS_BYTES == 0);
1638 sp_dmem_store(SP0_ID,
1639 (unsigned int)sp_address_of(host_sp_com) + offset,
1640 &event_irq_mask, sizeof(event_irq_mask));
1646 ia_css_event_get_irq_mask(const struct ia_css_pipe *pipe,
1647 unsigned int *or_mask,
1648 unsigned int *and_mask) {
1649 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1650 unsigned int offset;
1651 struct sh_css_event_irq_mask event_irq_mask;
1652 unsigned int pipe_num;
1654 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1656 IA_CSS_ENTER_LEAVE("");
1659 assert(IA_CSS_PIPE_ID_NUM == NR_OF_PIPELINES);
1661 pipe_num = ia_css_pipe_get_pipe_num(pipe);
1662 if (pipe_num >= IA_CSS_PIPE_ID_NUM)
1664 offset = (unsigned int)offsetof(struct host_sp_communication,
1665 host2sp_event_irq_mask[pipe_num]);
1666 assert(offset % HRT_BUS_BYTES == 0);
1667 sp_dmem_load(SP0_ID,
1668 (unsigned int)sp_address_of(host_sp_com) + offset,
1669 &event_irq_mask, sizeof(event_irq_mask));
1672 *or_mask = event_irq_mask.or_mask;
1675 *and_mask = event_irq_mask.and_mask;
1681 sh_css_sp_set_sp_running(bool flag)
1687 sh_css_sp_is_running(void)
1693 sh_css_sp_start_isp(void)
1695 const struct ia_css_fw_info *fw;
1696 unsigned int HIVE_ADDR_sp_sw_state;
1699 HIVE_ADDR_sp_sw_state = fw->info.sp.sw_state;
1704 (void)HIVE_ADDR_sp_sw_state; /* Suppres warnings in CRUN */
1706 /* no longer here, sp started immediately */
1707 /*ia_css_debug_pipe_graph_dump_epilogue();*/
1709 store_sp_group_data();
1710 store_sp_per_frame_data(fw);
1712 sp_dmem_store_uint32(SP0_ID,
1713 (unsigned int)sp_address_of(sp_sw_state),
1714 (uint32_t)(IA_CSS_SP_SW_TERMINATED));
1716 /* Note 1: The sp_start_isp function contains a wait till
1717 * the input network is configured by the SP.
1718 * Note 2: Not all SP binaries supports host2sp_commands.
1719 * In case a binary does support it, the host2sp_command
1720 * will have status cmd_ready after return of the function
1721 * sh_css_hrt_sp_start_isp. There is no race-condition here
1722 * because only after the process_frame command has been
1723 * received, the SP starts configuring the input network.
1726 /* we need to set sp_running before we call ia_css_mmu_invalidate_cache
1727 * as ia_css_mmu_invalidate_cache checks on sp_running to
1728 * avoid that it accesses dmem while the SP is not powered
1731 ia_css_mmu_invalidate_cache();
1732 /* Invalidate all MMU caches */
1733 mmu_invalidate_cache_all();
1735 ia_css_spctrl_start(SP0_ID);
1739 ia_css_isp_has_started(void)
1741 const struct ia_css_fw_info *fw = &sh_css_sp_fw;
1742 unsigned int HIVE_ADDR_ia_css_ispctrl_sp_isp_started = fw->info.sp.isp_started;
1743 (void)HIVE_ADDR_ia_css_ispctrl_sp_isp_started; /* Suppres warnings in CRUN */
1745 return (bool)load_sp_uint(ia_css_ispctrl_sp_isp_started);
1749 * @brief Initialize the DMA software-mask in the debug mode.
1750 * Refer to "sh_css_sp.h" for more details.
1753 sh_css_sp_init_dma_sw_reg(int dma_id)
1757 /* enable all the DMA channels */
1758 for (i = 0; i < N_DMA_CHANNEL_ID; i++) {
1759 /* enable the writing request */
1760 sh_css_sp_set_dma_sw_reg(dma_id,
1764 /* enable the reading request */
1765 sh_css_sp_set_dma_sw_reg(dma_id,
1775 * @brief Set the DMA software-mask in the debug mode.
1776 * Refer to "sh_css_sp.h" for more details.
1779 sh_css_sp_set_dma_sw_reg(int dma_id,
1791 assert(channel_id >= 0 && channel_id < N_DMA_CHANNEL_ID);
1792 assert(request_type >= 0);
1794 /* get the software-mask */
1796 sh_css_sp_group.debug.dma_sw_reg;
1798 /* get the offest of the target bit */
1799 bit_offset = (8 * request_type) + channel_id;
1801 /* clear the value of the target bit */
1802 bit_mask = ~(1 << bit_offset);
1805 /* set the value of the bit for the DMA channel */
1806 bit_val = enable ? 1 : 0;
1807 bit_val <<= bit_offset;
1810 /* update the software status of DMA channels */
1811 sh_css_sp_group.debug.dma_sw_reg = sw_reg;
1817 sh_css_sp_reset_global_vars(void)
1819 memset(&sh_css_sp_group, 0, sizeof(struct sh_css_sp_group));
1820 memset(&sh_css_sp_stage, 0, sizeof(struct sh_css_sp_stage));
1821 memset(&sh_css_isp_stage, 0, sizeof(struct sh_css_isp_stage));
1822 memset(&sh_css_sp_output, 0, sizeof(struct sh_css_sp_output));
1823 memset(&per_frame_data, 0, sizeof(struct sh_css_sp_per_frame_data));