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)&(((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"
66 #include "isp/kernels/io_ls/bayer_io_ls/ia_css_bayer_io.host.h"
68 #include "isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.h"
71 struct sh_css_sp_group sh_css_sp_group
;
72 struct sh_css_sp_stage sh_css_sp_stage
;
73 struct sh_css_isp_stage sh_css_isp_stage
;
74 struct sh_css_sp_output sh_css_sp_output
;
75 static struct sh_css_sp_per_frame_data per_frame_data
;
77 /* true if SP supports frame loop and host2sp_commands */
78 /* For the moment there is only code that sets this bool to true */
79 /* TODO: add code that sets this bool to false */
80 static bool sp_running
;
82 static enum ia_css_err
83 set_output_frame_buffer(const struct ia_css_frame
*frame
,
87 sh_css_copy_buffer_attr_to_spbuffer(struct ia_css_buffer_sp
*dest_buf
,
88 const enum sh_css_queue_id queue_id
,
89 const hrt_vaddress xmem_addr
,
90 const enum ia_css_buffer_type buf_type
);
93 initialize_frame_buffer_attribute(struct ia_css_buffer_sp
*buf_attr
);
96 initialize_stage_frames(struct ia_css_frames_sp
*frames
);
98 /* This data is stored every frame */
100 store_sp_group_data(void)
102 per_frame_data
.sp_group_addr
= sh_css_store_sp_group_to_ddr();
106 copy_isp_stage_to_sp_stage(void)
108 /* [WW07.5]type casting will cause potential issues */
109 sh_css_sp_stage
.num_stripes
= (uint8_t) sh_css_isp_stage
.binary_info
.iterator
.num_stripes
;
110 sh_css_sp_stage
.row_stripes_height
= (uint16_t) sh_css_isp_stage
.binary_info
.iterator
.row_stripes_height
;
111 sh_css_sp_stage
.row_stripes_overlap_lines
= (uint16_t) sh_css_isp_stage
.binary_info
.iterator
.row_stripes_overlap_lines
;
112 sh_css_sp_stage
.top_cropping
= (uint16_t) 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
= sh_css_isp_stage
.binary_info
.enable
.lace_stats
;
126 store_sp_stage_data(enum ia_css_pipe_id id
, unsigned int pipe_num
, unsigned stage
)
128 unsigned int thread_id
;
129 ia_css_pipeline_get_sp_thread_id(pipe_num
, &thread_id
);
130 copy_isp_stage_to_sp_stage();
131 if (id
!= IA_CSS_PIPE_ID_COPY
)
132 sh_css_sp_stage
.isp_stage_addr
=
133 sh_css_store_isp_stage_to_ddr(pipe_num
, stage
);
134 sh_css_sp_group
.pipe
[thread_id
].sp_stage_addr
[stage
] =
135 sh_css_store_sp_stage_to_ddr(pipe_num
, stage
);
137 /* Clear for next frame */
138 sh_css_sp_stage
.program_input_circuit
= false;
142 store_sp_per_frame_data(const struct ia_css_fw_info
*fw
)
144 unsigned int HIVE_ADDR_sp_per_frame_data
= 0;
149 case ia_css_sp_firmware
:
150 HIVE_ADDR_sp_per_frame_data
= fw
->info
.sp
.per_frame_data
;
152 case ia_css_acc_firmware
:
153 HIVE_ADDR_sp_per_frame_data
= fw
->info
.acc
.per_frame_data
;
155 case ia_css_isp_firmware
:
159 sp_dmem_store(SP0_ID
,
160 (unsigned int)sp_address_of(sp_per_frame_data
),
162 sizeof(per_frame_data
));
166 sh_css_store_sp_per_frame_data(enum ia_css_pipe_id pipe_id
,
167 unsigned int pipe_num
,
168 const struct ia_css_fw_info
*sp_fw
)
171 sp_fw
= &sh_css_sp_fw
;
173 store_sp_stage_data(pipe_id
, pipe_num
, 0);
174 store_sp_group_data();
175 store_sp_per_frame_data(sp_fw
);
178 #if SP_DEBUG != SP_DEBUG_NONE
181 sh_css_sp_get_debug_state(struct sh_css_sp_debug_state
*state
)
183 const struct ia_css_fw_info
*fw
= &sh_css_sp_fw
;
184 unsigned int HIVE_ADDR_sp_output
= fw
->info
.sp
.output
;
186 unsigned offset
= (unsigned int)offsetof(struct sh_css_sp_output
, debug
)/sizeof(int);
188 assert(state
!= NULL
);
190 (void)HIVE_ADDR_sp_output
; /* To get rid of warning in CRUN */
191 for (i
= 0; i
< sizeof(*state
)/sizeof(int); i
++)
192 ((unsigned *)state
)[i
] = load_sp_array_uint(sp_output
, i
+offset
);
198 sh_css_sp_start_binary_copy(unsigned int pipe_num
, struct ia_css_frame
*out_frame
,
201 enum ia_css_pipe_id pipe_id
;
202 unsigned int thread_id
;
203 struct sh_css_sp_pipeline
*pipe
;
204 uint8_t stage_num
= 0;
206 assert(out_frame
!= NULL
);
207 pipe_id
= IA_CSS_PIPE_ID_CAPTURE
;
208 ia_css_pipeline_get_sp_thread_id(pipe_num
, &thread_id
);
209 pipe
= &sh_css_sp_group
.pipe
[thread_id
];
211 pipe
->copy
.bin
.bytes_available
= out_frame
->data_bytes
;
212 pipe
->num_stages
= 1;
213 pipe
->pipe_id
= pipe_id
;
214 pipe
->pipe_num
= pipe_num
;
215 pipe
->thread_id
= thread_id
;
216 pipe
->pipe_config
= 0x0; /* No parameters */
217 pipe
->pipe_qos_config
= QOS_INVALID
;
219 if (pipe
->inout_port_config
== 0) {
220 SH_CSS_PIPE_PORT_CONFIG_SET(pipe
->inout_port_config
,
221 (uint8_t)SH_CSS_PORT_INPUT
,
222 (uint8_t)SH_CSS_HOST_TYPE
, 1);
223 SH_CSS_PIPE_PORT_CONFIG_SET(pipe
->inout_port_config
,
224 (uint8_t)SH_CSS_PORT_OUTPUT
,
225 (uint8_t)SH_CSS_HOST_TYPE
, 1);
227 IA_CSS_LOG("pipe_id %d port_config %08x",
228 pipe
->pipe_id
, pipe
->inout_port_config
);
230 #if !defined(HAS_NO_INPUT_FORMATTER)
231 sh_css_sp_group
.config
.input_formatter
.isp_2ppc
= (uint8_t)two_ppc
;
236 sh_css_sp_stage
.num
= stage_num
;
237 sh_css_sp_stage
.stage_type
= SH_CSS_SP_STAGE_TYPE
;
238 sh_css_sp_stage
.func
=
239 (unsigned int)IA_CSS_PIPELINE_BIN_COPY
;
241 set_output_frame_buffer(out_frame
, 0);
243 /* sp_bin_copy_init on the SP does not deal with dynamica/static yet */
244 /* For now always update the dynamic data from out frames. */
245 sh_css_store_sp_per_frame_data(pipe_id
, pipe_num
, &sh_css_sp_fw
);
249 sh_css_sp_start_raw_copy(struct ia_css_frame
*out_frame
,
252 unsigned max_input_width
,
253 enum sh_css_pipe_config_override pipe_conf_override
,
254 unsigned int if_config_index
)
256 enum ia_css_pipe_id pipe_id
;
257 unsigned int thread_id
;
258 uint8_t stage_num
= 0;
259 struct sh_css_sp_pipeline
*pipe
;
261 assert(out_frame
!= NULL
);
265 * Clear sh_css_sp_stage for easy debugging.
266 * program_input_circuit must be saved as it is set outside
269 uint8_t program_input_circuit
;
270 program_input_circuit
= sh_css_sp_stage
.program_input_circuit
;
271 memset(&sh_css_sp_stage
, 0, sizeof(sh_css_sp_stage
));
272 sh_css_sp_stage
.program_input_circuit
= program_input_circuit
;
275 pipe_id
= IA_CSS_PIPE_ID_COPY
;
276 ia_css_pipeline_get_sp_thread_id(pipe_num
, &thread_id
);
277 pipe
= &sh_css_sp_group
.pipe
[thread_id
];
279 pipe
->copy
.raw
.height
= out_frame
->info
.res
.height
;
280 pipe
->copy
.raw
.width
= out_frame
->info
.res
.width
;
281 pipe
->copy
.raw
.padded_width
= out_frame
->info
.padded_width
;
282 pipe
->copy
.raw
.raw_bit_depth
= out_frame
->info
.raw_bit_depth
;
283 pipe
->copy
.raw
.max_input_width
= max_input_width
;
284 pipe
->num_stages
= 1;
285 pipe
->pipe_id
= pipe_id
;
286 /* TODO: next indicates from which queues parameters need to be
287 sampled, needs checking/improvement */
288 if (pipe_conf_override
== SH_CSS_PIPE_CONFIG_OVRD_NO_OVRD
)
290 (SH_CSS_PIPE_CONFIG_SAMPLE_PARAMS
<< thread_id
);
292 pipe
->pipe_config
= pipe_conf_override
;
294 pipe
->pipe_qos_config
= QOS_INVALID
;
296 if (pipe
->inout_port_config
== 0) {
297 SH_CSS_PIPE_PORT_CONFIG_SET(pipe
->inout_port_config
,
298 (uint8_t)SH_CSS_PORT_INPUT
,
299 (uint8_t)SH_CSS_HOST_TYPE
, 1);
300 SH_CSS_PIPE_PORT_CONFIG_SET(pipe
->inout_port_config
,
301 (uint8_t)SH_CSS_PORT_OUTPUT
,
302 (uint8_t)SH_CSS_HOST_TYPE
, 1);
304 IA_CSS_LOG("pipe_id %d port_config %08x",
305 pipe
->pipe_id
, pipe
->inout_port_config
);
307 #if !defined(HAS_NO_INPUT_FORMATTER)
308 sh_css_sp_group
.config
.input_formatter
.isp_2ppc
= (uint8_t)two_ppc
;
313 sh_css_sp_stage
.num
= stage_num
;
314 sh_css_sp_stage
.xmem_bin_addr
= 0x0;
315 sh_css_sp_stage
.stage_type
= SH_CSS_SP_STAGE_TYPE
;
316 sh_css_sp_stage
.func
= (unsigned int)IA_CSS_PIPELINE_RAW_COPY
;
317 sh_css_sp_stage
.if_config_index
= (uint8_t) if_config_index
;
318 set_output_frame_buffer(out_frame
, 0);
320 ia_css_debug_pipe_graph_dump_sp_raw_copy(out_frame
);
324 sh_css_sp_start_isys_copy(struct ia_css_frame
*out_frame
,
325 unsigned pipe_num
, unsigned max_input_width
, unsigned int if_config_index
)
327 enum ia_css_pipe_id pipe_id
;
328 unsigned int thread_id
;
329 uint8_t stage_num
= 0;
330 struct sh_css_sp_pipeline
*pipe
;
331 #if defined SH_CSS_ENABLE_METADATA
332 enum sh_css_queue_id queue_id
;
335 assert(out_frame
!= NULL
);
339 * Clear sh_css_sp_stage for easy debugging.
340 * program_input_circuit must be saved as it is set outside
343 uint8_t program_input_circuit
;
344 program_input_circuit
= sh_css_sp_stage
.program_input_circuit
;
345 memset(&sh_css_sp_stage
, 0, sizeof(sh_css_sp_stage
));
346 sh_css_sp_stage
.program_input_circuit
= program_input_circuit
;
349 pipe_id
= IA_CSS_PIPE_ID_COPY
;
350 ia_css_pipeline_get_sp_thread_id(pipe_num
, &thread_id
);
351 pipe
= &sh_css_sp_group
.pipe
[thread_id
];
353 pipe
->copy
.raw
.height
= out_frame
->info
.res
.height
;
354 pipe
->copy
.raw
.width
= out_frame
->info
.res
.width
;
355 pipe
->copy
.raw
.padded_width
= out_frame
->info
.padded_width
;
356 pipe
->copy
.raw
.raw_bit_depth
= out_frame
->info
.raw_bit_depth
;
357 pipe
->copy
.raw
.max_input_width
= max_input_width
;
358 pipe
->num_stages
= 1;
359 pipe
->pipe_id
= pipe_id
;
360 pipe
->pipe_config
= 0x0; /* No parameters */
361 pipe
->pipe_qos_config
= QOS_INVALID
;
363 initialize_stage_frames(&sh_css_sp_stage
.frames
);
364 sh_css_sp_stage
.num
= stage_num
;
365 sh_css_sp_stage
.xmem_bin_addr
= 0x0;
366 sh_css_sp_stage
.stage_type
= SH_CSS_SP_STAGE_TYPE
;
367 sh_css_sp_stage
.func
= (unsigned int)IA_CSS_PIPELINE_ISYS_COPY
;
368 sh_css_sp_stage
.if_config_index
= (uint8_t) if_config_index
;
370 set_output_frame_buffer(out_frame
, 0);
372 #if defined SH_CSS_ENABLE_METADATA
373 if (pipe
->metadata
.height
> 0) {
374 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_METADATA
, thread_id
, &queue_id
);
375 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage
.frames
.metadata_buf
, queue_id
, mmgr_EXCEPTION
, IA_CSS_BUFFER_TYPE_METADATA
);
379 ia_css_debug_pipe_graph_dump_sp_raw_copy(out_frame
);
383 sh_css_sp_get_binary_copy_size(void)
385 const struct ia_css_fw_info
*fw
= &sh_css_sp_fw
;
386 unsigned int HIVE_ADDR_sp_output
= fw
->info
.sp
.output
;
387 unsigned int offset
= (unsigned int)offsetof(struct sh_css_sp_output
,
388 bin_copy_bytes_copied
) / sizeof(int);
389 (void)HIVE_ADDR_sp_output
; /* To get rid of warning in CRUN */
390 return load_sp_array_uint(sp_output
, offset
);
394 sh_css_sp_get_sw_interrupt_value(unsigned int irq
)
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
, sw_interrupt_value
)
400 (void)HIVE_ADDR_sp_output
; /* To get rid of warning in CRUN */
401 return load_sp_array_uint(sp_output
, offset
+irq
);
405 sh_css_copy_buffer_attr_to_spbuffer(struct ia_css_buffer_sp
*dest_buf
,
406 const enum sh_css_queue_id queue_id
,
407 const hrt_vaddress xmem_addr
,
408 const enum ia_css_buffer_type buf_type
)
410 assert(buf_type
< IA_CSS_NUM_BUFFER_TYPE
);
411 if (queue_id
> SH_CSS_INVALID_QUEUE_ID
) {
413 * value >=0 indicates that function init_frame_pointers()
414 * should use the dynamic data address
416 assert(queue_id
< SH_CSS_MAX_NUM_QUEUES
);
418 /* Klocwork assumes assert can be disabled;
419 Since we can get there with any type, and it does not
420 know that frame_in->dynamic_data_index can only be set
421 for one of the types in the assert) it has to assume we
422 can get here for any type. however this could lead to an
423 out of bounds reference when indexing buf_type about 10
424 lines below. In order to satisfy KW an additional if
425 has been added. This one will always yield true.
427 if ((queue_id
< SH_CSS_MAX_NUM_QUEUES
))
429 dest_buf
->buf_src
.queue_id
= queue_id
;
432 assert(xmem_addr
!= mmgr_EXCEPTION
);
433 dest_buf
->buf_src
.xmem_addr
= xmem_addr
;
435 dest_buf
->buf_type
= buf_type
;
439 sh_css_copy_frame_to_spframe(struct ia_css_frame_sp
*sp_frame_out
,
440 const struct ia_css_frame
*frame_in
)
442 assert(frame_in
!= NULL
);
444 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE
,
445 "sh_css_copy_frame_to_spframe():\n");
448 sh_css_copy_buffer_attr_to_spbuffer(&sp_frame_out
->buf_attr
,
449 frame_in
->dynamic_queue_id
,
453 ia_css_frame_info_to_frame_sp_info(&sp_frame_out
->info
, &frame_in
->info
);
455 switch (frame_in
->info
.format
) {
456 case IA_CSS_FRAME_FORMAT_RAW_PACKED
:
457 case IA_CSS_FRAME_FORMAT_RAW
:
458 sp_frame_out
->planes
.raw
.offset
= frame_in
->planes
.raw
.offset
;
460 case IA_CSS_FRAME_FORMAT_RGB565
:
461 case IA_CSS_FRAME_FORMAT_RGBA888
:
462 sp_frame_out
->planes
.rgb
.offset
= frame_in
->planes
.rgb
.offset
;
464 case IA_CSS_FRAME_FORMAT_PLANAR_RGB888
:
465 sp_frame_out
->planes
.planar_rgb
.r
.offset
=
466 frame_in
->planes
.planar_rgb
.r
.offset
;
467 sp_frame_out
->planes
.planar_rgb
.g
.offset
=
468 frame_in
->planes
.planar_rgb
.g
.offset
;
469 sp_frame_out
->planes
.planar_rgb
.b
.offset
=
470 frame_in
->planes
.planar_rgb
.b
.offset
;
472 case IA_CSS_FRAME_FORMAT_YUYV
:
473 case IA_CSS_FRAME_FORMAT_UYVY
:
474 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_8
:
475 case IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8
:
476 case IA_CSS_FRAME_FORMAT_YUV_LINE
:
477 sp_frame_out
->planes
.yuyv
.offset
= frame_in
->planes
.yuyv
.offset
;
479 case IA_CSS_FRAME_FORMAT_NV11
:
480 case IA_CSS_FRAME_FORMAT_NV12
:
481 case IA_CSS_FRAME_FORMAT_NV12_16
:
482 case IA_CSS_FRAME_FORMAT_NV12_TILEY
:
483 case IA_CSS_FRAME_FORMAT_NV21
:
484 case IA_CSS_FRAME_FORMAT_NV16
:
485 case IA_CSS_FRAME_FORMAT_NV61
:
486 sp_frame_out
->planes
.nv
.y
.offset
=
487 frame_in
->planes
.nv
.y
.offset
;
488 sp_frame_out
->planes
.nv
.uv
.offset
=
489 frame_in
->planes
.nv
.uv
.offset
;
491 case IA_CSS_FRAME_FORMAT_YUV420
:
492 case IA_CSS_FRAME_FORMAT_YUV422
:
493 case IA_CSS_FRAME_FORMAT_YUV444
:
494 case IA_CSS_FRAME_FORMAT_YUV420_16
:
495 case IA_CSS_FRAME_FORMAT_YUV422_16
:
496 case IA_CSS_FRAME_FORMAT_YV12
:
497 case IA_CSS_FRAME_FORMAT_YV16
:
498 sp_frame_out
->planes
.yuv
.y
.offset
=
499 frame_in
->planes
.yuv
.y
.offset
;
500 sp_frame_out
->planes
.yuv
.u
.offset
=
501 frame_in
->planes
.yuv
.u
.offset
;
502 sp_frame_out
->planes
.yuv
.v
.offset
=
503 frame_in
->planes
.yuv
.v
.offset
;
505 case IA_CSS_FRAME_FORMAT_QPLANE6
:
506 sp_frame_out
->planes
.plane6
.r
.offset
=
507 frame_in
->planes
.plane6
.r
.offset
;
508 sp_frame_out
->planes
.plane6
.r_at_b
.offset
=
509 frame_in
->planes
.plane6
.r_at_b
.offset
;
510 sp_frame_out
->planes
.plane6
.gr
.offset
=
511 frame_in
->planes
.plane6
.gr
.offset
;
512 sp_frame_out
->planes
.plane6
.gb
.offset
=
513 frame_in
->planes
.plane6
.gb
.offset
;
514 sp_frame_out
->planes
.plane6
.b
.offset
=
515 frame_in
->planes
.plane6
.b
.offset
;
516 sp_frame_out
->planes
.plane6
.b_at_r
.offset
=
517 frame_in
->planes
.plane6
.b_at_r
.offset
;
519 case IA_CSS_FRAME_FORMAT_BINARY_8
:
520 sp_frame_out
->planes
.binary
.data
.offset
=
521 frame_in
->planes
.binary
.data
.offset
;
524 /* This should not happen, but in case it does,
527 memset(&sp_frame_out
->planes
, 0, sizeof(sp_frame_out
->planes
));
533 static enum ia_css_err
534 set_input_frame_buffer(const struct ia_css_frame
*frame
)
537 return IA_CSS_ERR_INVALID_ARGUMENTS
;
539 switch (frame
->info
.format
) {
540 case IA_CSS_FRAME_FORMAT_QPLANE6
:
541 case IA_CSS_FRAME_FORMAT_YUV420_16
:
542 case IA_CSS_FRAME_FORMAT_RAW_PACKED
:
543 case IA_CSS_FRAME_FORMAT_RAW
:
544 case IA_CSS_FRAME_FORMAT_YUV420
:
545 case IA_CSS_FRAME_FORMAT_YUYV
:
546 case IA_CSS_FRAME_FORMAT_YUV_LINE
:
547 case IA_CSS_FRAME_FORMAT_NV12
:
548 case IA_CSS_FRAME_FORMAT_NV12_16
:
549 case IA_CSS_FRAME_FORMAT_NV12_TILEY
:
550 case IA_CSS_FRAME_FORMAT_NV21
:
551 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_8
:
552 case IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8
:
553 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_10
:
556 return IA_CSS_ERR_INVALID_ARGUMENTS
;
558 sh_css_copy_frame_to_spframe(&sh_css_sp_stage
.frames
.in
, frame
);
560 return IA_CSS_SUCCESS
;
563 static enum ia_css_err
564 set_output_frame_buffer(const struct ia_css_frame
*frame
,
568 return IA_CSS_ERR_INVALID_ARGUMENTS
;
570 switch (frame
->info
.format
) {
571 case IA_CSS_FRAME_FORMAT_YUV420
:
572 case IA_CSS_FRAME_FORMAT_YUV422
:
573 case IA_CSS_FRAME_FORMAT_YUV444
:
574 case IA_CSS_FRAME_FORMAT_YV12
:
575 case IA_CSS_FRAME_FORMAT_YV16
:
576 case IA_CSS_FRAME_FORMAT_YUV420_16
:
577 case IA_CSS_FRAME_FORMAT_YUV422_16
:
578 case IA_CSS_FRAME_FORMAT_NV11
:
579 case IA_CSS_FRAME_FORMAT_NV12
:
580 case IA_CSS_FRAME_FORMAT_NV12_16
:
581 case IA_CSS_FRAME_FORMAT_NV12_TILEY
:
582 case IA_CSS_FRAME_FORMAT_NV16
:
583 case IA_CSS_FRAME_FORMAT_NV21
:
584 case IA_CSS_FRAME_FORMAT_NV61
:
585 case IA_CSS_FRAME_FORMAT_YUYV
:
586 case IA_CSS_FRAME_FORMAT_UYVY
:
587 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_8
:
588 case IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8
:
589 case IA_CSS_FRAME_FORMAT_YUV_LINE
:
590 case IA_CSS_FRAME_FORMAT_RGB565
:
591 case IA_CSS_FRAME_FORMAT_RGBA888
:
592 case IA_CSS_FRAME_FORMAT_PLANAR_RGB888
:
593 case IA_CSS_FRAME_FORMAT_RAW
:
594 case IA_CSS_FRAME_FORMAT_RAW_PACKED
:
595 case IA_CSS_FRAME_FORMAT_QPLANE6
:
596 case IA_CSS_FRAME_FORMAT_BINARY_8
:
599 return IA_CSS_ERR_INVALID_ARGUMENTS
;
601 sh_css_copy_frame_to_spframe(&sh_css_sp_stage
.frames
.out
[idx
], frame
);
602 return IA_CSS_SUCCESS
;
605 static enum ia_css_err
606 set_view_finder_buffer(const struct ia_css_frame
*frame
)
609 return IA_CSS_ERR_INVALID_ARGUMENTS
;
611 switch (frame
->info
.format
) {
612 /* the dual output pin */
613 case IA_CSS_FRAME_FORMAT_NV12
:
614 case IA_CSS_FRAME_FORMAT_NV12_16
:
615 case IA_CSS_FRAME_FORMAT_NV21
:
616 case IA_CSS_FRAME_FORMAT_YUYV
:
617 case IA_CSS_FRAME_FORMAT_UYVY
:
618 case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_8
:
619 case IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8
:
620 case IA_CSS_FRAME_FORMAT_YUV420
:
621 case IA_CSS_FRAME_FORMAT_YV12
:
622 case IA_CSS_FRAME_FORMAT_NV12_TILEY
:
625 case IA_CSS_FRAME_FORMAT_YUV_LINE
:
628 return IA_CSS_ERR_INVALID_ARGUMENTS
;
631 sh_css_copy_frame_to_spframe(&sh_css_sp_stage
.frames
.out_vf
, frame
);
632 return IA_CSS_SUCCESS
;
635 #if !defined(HAS_NO_INPUT_FORMATTER)
636 void sh_css_sp_set_if_configs(
637 const input_formatter_cfg_t
*config_a
,
638 const input_formatter_cfg_t
*config_b
,
639 const uint8_t if_config_index
642 assert(if_config_index
< SH_CSS_MAX_IF_CONFIGS
);
643 assert(config_a
!= NULL
);
645 sh_css_sp_group
.config
.input_formatter
.set
[if_config_index
].config_a
= *config_a
;
646 sh_css_sp_group
.config
.input_formatter
.a_changed
= true;
648 if (config_b
!= NULL
) {
649 sh_css_sp_group
.config
.input_formatter
.set
[if_config_index
].config_b
= *config_b
;
650 sh_css_sp_group
.config
.input_formatter
.b_changed
= true;
657 #if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2)
659 sh_css_sp_program_input_circuit(int fmt_type
,
661 enum ia_css_input_mode input_mode
)
663 sh_css_sp_group
.config
.input_circuit
.no_side_band
= false;
664 sh_css_sp_group
.config
.input_circuit
.fmt_type
= fmt_type
;
665 sh_css_sp_group
.config
.input_circuit
.ch_id
= ch_id
;
666 sh_css_sp_group
.config
.input_circuit
.input_mode
= input_mode
;
668 * The SP group is only loaded at SP boot time and is read once
669 * change flags as "input_circuit_cfg_changed" must be reset on the SP
671 sh_css_sp_group
.config
.input_circuit_cfg_changed
= true;
672 sh_css_sp_stage
.program_input_circuit
= true;
676 #if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2)
678 sh_css_sp_configure_sync_gen(int width
, int height
,
682 sh_css_sp_group
.config
.sync_gen
.width
= width
;
683 sh_css_sp_group
.config
.sync_gen
.height
= height
;
684 sh_css_sp_group
.config
.sync_gen
.hblank_cycles
= hblank_cycles
;
685 sh_css_sp_group
.config
.sync_gen
.vblank_cycles
= vblank_cycles
;
689 sh_css_sp_configure_tpg(int x_mask
,
695 sh_css_sp_group
.config
.tpg
.x_mask
= x_mask
;
696 sh_css_sp_group
.config
.tpg
.y_mask
= y_mask
;
697 sh_css_sp_group
.config
.tpg
.x_delta
= x_delta
;
698 sh_css_sp_group
.config
.tpg
.y_delta
= y_delta
;
699 sh_css_sp_group
.config
.tpg
.xy_mask
= xy_mask
;
703 sh_css_sp_configure_prbs(int seed
)
705 sh_css_sp_group
.config
.prbs
.seed
= seed
;
710 sh_css_sp_configure_enable_raw_pool_locking(bool lock_all
)
712 sh_css_sp_group
.config
.enable_raw_pool_locking
= true;
713 sh_css_sp_group
.config
.lock_all
= lock_all
;
717 sh_css_sp_enable_isys_event_queue(bool enable
)
719 #if !defined(HAS_NO_INPUT_SYSTEM)
720 sh_css_sp_group
.config
.enable_isys_event_queue
= enable
;
727 sh_css_sp_set_disable_continuous_viewfinder(bool flag
)
729 sh_css_sp_group
.config
.disable_cont_vf
= flag
;
732 static enum ia_css_err
733 sh_css_sp_write_frame_pointers(const struct sh_css_binary_args
*args
)
735 enum ia_css_err err
= IA_CSS_SUCCESS
;
738 assert(args
!= NULL
);
741 err
= set_input_frame_buffer(args
->in_frame
);
742 if (err
== IA_CSS_SUCCESS
&& args
->out_vf_frame
)
743 err
= set_view_finder_buffer(args
->out_vf_frame
);
744 for (i
= 0; i
< IA_CSS_BINARY_MAX_OUTPUT_PORTS
; i
++) {
745 if (err
== IA_CSS_SUCCESS
&& args
->out_frame
[i
])
746 err
= set_output_frame_buffer(args
->out_frame
[i
], i
);
749 /* we don't pass this error back to the upper layer, so we add a assert here
750 because we actually hit the error here but it still works by accident... */
751 if (err
!= IA_CSS_SUCCESS
) assert(false);
756 sh_css_sp_init_group(bool two_ppc
,
757 enum ia_css_stream_format input_format
,
759 uint8_t if_config_index
)
761 #if !defined(HAS_NO_INPUT_FORMATTER)
762 sh_css_sp_group
.config
.input_formatter
.isp_2ppc
= two_ppc
;
767 sh_css_sp_group
.config
.no_isp_sync
= (uint8_t)no_isp_sync
;
768 /* decide whether the frame is processed online or offline */
769 if (if_config_index
== SH_CSS_IF_CONFIG_NOT_NEEDED
) return;
770 #if !defined(HAS_NO_INPUT_FORMATTER)
771 assert(if_config_index
< SH_CSS_MAX_IF_CONFIGS
);
772 sh_css_sp_group
.config
.input_formatter
.set
[if_config_index
].stream_format
= input_format
;
779 sh_css_stage_write_binary_info(struct ia_css_binary_info
*info
)
781 assert(info
!= NULL
);
782 sh_css_isp_stage
.binary_info
= *info
;
785 static enum ia_css_err
786 copy_isp_mem_if_to_ddr(struct ia_css_binary
*binary
)
790 err
= ia_css_isp_param_copy_isp_mem_if_to_ddr(
793 IA_CSS_PARAM_CLASS_CONFIG
);
794 if (err
!= IA_CSS_SUCCESS
)
796 err
= ia_css_isp_param_copy_isp_mem_if_to_ddr(
799 IA_CSS_PARAM_CLASS_STATE
);
800 if (err
!= IA_CSS_SUCCESS
)
802 return IA_CSS_SUCCESS
;
806 is_sp_stage(struct ia_css_pipeline_stage
*stage
)
808 assert(stage
!= NULL
);
809 return stage
->sp_func
!= IA_CSS_PIPELINE_NO_FUNC
;
812 static enum ia_css_err
813 configure_isp_from_args(
814 const struct sh_css_sp_pipeline
*pipeline
,
815 const struct ia_css_binary
*binary
,
816 const struct sh_css_binary_args
*args
,
820 enum ia_css_err err
= IA_CSS_SUCCESS
;
822 struct ia_css_pipe
*pipe
= find_pipe_by_num(pipeline
->pipe_num
);
823 const struct ia_css_resolution
*res
;
826 ia_css_fpn_configure(binary
, &binary
->in_frame_info
);
827 ia_css_crop_configure(binary
, &args
->delay_frames
[0]->info
);
828 ia_css_qplane_configure(pipeline
, binary
, &binary
->in_frame_info
);
829 ia_css_output0_configure(binary
, &args
->out_frame
[0]->info
);
830 ia_css_output1_configure(binary
, &args
->out_vf_frame
->info
);
831 ia_css_copy_output_configure(binary
, args
->copy_output
);
832 ia_css_output0_configure(binary
, &args
->out_frame
[0]->info
);
834 ia_css_sc_configure(binary
, pipeline
->shading
.internal_frame_origin_x_bqs_on_sctbl
,
835 pipeline
->shading
.internal_frame_origin_y_bqs_on_sctbl
);
837 ia_css_iterator_configure(binary
, &args
->in_frame
->info
);
838 ia_css_dvs_configure(binary
, &args
->out_frame
[0]->info
);
839 ia_css_output_configure(binary
, &args
->out_frame
[0]->info
);
840 ia_css_raw_configure(pipeline
, binary
, &args
->in_frame
->info
, &binary
->in_frame_info
, two_ppc
, deinterleaved
);
841 ia_css_ref_configure(binary
, (const struct ia_css_frame
**)args
->delay_frames
, pipeline
->dvs_frame_delay
);
842 ia_css_tnr_configure(binary
, (const struct ia_css_frame
**)args
->tnr_frames
);
843 ia_css_bayer_io_config(binary
, args
);
848 initialize_isp_states(const struct ia_css_binary
*binary
)
852 if (!binary
->info
->mem_offsets
.offsets
.state
)
854 for (i
= 0; i
< IA_CSS_NUM_STATE_IDS
; i
++) {
855 ia_css_kernel_init_state
[i
](binary
);
860 initialize_frame_buffer_attribute(struct ia_css_buffer_sp
*buf_attr
)
862 buf_attr
->buf_src
.queue_id
= SH_CSS_INVALID_QUEUE_ID
;
863 buf_attr
->buf_type
= IA_CSS_BUFFER_TYPE_INVALID
;
867 initialize_stage_frames(struct ia_css_frames_sp
*frames
)
871 initialize_frame_buffer_attribute(&frames
->in
.buf_attr
);
872 for (i
= 0; i
< IA_CSS_BINARY_MAX_OUTPUT_PORTS
; i
++) {
873 initialize_frame_buffer_attribute(&frames
->out
[i
].buf_attr
);
875 initialize_frame_buffer_attribute(&frames
->out_vf
.buf_attr
);
876 initialize_frame_buffer_attribute(&frames
->s3a_buf
);
877 initialize_frame_buffer_attribute(&frames
->dvs_buf
);
878 #if defined SH_CSS_ENABLE_METADATA
879 initialize_frame_buffer_attribute(&frames
->metadata_buf
);
883 static enum ia_css_err
884 sh_css_sp_init_stage(struct ia_css_binary
*binary
,
885 const char *binary_name
,
886 const struct ia_css_blob_info
*blob_info
,
887 const struct sh_css_binary_args
*args
,
888 unsigned int pipe_num
,
891 const struct ia_css_isp_param_css_segments
*isp_mem_if
,
892 unsigned int if_config_index
,
895 const struct ia_css_binary_xinfo
*xinfo
;
896 const struct ia_css_binary_info
*info
;
897 enum ia_css_err err
= IA_CSS_SUCCESS
;
899 struct ia_css_pipe
*pipe
= NULL
;
900 unsigned int thread_id
;
901 enum sh_css_queue_id queue_id
;
902 bool continuous
= sh_css_continuous_is_enabled((uint8_t)pipe_num
);
904 assert(binary
!= NULL
);
905 assert(blob_info
!= NULL
);
906 assert(args
!= NULL
);
907 assert(isp_mem_if
!= NULL
);
909 xinfo
= binary
->info
;
913 * Clear sh_css_sp_stage for easy debugging.
914 * program_input_circuit must be saved as it is set outside
917 uint8_t program_input_circuit
;
918 program_input_circuit
= sh_css_sp_stage
.program_input_circuit
;
919 memset(&sh_css_sp_stage
, 0, sizeof(sh_css_sp_stage
));
920 sh_css_sp_stage
.program_input_circuit
= (uint8_t)program_input_circuit
;
923 ia_css_pipeline_get_sp_thread_id(pipe_num
, &thread_id
);
926 sh_css_sp_group
.pipe
[thread_id
].sp_stage_addr
[stage
] = mmgr_NULL
;
927 return IA_CSS_SUCCESS
;
930 #if defined(USE_INPUT_SYSTEM_VERSION_2401)
932 sh_css_sp_stage
.deinterleaved
= 0;
934 sh_css_sp_stage
.deinterleaved
= ((stage
== 0) && continuous
);
937 initialize_stage_frames(&sh_css_sp_stage
.frames
);
939 * TODO: Make the Host dynamically determine
942 sh_css_sp_stage
.stage_type
= SH_CSS_ISP_STAGE_TYPE
;
943 sh_css_sp_stage
.num
= (uint8_t)stage
;
944 sh_css_sp_stage
.isp_online
= (uint8_t)binary
->online
;
945 sh_css_sp_stage
.isp_copy_vf
= (uint8_t)args
->copy_vf
;
946 sh_css_sp_stage
.isp_copy_output
= (uint8_t)args
->copy_output
;
947 sh_css_sp_stage
.enable
.vf_output
= (args
->out_vf_frame
!= NULL
);
949 /* Copy the frame infos first, to be overwritten by the frames,
950 if these are present.
952 sh_css_sp_stage
.frames
.effective_in_res
.width
= binary
->effective_in_frame_res
.width
;
953 sh_css_sp_stage
.frames
.effective_in_res
.height
= binary
->effective_in_frame_res
.height
;
955 ia_css_frame_info_to_frame_sp_info(&sh_css_sp_stage
.frames
.in
.info
,
956 &binary
->in_frame_info
);
957 for (i
= 0; i
< IA_CSS_BINARY_MAX_OUTPUT_PORTS
; i
++) {
958 ia_css_frame_info_to_frame_sp_info(&sh_css_sp_stage
.frames
.out
[i
].info
,
959 &binary
->out_frame_info
[i
]);
961 ia_css_frame_info_to_frame_sp_info(&sh_css_sp_stage
.frames
.internal_frame_info
,
962 &binary
->internal_frame_info
);
963 sh_css_sp_stage
.dvs_envelope
.width
= binary
->dvs_envelope
.width
;
964 sh_css_sp_stage
.dvs_envelope
.height
= binary
->dvs_envelope
.height
;
965 sh_css_sp_stage
.isp_pipe_version
= (uint8_t)info
->pipeline
.isp_pipe_version
;
966 sh_css_sp_stage
.isp_deci_log_factor
= (uint8_t)binary
->deci_factor_log2
;
967 sh_css_sp_stage
.isp_vf_downscale_bits
= (uint8_t)binary
->vf_downscale_log2
;
969 sh_css_sp_stage
.if_config_index
= (uint8_t) if_config_index
;
971 sh_css_sp_stage
.sp_enable_xnr
= (uint8_t)xnr
;
972 sh_css_sp_stage
.xmem_bin_addr
= xinfo
->xmem_addr
;
973 sh_css_sp_stage
.xmem_map_addr
= sh_css_params_ddr_address_map();
974 sh_css_isp_stage
.blob_info
= *blob_info
;
975 sh_css_stage_write_binary_info((struct ia_css_binary_info
*)info
);
977 /* Make sure binary name is smaller than allowed string size */
978 assert(strlen(binary_name
) < SH_CSS_MAX_BINARY_NAME
-1);
979 strncpy(sh_css_isp_stage
.binary_name
, binary_name
, SH_CSS_MAX_BINARY_NAME
-1);
980 sh_css_isp_stage
.binary_name
[SH_CSS_MAX_BINARY_NAME
- 1] = 0;
981 sh_css_isp_stage
.mem_initializers
= *isp_mem_if
;
984 * Even when a stage does not need uds and does not params,
985 * ia_css_uds_sp_scale_params() seems to be called (needs
986 * further investigation). This function can not deal with
990 err
= sh_css_sp_write_frame_pointers(args
);
991 /* TODO: move it to a better place */
992 if (binary
->info
->sp
.enable
.s3a
) {
993 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_3A_STATISTICS
, thread_id
, &queue_id
);
994 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage
.frames
.s3a_buf
, queue_id
, mmgr_EXCEPTION
, IA_CSS_BUFFER_TYPE_3A_STATISTICS
);
996 if (binary
->info
->sp
.enable
.dis
) {
997 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_DIS_STATISTICS
, thread_id
, &queue_id
);
998 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage
.frames
.dvs_buf
, queue_id
, mmgr_EXCEPTION
, IA_CSS_BUFFER_TYPE_DIS_STATISTICS
);
1000 #if defined SH_CSS_ENABLE_METADATA
1001 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_METADATA
, thread_id
, &queue_id
);
1002 sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage
.frames
.metadata_buf
, queue_id
, mmgr_EXCEPTION
, IA_CSS_BUFFER_TYPE_METADATA
);
1004 if (err
!= IA_CSS_SUCCESS
)
1007 #ifdef USE_INPUT_SYSTEM_VERSION_2401
1009 if (args
->in_frame
) {
1010 pipe
= find_pipe_by_num(sh_css_sp_group
.pipe
[thread_id
].pipe_num
);
1012 return IA_CSS_ERR_INTERNAL_ERROR
;
1013 ia_css_get_crop_offsets(pipe
, &args
->in_frame
->info
);
1014 } else if (&binary
->in_frame_info
) {
1015 pipe
= find_pipe_by_num(sh_css_sp_group
.pipe
[thread_id
].pipe_num
);
1017 return IA_CSS_ERR_INTERNAL_ERROR
;
1018 ia_css_get_crop_offsets(pipe
, &binary
->in_frame_info
);
1021 if (args
->in_frame
) {
1022 pipe
= find_pipe_by_num(sh_css_sp_group
.pipe
[thread_id
].pipe_num
);
1024 return IA_CSS_ERR_INTERNAL_ERROR
;
1025 ia_css_get_crop_offsets(pipe
, &args
->in_frame
->info
);
1026 } else if (&binary
->in_frame_info
) {
1027 pipe
= find_pipe_by_num(sh_css_sp_group
.pipe
[thread_id
].pipe_num
);
1029 return IA_CSS_ERR_INTERNAL_ERROR
;
1030 ia_css_get_crop_offsets(pipe
, &binary
->in_frame_info
);
1035 (void)pipe
; /*avoid build warning*/
1038 err
= configure_isp_from_args(&sh_css_sp_group
.pipe
[thread_id
],
1039 binary
, args
, two_ppc
, sh_css_sp_stage
.deinterleaved
);
1040 if (err
!= IA_CSS_SUCCESS
)
1043 initialize_isp_states(binary
);
1045 /* we do this only for preview pipe because in fill_binary_info function
1046 * we assign vf_out res to out res, but for ISP internal processing, we need
1047 * the original out res. for video pipe, it has two output pins --- out and
1048 * vf_out, so it can keep these two resolutions already. */
1049 if (binary
->info
->sp
.pipeline
.mode
== IA_CSS_BINARY_MODE_PREVIEW
&&
1050 (binary
->vf_downscale_log2
> 0)) {
1051 /* TODO: Remove this after preview output decimation is fixed
1052 * by configuring out&vf info fiels properly */
1053 sh_css_sp_stage
.frames
.out
[0].info
.padded_width
1054 <<= binary
->vf_downscale_log2
;
1055 sh_css_sp_stage
.frames
.out
[0].info
.res
.width
1056 <<= binary
->vf_downscale_log2
;
1057 sh_css_sp_stage
.frames
.out
[0].info
.res
.height
1058 <<= binary
->vf_downscale_log2
;
1060 err
= copy_isp_mem_if_to_ddr(binary
);
1061 if (err
!= IA_CSS_SUCCESS
)
1064 return IA_CSS_SUCCESS
;
1067 static enum ia_css_err
1068 sp_init_stage(struct ia_css_pipeline_stage
*stage
,
1069 unsigned int pipe_num
,
1071 unsigned int if_config_index
,
1074 struct ia_css_binary
*binary
;
1075 const struct ia_css_fw_info
*firmware
;
1076 const struct sh_css_binary_args
*args
;
1079 * Initialiser required because of the "else" path below.
1080 * Is this a valid path ?
1082 const char *binary_name
= "";
1083 const struct ia_css_binary_xinfo
*info
= NULL
;
1084 /* note: the var below is made static as it is quite large;
1085 if it is not static it ends up on the stack which could
1086 cause issues for drivers
1088 static struct ia_css_binary tmp_binary
;
1089 const struct ia_css_blob_info
*blob_info
= NULL
;
1090 struct ia_css_isp_param_css_segments isp_mem_if
;
1091 /* LA: should be ia_css_data, should not contain host pointer.
1092 However, CSS/DDR pointer is not available yet.
1093 Hack is to store it in params->ddr_ptrs and then copy it late in the SP just before vmem init.
1094 TODO: Call this after CSS/DDR allocation and store that pointer.
1095 Best is to allocate it at stage creation time together with host pointer.
1096 Remove vmem from params.
1098 struct ia_css_isp_param_css_segments
*mem_if
= &isp_mem_if
;
1100 enum ia_css_err err
= IA_CSS_SUCCESS
;
1102 assert(stage
!= NULL
);
1104 binary
= stage
->binary
;
1105 firmware
= stage
->firmware
;
1106 args
= &stage
->args
;
1107 stage_num
= stage
->stage_num
;
1111 info
= binary
->info
;
1112 binary_name
= (const char *)(info
->blob
->name
);
1113 blob_info
= &info
->blob
->header
.blob
;
1114 ia_css_init_memory_interface(mem_if
, &binary
->mem_params
, &binary
->css_params
);
1115 } else if (firmware
) {
1116 const struct ia_css_frame_info
*out_infos
[IA_CSS_BINARY_MAX_OUTPUT_PORTS
] = {NULL
};
1117 if (args
->out_frame
[0])
1118 out_infos
[0] = &args
->out_frame
[0]->info
;
1119 info
= &firmware
->info
.isp
;
1120 ia_css_binary_fill_info(info
, false, false,
1121 IA_CSS_STREAM_FORMAT_RAW_10
,
1122 args
->in_frame
? &args
->in_frame
->info
: NULL
,
1125 args
->out_vf_frame
? &args
->out_vf_frame
->info
1130 binary
= &tmp_binary
;
1131 binary
->info
= info
;
1132 binary_name
= IA_CSS_EXT_ISP_PROG_NAME(firmware
);
1133 blob_info
= &firmware
->blob
;
1134 mem_if
= (struct ia_css_isp_param_css_segments
*)&firmware
->mem_initializers
;
1137 assert(stage
->sp_func
!= IA_CSS_PIPELINE_NO_FUNC
);
1138 /* binary and blob_info are now NULL.
1139 These will be passed to sh_css_sp_init_stage
1140 and dereferenced there, so passing a NULL
1141 pointer is no good. return an error */
1142 return IA_CSS_ERR_INTERNAL_ERROR
;
1145 err
= sh_css_sp_init_stage(binary
,
1146 (const char *)binary_name
,
1159 sp_init_sp_stage(struct ia_css_pipeline_stage
*stage
,
1162 enum sh_css_pipe_config_override copy_ovrd
,
1163 unsigned int if_config_index
)
1165 const struct sh_css_binary_args
*args
= &stage
->args
;
1167 assert(stage
!= NULL
);
1168 switch (stage
->sp_func
) {
1169 case IA_CSS_PIPELINE_RAW_COPY
:
1170 sh_css_sp_start_raw_copy(args
->out_frame
[0],
1172 stage
->max_input_width
,
1173 copy_ovrd
, if_config_index
);
1175 case IA_CSS_PIPELINE_BIN_COPY
:
1176 assert(false); /* TBI */
1177 case IA_CSS_PIPELINE_ISYS_COPY
:
1178 sh_css_sp_start_isys_copy(args
->out_frame
[0],
1179 pipe_num
, stage
->max_input_width
, if_config_index
);
1181 case IA_CSS_PIPELINE_NO_FUNC
:
1187 sh_css_sp_init_pipeline(struct ia_css_pipeline
*me
,
1188 enum ia_css_pipe_id id
,
1194 unsigned int required_bds_factor
,
1195 enum sh_css_pipe_config_override copy_ovrd
,
1196 enum ia_css_input_mode input_mode
,
1197 const struct ia_css_metadata_config
*md_config
,
1198 const struct ia_css_metadata_info
*md_info
,
1199 #if !defined(HAS_NO_INPUT_SYSTEM)
1200 const mipi_port_ID_t port_id
1204 const struct ia_css_coordinate
*internal_frame_origin_bqs_on_sctbl
, /* Origin of internal frame
1205 positioned on shading table at shading correction in ISP. */
1206 const struct ia_css_isp_parameters
*params
1210 /* Get first stage */
1211 struct ia_css_pipeline_stage
*stage
= NULL
;
1212 struct ia_css_binary
*first_binary
= NULL
;
1213 struct ia_css_pipe
*pipe
= NULL
;
1216 enum ia_css_pipe_id pipe_id
= id
;
1217 unsigned int thread_id
;
1218 uint8_t if_config_index
, tmp_if_config_index
;
1222 #if !defined(HAS_NO_INPUT_SYSTEM)
1223 assert(me
->stages
!= NULL
);
1225 first_binary
= me
->stages
->binary
;
1227 if (input_mode
== IA_CSS_INPUT_MODE_SENSOR
||
1228 input_mode
== IA_CSS_INPUT_MODE_BUFFERED_SENSOR
) {
1229 assert(port_id
< N_MIPI_PORT_ID
);
1230 if (port_id
>= N_MIPI_PORT_ID
) /* should not happen but KW does not know */
1231 return; /* we should be able to return an error */
1232 if_config_index
= (uint8_t) (port_id
- MIPI_PORT0_ID
);
1233 } else if (input_mode
== IA_CSS_INPUT_MODE_MEMORY
) {
1234 if_config_index
= SH_CSS_IF_CONFIG_NOT_NEEDED
;
1236 if_config_index
= 0x0;
1240 if_config_index
= SH_CSS_IF_CONFIG_NOT_NEEDED
;
1243 ia_css_pipeline_get_sp_thread_id(pipe_num
, &thread_id
);
1244 memset(&sh_css_sp_group
.pipe
[thread_id
], 0, sizeof(struct sh_css_sp_pipeline
));
1247 for (stage
= me
->stages
, num
= 0; stage
; stage
= stage
->next
, num
++) {
1248 stage
->stage_num
= num
;
1249 ia_css_debug_pipe_graph_dump_stage(stage
, id
);
1251 me
->num_stages
= num
;
1253 if (first_binary
!= NULL
) {
1254 /* Init pipeline data */
1255 sh_css_sp_init_group(two_ppc
, first_binary
->input_format
,
1256 offline
, if_config_index
);
1257 } /* if (first_binary != NULL) */
1259 #if defined(USE_INPUT_SYSTEM_VERSION_2401) || defined(USE_INPUT_SYSTEM_VERSION_2)
1260 /* Signal the host immediately after start for SP_ISYS_COPY only */
1261 if ((me
->num_stages
== 1) && me
->stages
&&
1262 (me
->stages
->sp_func
== IA_CSS_PIPELINE_ISYS_COPY
))
1263 sh_css_sp_group
.config
.no_isp_sync
= true;
1266 /* Init stage data */
1267 sh_css_init_host2sp_frame_data();
1269 sh_css_sp_group
.pipe
[thread_id
].num_stages
= 0;
1270 sh_css_sp_group
.pipe
[thread_id
].pipe_id
= pipe_id
;
1271 sh_css_sp_group
.pipe
[thread_id
].thread_id
= thread_id
;
1272 sh_css_sp_group
.pipe
[thread_id
].pipe_num
= pipe_num
;
1273 sh_css_sp_group
.pipe
[thread_id
].num_execs
= me
->num_execs
;
1274 sh_css_sp_group
.pipe
[thread_id
].pipe_qos_config
= me
->pipe_qos_config
;
1275 sh_css_sp_group
.pipe
[thread_id
].required_bds_factor
= required_bds_factor
;
1276 #if !defined(HAS_NO_INPUT_SYSTEM)
1277 sh_css_sp_group
.pipe
[thread_id
].input_system_mode
1278 = (uint32_t)input_mode
;
1279 sh_css_sp_group
.pipe
[thread_id
].port_id
= port_id
;
1281 sh_css_sp_group
.pipe
[thread_id
].dvs_frame_delay
= (uint32_t)me
->dvs_frame_delay
;
1283 /* TODO: next indicates from which queues parameters need to be
1284 sampled, needs checking/improvement */
1285 if (ia_css_pipeline_uses_params(me
)) {
1286 sh_css_sp_group
.pipe
[thread_id
].pipe_config
=
1287 SH_CSS_PIPE_CONFIG_SAMPLE_PARAMS
<< thread_id
;
1290 /* For continuous use-cases, SP copy is responsible for sampling the
1293 sh_css_sp_group
.pipe
[thread_id
].pipe_config
= 0;
1295 sh_css_sp_group
.pipe
[thread_id
].inout_port_config
= me
->inout_port_config
;
1297 pipe
= find_pipe_by_num(pipe_num
);
1298 assert(pipe
!= NULL
);
1302 sh_css_sp_group
.pipe
[thread_id
].scaler_pp_lut
= sh_css_pipe_get_pp_gdc_lut(pipe
);
1304 #if defined(SH_CSS_ENABLE_METADATA)
1305 if (md_info
!= NULL
&& md_info
->size
> 0) {
1306 sh_css_sp_group
.pipe
[thread_id
].metadata
.width
= md_info
->resolution
.width
;
1307 sh_css_sp_group
.pipe
[thread_id
].metadata
.height
= md_info
->resolution
.height
;
1308 sh_css_sp_group
.pipe
[thread_id
].metadata
.stride
= md_info
->stride
;
1309 sh_css_sp_group
.pipe
[thread_id
].metadata
.size
= md_info
->size
;
1310 ia_css_isys_convert_stream_format_to_mipi_format(
1311 md_config
->data_type
, MIPI_PREDICTOR_NONE
,
1312 &sh_css_sp_group
.pipe
[thread_id
].metadata
.format
);
1319 #if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
1320 sh_css_sp_group
.pipe
[thread_id
].output_frame_queue_id
= (uint32_t)SH_CSS_INVALID_QUEUE_ID
;
1321 if (IA_CSS_PIPE_ID_COPY
!= pipe_id
) {
1322 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_OUTPUT_FRAME
, thread_id
, (enum sh_css_queue_id
*)(&sh_css_sp_group
.pipe
[thread_id
].output_frame_queue_id
));
1327 /* For the shading correction type 1 (the legacy shading table conversion in css is not used),
1328 * the parameters are passed to the isp for the shading table centering.
1330 if (internal_frame_origin_bqs_on_sctbl
!= NULL
&&
1331 params
!= NULL
&& params
->shading_settings
.enable_shading_table_conversion
== 0) {
1332 sh_css_sp_group
.pipe
[thread_id
].shading
.internal_frame_origin_x_bqs_on_sctbl
1333 = (uint32_t)internal_frame_origin_bqs_on_sctbl
->x
;
1334 sh_css_sp_group
.pipe
[thread_id
].shading
.internal_frame_origin_y_bqs_on_sctbl
1335 = (uint32_t)internal_frame_origin_bqs_on_sctbl
->y
;
1337 sh_css_sp_group
.pipe
[thread_id
].shading
.internal_frame_origin_x_bqs_on_sctbl
= 0;
1338 sh_css_sp_group
.pipe
[thread_id
].shading
.internal_frame_origin_y_bqs_on_sctbl
= 0;
1342 IA_CSS_LOG("pipe_id %d port_config %08x",
1343 pipe_id
, sh_css_sp_group
.pipe
[thread_id
].inout_port_config
);
1345 for (stage
= me
->stages
, num
= 0; stage
; stage
= stage
->next
, num
++) {
1346 sh_css_sp_group
.pipe
[thread_id
].num_stages
++;
1347 if (is_sp_stage(stage
)) {
1348 sp_init_sp_stage(stage
, pipe_num
, two_ppc
,
1349 copy_ovrd
, if_config_index
);
1351 if ((stage
->stage_num
!= 0) || SH_CSS_PIPE_PORT_CONFIG_IS_CONTINUOUS(me
->inout_port_config
))
1352 tmp_if_config_index
= SH_CSS_IF_CONFIG_NOT_NEEDED
;
1354 tmp_if_config_index
= if_config_index
;
1355 sp_init_stage(stage
, pipe_num
,
1356 xnr
, tmp_if_config_index
, two_ppc
);
1359 store_sp_stage_data(pipe_id
, pipe_num
, num
);
1361 sh_css_sp_group
.pipe
[thread_id
].pipe_config
|= (uint32_t)
1362 (me
->acquire_isp_each_stage
<< IA_CSS_ACQUIRE_ISP_POS
);
1363 store_sp_group_data();
1368 sh_css_sp_uninit_pipeline(unsigned int pipe_num
)
1370 unsigned int thread_id
;
1371 ia_css_pipeline_get_sp_thread_id(pipe_num
, &thread_id
);
1372 /*memset(&sh_css_sp_group.pipe[thread_id], 0, sizeof(struct sh_css_sp_pipeline));*/
1373 sh_css_sp_group
.pipe
[thread_id
].num_stages
= 0;
1376 bool sh_css_write_host2sp_command(enum host2sp_commands host2sp_command
)
1378 unsigned int HIVE_ADDR_host_sp_com
= sh_css_sp_fw
.info
.sp
.host_sp_com
;
1379 unsigned int offset
= (unsigned int)offsetof(struct host_sp_communication
, host2sp_command
)
1381 enum host2sp_commands last_cmd
= host2sp_cmd_error
;
1382 (void)HIVE_ADDR_host_sp_com
; /* Suppres warnings in CRUN */
1384 /* Previous command must be handled by SP (by design) */
1385 last_cmd
= load_sp_array_uint(host_sp_com
, offset
);
1386 if (last_cmd
!= host2sp_cmd_ready
)
1387 IA_CSS_ERROR("last host command not handled by SP(%d)", last_cmd
);
1389 store_sp_array_uint(host_sp_com
, offset
, host2sp_command
);
1391 return (last_cmd
== host2sp_cmd_ready
);
1394 enum host2sp_commands
1395 sh_css_read_host2sp_command(void)
1397 unsigned int HIVE_ADDR_host_sp_com
= sh_css_sp_fw
.info
.sp
.host_sp_com
;
1398 unsigned int offset
= (unsigned int)offsetof(struct host_sp_communication
, host2sp_command
)
1400 (void)HIVE_ADDR_host_sp_com
; /* Suppres warnings in CRUN */
1401 return (enum host2sp_commands
)load_sp_array_uint(host_sp_com
, offset
);
1406 * Frame data is no longer part of the sp_stage structure but part of a
1407 * seperate structure. The aim is to make the sp_data struct static
1408 * (it defines a pipeline) and that the dynamic (per frame) data is stored
1411 * This function must be called first every where were you start constructing
1412 * a new pipeline by defining one or more stages with use of variable
1413 * sh_css_sp_stage. Even the special cases like accelerator and copy_frame
1414 * These have a pipeline of just 1 stage.
1417 sh_css_init_host2sp_frame_data(void)
1420 unsigned int HIVE_ADDR_host_sp_com
= sh_css_sp_fw
.info
.sp
.host_sp_com
;
1422 (void)HIVE_ADDR_host_sp_com
; /* Suppres warnings in CRUN */
1424 * rvanimme: don't clean it to save static frame info line ref_in
1425 * ref_out, and tnr_frames. Once this static data is in a
1426 * seperate data struct, this may be enable (but still, there is
1433 * @brief Update the offline frame information in host_sp_communication.
1434 * Refer to "sh_css_sp.h" for more details.
1437 sh_css_update_host2sp_offline_frame(
1439 struct ia_css_frame
*frame
,
1440 struct ia_css_metadata
*metadata
)
1442 unsigned int HIVE_ADDR_host_sp_com
;
1443 unsigned int offset
;
1445 (void)HIVE_ADDR_host_sp_com
; /* Suppres warnings in CRUN */
1447 assert(frame_num
< NUM_CONTINUOUS_FRAMES
);
1449 /* Write new frame data into SP DMEM */
1450 HIVE_ADDR_host_sp_com
= sh_css_sp_fw
.info
.sp
.host_sp_com
;
1451 offset
= (unsigned int)offsetof(struct host_sp_communication
, host2sp_offline_frames
)
1453 offset
+= frame_num
;
1454 store_sp_array_uint(host_sp_com
, offset
, frame
? frame
->data
: 0);
1456 /* Write metadata buffer into SP DMEM */
1457 offset
= (unsigned int)offsetof(struct host_sp_communication
, host2sp_offline_metadata
)
1459 offset
+= frame_num
;
1460 store_sp_array_uint(host_sp_com
, offset
, metadata
? metadata
->address
: 0);
1463 #if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
1465 * @brief Update the mipi frame information in host_sp_communication.
1466 * Refer to "sh_css_sp.h" for more details.
1469 sh_css_update_host2sp_mipi_frame(
1471 struct ia_css_frame
*frame
)
1473 unsigned int HIVE_ADDR_host_sp_com
;
1474 unsigned int offset
;
1476 (void)HIVE_ADDR_host_sp_com
; /* Suppres warnings in CRUN */
1478 /* MIPI buffers are dedicated to port, so now there are more of them. */
1479 assert(frame_num
< (N_CSI_PORTS
* NUM_MIPI_FRAMES_PER_STREAM
));
1481 /* Write new frame data into SP DMEM */
1482 HIVE_ADDR_host_sp_com
= sh_css_sp_fw
.info
.sp
.host_sp_com
;
1483 offset
= (unsigned int)offsetof(struct host_sp_communication
, host2sp_mipi_frames
)
1485 offset
+= frame_num
;
1487 store_sp_array_uint(host_sp_com
, offset
,
1488 frame
? frame
->data
: 0);
1492 * @brief Update the mipi metadata information in host_sp_communication.
1493 * Refer to "sh_css_sp.h" for more details.
1496 sh_css_update_host2sp_mipi_metadata(
1498 struct ia_css_metadata
*metadata
)
1500 unsigned int HIVE_ADDR_host_sp_com
;
1503 (void)HIVE_ADDR_host_sp_com
; /* Suppres warnings in CRUN */
1505 /* MIPI buffers are dedicated to port, so now there are more of them. */
1506 assert(frame_num
< (N_CSI_PORTS
* NUM_MIPI_FRAMES_PER_STREAM
));
1508 /* Write new frame data into SP DMEM */
1509 HIVE_ADDR_host_sp_com
= sh_css_sp_fw
.info
.sp
.host_sp_com
;
1510 o
= offsetof(struct host_sp_communication
, host2sp_mipi_metadata
)
1513 store_sp_array_uint(host_sp_com
, o
,
1514 metadata
? metadata
->address
: 0);
1518 sh_css_update_host2sp_num_mipi_frames(unsigned num_frames
)
1520 unsigned int HIVE_ADDR_host_sp_com
;
1521 unsigned int offset
;
1523 (void)HIVE_ADDR_host_sp_com
; /* Suppres warnings in CRUN */
1525 /* Write new frame data into SP DMEM */
1526 HIVE_ADDR_host_sp_com
= sh_css_sp_fw
.info
.sp
.host_sp_com
;
1527 offset
= (unsigned int)offsetof(struct host_sp_communication
, host2sp_num_mipi_frames
)
1530 store_sp_array_uint(host_sp_com
, offset
, num_frames
);
1535 sh_css_update_host2sp_cont_num_raw_frames(unsigned num_frames
, bool set_avail
)
1537 const struct ia_css_fw_info
*fw
;
1538 unsigned int HIVE_ADDR_host_sp_com
;
1539 unsigned int extra_num_frames
, avail_num_frames
;
1540 unsigned int offset
, offset_extra
;
1542 (void)HIVE_ADDR_host_sp_com
; /* Suppres warnings in CRUN */
1544 /* Write new frame data into SP DMEM */
1546 HIVE_ADDR_host_sp_com
= fw
->info
.sp
.host_sp_com
;
1548 offset
= (unsigned int)offsetof(struct host_sp_communication
, host2sp_cont_avail_num_raw_frames
)
1550 avail_num_frames
= load_sp_array_uint(host_sp_com
, offset
);
1551 extra_num_frames
= num_frames
- avail_num_frames
;
1552 offset_extra
= (unsigned int)offsetof(struct host_sp_communication
, host2sp_cont_extra_num_raw_frames
)
1554 store_sp_array_uint(host_sp_com
, offset_extra
, extra_num_frames
);
1556 offset
= (unsigned int)offsetof(struct host_sp_communication
, host2sp_cont_target_num_raw_frames
)
1559 store_sp_array_uint(host_sp_com
, offset
, num_frames
);
1563 sh_css_event_init_irq_mask(void)
1566 unsigned int HIVE_ADDR_host_sp_com
= sh_css_sp_fw
.info
.sp
.host_sp_com
;
1567 unsigned int offset
;
1568 struct sh_css_event_irq_mask event_irq_mask_init
;
1570 event_irq_mask_init
.or_mask
= IA_CSS_EVENT_TYPE_ALL
;
1571 event_irq_mask_init
.and_mask
= IA_CSS_EVENT_TYPE_NONE
;
1572 (void)HIVE_ADDR_host_sp_com
; /* Suppress warnings in CRUN */
1574 assert(sizeof(event_irq_mask_init
) % HRT_BUS_BYTES
== 0);
1575 for (i
= 0; i
< IA_CSS_PIPE_ID_NUM
; i
++) {
1576 offset
= (unsigned int)offsetof(struct host_sp_communication
,
1577 host2sp_event_irq_mask
[i
]);
1578 assert(offset
% HRT_BUS_BYTES
== 0);
1579 sp_dmem_store(SP0_ID
,
1580 (unsigned int)sp_address_of(host_sp_com
) + offset
,
1581 &event_irq_mask_init
, sizeof(event_irq_mask_init
));
1587 ia_css_pipe_set_irq_mask(struct ia_css_pipe
*pipe
,
1588 unsigned int or_mask
,
1589 unsigned int and_mask
)
1591 unsigned int HIVE_ADDR_host_sp_com
= sh_css_sp_fw
.info
.sp
.host_sp_com
;
1592 unsigned int offset
;
1593 struct sh_css_event_irq_mask event_irq_mask
;
1594 unsigned int pipe_num
;
1596 assert(pipe
!= NULL
);
1598 assert(IA_CSS_PIPE_ID_NUM
== NR_OF_PIPELINES
);
1599 /* Linux kernel does not have UINT16_MAX
1600 * Therefore decided to comment out these 2 asserts for Linux
1601 * Alternatives that were not chosen:
1602 * - add a conditional #define for UINT16_MAX
1603 * - compare with (uint16_t)~0 or 0xffff
1604 * - different assert for Linux and Windows
1607 assert(or_mask
<= UINT16_MAX
);
1608 assert(and_mask
<= UINT16_MAX
);
1611 (void)HIVE_ADDR_host_sp_com
; /* Suppres warnings in CRUN */
1613 IA_CSS_LOG("or_mask=%x, and_mask=%x", or_mask
, and_mask
);
1614 event_irq_mask
.or_mask
= (uint16_t)or_mask
;
1615 event_irq_mask
.and_mask
= (uint16_t)and_mask
;
1617 pipe_num
= ia_css_pipe_get_pipe_num(pipe
);
1618 if (pipe_num
>= IA_CSS_PIPE_ID_NUM
)
1619 return IA_CSS_ERR_INTERNAL_ERROR
;
1620 offset
= (unsigned int)offsetof(struct host_sp_communication
,
1621 host2sp_event_irq_mask
[pipe_num
]);
1622 assert(offset
% HRT_BUS_BYTES
== 0);
1623 sp_dmem_store(SP0_ID
,
1624 (unsigned int)sp_address_of(host_sp_com
) + offset
,
1625 &event_irq_mask
, sizeof(event_irq_mask
));
1627 return IA_CSS_SUCCESS
;
1631 ia_css_event_get_irq_mask(const struct ia_css_pipe
*pipe
,
1632 unsigned int *or_mask
,
1633 unsigned int *and_mask
)
1635 unsigned int HIVE_ADDR_host_sp_com
= sh_css_sp_fw
.info
.sp
.host_sp_com
;
1636 unsigned int offset
;
1637 struct sh_css_event_irq_mask event_irq_mask
;
1638 unsigned int pipe_num
;
1640 (void)HIVE_ADDR_host_sp_com
; /* Suppres warnings in CRUN */
1642 IA_CSS_ENTER_LEAVE("");
1644 assert(pipe
!= NULL
);
1645 assert(IA_CSS_PIPE_ID_NUM
== NR_OF_PIPELINES
);
1647 pipe_num
= ia_css_pipe_get_pipe_num(pipe
);
1648 if (pipe_num
>= IA_CSS_PIPE_ID_NUM
)
1649 return IA_CSS_ERR_INTERNAL_ERROR
;
1650 offset
= (unsigned int)offsetof(struct host_sp_communication
,
1651 host2sp_event_irq_mask
[pipe_num
]);
1652 assert(offset
% HRT_BUS_BYTES
== 0);
1653 sp_dmem_load(SP0_ID
,
1654 (unsigned int)sp_address_of(host_sp_com
) + offset
,
1655 &event_irq_mask
, sizeof(event_irq_mask
));
1658 *or_mask
= event_irq_mask
.or_mask
;
1661 *and_mask
= event_irq_mask
.and_mask
;
1663 return IA_CSS_SUCCESS
;
1667 sh_css_sp_set_sp_running(bool flag
)
1673 sh_css_sp_is_running(void)
1679 sh_css_sp_start_isp(void)
1681 const struct ia_css_fw_info
*fw
;
1682 unsigned int HIVE_ADDR_sp_sw_state
;
1685 HIVE_ADDR_sp_sw_state
= fw
->info
.sp
.sw_state
;
1691 (void)HIVE_ADDR_sp_sw_state
; /* Suppres warnings in CRUN */
1693 /* no longer here, sp started immediately */
1694 /*ia_css_debug_pipe_graph_dump_epilogue();*/
1696 store_sp_group_data();
1697 store_sp_per_frame_data(fw
);
1699 sp_dmem_store_uint32(SP0_ID
,
1700 (unsigned int)sp_address_of(sp_sw_state
),
1701 (uint32_t)(IA_CSS_SP_SW_TERMINATED
));
1704 /* Note 1: The sp_start_isp function contains a wait till
1705 * the input network is configured by the SP.
1706 * Note 2: Not all SP binaries supports host2sp_commands.
1707 * In case a binary does support it, the host2sp_command
1708 * will have status cmd_ready after return of the function
1709 * sh_css_hrt_sp_start_isp. There is no race-condition here
1710 * because only after the process_frame command has been
1711 * received, the SP starts configuring the input network.
1714 /* we need to set sp_running before we call ia_css_mmu_invalidate_cache
1715 * as ia_css_mmu_invalidate_cache checks on sp_running to
1716 * avoid that it accesses dmem while the SP is not powered
1719 ia_css_mmu_invalidate_cache();
1720 /* Invalidate all MMU caches */
1721 mmu_invalidate_cache_all();
1723 ia_css_spctrl_start(SP0_ID
);
1728 ia_css_isp_has_started(void)
1730 const struct ia_css_fw_info
*fw
= &sh_css_sp_fw
;
1731 unsigned int HIVE_ADDR_ia_css_ispctrl_sp_isp_started
= fw
->info
.sp
.isp_started
;
1732 (void)HIVE_ADDR_ia_css_ispctrl_sp_isp_started
; /* Suppres warnings in CRUN */
1734 return (bool)load_sp_uint(ia_css_ispctrl_sp_isp_started
);
1739 * @brief Initialize the DMA software-mask in the debug mode.
1740 * Refer to "sh_css_sp.h" for more details.
1743 sh_css_sp_init_dma_sw_reg(int dma_id
)
1747 /* enable all the DMA channels */
1748 for (i
= 0; i
< N_DMA_CHANNEL_ID
; i
++) {
1749 /* enable the writing request */
1750 sh_css_sp_set_dma_sw_reg(dma_id
,
1754 /* enable the reading request */
1755 sh_css_sp_set_dma_sw_reg(dma_id
,
1765 * @brief Set the DMA software-mask in the debug mode.
1766 * Refer to "sh_css_sp.h" for more details.
1769 sh_css_sp_set_dma_sw_reg(int dma_id
,
1776 uint32_t bit_offset
;
1781 assert(channel_id
>= 0 && channel_id
< N_DMA_CHANNEL_ID
);
1782 assert(request_type
>= 0);
1784 /* get the software-mask */
1786 sh_css_sp_group
.debug
.dma_sw_reg
;
1788 /* get the offest of the target bit */
1789 bit_offset
= (8 * request_type
) + channel_id
;
1791 /* clear the value of the target bit */
1792 bit_mask
= ~(1 << bit_offset
);
1795 /* set the value of the bit for the DMA channel */
1796 bit_val
= enable
? 1 : 0;
1797 bit_val
<<= bit_offset
;
1800 /* update the software status of DMA channels */
1801 sh_css_sp_group
.debug
.dma_sw_reg
= sw_reg
;
1807 sh_css_sp_reset_global_vars(void)
1809 memset(&sh_css_sp_group
, 0, sizeof(struct sh_css_sp_group
));
1810 memset(&sh_css_sp_stage
, 0, sizeof(struct sh_css_sp_stage
));
1811 memset(&sh_css_isp_stage
, 0, sizeof(struct sh_css_isp_stage
));
1812 memset(&sh_css_sp_output
, 0, sizeof(struct sh_css_sp_output
));
1813 memset(&per_frame_data
, 0, sizeof(struct sh_css_sp_per_frame_data
));