2 * Support for Intel Camera Imaging ISP subsystem.
3 * Copyright (c) 2015, Intel Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 #include "sh_css_sp.h"
17 #if !defined(HAS_NO_INPUT_FORMATTER)
18 #include "input_formatter.h"
21 #include "dma.h" /* N_DMA_CHANNEL_ID */
23 #include "ia_css_buffer.h"
24 #include "ia_css_binary.h"
25 #include "sh_css_hrt.h"
26 #include "sh_css_defs.h"
27 #include "sh_css_internal.h"
28 #include "ia_css_control.h"
29 #include "ia_css_debug.h"
30 #include "ia_css_debug_pipe.h"
31 #include "ia_css_event_public.h"
32 #include "ia_css_mmu.h"
33 #include "ia_css_stream.h"
34 #include "ia_css_isp_param.h"
35 #include "sh_css_params.h"
36 #include "sh_css_legacy.h"
37 #include "ia_css_frame_comm.h"
38 #if !defined(HAS_NO_INPUT_SYSTEM)
39 #include "ia_css_isys.h"
42 #include "gdc_device.h" /* HRT_GDC_N */
44 /*#include "sp.h"*/ /* host2sp_enqueue_frame_data() */
46 #include "memory_access.h"
48 #include "assert_support.h"
49 #include "platform_support.h" /* hrt_sleep() */
51 #include "sw_event_global.h" /* Event IDs.*/
52 #include "ia_css_event.h"
53 #include "mmu_device.h"
54 #include "ia_css_spctrl.h"
57 #define offsetof(T, x) ((unsigned int)&(((T *)0)->x))
60 #define IA_CSS_INCLUDE_CONFIGURATIONS
61 #include "ia_css_isp_configs.h"
62 #define IA_CSS_INCLUDE_STATES
63 #include "ia_css_isp_states.h"
65 #include "isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.h"
67 struct sh_css_sp_group sh_css_sp_group;
68 struct sh_css_sp_stage sh_css_sp_stage;
69 struct sh_css_isp_stage sh_css_isp_stage;
70 static struct sh_css_sp_output sh_css_sp_output;
71 static struct sh_css_sp_per_frame_data per_frame_data;
73 /* true if SP supports frame loop and host2sp_commands */
74 /* For the moment there is only code that sets this bool to true */
75 /* TODO: add code that sets this bool to false */
76 static bool sp_running;
78 static enum ia_css_err
79 set_output_frame_buffer(const struct ia_css_frame *frame,
83 sh_css_copy_buffer_attr_to_spbuffer(struct ia_css_buffer_sp *dest_buf,
84 const enum sh_css_queue_id queue_id,
85 const hrt_vaddress xmem_addr,
86 const enum ia_css_buffer_type buf_type);
89 initialize_frame_buffer_attribute(struct ia_css_buffer_sp *buf_attr);
92 initialize_stage_frames(struct ia_css_frames_sp *frames);
94 /* This data is stored every frame */
96 store_sp_group_data(void)
98 per_frame_data.sp_group_addr = sh_css_store_sp_group_to_ddr();
102 copy_isp_stage_to_sp_stage(void)
104 /* [WW07.5]type casting will cause potential issues */
105 sh_css_sp_stage.num_stripes = (uint8_t)
106 sh_css_isp_stage.binary_info.iterator.num_stripes;
107 sh_css_sp_stage.row_stripes_height = (uint16_t)
108 sh_css_isp_stage.binary_info.iterator.row_stripes_height;
109 sh_css_sp_stage.row_stripes_overlap_lines = (uint16_t)
110 sh_css_isp_stage.binary_info.iterator.row_stripes_overlap_lines;
111 sh_css_sp_stage.top_cropping = (uint16_t)
112 sh_css_isp_stage.binary_info.pipeline.top_cropping;
113 /* moved to sh_css_sp_init_stage
114 sh_css_sp_stage.enable.vf_output =
115 sh_css_isp_stage.binary_info.enable.vf_veceven ||
116 sh_css_isp_stage.binary_info.num_output_pins > 1;
118 sh_css_sp_stage.enable.sdis = sh_css_isp_stage.binary_info.enable.dis;
119 sh_css_sp_stage.enable.s3a = sh_css_isp_stage.binary_info.enable.s3a;
121 sh_css_sp_stage.enable.lace_stats =
122 sh_css_isp_stage.binary_info.enable.lace_stats;
127 store_sp_stage_data(enum ia_css_pipe_id id, unsigned int pipe_num,
130 unsigned int thread_id;
132 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
133 copy_isp_stage_to_sp_stage();
134 if (id != IA_CSS_PIPE_ID_COPY)
135 sh_css_sp_stage.isp_stage_addr =
136 sh_css_store_isp_stage_to_ddr(pipe_num, stage);
137 sh_css_sp_group.pipe[thread_id].sp_stage_addr[stage] =
138 sh_css_store_sp_stage_to_ddr(pipe_num, stage);
140 /* Clear for next frame */
141 sh_css_sp_stage.program_input_circuit = false;
145 store_sp_per_frame_data(const struct ia_css_fw_info *fw)
147 unsigned int HIVE_ADDR_sp_per_frame_data = 0;
152 case ia_css_sp_firmware:
153 HIVE_ADDR_sp_per_frame_data = fw->info.sp.per_frame_data;
155 case ia_css_acc_firmware:
156 HIVE_ADDR_sp_per_frame_data = fw->info.acc.per_frame_data;
158 case ia_css_isp_firmware:
162 sp_dmem_store(SP0_ID,
163 (unsigned int)sp_address_of(sp_per_frame_data),
165 sizeof(per_frame_data));
169 sh_css_store_sp_per_frame_data(enum ia_css_pipe_id pipe_id,
170 unsigned int pipe_num,
171 const struct ia_css_fw_info *sp_fw)
174 sp_fw = &sh_css_sp_fw;
176 store_sp_stage_data(pipe_id, pipe_num, 0);
177 store_sp_group_data();
178 store_sp_per_frame_data(sp_fw);
181 #if SP_DEBUG != SP_DEBUG_NONE
184 sh_css_sp_get_debug_state(struct sh_css_sp_debug_state *state)
186 const struct ia_css_fw_info *fw = &sh_css_sp_fw;
187 unsigned int HIVE_ADDR_sp_output = fw->info.sp.output;
189 unsigned int offset = (unsigned int)offsetof(struct sh_css_sp_output,
190 debug) / sizeof(int);
194 (void)HIVE_ADDR_sp_output; /* To get rid of warning in CRUN */
195 for (i = 0; i < sizeof(*state) / sizeof(int); i++)
196 ((unsigned *)state)[i] = load_sp_array_uint(sp_output, i + offset);
202 sh_css_sp_start_binary_copy(unsigned int pipe_num,
203 struct ia_css_frame *out_frame,
204 unsigned int two_ppc)
206 enum ia_css_pipe_id pipe_id;
207 unsigned int thread_id;
208 struct sh_css_sp_pipeline *pipe;
212 pipe_id = IA_CSS_PIPE_ID_CAPTURE;
213 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
214 pipe = &sh_css_sp_group.pipe[thread_id];
216 pipe->copy.bin.bytes_available = out_frame->data_bytes;
217 pipe->num_stages = 1;
218 pipe->pipe_id = pipe_id;
219 pipe->pipe_num = pipe_num;
220 pipe->thread_id = thread_id;
221 pipe->pipe_config = 0x0; /* No parameters */
222 pipe->pipe_qos_config = QOS_INVALID;
224 if (pipe->inout_port_config == 0) {
225 SH_CSS_PIPE_PORT_CONFIG_SET(pipe->inout_port_config,
226 (uint8_t)SH_CSS_PORT_INPUT,
227 (uint8_t)SH_CSS_HOST_TYPE, 1);
228 SH_CSS_PIPE_PORT_CONFIG_SET(pipe->inout_port_config,
229 (uint8_t)SH_CSS_PORT_OUTPUT,
230 (uint8_t)SH_CSS_HOST_TYPE, 1);
232 IA_CSS_LOG("pipe_id %d port_config %08x",
233 pipe->pipe_id, pipe->inout_port_config);
235 #if !defined(HAS_NO_INPUT_FORMATTER)
236 sh_css_sp_group.config.input_formatter.isp_2ppc = (uint8_t)two_ppc;
241 sh_css_sp_stage.num = stage_num;
242 sh_css_sp_stage.stage_type = SH_CSS_SP_STAGE_TYPE;
243 sh_css_sp_stage.func =
244 (unsigned int)IA_CSS_PIPELINE_BIN_COPY;
246 set_output_frame_buffer(out_frame, 0);
248 /* sp_bin_copy_init on the SP does not deal with dynamica/static yet */
249 /* For now always update the dynamic data from out frames. */
250 sh_css_store_sp_per_frame_data(pipe_id, pipe_num, &sh_css_sp_fw);
254 sh_css_sp_start_raw_copy(struct ia_css_frame *out_frame,
255 unsigned int pipe_num,
256 unsigned int two_ppc,
257 unsigned int max_input_width,
258 enum sh_css_pipe_config_override pipe_conf_override,
259 unsigned int if_config_index)
261 enum ia_css_pipe_id pipe_id;
262 unsigned int thread_id;
264 struct sh_css_sp_pipeline *pipe;
270 * Clear sh_css_sp_stage for easy debugging.
271 * program_input_circuit must be saved as it is set outside
274 u8 program_input_circuit;
276 program_input_circuit = sh_css_sp_stage.program_input_circuit;
277 memset(&sh_css_sp_stage, 0, sizeof(sh_css_sp_stage));
278 sh_css_sp_stage.program_input_circuit = program_input_circuit;
281 pipe_id = IA_CSS_PIPE_ID_COPY;
282 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
283 pipe = &sh_css_sp_group.pipe[thread_id];
285 pipe->copy.raw.height = out_frame->info.res.height;
286 pipe->copy.raw.width = out_frame->info.res.width;
287 pipe->copy.raw.padded_width = out_frame->info.padded_width;
288 pipe->copy.raw.raw_bit_depth = out_frame->info.raw_bit_depth;
289 pipe->copy.raw.max_input_width = max_input_width;
290 pipe->num_stages = 1;
291 pipe->pipe_id = pipe_id;
292 /* TODO: next indicates from which queues parameters need to be
293 sampled, needs checking/improvement */
294 if (pipe_conf_override == SH_CSS_PIPE_CONFIG_OVRD_NO_OVRD)
296 (SH_CSS_PIPE_CONFIG_SAMPLE_PARAMS << thread_id);
298 pipe->pipe_config = pipe_conf_override;
300 pipe->pipe_qos_config = QOS_INVALID;
302 if (pipe->inout_port_config == 0) {
303 SH_CSS_PIPE_PORT_CONFIG_SET(pipe->inout_port_config,
304 (uint8_t)SH_CSS_PORT_INPUT,
305 (uint8_t)SH_CSS_HOST_TYPE, 1);
306 SH_CSS_PIPE_PORT_CONFIG_SET(pipe->inout_port_config,
307 (uint8_t)SH_CSS_PORT_OUTPUT,
308 (uint8_t)SH_CSS_HOST_TYPE, 1);
310 IA_CSS_LOG("pipe_id %d port_config %08x",
311 pipe->pipe_id, pipe->inout_port_config);
313 #if !defined(HAS_NO_INPUT_FORMATTER)
314 sh_css_sp_group.config.input_formatter.isp_2ppc = (uint8_t)two_ppc;
319 sh_css_sp_stage.num = stage_num;
320 sh_css_sp_stage.xmem_bin_addr = 0x0;
321 sh_css_sp_stage.stage_type = SH_CSS_SP_STAGE_TYPE;
322 sh_css_sp_stage.func = (unsigned int)IA_CSS_PIPELINE_RAW_COPY;
323 sh_css_sp_stage.if_config_index = (uint8_t)if_config_index;
324 set_output_frame_buffer(out_frame, 0);
326 ia_css_debug_pipe_graph_dump_sp_raw_copy(out_frame);
330 sh_css_sp_start_isys_copy(struct ia_css_frame *out_frame,
331 unsigned int pipe_num, unsigned int max_input_width,
332 unsigned int if_config_index)
334 enum ia_css_pipe_id pipe_id;
335 unsigned int thread_id;
337 struct sh_css_sp_pipeline *pipe;
338 #if defined SH_CSS_ENABLE_METADATA
339 enum sh_css_queue_id queue_id;
346 * Clear sh_css_sp_stage for easy debugging.
347 * program_input_circuit must be saved as it is set outside
350 u8 program_input_circuit;
352 program_input_circuit = sh_css_sp_stage.program_input_circuit;
353 memset(&sh_css_sp_stage, 0, sizeof(sh_css_sp_stage));
354 sh_css_sp_stage.program_input_circuit = program_input_circuit;
357 pipe_id = IA_CSS_PIPE_ID_COPY;
358 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
359 pipe = &sh_css_sp_group.pipe[thread_id];
361 pipe->copy.raw.height = out_frame->info.res.height;
362 pipe->copy.raw.width = out_frame->info.res.width;
363 pipe->copy.raw.padded_width = out_frame->info.padded_width;
364 pipe->copy.raw.raw_bit_depth = out_frame->info.raw_bit_depth;
365 pipe->copy.raw.max_input_width = max_input_width;
366 pipe->num_stages = 1;
367 pipe->pipe_id = pipe_id;
368 pipe->pipe_config = 0x0; /* No parameters */
369 pipe->pipe_qos_config = QOS_INVALID;
371 initialize_stage_frames(&sh_css_sp_stage.frames);
372 sh_css_sp_stage.num = stage_num;
373 sh_css_sp_stage.xmem_bin_addr = 0x0;
374 sh_css_sp_stage.stage_type = SH_CSS_SP_STAGE_TYPE;
375 sh_css_sp_stage.func = (unsigned int)IA_CSS_PIPELINE_ISYS_COPY;
376 sh_css_sp_stage.if_config_index = (uint8_t)if_config_index;
378 set_output_frame_buffer(out_frame, 0);
380 #if defined SH_CSS_ENABLE_METADATA
381 if (pipe->metadata.height > 0) {
382 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_METADATA, thread_id,
384 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage.frames.metadata_buf,
385 queue_id, mmgr_EXCEPTION,
386 IA_CSS_BUFFER_TYPE_METADATA);
390 ia_css_debug_pipe_graph_dump_sp_raw_copy(out_frame);
394 sh_css_sp_get_binary_copy_size(void)
396 const struct ia_css_fw_info *fw = &sh_css_sp_fw;
397 unsigned int HIVE_ADDR_sp_output = fw->info.sp.output;
398 unsigned int offset = (unsigned int)offsetof(struct sh_css_sp_output,
399 bin_copy_bytes_copied) / sizeof(int);
400 (void)HIVE_ADDR_sp_output; /* To get rid of warning in CRUN */
401 return load_sp_array_uint(sp_output, offset);
405 sh_css_sp_get_sw_interrupt_value(unsigned int irq)
407 const struct ia_css_fw_info *fw = &sh_css_sp_fw;
408 unsigned int HIVE_ADDR_sp_output = fw->info.sp.output;
409 unsigned int offset = (unsigned int)offsetof(struct sh_css_sp_output,
412 (void)HIVE_ADDR_sp_output; /* To get rid of warning in CRUN */
413 return load_sp_array_uint(sp_output, offset + irq);
417 sh_css_copy_buffer_attr_to_spbuffer(struct ia_css_buffer_sp *dest_buf,
418 const enum sh_css_queue_id queue_id,
419 const hrt_vaddress xmem_addr,
420 const enum ia_css_buffer_type buf_type)
422 assert(buf_type < IA_CSS_NUM_BUFFER_TYPE);
423 if (queue_id > SH_CSS_INVALID_QUEUE_ID) {
425 * value >=0 indicates that function init_frame_pointers()
426 * should use the dynamic data address
428 assert(queue_id < SH_CSS_MAX_NUM_QUEUES);
430 /* Klocwork assumes assert can be disabled;
431 Since we can get there with any type, and it does not
432 know that frame_in->dynamic_data_index can only be set
433 for one of the types in the assert) it has to assume we
434 can get here for any type. however this could lead to an
435 out of bounds reference when indexing buf_type about 10
436 lines below. In order to satisfy KW an additional if
437 has been added. This one will always yield true.
439 if ((queue_id < SH_CSS_MAX_NUM_QUEUES)) {
440 dest_buf->buf_src.queue_id = queue_id;
443 assert(xmem_addr != mmgr_EXCEPTION);
444 dest_buf->buf_src.xmem_addr = xmem_addr;
446 dest_buf->buf_type = buf_type;
450 sh_css_copy_frame_to_spframe(struct ia_css_frame_sp *sp_frame_out,
451 const struct ia_css_frame *frame_in)
455 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
456 "sh_css_copy_frame_to_spframe():\n");
458 sh_css_copy_buffer_attr_to_spbuffer(&sp_frame_out->buf_attr,
459 frame_in->dynamic_queue_id,
463 ia_css_frame_info_to_frame_sp_info(&sp_frame_out->info, &frame_in->info);
465 switch (frame_in->info.format) {
466 case IA_CSS_FRAME_FORMAT_RAW_PACKED:
467 case IA_CSS_FRAME_FORMAT_RAW:
468 sp_frame_out->planes.raw.offset = frame_in->planes.raw.offset;
470 case IA_CSS_FRAME_FORMAT_RGB565:
471 case IA_CSS_FRAME_FORMAT_RGBA888:
472 sp_frame_out->planes.rgb.offset = frame_in->planes.rgb.offset;
474 case IA_CSS_FRAME_FORMAT_PLANAR_RGB888:
475 sp_frame_out->planes.planar_rgb.r.offset =
476 frame_in->planes.planar_rgb.r.offset;
477 sp_frame_out->planes.planar_rgb.g.offset =
478 frame_in->planes.planar_rgb.g.offset;
479 sp_frame_out->planes.planar_rgb.b.offset =
480 frame_in->planes.planar_rgb.b.offset;
482 case IA_CSS_FRAME_FORMAT_YUYV:
483 case IA_CSS_FRAME_FORMAT_UYVY:
484 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_8:
485 case IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8:
486 case IA_CSS_FRAME_FORMAT_YUV_LINE:
487 sp_frame_out->planes.yuyv.offset = frame_in->planes.yuyv.offset;
489 case IA_CSS_FRAME_FORMAT_NV11:
490 case IA_CSS_FRAME_FORMAT_NV12:
491 case IA_CSS_FRAME_FORMAT_NV12_16:
492 case IA_CSS_FRAME_FORMAT_NV12_TILEY:
493 case IA_CSS_FRAME_FORMAT_NV21:
494 case IA_CSS_FRAME_FORMAT_NV16:
495 case IA_CSS_FRAME_FORMAT_NV61:
496 sp_frame_out->planes.nv.y.offset =
497 frame_in->planes.nv.y.offset;
498 sp_frame_out->planes.nv.uv.offset =
499 frame_in->planes.nv.uv.offset;
501 case IA_CSS_FRAME_FORMAT_YUV420:
502 case IA_CSS_FRAME_FORMAT_YUV422:
503 case IA_CSS_FRAME_FORMAT_YUV444:
504 case IA_CSS_FRAME_FORMAT_YUV420_16:
505 case IA_CSS_FRAME_FORMAT_YUV422_16:
506 case IA_CSS_FRAME_FORMAT_YV12:
507 case IA_CSS_FRAME_FORMAT_YV16:
508 sp_frame_out->planes.yuv.y.offset =
509 frame_in->planes.yuv.y.offset;
510 sp_frame_out->planes.yuv.u.offset =
511 frame_in->planes.yuv.u.offset;
512 sp_frame_out->planes.yuv.v.offset =
513 frame_in->planes.yuv.v.offset;
515 case IA_CSS_FRAME_FORMAT_QPLANE6:
516 sp_frame_out->planes.plane6.r.offset =
517 frame_in->planes.plane6.r.offset;
518 sp_frame_out->planes.plane6.r_at_b.offset =
519 frame_in->planes.plane6.r_at_b.offset;
520 sp_frame_out->planes.plane6.gr.offset =
521 frame_in->planes.plane6.gr.offset;
522 sp_frame_out->planes.plane6.gb.offset =
523 frame_in->planes.plane6.gb.offset;
524 sp_frame_out->planes.plane6.b.offset =
525 frame_in->planes.plane6.b.offset;
526 sp_frame_out->planes.plane6.b_at_r.offset =
527 frame_in->planes.plane6.b_at_r.offset;
529 case IA_CSS_FRAME_FORMAT_BINARY_8:
530 sp_frame_out->planes.binary.data.offset =
531 frame_in->planes.binary.data.offset;
534 /* This should not happen, but in case it does,
537 memset(&sp_frame_out->planes, 0, sizeof(sp_frame_out->planes));
542 static enum ia_css_err
543 set_input_frame_buffer(const struct ia_css_frame *frame) {
545 return IA_CSS_ERR_INVALID_ARGUMENTS;
547 switch (frame->info.format)
549 case IA_CSS_FRAME_FORMAT_QPLANE6:
550 case IA_CSS_FRAME_FORMAT_YUV420_16:
551 case IA_CSS_FRAME_FORMAT_RAW_PACKED:
552 case IA_CSS_FRAME_FORMAT_RAW:
553 case IA_CSS_FRAME_FORMAT_YUV420:
554 case IA_CSS_FRAME_FORMAT_YUYV:
555 case IA_CSS_FRAME_FORMAT_YUV_LINE:
556 case IA_CSS_FRAME_FORMAT_NV12:
557 case IA_CSS_FRAME_FORMAT_NV12_16:
558 case IA_CSS_FRAME_FORMAT_NV12_TILEY:
559 case IA_CSS_FRAME_FORMAT_NV21:
560 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_8:
561 case IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8:
562 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_10:
565 return IA_CSS_ERR_INVALID_ARGUMENTS;
567 sh_css_copy_frame_to_spframe(&sh_css_sp_stage.frames.in, frame);
569 return IA_CSS_SUCCESS;
572 static enum ia_css_err
573 set_output_frame_buffer(const struct ia_css_frame *frame,
576 return IA_CSS_ERR_INVALID_ARGUMENTS;
578 switch (frame->info.format)
580 case IA_CSS_FRAME_FORMAT_YUV420:
581 case IA_CSS_FRAME_FORMAT_YUV422:
582 case IA_CSS_FRAME_FORMAT_YUV444:
583 case IA_CSS_FRAME_FORMAT_YV12:
584 case IA_CSS_FRAME_FORMAT_YV16:
585 case IA_CSS_FRAME_FORMAT_YUV420_16:
586 case IA_CSS_FRAME_FORMAT_YUV422_16:
587 case IA_CSS_FRAME_FORMAT_NV11:
588 case IA_CSS_FRAME_FORMAT_NV12:
589 case IA_CSS_FRAME_FORMAT_NV12_16:
590 case IA_CSS_FRAME_FORMAT_NV12_TILEY:
591 case IA_CSS_FRAME_FORMAT_NV16:
592 case IA_CSS_FRAME_FORMAT_NV21:
593 case IA_CSS_FRAME_FORMAT_NV61:
594 case IA_CSS_FRAME_FORMAT_YUYV:
595 case IA_CSS_FRAME_FORMAT_UYVY:
596 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_8:
597 case IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8:
598 case IA_CSS_FRAME_FORMAT_YUV_LINE:
599 case IA_CSS_FRAME_FORMAT_RGB565:
600 case IA_CSS_FRAME_FORMAT_RGBA888:
601 case IA_CSS_FRAME_FORMAT_PLANAR_RGB888:
602 case IA_CSS_FRAME_FORMAT_RAW:
603 case IA_CSS_FRAME_FORMAT_RAW_PACKED:
604 case IA_CSS_FRAME_FORMAT_QPLANE6:
605 case IA_CSS_FRAME_FORMAT_BINARY_8:
608 return IA_CSS_ERR_INVALID_ARGUMENTS;
610 sh_css_copy_frame_to_spframe(&sh_css_sp_stage.frames.out[idx], frame);
611 return IA_CSS_SUCCESS;
614 static enum ia_css_err
615 set_view_finder_buffer(const struct ia_css_frame *frame) {
617 return IA_CSS_ERR_INVALID_ARGUMENTS;
619 switch (frame->info.format)
621 /* the dual output pin */
622 case IA_CSS_FRAME_FORMAT_NV12:
623 case IA_CSS_FRAME_FORMAT_NV12_16:
624 case IA_CSS_FRAME_FORMAT_NV21:
625 case IA_CSS_FRAME_FORMAT_YUYV:
626 case IA_CSS_FRAME_FORMAT_UYVY:
627 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_8:
628 case IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8:
629 case IA_CSS_FRAME_FORMAT_YUV420:
630 case IA_CSS_FRAME_FORMAT_YV12:
631 case IA_CSS_FRAME_FORMAT_NV12_TILEY:
634 case IA_CSS_FRAME_FORMAT_YUV_LINE:
637 return IA_CSS_ERR_INVALID_ARGUMENTS;
640 sh_css_copy_frame_to_spframe(&sh_css_sp_stage.frames.out_vf, frame);
641 return IA_CSS_SUCCESS;
644 #if !defined(HAS_NO_INPUT_FORMATTER)
645 void sh_css_sp_set_if_configs(
646 const input_formatter_cfg_t *config_a,
647 const input_formatter_cfg_t *config_b,
648 const uint8_t if_config_index
651 assert(if_config_index < SH_CSS_MAX_IF_CONFIGS);
654 sh_css_sp_group.config.input_formatter.set[if_config_index].config_a =
656 sh_css_sp_group.config.input_formatter.a_changed = true;
659 sh_css_sp_group.config.input_formatter.set[if_config_index].config_b =
661 sh_css_sp_group.config.input_formatter.b_changed = true;
668 #if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2)
670 sh_css_sp_program_input_circuit(int fmt_type,
672 enum ia_css_input_mode input_mode)
674 sh_css_sp_group.config.input_circuit.no_side_band = false;
675 sh_css_sp_group.config.input_circuit.fmt_type = fmt_type;
676 sh_css_sp_group.config.input_circuit.ch_id = ch_id;
677 sh_css_sp_group.config.input_circuit.input_mode = input_mode;
679 * The SP group is only loaded at SP boot time and is read once
680 * change flags as "input_circuit_cfg_changed" must be reset on the SP
682 sh_css_sp_group.config.input_circuit_cfg_changed = true;
683 sh_css_sp_stage.program_input_circuit = true;
687 #if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2)
689 sh_css_sp_configure_sync_gen(int width, int height,
693 sh_css_sp_group.config.sync_gen.width = width;
694 sh_css_sp_group.config.sync_gen.height = height;
695 sh_css_sp_group.config.sync_gen.hblank_cycles = hblank_cycles;
696 sh_css_sp_group.config.sync_gen.vblank_cycles = vblank_cycles;
700 sh_css_sp_configure_tpg(int x_mask,
706 sh_css_sp_group.config.tpg.x_mask = x_mask;
707 sh_css_sp_group.config.tpg.y_mask = y_mask;
708 sh_css_sp_group.config.tpg.x_delta = x_delta;
709 sh_css_sp_group.config.tpg.y_delta = y_delta;
710 sh_css_sp_group.config.tpg.xy_mask = xy_mask;
714 sh_css_sp_configure_prbs(int seed)
716 sh_css_sp_group.config.prbs.seed = seed;
721 sh_css_sp_configure_enable_raw_pool_locking(bool lock_all)
723 sh_css_sp_group.config.enable_raw_pool_locking = true;
724 sh_css_sp_group.config.lock_all = lock_all;
728 sh_css_sp_enable_isys_event_queue(bool enable)
730 #if !defined(HAS_NO_INPUT_SYSTEM)
731 sh_css_sp_group.config.enable_isys_event_queue = enable;
738 sh_css_sp_set_disable_continuous_viewfinder(bool flag)
740 sh_css_sp_group.config.disable_cont_vf = flag;
743 static enum ia_css_err
744 sh_css_sp_write_frame_pointers(const struct sh_css_binary_args *args) {
745 enum ia_css_err err = IA_CSS_SUCCESS;
751 err = set_input_frame_buffer(args->in_frame);
752 if (err == IA_CSS_SUCCESS && args->out_vf_frame)
753 err = set_view_finder_buffer(args->out_vf_frame);
754 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
756 if (err == IA_CSS_SUCCESS && args->out_frame[i])
757 err = set_output_frame_buffer(args->out_frame[i], i);
760 /* we don't pass this error back to the upper layer, so we add a assert here
761 because we actually hit the error here but it still works by accident... */
762 if (err != IA_CSS_SUCCESS) assert(false);
767 sh_css_sp_init_group(bool two_ppc,
768 enum atomisp_input_format input_format,
770 uint8_t if_config_index)
772 #if !defined(HAS_NO_INPUT_FORMATTER)
773 sh_css_sp_group.config.input_formatter.isp_2ppc = two_ppc;
778 sh_css_sp_group.config.no_isp_sync = (uint8_t)no_isp_sync;
779 /* decide whether the frame is processed online or offline */
780 if (if_config_index == SH_CSS_IF_CONFIG_NOT_NEEDED) return;
781 #if !defined(HAS_NO_INPUT_FORMATTER)
782 assert(if_config_index < SH_CSS_MAX_IF_CONFIGS);
783 sh_css_sp_group.config.input_formatter.set[if_config_index].stream_format =
791 sh_css_stage_write_binary_info(struct ia_css_binary_info *info)
794 sh_css_isp_stage.binary_info = *info;
797 static enum ia_css_err
798 copy_isp_mem_if_to_ddr(struct ia_css_binary *binary) {
801 err = ia_css_isp_param_copy_isp_mem_if_to_ddr(
804 IA_CSS_PARAM_CLASS_CONFIG);
805 if (err != IA_CSS_SUCCESS)
807 err = ia_css_isp_param_copy_isp_mem_if_to_ddr(
810 IA_CSS_PARAM_CLASS_STATE);
811 if (err != IA_CSS_SUCCESS)
813 return IA_CSS_SUCCESS;
817 is_sp_stage(struct ia_css_pipeline_stage *stage)
820 return stage->sp_func != IA_CSS_PIPELINE_NO_FUNC;
823 static enum ia_css_err
824 configure_isp_from_args(
825 const struct sh_css_sp_pipeline *pipeline,
826 const struct ia_css_binary *binary,
827 const struct sh_css_binary_args *args,
829 bool deinterleaved) {
831 struct ia_css_pipe *pipe = find_pipe_by_num(pipeline->pipe_num);
832 const struct ia_css_resolution *res;
835 ia_css_fpn_configure(binary, &binary->in_frame_info);
836 ia_css_crop_configure(binary, &args->delay_frames[0]->info);
837 ia_css_qplane_configure(pipeline, binary, &binary->in_frame_info);
838 ia_css_output0_configure(binary, &args->out_frame[0]->info);
839 ia_css_output1_configure(binary, &args->out_vf_frame->info);
840 ia_css_copy_output_configure(binary, args->copy_output);
841 ia_css_output0_configure(binary, &args->out_frame[0]->info);
843 ia_css_sc_configure(binary, pipeline->shading.internal_frame_origin_x_bqs_on_sctbl,
844 pipeline->shading.internal_frame_origin_y_bqs_on_sctbl);
846 ia_css_iterator_configure(binary, &args->in_frame->info);
847 ia_css_dvs_configure(binary, &args->out_frame[0]->info);
848 ia_css_output_configure(binary, &args->out_frame[0]->info);
849 ia_css_raw_configure(pipeline, binary, &args->in_frame->info, &binary->in_frame_info, two_ppc, deinterleaved);
850 ia_css_ref_configure(binary, (const struct ia_css_frame **)args->delay_frames, pipeline->dvs_frame_delay);
851 ia_css_tnr_configure(binary, (const struct ia_css_frame **)args->tnr_frames);
852 ia_css_bayer_io_config(binary, args);
853 return IA_CSS_SUCCESS;
857 initialize_isp_states(const struct ia_css_binary *binary)
861 if (!binary->info->mem_offsets.offsets.state)
863 for (i = 0; i < IA_CSS_NUM_STATE_IDS; i++) {
864 ia_css_kernel_init_state[i](binary);
869 initialize_frame_buffer_attribute(struct ia_css_buffer_sp *buf_attr)
871 buf_attr->buf_src.queue_id = SH_CSS_INVALID_QUEUE_ID;
872 buf_attr->buf_type = IA_CSS_BUFFER_TYPE_INVALID;
876 initialize_stage_frames(struct ia_css_frames_sp *frames)
880 initialize_frame_buffer_attribute(&frames->in.buf_attr);
881 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) {
882 initialize_frame_buffer_attribute(&frames->out[i].buf_attr);
884 initialize_frame_buffer_attribute(&frames->out_vf.buf_attr);
885 initialize_frame_buffer_attribute(&frames->s3a_buf);
886 initialize_frame_buffer_attribute(&frames->dvs_buf);
887 #if defined SH_CSS_ENABLE_METADATA
888 initialize_frame_buffer_attribute(&frames->metadata_buf);
892 static enum ia_css_err
893 sh_css_sp_init_stage(struct ia_css_binary *binary,
894 const char *binary_name,
895 const struct ia_css_blob_info *blob_info,
896 const struct sh_css_binary_args *args,
897 unsigned int pipe_num,
900 const struct ia_css_isp_param_css_segments *isp_mem_if,
901 unsigned int if_config_index,
903 const struct ia_css_binary_xinfo *xinfo;
904 const struct ia_css_binary_info *info;
905 enum ia_css_err err = IA_CSS_SUCCESS;
907 struct ia_css_pipe *pipe = NULL;
908 unsigned int thread_id;
909 enum sh_css_queue_id queue_id;
910 bool continuous = sh_css_continuous_is_enabled((uint8_t)pipe_num);
917 xinfo = binary->info;
921 * Clear sh_css_sp_stage for easy debugging.
922 * program_input_circuit must be saved as it is set outside
925 u8 program_input_circuit;
927 program_input_circuit = sh_css_sp_stage.program_input_circuit;
928 memset(&sh_css_sp_stage, 0, sizeof(sh_css_sp_stage));
929 sh_css_sp_stage.program_input_circuit = (uint8_t)program_input_circuit;
932 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
936 sh_css_sp_group.pipe[thread_id].sp_stage_addr[stage] = mmgr_NULL;
937 return IA_CSS_SUCCESS;
940 #if defined(USE_INPUT_SYSTEM_VERSION_2401)
942 sh_css_sp_stage.deinterleaved = 0;
944 sh_css_sp_stage.deinterleaved = ((stage == 0) && continuous);
947 initialize_stage_frames(&sh_css_sp_stage.frames);
949 * TODO: Make the Host dynamically determine
952 sh_css_sp_stage.stage_type = SH_CSS_ISP_STAGE_TYPE;
953 sh_css_sp_stage.num = (uint8_t)stage;
954 sh_css_sp_stage.isp_online = (uint8_t)binary->online;
955 sh_css_sp_stage.isp_copy_vf = (uint8_t)args->copy_vf;
956 sh_css_sp_stage.isp_copy_output = (uint8_t)args->copy_output;
957 sh_css_sp_stage.enable.vf_output = (args->out_vf_frame != NULL);
959 /* Copy the frame infos first, to be overwritten by the frames,
960 if these are present.
962 sh_css_sp_stage.frames.effective_in_res.width = binary->effective_in_frame_res.width;
963 sh_css_sp_stage.frames.effective_in_res.height = binary->effective_in_frame_res.height;
965 ia_css_frame_info_to_frame_sp_info(&sh_css_sp_stage.frames.in.info,
966 &binary->in_frame_info);
967 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
969 ia_css_frame_info_to_frame_sp_info(&sh_css_sp_stage.frames.out[i].info,
970 &binary->out_frame_info[i]);
972 ia_css_frame_info_to_frame_sp_info(&sh_css_sp_stage.frames.internal_frame_info,
973 &binary->internal_frame_info);
974 sh_css_sp_stage.dvs_envelope.width = binary->dvs_envelope.width;
975 sh_css_sp_stage.dvs_envelope.height = binary->dvs_envelope.height;
976 sh_css_sp_stage.isp_pipe_version = (uint8_t)info->pipeline.isp_pipe_version;
977 sh_css_sp_stage.isp_deci_log_factor = (uint8_t)binary->deci_factor_log2;
978 sh_css_sp_stage.isp_vf_downscale_bits = (uint8_t)binary->vf_downscale_log2;
980 sh_css_sp_stage.if_config_index = (uint8_t)if_config_index;
982 sh_css_sp_stage.sp_enable_xnr = (uint8_t)xnr;
983 sh_css_sp_stage.xmem_bin_addr = xinfo->xmem_addr;
984 sh_css_sp_stage.xmem_map_addr = sh_css_params_ddr_address_map();
985 sh_css_isp_stage.blob_info = *blob_info;
986 sh_css_stage_write_binary_info((struct ia_css_binary_info *)info);
988 /* Make sure binary name is smaller than allowed string size */
989 assert(strlen(binary_name) < SH_CSS_MAX_BINARY_NAME - 1);
990 strncpy(sh_css_isp_stage.binary_name, binary_name, SH_CSS_MAX_BINARY_NAME - 1);
991 sh_css_isp_stage.binary_name[SH_CSS_MAX_BINARY_NAME - 1] = 0;
992 sh_css_isp_stage.mem_initializers = *isp_mem_if;
995 * Even when a stage does not need uds and does not params,
996 * ia_css_uds_sp_scale_params() seems to be called (needs
997 * further investigation). This function can not deal with
1001 err = sh_css_sp_write_frame_pointers(args);
1002 /* TODO: move it to a better place */
1003 if (binary->info->sp.enable.s3a)
1005 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_3A_STATISTICS, thread_id,
1007 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage.frames.s3a_buf, queue_id,
1009 IA_CSS_BUFFER_TYPE_3A_STATISTICS);
1011 if (binary->info->sp.enable.dis)
1013 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_DIS_STATISTICS, thread_id,
1015 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage.frames.dvs_buf, queue_id,
1017 IA_CSS_BUFFER_TYPE_DIS_STATISTICS);
1019 #if defined SH_CSS_ENABLE_METADATA
1020 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_METADATA, thread_id, &queue_id);
1021 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage.frames.metadata_buf, queue_id, mmgr_EXCEPTION, IA_CSS_BUFFER_TYPE_METADATA);
1023 if (err != IA_CSS_SUCCESS)
1026 #ifdef USE_INPUT_SYSTEM_VERSION_2401
1030 pipe = find_pipe_by_num(sh_css_sp_group.pipe[thread_id].pipe_num);
1032 return IA_CSS_ERR_INTERNAL_ERROR;
1033 ia_css_get_crop_offsets(pipe, &args->in_frame->info);
1034 } else if (&binary->in_frame_info)
1036 pipe = find_pipe_by_num(sh_css_sp_group.pipe[thread_id].pipe_num);
1038 return IA_CSS_ERR_INTERNAL_ERROR;
1039 ia_css_get_crop_offsets(pipe, &binary->in_frame_info);
1043 if (args->in_frame) {
1044 pipe = find_pipe_by_num(sh_css_sp_group.pipe[thread_id].pipe_num);
1046 return IA_CSS_ERR_INTERNAL_ERROR;
1047 ia_css_get_crop_offsets(pipe, &args->in_frame->info);
1048 } else if (&binary->in_frame_info) {
1049 pipe = find_pipe_by_num(sh_css_sp_group.pipe[thread_id].pipe_num);
1051 return IA_CSS_ERR_INTERNAL_ERROR;
1052 ia_css_get_crop_offsets(pipe, &binary->in_frame_info);
1057 (void)pipe; /*avoid build warning*/
1060 err = configure_isp_from_args(&sh_css_sp_group.pipe[thread_id],
1061 binary, args, two_ppc, sh_css_sp_stage.deinterleaved);
1062 if (err != IA_CSS_SUCCESS)
1065 initialize_isp_states(binary);
1067 /* we do this only for preview pipe because in fill_binary_info function
1068 * we assign vf_out res to out res, but for ISP internal processing, we need
1069 * the original out res. for video pipe, it has two output pins --- out and
1070 * vf_out, so it can keep these two resolutions already. */
1071 if (binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_PREVIEW &&
1072 (binary->vf_downscale_log2 > 0))
1074 /* TODO: Remove this after preview output decimation is fixed
1075 * by configuring out&vf info fiels properly */
1076 sh_css_sp_stage.frames.out[0].info.padded_width
1077 <<= binary->vf_downscale_log2;
1078 sh_css_sp_stage.frames.out[0].info.res.width
1079 <<= binary->vf_downscale_log2;
1080 sh_css_sp_stage.frames.out[0].info.res.height
1081 <<= binary->vf_downscale_log2;
1083 err = copy_isp_mem_if_to_ddr(binary);
1084 if (err != IA_CSS_SUCCESS)
1087 return IA_CSS_SUCCESS;
1090 static enum ia_css_err
1091 sp_init_stage(struct ia_css_pipeline_stage *stage,
1092 unsigned int pipe_num,
1094 unsigned int if_config_index,
1096 struct ia_css_binary *binary;
1097 const struct ia_css_fw_info *firmware;
1098 const struct sh_css_binary_args *args;
1099 unsigned int stage_num;
1101 * Initialiser required because of the "else" path below.
1102 * Is this a valid path ?
1104 const char *binary_name = "";
1105 const struct ia_css_binary_xinfo *info = NULL;
1106 /* note: the var below is made static as it is quite large;
1107 if it is not static it ends up on the stack which could
1108 cause issues for drivers
1110 static struct ia_css_binary tmp_binary;
1111 const struct ia_css_blob_info *blob_info = NULL;
1112 struct ia_css_isp_param_css_segments isp_mem_if;
1113 /* LA: should be ia_css_data, should not contain host pointer.
1114 However, CSS/DDR pointer is not available yet.
1115 Hack is to store it in params->ddr_ptrs and then copy it late in the SP just before vmem init.
1116 TODO: Call this after CSS/DDR allocation and store that pointer.
1117 Best is to allocate it at stage creation time together with host pointer.
1118 Remove vmem from params.
1120 struct ia_css_isp_param_css_segments *mem_if = &isp_mem_if;
1122 enum ia_css_err err = IA_CSS_SUCCESS;
1126 binary = stage->binary;
1127 firmware = stage->firmware;
1128 args = &stage->args;
1129 stage_num = stage->stage_num;
1133 info = binary->info;
1134 binary_name = (const char *)(info->blob->name);
1135 blob_info = &info->blob->header.blob;
1136 ia_css_init_memory_interface(mem_if, &binary->mem_params, &binary->css_params);
1137 } else if (firmware)
1139 const struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS] = {NULL};
1141 if (args->out_frame[0])
1142 out_infos[0] = &args->out_frame[0]->info;
1143 info = &firmware->info.isp;
1144 ia_css_binary_fill_info(info, false, false,
1145 ATOMISP_INPUT_FORMAT_RAW_10,
1146 args->in_frame ? &args->in_frame->info : NULL,
1149 args->out_vf_frame ? &args->out_vf_frame->info
1154 binary = &tmp_binary;
1155 binary->info = info;
1156 binary_name = IA_CSS_EXT_ISP_PROG_NAME(firmware);
1157 blob_info = &firmware->blob;
1158 mem_if = (struct ia_css_isp_param_css_segments *)&firmware->mem_initializers;
1162 assert(stage->sp_func != IA_CSS_PIPELINE_NO_FUNC);
1163 /* binary and blob_info are now NULL.
1164 These will be passed to sh_css_sp_init_stage
1165 and dereferenced there, so passing a NULL
1166 pointer is no good. return an error */
1167 return IA_CSS_ERR_INTERNAL_ERROR;
1170 err = sh_css_sp_init_stage(binary,
1171 (const char *)binary_name,
1184 sp_init_sp_stage(struct ia_css_pipeline_stage *stage,
1185 unsigned int pipe_num,
1187 enum sh_css_pipe_config_override copy_ovrd,
1188 unsigned int if_config_index)
1190 const struct sh_css_binary_args *args = &stage->args;
1193 switch (stage->sp_func) {
1194 case IA_CSS_PIPELINE_RAW_COPY:
1195 sh_css_sp_start_raw_copy(args->out_frame[0],
1197 stage->max_input_width,
1198 copy_ovrd, if_config_index);
1200 case IA_CSS_PIPELINE_BIN_COPY:
1201 assert(false); /* TBI */
1202 case IA_CSS_PIPELINE_ISYS_COPY:
1203 sh_css_sp_start_isys_copy(args->out_frame[0],
1204 pipe_num, stage->max_input_width, if_config_index);
1206 case IA_CSS_PIPELINE_NO_FUNC:
1212 sh_css_sp_init_pipeline(struct ia_css_pipeline *me,
1213 enum ia_css_pipe_id id,
1219 unsigned int required_bds_factor,
1220 enum sh_css_pipe_config_override copy_ovrd,
1221 enum ia_css_input_mode input_mode,
1222 const struct ia_css_metadata_config *md_config,
1223 const struct ia_css_metadata_info *md_info,
1224 #if !defined(HAS_NO_INPUT_SYSTEM)
1225 const enum mipi_port_id port_id,
1227 const struct ia_css_coordinate
1228 *internal_frame_origin_bqs_on_sctbl, /* Origin of internal frame
1229 positioned on shading table at shading correction in ISP. */
1230 const struct ia_css_isp_parameters *params
1232 /* Get first stage */
1233 struct ia_css_pipeline_stage *stage = NULL;
1234 struct ia_css_binary *first_binary = NULL;
1235 struct ia_css_pipe *pipe = NULL;
1238 enum ia_css_pipe_id pipe_id = id;
1239 unsigned int thread_id;
1240 u8 if_config_index, tmp_if_config_index;
1244 #if !defined(HAS_NO_INPUT_SYSTEM)
1247 first_binary = me->stages->binary;
1249 if (input_mode == IA_CSS_INPUT_MODE_SENSOR ||
1250 input_mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
1252 assert(port_id < N_MIPI_PORT_ID);
1253 if (port_id >= N_MIPI_PORT_ID) /* should not happen but KW does not know */
1254 return; /* we should be able to return an error */
1255 if_config_index = (uint8_t)(port_id - MIPI_PORT0_ID);
1256 } else if (input_mode == IA_CSS_INPUT_MODE_MEMORY)
1258 if_config_index = SH_CSS_IF_CONFIG_NOT_NEEDED;
1261 if_config_index = 0x0;
1265 if_config_index = SH_CSS_IF_CONFIG_NOT_NEEDED;
1268 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
1269 memset(&sh_css_sp_group.pipe[thread_id], 0, sizeof(struct sh_css_sp_pipeline));
1272 for (stage = me->stages, num = 0; stage; stage = stage->next, num++)
1274 stage->stage_num = num;
1275 ia_css_debug_pipe_graph_dump_stage(stage, id);
1277 me->num_stages = num;
1281 /* Init pipeline data */
1282 sh_css_sp_init_group(two_ppc, first_binary->input_format,
1283 offline, if_config_index);
1284 } /* if (first_binary != NULL) */
1286 #if defined(USE_INPUT_SYSTEM_VERSION_2401) || defined(USE_INPUT_SYSTEM_VERSION_2)
1287 /* Signal the host immediately after start for SP_ISYS_COPY only */
1288 if ((me->num_stages == 1) && me->stages &&
1289 (me->stages->sp_func == IA_CSS_PIPELINE_ISYS_COPY))
1290 sh_css_sp_group.config.no_isp_sync = true;
1293 /* Init stage data */
1294 sh_css_init_host2sp_frame_data();
1296 sh_css_sp_group.pipe[thread_id].num_stages = 0;
1297 sh_css_sp_group.pipe[thread_id].pipe_id = pipe_id;
1298 sh_css_sp_group.pipe[thread_id].thread_id = thread_id;
1299 sh_css_sp_group.pipe[thread_id].pipe_num = pipe_num;
1300 sh_css_sp_group.pipe[thread_id].num_execs = me->num_execs;
1301 sh_css_sp_group.pipe[thread_id].pipe_qos_config = me->pipe_qos_config;
1302 sh_css_sp_group.pipe[thread_id].required_bds_factor = required_bds_factor;
1303 #if !defined(HAS_NO_INPUT_SYSTEM)
1304 sh_css_sp_group.pipe[thread_id].input_system_mode
1305 = (uint32_t)input_mode;
1306 sh_css_sp_group.pipe[thread_id].port_id = port_id;
1308 sh_css_sp_group.pipe[thread_id].dvs_frame_delay = (uint32_t)me->dvs_frame_delay;
1310 /* TODO: next indicates from which queues parameters need to be
1311 sampled, needs checking/improvement */
1312 if (ia_css_pipeline_uses_params(me))
1314 sh_css_sp_group.pipe[thread_id].pipe_config =
1315 SH_CSS_PIPE_CONFIG_SAMPLE_PARAMS << thread_id;
1318 /* For continuous use-cases, SP copy is responsible for sampling the
1321 sh_css_sp_group.pipe[thread_id].pipe_config = 0;
1323 sh_css_sp_group.pipe[thread_id].inout_port_config = me->inout_port_config;
1325 pipe = find_pipe_by_num(pipe_num);
1331 sh_css_sp_group.pipe[thread_id].scaler_pp_lut = sh_css_pipe_get_pp_gdc_lut(pipe);
1333 #if defined(SH_CSS_ENABLE_METADATA)
1334 if (md_info && md_info->size > 0)
1336 sh_css_sp_group.pipe[thread_id].metadata.width = md_info->resolution.width;
1337 sh_css_sp_group.pipe[thread_id].metadata.height = md_info->resolution.height;
1338 sh_css_sp_group.pipe[thread_id].metadata.stride = md_info->stride;
1339 sh_css_sp_group.pipe[thread_id].metadata.size = md_info->size;
1340 ia_css_isys_convert_stream_format_to_mipi_format(
1341 md_config->data_type, MIPI_PREDICTOR_NONE,
1342 &sh_css_sp_group.pipe[thread_id].metadata.format);
1349 #if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
1350 sh_css_sp_group.pipe[thread_id].output_frame_queue_id = (uint32_t)SH_CSS_INVALID_QUEUE_ID;
1351 if (pipe_id != IA_CSS_PIPE_ID_COPY)
1353 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, thread_id,
1354 (enum sh_css_queue_id *)(
1355 &sh_css_sp_group.pipe[thread_id].output_frame_queue_id));
1359 if (atomisp_hw_is_isp2401) {
1360 /* For the shading correction type 1 (the legacy shading table conversion in css is not used),
1361 * the parameters are passed to the isp for the shading table centering.
1363 if (internal_frame_origin_bqs_on_sctbl &&
1364 params && params->shading_settings.enable_shading_table_conversion == 0)
1366 sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_x_bqs_on_sctbl
1367 = (uint32_t)internal_frame_origin_bqs_on_sctbl->x;
1368 sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_y_bqs_on_sctbl
1369 = (uint32_t)internal_frame_origin_bqs_on_sctbl->y;
1372 sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_x_bqs_on_sctbl =
1374 sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_y_bqs_on_sctbl =
1379 IA_CSS_LOG("pipe_id %d port_config %08x",
1380 pipe_id, sh_css_sp_group.pipe[thread_id].inout_port_config);
1382 for (stage = me->stages, num = 0; stage; stage = stage->next, num++)
1384 sh_css_sp_group.pipe[thread_id].num_stages++;
1385 if (is_sp_stage(stage)) {
1386 sp_init_sp_stage(stage, pipe_num, two_ppc,
1387 copy_ovrd, if_config_index);
1389 if ((stage->stage_num != 0) ||
1390 SH_CSS_PIPE_PORT_CONFIG_IS_CONTINUOUS(me->inout_port_config))
1391 tmp_if_config_index = SH_CSS_IF_CONFIG_NOT_NEEDED;
1393 tmp_if_config_index = if_config_index;
1394 sp_init_stage(stage, pipe_num,
1395 xnr, tmp_if_config_index, two_ppc);
1398 store_sp_stage_data(pipe_id, pipe_num, num);
1400 sh_css_sp_group.pipe[thread_id].pipe_config |= (uint32_t)
1401 (me->acquire_isp_each_stage << IA_CSS_ACQUIRE_ISP_POS);
1402 store_sp_group_data();
1406 sh_css_sp_uninit_pipeline(unsigned int pipe_num)
1408 unsigned int thread_id;
1410 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
1411 /*memset(&sh_css_sp_group.pipe[thread_id], 0, sizeof(struct sh_css_sp_pipeline));*/
1412 sh_css_sp_group.pipe[thread_id].num_stages = 0;
1415 bool sh_css_write_host2sp_command(enum host2sp_commands host2sp_command)
1417 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1418 unsigned int offset = (unsigned int)offsetof(struct host_sp_communication,
1421 enum host2sp_commands last_cmd = host2sp_cmd_error;
1422 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1424 /* Previous command must be handled by SP (by design) */
1425 last_cmd = load_sp_array_uint(host_sp_com, offset);
1426 if (last_cmd != host2sp_cmd_ready)
1427 IA_CSS_ERROR("last host command not handled by SP(%d)", last_cmd);
1429 store_sp_array_uint(host_sp_com, offset, host2sp_command);
1431 return (last_cmd == host2sp_cmd_ready);
1434 enum host2sp_commands
1435 sh_css_read_host2sp_command(void) {
1436 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1437 unsigned int offset = (unsigned int)offsetof(struct host_sp_communication, host2sp_command)
1439 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1440 return (enum host2sp_commands)load_sp_array_uint(host_sp_com, offset);
1444 * Frame data is no longer part of the sp_stage structure but part of a
1445 * separate structure. The aim is to make the sp_data struct static
1446 * (it defines a pipeline) and that the dynamic (per frame) data is stored
1449 * This function must be called first every where were you start constructing
1450 * a new pipeline by defining one or more stages with use of variable
1451 * sh_css_sp_stage. Even the special cases like accelerator and copy_frame
1452 * These have a pipeline of just 1 stage.
1455 sh_css_init_host2sp_frame_data(void)
1458 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1460 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1462 * rvanimme: don't clean it to save static frame info line ref_in
1463 * ref_out, and tnr_frames. Once this static data is in a
1464 * separate data struct, this may be enable (but still, there is
1470 * @brief Update the offline frame information in host_sp_communication.
1471 * Refer to "sh_css_sp.h" for more details.
1474 sh_css_update_host2sp_offline_frame(
1475 unsigned int frame_num,
1476 struct ia_css_frame *frame,
1477 struct ia_css_metadata *metadata)
1479 unsigned int HIVE_ADDR_host_sp_com;
1480 unsigned int offset;
1482 assert(frame_num < NUM_CONTINUOUS_FRAMES);
1484 /* Write new frame data into SP DMEM */
1485 HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1486 offset = (unsigned int)offsetof(struct host_sp_communication,
1487 host2sp_offline_frames)
1489 offset += frame_num;
1490 store_sp_array_uint(host_sp_com, offset, frame ? frame->data : 0);
1492 /* Write metadata buffer into SP DMEM */
1493 offset = (unsigned int)offsetof(struct host_sp_communication,
1494 host2sp_offline_metadata)
1496 offset += frame_num;
1497 store_sp_array_uint(host_sp_com, offset, metadata ? metadata->address : 0);
1500 #if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
1502 * @brief Update the mipi frame information in host_sp_communication.
1503 * Refer to "sh_css_sp.h" for more details.
1506 sh_css_update_host2sp_mipi_frame(
1507 unsigned int frame_num,
1508 struct ia_css_frame *frame)
1510 unsigned int HIVE_ADDR_host_sp_com;
1511 unsigned int offset;
1513 /* MIPI buffers are dedicated to port, so now there are more of them. */
1514 assert(frame_num < (N_CSI_PORTS * NUM_MIPI_FRAMES_PER_STREAM));
1516 /* Write new frame data into SP DMEM */
1517 HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1518 offset = (unsigned int)offsetof(struct host_sp_communication,
1519 host2sp_mipi_frames)
1521 offset += frame_num;
1523 store_sp_array_uint(host_sp_com, offset,
1524 frame ? frame->data : 0);
1528 * @brief Update the mipi metadata information in host_sp_communication.
1529 * Refer to "sh_css_sp.h" for more details.
1532 sh_css_update_host2sp_mipi_metadata(
1533 unsigned int frame_num,
1534 struct ia_css_metadata *metadata)
1536 unsigned int HIVE_ADDR_host_sp_com;
1539 /* MIPI buffers are dedicated to port, so now there are more of them. */
1540 assert(frame_num < (N_CSI_PORTS * NUM_MIPI_FRAMES_PER_STREAM));
1542 /* Write new frame data into SP DMEM */
1543 HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1544 o = offsetof(struct host_sp_communication, host2sp_mipi_metadata)
1547 store_sp_array_uint(host_sp_com, o,
1548 metadata ? metadata->address : 0);
1552 sh_css_update_host2sp_num_mipi_frames(unsigned int num_frames)
1554 unsigned int HIVE_ADDR_host_sp_com;
1555 unsigned int offset;
1557 /* Write new frame data into SP DMEM */
1558 HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1559 offset = (unsigned int)offsetof(struct host_sp_communication,
1560 host2sp_num_mipi_frames)
1563 store_sp_array_uint(host_sp_com, offset, num_frames);
1568 sh_css_update_host2sp_cont_num_raw_frames(unsigned int num_frames,
1571 const struct ia_css_fw_info *fw;
1572 unsigned int HIVE_ADDR_host_sp_com;
1573 unsigned int extra_num_frames, avail_num_frames;
1574 unsigned int offset, offset_extra;
1576 /* Write new frame data into SP DMEM */
1578 HIVE_ADDR_host_sp_com = fw->info.sp.host_sp_com;
1580 offset = (unsigned int)offsetof(struct host_sp_communication,
1581 host2sp_cont_avail_num_raw_frames)
1583 avail_num_frames = load_sp_array_uint(host_sp_com, offset);
1584 extra_num_frames = num_frames - avail_num_frames;
1585 offset_extra = (unsigned int)offsetof(struct host_sp_communication,
1586 host2sp_cont_extra_num_raw_frames)
1588 store_sp_array_uint(host_sp_com, offset_extra, extra_num_frames);
1590 offset = (unsigned int)offsetof(struct host_sp_communication,
1591 host2sp_cont_target_num_raw_frames)
1594 store_sp_array_uint(host_sp_com, offset, num_frames);
1598 sh_css_event_init_irq_mask(void)
1601 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1602 unsigned int offset;
1603 struct sh_css_event_irq_mask event_irq_mask_init;
1605 event_irq_mask_init.or_mask = IA_CSS_EVENT_TYPE_ALL;
1606 event_irq_mask_init.and_mask = IA_CSS_EVENT_TYPE_NONE;
1607 (void)HIVE_ADDR_host_sp_com; /* Suppress warnings in CRUN */
1609 assert(sizeof(event_irq_mask_init) % HRT_BUS_BYTES == 0);
1610 for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++) {
1611 offset = (unsigned int)offsetof(struct host_sp_communication,
1612 host2sp_event_irq_mask[i]);
1613 assert(offset % HRT_BUS_BYTES == 0);
1614 sp_dmem_store(SP0_ID,
1615 (unsigned int)sp_address_of(host_sp_com) + offset,
1616 &event_irq_mask_init, sizeof(event_irq_mask_init));
1621 ia_css_pipe_set_irq_mask(struct ia_css_pipe *pipe,
1622 unsigned int or_mask,
1623 unsigned int and_mask) {
1624 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1625 unsigned int offset;
1626 struct sh_css_event_irq_mask event_irq_mask;
1627 unsigned int pipe_num;
1631 assert(IA_CSS_PIPE_ID_NUM == NR_OF_PIPELINES);
1632 /* Linux kernel does not have UINT16_MAX
1633 * Therefore decided to comment out these 2 asserts for Linux
1634 * Alternatives that were not chosen:
1635 * - add a conditional #define for UINT16_MAX
1636 * - compare with (uint16_t)~0 or 0xffff
1637 * - different assert for Linux and Windows
1640 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1642 IA_CSS_LOG("or_mask=%x, and_mask=%x", or_mask, and_mask);
1643 event_irq_mask.or_mask = (uint16_t)or_mask;
1644 event_irq_mask.and_mask = (uint16_t)and_mask;
1646 pipe_num = ia_css_pipe_get_pipe_num(pipe);
1647 if (pipe_num >= IA_CSS_PIPE_ID_NUM)
1648 return IA_CSS_ERR_INTERNAL_ERROR;
1649 offset = (unsigned int)offsetof(struct host_sp_communication,
1650 host2sp_event_irq_mask[pipe_num]);
1651 assert(offset % HRT_BUS_BYTES == 0);
1652 sp_dmem_store(SP0_ID,
1653 (unsigned int)sp_address_of(host_sp_com) + offset,
1654 &event_irq_mask, sizeof(event_irq_mask));
1656 return IA_CSS_SUCCESS;
1660 ia_css_event_get_irq_mask(const struct ia_css_pipe *pipe,
1661 unsigned int *or_mask,
1662 unsigned int *and_mask) {
1663 unsigned int HIVE_ADDR_host_sp_com = sh_css_sp_fw.info.sp.host_sp_com;
1664 unsigned int offset;
1665 struct sh_css_event_irq_mask event_irq_mask;
1666 unsigned int pipe_num;
1668 (void)HIVE_ADDR_host_sp_com; /* Suppres warnings in CRUN */
1670 IA_CSS_ENTER_LEAVE("");
1673 assert(IA_CSS_PIPE_ID_NUM == NR_OF_PIPELINES);
1675 pipe_num = ia_css_pipe_get_pipe_num(pipe);
1676 if (pipe_num >= IA_CSS_PIPE_ID_NUM)
1677 return IA_CSS_ERR_INTERNAL_ERROR;
1678 offset = (unsigned int)offsetof(struct host_sp_communication,
1679 host2sp_event_irq_mask[pipe_num]);
1680 assert(offset % HRT_BUS_BYTES == 0);
1681 sp_dmem_load(SP0_ID,
1682 (unsigned int)sp_address_of(host_sp_com) + offset,
1683 &event_irq_mask, sizeof(event_irq_mask));
1686 *or_mask = event_irq_mask.or_mask;
1689 *and_mask = event_irq_mask.and_mask;
1691 return IA_CSS_SUCCESS;
1695 sh_css_sp_set_sp_running(bool flag)
1701 sh_css_sp_is_running(void)
1707 sh_css_sp_start_isp(void)
1709 const struct ia_css_fw_info *fw;
1710 unsigned int HIVE_ADDR_sp_sw_state;
1713 HIVE_ADDR_sp_sw_state = fw->info.sp.sw_state;
1718 (void)HIVE_ADDR_sp_sw_state; /* Suppres warnings in CRUN */
1720 /* no longer here, sp started immediately */
1721 /*ia_css_debug_pipe_graph_dump_epilogue();*/
1723 store_sp_group_data();
1724 store_sp_per_frame_data(fw);
1726 sp_dmem_store_uint32(SP0_ID,
1727 (unsigned int)sp_address_of(sp_sw_state),
1728 (uint32_t)(IA_CSS_SP_SW_TERMINATED));
1730 /* Note 1: The sp_start_isp function contains a wait till
1731 * the input network is configured by the SP.
1732 * Note 2: Not all SP binaries supports host2sp_commands.
1733 * In case a binary does support it, the host2sp_command
1734 * will have status cmd_ready after return of the function
1735 * sh_css_hrt_sp_start_isp. There is no race-condition here
1736 * because only after the process_frame command has been
1737 * received, the SP starts configuring the input network.
1740 /* we need to set sp_running before we call ia_css_mmu_invalidate_cache
1741 * as ia_css_mmu_invalidate_cache checks on sp_running to
1742 * avoid that it accesses dmem while the SP is not powered
1745 ia_css_mmu_invalidate_cache();
1746 /* Invalidate all MMU caches */
1747 mmu_invalidate_cache_all();
1749 ia_css_spctrl_start(SP0_ID);
1753 ia_css_isp_has_started(void)
1755 const struct ia_css_fw_info *fw = &sh_css_sp_fw;
1756 unsigned int HIVE_ADDR_ia_css_ispctrl_sp_isp_started = fw->info.sp.isp_started;
1757 (void)HIVE_ADDR_ia_css_ispctrl_sp_isp_started; /* Suppres warnings in CRUN */
1759 return (bool)load_sp_uint(ia_css_ispctrl_sp_isp_started);
1763 * @brief Initialize the DMA software-mask in the debug mode.
1764 * Refer to "sh_css_sp.h" for more details.
1767 sh_css_sp_init_dma_sw_reg(int dma_id)
1771 /* enable all the DMA channels */
1772 for (i = 0; i < N_DMA_CHANNEL_ID; i++) {
1773 /* enable the writing request */
1774 sh_css_sp_set_dma_sw_reg(dma_id,
1778 /* enable the reading request */
1779 sh_css_sp_set_dma_sw_reg(dma_id,
1789 * @brief Set the DMA software-mask in the debug mode.
1790 * Refer to "sh_css_sp.h" for more details.
1793 sh_css_sp_set_dma_sw_reg(int dma_id,
1805 assert(channel_id >= 0 && channel_id < N_DMA_CHANNEL_ID);
1806 assert(request_type >= 0);
1808 /* get the software-mask */
1810 sh_css_sp_group.debug.dma_sw_reg;
1812 /* get the offest of the target bit */
1813 bit_offset = (8 * request_type) + channel_id;
1815 /* clear the value of the target bit */
1816 bit_mask = ~(1 << bit_offset);
1819 /* set the value of the bit for the DMA channel */
1820 bit_val = enable ? 1 : 0;
1821 bit_val <<= bit_offset;
1824 /* update the software status of DMA channels */
1825 sh_css_sp_group.debug.dma_sw_reg = sw_reg;
1831 sh_css_sp_reset_global_vars(void)
1833 memset(&sh_css_sp_group, 0, sizeof(struct sh_css_sp_group));
1834 memset(&sh_css_sp_stage, 0, sizeof(struct sh_css_sp_stage));
1835 memset(&sh_css_isp_stage, 0, sizeof(struct sh_css_isp_stage));
1836 memset(&sh_css_sp_output, 0, sizeof(struct sh_css_sp_output));
1837 memset(&per_frame_data, 0, sizeof(struct sh_css_sp_per_frame_data));