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 strncpy(sh_css_isp_stage.binary_name, binary_name, SH_CSS_MAX_BINARY_NAME - 1);
995 sh_css_isp_stage.binary_name[SH_CSS_MAX_BINARY_NAME - 1] = 0;
996 sh_css_isp_stage.mem_initializers = *isp_mem_if;
999 * Even when a stage does not need uds and does not params,
1000 * ia_css_uds_sp_scale_params() seems to be called (needs
1001 * further investigation). This function can not deal with
1005 err = sh_css_sp_write_frame_pointers(args);
1006 /* TODO: move it to a better place */
1007 if (binary->info->sp.enable.s3a)
1009 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_3A_STATISTICS, thread_id,
1011 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage.frames.s3a_buf, queue_id,
1013 IA_CSS_BUFFER_TYPE_3A_STATISTICS);
1015 if (binary->info->sp.enable.dis)
1017 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_DIS_STATISTICS, thread_id,
1019 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage.frames.dvs_buf, queue_id,
1021 IA_CSS_BUFFER_TYPE_DIS_STATISTICS);
1023 #if defined SH_CSS_ENABLE_METADATA
1024 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_METADATA, thread_id, &queue_id);
1025 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage.frames.metadata_buf, queue_id, mmgr_EXCEPTION, IA_CSS_BUFFER_TYPE_METADATA);
1030 #ifdef USE_INPUT_SYSTEM_VERSION_2401
1032 pipe = find_pipe_by_num(sh_css_sp_group.pipe[thread_id].pipe_num);
1037 ia_css_get_crop_offsets(pipe, &args->in_frame->info);
1039 ia_css_get_crop_offsets(pipe, &binary->in_frame_info);
1042 (void)pipe; /*avoid build warning*/
1045 err = configure_isp_from_args(&sh_css_sp_group.pipe[thread_id],
1046 binary, args, two_ppc, sh_css_sp_stage.deinterleaved);
1050 initialize_isp_states(binary);
1052 /* we do this only for preview pipe because in fill_binary_info function
1053 * we assign vf_out res to out res, but for ISP internal processing, we need
1054 * the original out res. for video pipe, it has two output pins --- out and
1055 * vf_out, so it can keep these two resolutions already. */
1056 if (binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_PREVIEW &&
1057 (binary->vf_downscale_log2 > 0))
1059 /* TODO: Remove this after preview output decimation is fixed
1060 * by configuring out&vf info fiels properly */
1061 sh_css_sp_stage.frames.out[0].info.padded_width
1062 <<= binary->vf_downscale_log2;
1063 sh_css_sp_stage.frames.out[0].info.res.width
1064 <<= binary->vf_downscale_log2;
1065 sh_css_sp_stage.frames.out[0].info.res.height
1066 <<= binary->vf_downscale_log2;
1068 err = copy_isp_mem_if_to_ddr(binary);
1076 sp_init_stage(struct ia_css_pipeline_stage *stage,
1077 unsigned int pipe_num,
1079 unsigned int if_config_index,
1081 struct ia_css_binary *binary;
1082 const struct ia_css_fw_info *firmware;
1083 const struct sh_css_binary_args *args;
1084 unsigned int stage_num;
1086 * Initialiser required because of the "else" path below.
1087 * Is this a valid path ?
1089 const char *binary_name = "";
1090 const struct ia_css_binary_xinfo *info = NULL;
1091 /* note: the var below is made static as it is quite large;
1092 if it is not static it ends up on the stack which could
1093 cause issues for drivers
1095 static struct ia_css_binary tmp_binary;
1096 const struct ia_css_blob_info *blob_info = NULL;
1097 struct ia_css_isp_param_css_segments isp_mem_if;
1098 /* LA: should be ia_css_data, should not contain host pointer.
1099 However, CSS/DDR pointer is not available yet.
1100 Hack is to store it in params->ddr_ptrs and then copy it late in the SP just before vmem init.
1101 TODO: Call this after CSS/DDR allocation and store that pointer.
1102 Best is to allocate it at stage creation time together with host pointer.
1103 Remove vmem from params.
1105 struct ia_css_isp_param_css_segments *mem_if = &isp_mem_if;
1111 binary = stage->binary;
1112 firmware = stage->firmware;
1113 args = &stage->args;
1114 stage_num = stage->stage_num;
1118 info = binary->info;
1119 binary_name = (const char *)(info->blob->name);
1120 blob_info = &info->blob->header.blob;
1121 ia_css_init_memory_interface(mem_if, &binary->mem_params, &binary->css_params);
1122 } else if (firmware)
1124 const struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS] = {NULL};
1126 if (args->out_frame[0])
1127 out_infos[0] = &args->out_frame[0]->info;
1128 info = &firmware->info.isp;
1129 ia_css_binary_fill_info(info, false, false,
1130 ATOMISP_INPUT_FORMAT_RAW_10,
1131 args->in_frame ? &args->in_frame->info : NULL,
1134 args->out_vf_frame ? &args->out_vf_frame->info
1139 binary = &tmp_binary;
1140 binary->info = info;
1141 binary_name = IA_CSS_EXT_ISP_PROG_NAME(firmware);
1142 blob_info = &firmware->blob;
1143 mem_if = (struct ia_css_isp_param_css_segments *)&firmware->mem_initializers;
1147 assert(stage->sp_func != IA_CSS_PIPELINE_NO_FUNC);
1148 /* binary and blob_info are now NULL.
1149 These will be passed to sh_css_sp_init_stage
1150 and dereferenced there, so passing a NULL
1151 pointer is no good. return an error */
1155 err = sh_css_sp_init_stage(binary,
1156 (const char *)binary_name,
1169 sp_init_sp_stage(struct ia_css_pipeline_stage *stage,
1170 unsigned int pipe_num,
1172 enum sh_css_pipe_config_override copy_ovrd,
1173 unsigned int if_config_index)
1175 const struct sh_css_binary_args *args = &stage->args;
1178 switch (stage->sp_func) {
1179 case IA_CSS_PIPELINE_RAW_COPY:
1180 sh_css_sp_start_raw_copy(args->out_frame[0],
1182 stage->max_input_width,
1183 copy_ovrd, if_config_index);
1185 case IA_CSS_PIPELINE_BIN_COPY:
1186 assert(false); /* TBI */
1188 case IA_CSS_PIPELINE_ISYS_COPY:
1189 sh_css_sp_start_isys_copy(args->out_frame[0],
1190 pipe_num, stage->max_input_width, if_config_index);
1192 case IA_CSS_PIPELINE_NO_FUNC:
1199 sh_css_sp_init_pipeline(struct ia_css_pipeline *me,
1200 enum ia_css_pipe_id id,
1206 unsigned int required_bds_factor,
1207 enum sh_css_pipe_config_override copy_ovrd,
1208 enum ia_css_input_mode input_mode,
1209 const struct ia_css_metadata_config *md_config,
1210 const struct ia_css_metadata_info *md_info,
1211 #if !defined(HAS_NO_INPUT_SYSTEM)
1212 const enum mipi_port_id port_id,
1214 const struct ia_css_coordinate
1215 *internal_frame_origin_bqs_on_sctbl, /* Origin of internal frame
1216 positioned on shading table at shading correction in ISP. */
1217 const struct ia_css_isp_parameters *params
1219 /* Get first stage */
1220 struct ia_css_pipeline_stage *stage = NULL;
1221 struct ia_css_binary *first_binary = NULL;
1222 struct ia_css_pipe *pipe = NULL;
1225 enum ia_css_pipe_id pipe_id = id;
1226 unsigned int thread_id;
1227 u8 if_config_index, tmp_if_config_index;
1231 #if !defined(HAS_NO_INPUT_SYSTEM)
1234 first_binary = me->stages->binary;
1236 if (input_mode == IA_CSS_INPUT_MODE_SENSOR ||
1237 input_mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
1239 assert(port_id < N_MIPI_PORT_ID);
1240 if (port_id >= N_MIPI_PORT_ID) /* should not happen but KW does not know */
1241 return; /* we should be able to return an error */
1242 if_config_index = (uint8_t)(port_id - MIPI_PORT0_ID);
1243 } else if (input_mode == IA_CSS_INPUT_MODE_MEMORY)
1245 if_config_index = SH_CSS_IF_CONFIG_NOT_NEEDED;
1248 if_config_index = 0x0;
1252 if_config_index = SH_CSS_IF_CONFIG_NOT_NEEDED;
1255 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
1256 memset(&sh_css_sp_group.pipe[thread_id], 0, sizeof(struct sh_css_sp_pipeline));
1259 for (stage = me->stages, num = 0; stage; stage = stage->next, num++)
1261 stage->stage_num = num;
1262 ia_css_debug_pipe_graph_dump_stage(stage, id);
1264 me->num_stages = num;
1268 /* Init pipeline data */
1269 sh_css_sp_init_group(two_ppc, first_binary->input_format,
1270 offline, if_config_index);
1271 } /* if (first_binary != NULL) */
1273 #if defined(USE_INPUT_SYSTEM_VERSION_2401) || defined(USE_INPUT_SYSTEM_VERSION_2)
1274 /* Signal the host immediately after start for SP_ISYS_COPY only */
1275 if ((me->num_stages == 1) && me->stages &&
1276 (me->stages->sp_func == IA_CSS_PIPELINE_ISYS_COPY))
1277 sh_css_sp_group.config.no_isp_sync = true;
1280 /* Init stage data */
1281 sh_css_init_host2sp_frame_data();
1283 sh_css_sp_group.pipe[thread_id].num_stages = 0;
1284 sh_css_sp_group.pipe[thread_id].pipe_id = pipe_id;
1285 sh_css_sp_group.pipe[thread_id].thread_id = thread_id;
1286 sh_css_sp_group.pipe[thread_id].pipe_num = pipe_num;
1287 sh_css_sp_group.pipe[thread_id].num_execs = me->num_execs;
1288 sh_css_sp_group.pipe[thread_id].pipe_qos_config = me->pipe_qos_config;
1289 sh_css_sp_group.pipe[thread_id].required_bds_factor = required_bds_factor;
1290 #if !defined(HAS_NO_INPUT_SYSTEM)
1291 sh_css_sp_group.pipe[thread_id].input_system_mode
1292 = (uint32_t)input_mode;
1293 sh_css_sp_group.pipe[thread_id].port_id = port_id;
1295 sh_css_sp_group.pipe[thread_id].dvs_frame_delay = (uint32_t)me->dvs_frame_delay;
1297 /* TODO: next indicates from which queues parameters need to be
1298 sampled, needs checking/improvement */
1299 if (ia_css_pipeline_uses_params(me))
1301 sh_css_sp_group.pipe[thread_id].pipe_config =
1302 SH_CSS_PIPE_CONFIG_SAMPLE_PARAMS << thread_id;
1305 /* For continuous use-cases, SP copy is responsible for sampling the
1308 sh_css_sp_group.pipe[thread_id].pipe_config = 0;
1310 sh_css_sp_group.pipe[thread_id].inout_port_config = me->inout_port_config;
1312 pipe = find_pipe_by_num(pipe_num);
1318 sh_css_sp_group.pipe[thread_id].scaler_pp_lut = sh_css_pipe_get_pp_gdc_lut(pipe);
1320 #if defined(SH_CSS_ENABLE_METADATA)
1321 if (md_info && md_info->size > 0)
1323 sh_css_sp_group.pipe[thread_id].metadata.width = md_info->resolution.width;
1324 sh_css_sp_group.pipe[thread_id].metadata.height = md_info->resolution.height;
1325 sh_css_sp_group.pipe[thread_id].metadata.stride = md_info->stride;
1326 sh_css_sp_group.pipe[thread_id].metadata.size = md_info->size;
1327 ia_css_isys_convert_stream_format_to_mipi_format(
1328 md_config->data_type, MIPI_PREDICTOR_NONE,
1329 &sh_css_sp_group.pipe[thread_id].metadata.format);
1336 #if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
1337 sh_css_sp_group.pipe[thread_id].output_frame_queue_id = (uint32_t)SH_CSS_INVALID_QUEUE_ID;
1338 if (pipe_id != IA_CSS_PIPE_ID_COPY)
1340 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, thread_id,
1341 (enum sh_css_queue_id *)(
1342 &sh_css_sp_group.pipe[thread_id].output_frame_queue_id));
1347 /* For the shading correction type 1 (the legacy shading table conversion in css is not used),
1348 * the parameters are passed to the isp for the shading table centering.
1350 if (internal_frame_origin_bqs_on_sctbl &&
1351 params && params->shading_settings.enable_shading_table_conversion == 0)
1353 sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_x_bqs_on_sctbl
1354 = (uint32_t)internal_frame_origin_bqs_on_sctbl->x;
1355 sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_y_bqs_on_sctbl
1356 = (uint32_t)internal_frame_origin_bqs_on_sctbl->y;
1359 sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_x_bqs_on_sctbl =
1361 sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_y_bqs_on_sctbl =
1366 IA_CSS_LOG("pipe_id %d port_config %08x",
1367 pipe_id, sh_css_sp_group.pipe[thread_id].inout_port_config);
1369 for (stage = me->stages, num = 0; stage; stage = stage->next, num++)
1371 sh_css_sp_group.pipe[thread_id].num_stages++;
1372 if (is_sp_stage(stage)) {
1373 sp_init_sp_stage(stage, pipe_num, two_ppc,
1374 copy_ovrd, if_config_index);
1376 if ((stage->stage_num != 0) ||
1377 SH_CSS_PIPE_PORT_CONFIG_IS_CONTINUOUS(me->inout_port_config))
1378 tmp_if_config_index = SH_CSS_IF_CONFIG_NOT_NEEDED;
1380 tmp_if_config_index = if_config_index;
1381 sp_init_stage(stage, pipe_num,
1382 xnr, tmp_if_config_index, two_ppc);
1385 store_sp_stage_data(pipe_id, pipe_num, num);
1387 sh_css_sp_group.pipe[thread_id].pipe_config |= (uint32_t)
1388 (me->acquire_isp_each_stage << IA_CSS_ACQUIRE_ISP_POS);
1389 store_sp_group_data();
1393 sh_css_sp_uninit_pipeline(unsigned int pipe_num)
1395 unsigned int thread_id;
1397 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
1398 /*memset(&sh_css_sp_group.pipe[thread_id], 0, sizeof(struct sh_css_sp_pipeline));*/
1399 sh_css_sp_group.pipe[thread_id].num_stages = 0;
1402 bool sh_css_write_host2sp_command(enum host2sp_commands host2sp_command)
1404 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1405 unsigned int offset = (unsigned int)offsetof(struct host_sp_communication,
1408 enum host2sp_commands last_cmd = host2sp_cmd_error;
1409 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1411 /* Previous command must be handled by SP (by design) */
1412 last_cmd = load_sp_array_uint(host_sp_com, offset);
1413 if (last_cmd != host2sp_cmd_ready)
1414 IA_CSS_ERROR("last host command not handled by SP(%d)", last_cmd);
1416 store_sp_array_uint(host_sp_com, offset, host2sp_command);
1418 return (last_cmd == host2sp_cmd_ready);
1421 enum host2sp_commands
1422 sh_css_read_host2sp_command(void) {
1423 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1424 unsigned int offset = (unsigned int)offsetof(struct host_sp_communication, host2sp_command)
1426 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1427 return (enum host2sp_commands)load_sp_array_uint(host_sp_com, offset);
1431 * Frame data is no longer part of the sp_stage structure but part of a
1432 * separate structure. The aim is to make the sp_data struct static
1433 * (it defines a pipeline) and that the dynamic (per frame) data is stored
1436 * This function must be called first every where were you start constructing
1437 * a new pipeline by defining one or more stages with use of variable
1438 * sh_css_sp_stage. Even the special cases like accelerator and copy_frame
1439 * These have a pipeline of just 1 stage.
1442 sh_css_init_host2sp_frame_data(void)
1445 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1447 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1449 * rvanimme: don't clean it to save static frame info line ref_in
1450 * ref_out, and tnr_frames. Once this static data is in a
1451 * separate data struct, this may be enable (but still, there is
1457 * @brief Update the offline frame information in host_sp_communication.
1458 * Refer to "sh_css_sp.h" for more details.
1461 sh_css_update_host2sp_offline_frame(
1462 unsigned int frame_num,
1463 struct ia_css_frame *frame,
1464 struct ia_css_metadata *metadata)
1466 unsigned int HIVE_ADDR_host_sp_com;
1467 unsigned int offset;
1469 assert(frame_num < NUM_CONTINUOUS_FRAMES);
1471 /* Write new frame data into SP DMEM */
1472 HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1473 offset = (unsigned int)offsetof(struct host_sp_communication,
1474 host2sp_offline_frames)
1476 offset += frame_num;
1477 store_sp_array_uint(host_sp_com, offset, frame ? frame->data : 0);
1479 /* Write metadata buffer into SP DMEM */
1480 offset = (unsigned int)offsetof(struct host_sp_communication,
1481 host2sp_offline_metadata)
1483 offset += frame_num;
1484 store_sp_array_uint(host_sp_com, offset, metadata ? metadata->address : 0);
1487 #if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
1489 * @brief Update the mipi frame information in host_sp_communication.
1490 * Refer to "sh_css_sp.h" for more details.
1493 sh_css_update_host2sp_mipi_frame(
1494 unsigned int frame_num,
1495 struct ia_css_frame *frame)
1497 unsigned int HIVE_ADDR_host_sp_com;
1498 unsigned int offset;
1500 /* MIPI buffers are dedicated to port, so now there are more of them. */
1501 assert(frame_num < (N_CSI_PORTS * NUM_MIPI_FRAMES_PER_STREAM));
1503 /* Write new frame data into SP DMEM */
1504 HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1505 offset = (unsigned int)offsetof(struct host_sp_communication,
1506 host2sp_mipi_frames)
1508 offset += frame_num;
1510 store_sp_array_uint(host_sp_com, offset,
1511 frame ? frame->data : 0);
1515 * @brief Update the mipi metadata information in host_sp_communication.
1516 * Refer to "sh_css_sp.h" for more details.
1519 sh_css_update_host2sp_mipi_metadata(
1520 unsigned int frame_num,
1521 struct ia_css_metadata *metadata)
1523 unsigned int HIVE_ADDR_host_sp_com;
1526 /* MIPI buffers are dedicated to port, so now there are more of them. */
1527 assert(frame_num < (N_CSI_PORTS * NUM_MIPI_FRAMES_PER_STREAM));
1529 /* Write new frame data into SP DMEM */
1530 HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1531 o = offsetof(struct host_sp_communication, host2sp_mipi_metadata)
1534 store_sp_array_uint(host_sp_com, o,
1535 metadata ? metadata->address : 0);
1539 sh_css_update_host2sp_num_mipi_frames(unsigned int num_frames)
1541 unsigned int HIVE_ADDR_host_sp_com;
1542 unsigned int offset;
1544 /* Write new frame data into SP DMEM */
1545 HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1546 offset = (unsigned int)offsetof(struct host_sp_communication,
1547 host2sp_num_mipi_frames)
1550 store_sp_array_uint(host_sp_com, offset, num_frames);
1555 sh_css_update_host2sp_cont_num_raw_frames(unsigned int num_frames,
1558 const struct ia_css_fw_info *fw;
1559 unsigned int HIVE_ADDR_host_sp_com;
1560 unsigned int extra_num_frames, avail_num_frames;
1561 unsigned int offset, offset_extra;
1563 /* Write new frame data into SP DMEM */
1565 HIVE_ADDR_host_sp_com = fw->info.sp.host_sp_com;
1567 offset = (unsigned int)offsetof(struct host_sp_communication,
1568 host2sp_cont_avail_num_raw_frames)
1570 avail_num_frames = load_sp_array_uint(host_sp_com, offset);
1571 extra_num_frames = num_frames - avail_num_frames;
1572 offset_extra = (unsigned int)offsetof(struct host_sp_communication,
1573 host2sp_cont_extra_num_raw_frames)
1575 store_sp_array_uint(host_sp_com, offset_extra, extra_num_frames);
1577 offset = (unsigned int)offsetof(struct host_sp_communication,
1578 host2sp_cont_target_num_raw_frames)
1581 store_sp_array_uint(host_sp_com, offset, num_frames);
1585 sh_css_event_init_irq_mask(void)
1588 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1589 unsigned int offset;
1590 struct sh_css_event_irq_mask event_irq_mask_init;
1592 event_irq_mask_init.or_mask = IA_CSS_EVENT_TYPE_ALL;
1593 event_irq_mask_init.and_mask = IA_CSS_EVENT_TYPE_NONE;
1594 (void)HIVE_ADDR_host_sp_com; /* Suppress warnings in CRUN */
1596 assert(sizeof(event_irq_mask_init) % HRT_BUS_BYTES == 0);
1597 for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++) {
1598 offset = (unsigned int)offsetof(struct host_sp_communication,
1599 host2sp_event_irq_mask[i]);
1600 assert(offset % HRT_BUS_BYTES == 0);
1601 sp_dmem_store(SP0_ID,
1602 (unsigned int)sp_address_of(host_sp_com) + offset,
1603 &event_irq_mask_init, sizeof(event_irq_mask_init));
1608 ia_css_pipe_set_irq_mask(struct ia_css_pipe *pipe,
1609 unsigned int or_mask,
1610 unsigned int and_mask) {
1611 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1612 unsigned int offset;
1613 struct sh_css_event_irq_mask event_irq_mask;
1614 unsigned int pipe_num;
1618 assert(IA_CSS_PIPE_ID_NUM == NR_OF_PIPELINES);
1619 /* Linux kernel does not have UINT16_MAX
1620 * Therefore decided to comment out these 2 asserts for Linux
1621 * Alternatives that were not chosen:
1622 * - add a conditional #define for UINT16_MAX
1623 * - compare with (uint16_t)~0 or 0xffff
1624 * - different assert for Linux and Windows
1627 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1629 IA_CSS_LOG("or_mask=%x, and_mask=%x", or_mask, and_mask);
1630 event_irq_mask.or_mask = (uint16_t)or_mask;
1631 event_irq_mask.and_mask = (uint16_t)and_mask;
1633 pipe_num = ia_css_pipe_get_pipe_num(pipe);
1634 if (pipe_num >= IA_CSS_PIPE_ID_NUM)
1636 offset = (unsigned int)offsetof(struct host_sp_communication,
1637 host2sp_event_irq_mask[pipe_num]);
1638 assert(offset % HRT_BUS_BYTES == 0);
1639 sp_dmem_store(SP0_ID,
1640 (unsigned int)sp_address_of(host_sp_com) + offset,
1641 &event_irq_mask, sizeof(event_irq_mask));
1647 ia_css_event_get_irq_mask(const struct ia_css_pipe *pipe,
1648 unsigned int *or_mask,
1649 unsigned int *and_mask) {
1650 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1651 unsigned int offset;
1652 struct sh_css_event_irq_mask event_irq_mask;
1653 unsigned int pipe_num;
1655 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1657 IA_CSS_ENTER_LEAVE("");
1660 assert(IA_CSS_PIPE_ID_NUM == NR_OF_PIPELINES);
1662 pipe_num = ia_css_pipe_get_pipe_num(pipe);
1663 if (pipe_num >= IA_CSS_PIPE_ID_NUM)
1665 offset = (unsigned int)offsetof(struct host_sp_communication,
1666 host2sp_event_irq_mask[pipe_num]);
1667 assert(offset % HRT_BUS_BYTES == 0);
1668 sp_dmem_load(SP0_ID,
1669 (unsigned int)sp_address_of(host_sp_com) + offset,
1670 &event_irq_mask, sizeof(event_irq_mask));
1673 *or_mask = event_irq_mask.or_mask;
1676 *and_mask = event_irq_mask.and_mask;
1682 sh_css_sp_set_sp_running(bool flag)
1688 sh_css_sp_is_running(void)
1694 sh_css_sp_start_isp(void)
1696 const struct ia_css_fw_info *fw;
1697 unsigned int HIVE_ADDR_sp_sw_state;
1700 HIVE_ADDR_sp_sw_state = fw->info.sp.sw_state;
1705 (void)HIVE_ADDR_sp_sw_state; /* Suppres warnings in CRUN */
1707 /* no longer here, sp started immediately */
1708 /*ia_css_debug_pipe_graph_dump_epilogue();*/
1710 store_sp_group_data();
1711 store_sp_per_frame_data(fw);
1713 sp_dmem_store_uint32(SP0_ID,
1714 (unsigned int)sp_address_of(sp_sw_state),
1715 (uint32_t)(IA_CSS_SP_SW_TERMINATED));
1717 /* Note 1: The sp_start_isp function contains a wait till
1718 * the input network is configured by the SP.
1719 * Note 2: Not all SP binaries supports host2sp_commands.
1720 * In case a binary does support it, the host2sp_command
1721 * will have status cmd_ready after return of the function
1722 * sh_css_hrt_sp_start_isp. There is no race-condition here
1723 * because only after the process_frame command has been
1724 * received, the SP starts configuring the input network.
1727 /* we need to set sp_running before we call ia_css_mmu_invalidate_cache
1728 * as ia_css_mmu_invalidate_cache checks on sp_running to
1729 * avoid that it accesses dmem while the SP is not powered
1732 ia_css_mmu_invalidate_cache();
1733 /* Invalidate all MMU caches */
1734 mmu_invalidate_cache_all();
1736 ia_css_spctrl_start(SP0_ID);
1740 ia_css_isp_has_started(void)
1742 const struct ia_css_fw_info *fw = &sh_css_sp_fw;
1743 unsigned int HIVE_ADDR_ia_css_ispctrl_sp_isp_started = fw->info.sp.isp_started;
1744 (void)HIVE_ADDR_ia_css_ispctrl_sp_isp_started; /* Suppres warnings in CRUN */
1746 return (bool)load_sp_uint(ia_css_ispctrl_sp_isp_started);
1750 * @brief Initialize the DMA software-mask in the debug mode.
1751 * Refer to "sh_css_sp.h" for more details.
1754 sh_css_sp_init_dma_sw_reg(int dma_id)
1758 /* enable all the DMA channels */
1759 for (i = 0; i < N_DMA_CHANNEL_ID; i++) {
1760 /* enable the writing request */
1761 sh_css_sp_set_dma_sw_reg(dma_id,
1765 /* enable the reading request */
1766 sh_css_sp_set_dma_sw_reg(dma_id,
1776 * @brief Set the DMA software-mask in the debug mode.
1777 * Refer to "sh_css_sp.h" for more details.
1780 sh_css_sp_set_dma_sw_reg(int dma_id,
1792 assert(channel_id >= 0 && channel_id < N_DMA_CHANNEL_ID);
1793 assert(request_type >= 0);
1795 /* get the software-mask */
1797 sh_css_sp_group.debug.dma_sw_reg;
1799 /* get the offest of the target bit */
1800 bit_offset = (8 * request_type) + channel_id;
1802 /* clear the value of the target bit */
1803 bit_mask = ~(1 << bit_offset);
1806 /* set the value of the bit for the DMA channel */
1807 bit_val = enable ? 1 : 0;
1808 bit_val <<= bit_offset;
1811 /* update the software status of DMA channels */
1812 sh_css_sp_group.debug.dma_sw_reg = sw_reg;
1818 sh_css_sp_reset_global_vars(void)
1820 memset(&sh_css_sp_group, 0, sizeof(struct sh_css_sp_group));
1821 memset(&sh_css_sp_stage, 0, sizeof(struct sh_css_sp_stage));
1822 memset(&sh_css_isp_stage, 0, sizeof(struct sh_css_isp_stage));
1823 memset(&sh_css_sp_output, 0, sizeof(struct sh_css_sp_output));
1824 memset(&per_frame_data, 0, sizeof(struct sh_css_sp_per_frame_data));