1 /*
2 *
3 * SPDX-License-Identifier: GPL-2.0
4 *
5 * Copyright (C) 2011-2018 ARM or its affiliates
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20 #include "acamera_logger.h"
21 #include "system_interrupts.h"
22 #include "system_stdlib.h"
23 #include "dma_writer_api.h"
24 #include "dma_writer.h"
25 #include "acamera_firmware_config.h"
26 #include "acamera.h"
27
28 #ifdef LOG_MODULE
29 #undef LOG_MODULE
30 #define LOG_MODULE LOG_MODULE_DMA_WRITER
31 #endif
32
33 #define TAG "DMA_WRITER"
34
35 //#define DMA_PRINTF(a) printf a
36 #define DMA_PRINTF( a ) (void)0
37
38 static dma_handle s_handle[FIRMWARE_CONTEXT_NUMBER];
39 static int32_t ctx_pos = 0;
dma_writer_create(void ** handle)40 dma_error dma_writer_create( void **handle )
41 {
42 dma_error result = edma_ok;
43 if ( handle != NULL ) {
44
45 if ( ctx_pos < acamera_get_context_number() ) {
46 *handle = &s_handle[ctx_pos];
47 system_memset( (void *)*handle, 0, sizeof( dma_handle ) );
48 ctx_pos++;
49 } else {
50 *handle = NULL;
51 result = edma_fail;
52 LOG( LOG_CRIT, "dma context overshoot\n" );
53 }
54 } else {
55 result = edma_fail;
56 }
57 return result;
58 }
59
dma_writer_exit(void * handle)60 void dma_writer_exit( void *handle )
61 {
62 ctx_pos = 0;
63 }
64
dma_writer_update_state(dma_pipe * pipe)65 dma_error dma_writer_update_state( dma_pipe *pipe )
66 {
67 dma_error result = edma_ok;
68 if ( pipe != NULL ) {
69 LOG( LOG_DEBUG, "state update %dx%d\n", (int)pipe->settings.width, (int)pipe->settings.height );
70 if ( pipe->settings.width == 0 || pipe->settings.height == 0 ) {
71 result = edma_invalid_settings;
72 pipe->settings.enabled = 0;
73 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write( pipe->settings.isp_base, pipe->settings.enabled ); //disable pipe on invalid settings
74 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write_uv( pipe->settings.isp_base, pipe->settings.enabled );
75 return result;
76 }
77
78
79 //set default settings here
80 pipe->api.p_acamera_isp_dma_writer_max_bank_write( pipe->settings.isp_base, 0 );
81 pipe->api.p_acamera_isp_dma_writer_active_width_write( pipe->settings.isp_base, pipe->settings.width );
82 pipe->api.p_acamera_isp_dma_writer_active_height_write( pipe->settings.isp_base, pipe->settings.height );
83
84 pipe->api.p_acamera_isp_dma_writer_max_bank_write_uv( pipe->settings.isp_base, 0 );
85 pipe->api.p_acamera_isp_dma_writer_active_width_write_uv( pipe->settings.isp_base, pipe->settings.width );
86 pipe->api.p_acamera_isp_dma_writer_active_height_write_uv( pipe->settings.isp_base, pipe->settings.height );
87 } else {
88 result = edma_fail;
89 }
90 return result;
91 }
92
93
dma_writer_get_settings(void * handle,dma_type type,dma_pipe_settings * settings)94 dma_error dma_writer_get_settings( void *handle, dma_type type, dma_pipe_settings *settings )
95 {
96 dma_error result = edma_ok;
97 if ( handle != NULL ) {
98 dma_handle *p_dma = (dma_handle *)handle;
99 system_memcpy( (void *)settings, &p_dma->pipe[type].settings, sizeof( dma_pipe_settings ) );
100 } else {
101 result = edma_fail;
102 }
103 return result;
104 }
105
106
dma_writer_set_settings(void * handle,dma_type type,dma_pipe_settings * settings)107 dma_error dma_writer_set_settings( void *handle, dma_type type, dma_pipe_settings *settings )
108 {
109 dma_error result = edma_ok;
110 if ( handle != NULL ) {
111 dma_handle *p_dma = (dma_handle *)handle;
112 system_memcpy( (void *)&p_dma->pipe[type].settings, settings, sizeof( dma_pipe_settings ) );
113 result = dma_writer_update_state( &p_dma->pipe[type] );
114
115 } else {
116 LOG( LOG_ERR, "set settings handle null\n" );
117 result = edma_fail;
118 }
119 return result;
120 }
121
dma_writer_get_ptr_settings(void * handle,dma_type type,dma_pipe_settings ** settings)122 dma_error dma_writer_get_ptr_settings( void *handle, dma_type type, dma_pipe_settings **settings )
123 {
124 dma_error result = edma_ok;
125 if ( handle != NULL ) {
126 dma_handle *p_dma = (dma_handle *)handle;
127 *settings = &p_dma->pipe[type].settings;
128 } else {
129 result = edma_fail;
130 }
131 return result;
132 }
133
dma_writer_set_initialized(void * handle,dma_type type,uint8_t initialized)134 void dma_writer_set_initialized( void *handle, dma_type type, uint8_t initialized )
135 {
136 if ( handle != NULL ) {
137 dma_handle *p_dma = (dma_handle *)handle;
138 p_dma->pipe[type].state.initialized = initialized;
139 }
140 }
141
dma_writer_init(void * handle,dma_type type,dma_pipe_settings * settings,dma_api * api)142 dma_error dma_writer_init( void *handle, dma_type type, dma_pipe_settings *settings, dma_api *api )
143 {
144 dma_error result = edma_ok;
145 if ( handle != NULL ) {
146 dma_handle *p_dma = (dma_handle *)handle;
147 p_dma->pipe[type].type = type;
148 system_memcpy( (void *)&p_dma->pipe[type].api, api, sizeof( dma_api ) );
149 result = dma_writer_set_settings( handle, type, settings );
150 result |= dma_writer_reset( handle, type );
151
152 if ( result == edma_ok ) {
153 LOG( LOG_INFO, "%s: initialized a dma writer output. %dx%d ", TAG, (int)settings->width, (int)settings->height );
154 } else {
155 LOG( LOG_ERR, "%s: Failed to initialize a dma writer type:%d output. %dx%d ", TAG, (int)type, (int)settings->width, (int)settings->height );
156 }
157 } else {
158 result = edma_fail;
159 }
160 return result;
161 }
162
dma_writer_init_frame_queue(dma_pipe * pipe)163 void dma_writer_init_frame_queue( dma_pipe *pipe )
164 { //init all buffer to inuse so we can remove it from the queue
165 int i;
166 for ( i = 0; i < MAX_DMA_QUEUE_FRAMES; i++ ) {
167 pipe->settings.frame_buf_queue[i].primary.status = dma_buf_purge;
168 pipe->settings.frame_buf_queue[i].secondary.status = dma_buf_purge;
169 }
170 DMA_PRINTF( ( "all frames to dma_buf_purge\n" ) );
171 return;
172 }
173
dma_writer_reset(void * handle,dma_type type)174 dma_error dma_writer_reset( void *handle, dma_type type )
175 {
176 dma_error result = edma_ok;
177 if ( handle != NULL ) {
178 dma_handle *p_dma = (dma_handle *)handle;
179 dma_pipe *pipe = &p_dma->pipe[type];
180 pipe->state.buf_num_rdi = 0;
181 pipe->state.buf_num_wri = 0;
182 pipe->state.buf_num_size = 0;
183 pipe->settings.last_tframe = NULL;
184 pipe->settings.inqueue_tframe[0] = NULL;
185 pipe->settings.inqueue_tframe[1] = NULL;
186 pipe->settings.init_delay = 1;
187 dma_writer_init_frame_queue( pipe );
188 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write( pipe->settings.isp_base, 0 );
189 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write_uv( pipe->settings.isp_base, 0 );
190 pipe->settings.enabled = 0;
191 pipe->settings.c_fps = 0;
192 pipe->settings.t_fps = 0;
193 pipe->settings.inter_val = 0;
194 pipe->settings.back_tframe = NULL;
195 } else {
196 result = edma_fail;
197 }
198 return result;
199 }
200
dma_writer_set_pipe_fps(void * handle,dma_type type,uint32_t c_fps,uint32_t t_fps)201 dma_error dma_writer_set_pipe_fps(void *handle, dma_type type,
202 uint32_t c_fps, uint32_t t_fps)
203 {
204 dma_handle *p_dma = NULL;
205 dma_pipe *pipe = NULL;
206 uint32_t inter_val = 0;
207
208 if (handle == NULL || c_fps == 0 || t_fps == 0 || (t_fps > c_fps)) {
209 LOG(LOG_ERR, "Error input param\n");
210 return edma_wrong_parameters;
211 }
212
213 p_dma = handle;
214 pipe = &p_dma->pipe[type];
215 pipe->settings.c_fps = c_fps;
216 pipe->settings.t_fps = t_fps;
217
218 inter_val = c_fps / t_fps;
219 if (c_fps % t_fps != 0)
220 inter_val += 1;
221
222 pipe->settings.inter_val = inter_val;
223
224 LOG(LOG_INFO, "c_fps: %d, t_fps: %d, interval %d\n", c_fps, t_fps, inter_val);
225
226 return edma_ok;
227 }
228
229
dma_writer_get_default_settings(void * handle,dma_type type,dma_pipe_settings * settings)230 dma_error dma_writer_get_default_settings( void *handle, dma_type type, dma_pipe_settings *settings )
231 {
232 dma_error result = edma_ok;
233 return result;
234 }
235
dma_writer_write_frame_queue(void * handle,dma_type type,tframe_t * frame_buf_array,uint16_t frame_buf_len)236 uint16_t dma_writer_write_frame_queue( void *handle, dma_type type, tframe_t *frame_buf_array, uint16_t frame_buf_len )
237 {
238
239 int i, set_i = 0;
240 dma_handle *p_dma = (dma_handle *)handle;
241 dma_pipe *pipe = &p_dma->pipe[type];
242
243 if ( handle == NULL || frame_buf_array == NULL || pipe == NULL ) {
244 LOG( LOG_CRIT, "NULL detected handle:%p,frame_buf_array:%p,pipe:%p\n", handle, frame_buf_array, pipe );
245 return 0;
246 }
247
248 if ( frame_buf_len == 0 )
249 return 0;
250
251 int index = 0;
252 for ( i = 0; i < MAX_DMA_QUEUE_FRAMES; i++ ) {
253 index = ( i + pipe->state.buf_num_rdi ) % MAX_DMA_QUEUE_FRAMES;
254
255 if ( pipe->settings.frame_buf_queue[index].primary.status == dma_buf_purge ) { //replace the buffer when it is in use
256 /* init tframe status first */
257 frame_buf_array[set_i].primary.status = dma_buf_purge;
258 frame_buf_array[set_i].secondary.status = dma_buf_purge;
259 pipe->settings.frame_buf_queue[index] = frame_buf_array[set_i];
260 pipe->settings.frame_buf_queue[index].primary.status = dma_buf_empty;
261 pipe->settings.frame_buf_queue[index].secondary.status = dma_buf_empty;
262 set_i++;
263 }
264 if ( set_i >= frame_buf_len ) {
265 set_i = i++;
266 break;
267 }
268 }
269
270 if ( i > pipe->state.buf_num_size ) {
271 pipe->state.buf_num_size = i;
272 DMA_PRINTF( ( "dma buf_num_size changed %d\n", (int)pipe->state.buf_num_size ) );
273 }
274
275 if ( pipe->settings.enabled == 0 ) {
276 DMA_PRINTF( ( "dma re-enabling\n" ) );
277 pipe->api.p_acamera_isp_dma_writer_bank0_base_write( pipe->settings.isp_base, pipe->settings.frame_buf_queue[set_i].primary.address );
278 pipe->api.p_acamera_isp_dma_writer_bank0_base_write_uv( pipe->settings.isp_base, pipe->settings.frame_buf_queue[set_i].secondary.address );
279 pipe->settings.inqueue_tframe[1] = &pipe->settings.frame_buf_queue[set_i];
280 pipe->settings.frame_buf_queue[set_i].primary.status = dma_buf_busy;
281 pipe->settings.enabled = 1;
282 if ( pipe->api.p_acamera_isp_dma_writer_format_read( pipe->settings.isp_base ) != DMA_FORMAT_DISABLE )
283 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write( pipe->settings.isp_base, 1 );
284 else
285 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write( pipe->settings.isp_base, 0 );
286
287 pipe->api.p_acamera_isp_dma_writer_line_offset_write( pipe->settings.isp_base, pipe->settings.frame_buf_queue[set_i].primary.line_offset);
288
289 //check if format is for UV
290 if ( pipe->api.p_acamera_isp_dma_writer_format_read_uv( pipe->settings.isp_base ) != DMA_FORMAT_DISABLE ) {
291 pipe->settings.frame_buf_queue[set_i].secondary.status = dma_buf_busy;
292 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write_uv( pipe->settings.isp_base, 1 );
293 pipe->api.p_acamera_isp_dma_writer_line_offset_write_uv( pipe->settings.isp_base, pipe->settings.frame_buf_queue[set_i].secondary.line_offset);
294 LOG( LOG_DEBUG, "enabled uv %d", pipe->api.p_acamera_isp_dma_writer_format_read_uv( pipe->settings.isp_base ) );
295 } else {
296 //cannot enable
297 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write_uv( pipe->settings.isp_base, 0 );
298 LOG( LOG_DEBUG, "cannot enable uv %d", pipe->api.p_acamera_isp_dma_writer_format_read_uv( pipe->settings.isp_base ) );
299 }
300 }
301 return i;
302 }
303
dma_get_next_empty_frame(dma_pipe * pipe)304 tframe_t *dma_get_next_empty_frame( dma_pipe *pipe )
305 {
306 int i, index = 0, last_index;
307 for ( i = 0; i < MAX_DMA_QUEUE_FRAMES; i++ ) {
308 index = ( i + pipe->state.buf_num_wri ) % MAX_DMA_QUEUE_FRAMES;
309 last_index = pipe->state.buf_num_wri;
310 if ( pipe->settings.frame_buf_queue[index].primary.status == dma_buf_empty ) {
311 pipe->state.buf_num_wri = ( index + 1 ) % MAX_DMA_QUEUE_FRAMES;
312 //recover busy frames not returned by dma
313 if (( pipe->settings.frame_buf_queue[last_index].primary.status == dma_buf_busy )
314 && (&pipe->settings.frame_buf_queue[last_index] != pipe->settings.last_tframe)
315 && (&pipe->settings.frame_buf_queue[last_index] != pipe->settings.inqueue_tframe[0])
316 && (&pipe->settings.frame_buf_queue[last_index] != pipe->settings.inqueue_tframe[1])) {
317 pipe->settings.frame_buf_queue[last_index].primary.status = dma_buf_empty;
318 pipe->settings.frame_buf_queue[last_index].secondary.status = dma_buf_empty;
319 DMA_PRINTF( ( "recovered 0x%lx\n", pipe->settings.frame_buf_queue[last_index].primary.address ) );
320 }
321 return &( pipe->settings.frame_buf_queue[index] );
322 }
323 }
324
325 return 0;
326 }
327
328
dma_get_next_ready_frame(dma_pipe * pipe)329 tframe_t *dma_get_next_ready_frame( dma_pipe *pipe )
330 {
331 int i, index;
332 for ( i = 0; i < MAX_DMA_QUEUE_FRAMES; i++ ) {
333 index = ( i + pipe->state.buf_num_rdi ) % MAX_DMA_QUEUE_FRAMES;
334 if ( pipe->settings.frame_buf_queue[index].primary.status == dma_buf_ready ) {
335 pipe->state.buf_num_rdi = ( index + 1 ) % MAX_DMA_QUEUE_FRAMES;
336 return &( pipe->settings.frame_buf_queue[index] );
337 }
338 }
339 return 0;
340 }
341
342
dma_writer_api_return_next_ready_frame(void * handle,dma_type type)343 tframe_t *dma_writer_api_return_next_ready_frame( void *handle, dma_type type )
344 {
345 dma_handle *p_dma = (dma_handle *)handle;
346 dma_pipe *pipe = &p_dma->pipe[type];
347 return dma_get_next_ready_frame( pipe );
348 }
349
350
351 extern int32_t acamera_get_api_context( void );
352
353 //extern void dma_input_reset();
dma_writer_pipe_update(dma_pipe * pipe,bool drop_frame)354 dma_error dma_writer_pipe_update( dma_pipe *pipe , bool drop_frame)
355 {
356 dma_error result = edma_ok;
357 tframe_t *empty_frame = NULL;
358 uint32_t addr = 0;
359 #if ISP_HAS_FPGA_WRAPPER && ISP_CONTROLS_DMA_READER
360 uint32_t addr_uv = 0;
361 #endif
362 //only update if there are frames
363 if ( pipe != NULL && pipe->state.buf_num_size ) {
364 if ( pipe->state.initialized && pipe->settings.pause == 0 ) {
365
366 //only check primary status
367 if ( pipe->settings.last_tframe ) {
368 if (pipe->settings.init_delay > 0) {
369 /* recycle the buffer as empty */
370 pipe->settings.init_delay--;
371 pipe->settings.last_tframe->primary.status = dma_buf_empty;
372 pipe->settings.last_tframe->secondary.status = dma_buf_empty;
373 pipe->settings.last_tframe = NULL;
374 } else if (drop_frame) {
375 /* recycle the buffer as empty */
376 pipe->settings.last_tframe->primary.status = dma_buf_empty;
377 pipe->settings.last_tframe->secondary.status = dma_buf_empty;
378 pipe->settings.last_tframe = NULL;
379 } else {
380 addr = pipe->settings.last_tframe->primary.address;
381 #if ISP_HAS_FPGA_WRAPPER && ISP_CONTROLS_DMA_READER
382 addr_uv = pipe->settings.last_tframe->secondary.address;
383 #endif
384 pipe->settings.last_tframe->primary.status = dma_buf_ready;
385 pipe->settings.last_tframe->secondary.status = dma_buf_ready;
386 }
387 LOG( LOG_DEBUG, "wbase_last_read:0x%lx\n", addr );
388 }
389 // update frame reader address
390 #if ISP_HAS_FPGA_WRAPPER && ISP_CONTROLS_DMA_READER
391 static uint32_t addr_late, addr_late1;
392 static uint32_t addr_late_uv, addr_late1_uv;
393 if ( pipe->settings.active && pipe->settings.ctx_id == acamera_get_api_context() && pipe->settings.last_tframe ) {
394 pipe->api.p_acamera_fpga_frame_reader_rbase_write( pipe->settings.isp_base, addr_late + pipe->settings.read_offset );
395 LOG( LOG_DEBUG, "ctx_id: %d, dma_pipe_type: %d, frame_reader_rbase: 0x%08x.", (int)pipe->settings.ctx_id, (int)pipe->type, (unsigned int)( addr_late + pipe->settings.read_offset ) );
396 pipe->api.p_acamera_fpga_frame_reader_line_offset_write( pipe->settings.isp_base, pipe->settings.last_tframe->primary.line_offset );
397 pipe->api.p_acamera_fpga_frame_reader_format_write( pipe->settings.isp_base, pipe->api.p_acamera_isp_dma_writer_format_read( pipe->settings.isp_base ) );
398 pipe->api.p_acamera_fpga_frame_reader_rbase_load_write( pipe->settings.isp_base, 1 );
399 pipe->api.p_acamera_fpga_frame_reader_rbase_load_write( pipe->settings.isp_base, 0 );
400
401 if ( pipe->api.p_acamera_isp_dma_writer_format_read_uv( pipe->settings.isp_base ) != DMA_FORMAT_DISABLE ) {
402 pipe->api.p_acamera_fpga_frame_reader_rbase_write_uv( pipe->settings.isp_base, addr_late_uv + pipe->settings.read_offset );
403 pipe->api.p_acamera_fpga_frame_reader_line_offset_write_uv( pipe->settings.isp_base, pipe->settings.last_tframe->secondary.line_offset );
404 pipe->api.p_acamera_fpga_frame_reader_format_write_uv( pipe->settings.isp_base, pipe->api.p_acamera_isp_dma_writer_format_read_uv( pipe->settings.isp_base ) );
405 pipe->api.p_acamera_fpga_frame_reader_rbase_load_write_uv( pipe->settings.isp_base, 1 );
406 pipe->api.p_acamera_fpga_frame_reader_rbase_load_write_uv( pipe->settings.isp_base, 0 );
407 }
408 addr_late = addr_late1;
409 addr_late1 = addr;
410
411 addr_late_uv = addr_late1_uv;
412 addr_late1_uv = addr_uv;
413 }
414 #endif
415 pipe->settings.last_tframe = pipe->settings.inqueue_tframe[0];
416 pipe->settings.inqueue_tframe[0] = pipe->settings.inqueue_tframe[1];
417 pipe->settings.inqueue_tframe[1] = NULL;
418
419 if (pipe->settings.back_tframe != NULL)
420 empty_frame = pipe->settings.back_tframe;
421 else
422 empty_frame = dma_get_next_empty_frame(pipe);
423
424 if ( empty_frame != NULL ) {
425 empty_frame->primary.type = pipe->api.p_acamera_isp_dma_writer_format_read( pipe->settings.isp_base );
426 if ( empty_frame->primary.type != DMA_FORMAT_DISABLE ) {
427 empty_frame->primary.width = pipe->api.p_acamera_isp_dma_writer_active_width_read( pipe->settings.isp_base );
428 empty_frame->primary.height = pipe->api.p_acamera_isp_dma_writer_active_height_read( pipe->settings.isp_base );
429 empty_frame->primary.line_offset = acamera_line_offset( empty_frame->primary.width, _get_pixel_width( empty_frame->primary.type ) );
430 uint32_t frame_size = empty_frame->primary.line_offset * empty_frame->primary.height;
431 addr = empty_frame->primary.address;
432 pipe->settings.inqueue_tframe[1] = empty_frame;
433 LOG( LOG_DEBUG, "next dma addr:0x%lx\n", addr );
434 if ( pipe->settings.vflip ) {
435 addr += frame_size - empty_frame->primary.line_offset;
436 pipe->api.p_acamera_isp_dma_writer_line_offset_write( pipe->settings.isp_base, -(uint32_t)empty_frame->primary.line_offset );
437 } else {
438 pipe->api.p_acamera_isp_dma_writer_line_offset_write( pipe->settings.isp_base, empty_frame->primary.line_offset );
439 }
440
441 //multicontext change in resolution
442 pipe->api.p_acamera_isp_dma_writer_active_width_write( pipe->settings.isp_base, empty_frame->primary.width );
443 pipe->api.p_acamera_isp_dma_writer_active_height_write( pipe->settings.isp_base, empty_frame->primary.height );
444
445 addr += pipe->settings.write_offset;
446 if ( frame_size > empty_frame->primary.size ) { //check frame buffer size
447 LOG( LOG_CRIT, "%s: frame_size greater than available buffer. fr %d vs %d ", TAG, (int)frame_size, (int)empty_frame->primary.size );
448 result = edma_fail;
449 } else {
450 LOG( LOG_DEBUG, "ctx_id: %d, isp_base: %x, dma_pipe_type: %d, dma_writer_bank0_base_addr: 0x%08x.", (int)pipe->settings.ctx_id, (unsigned int)pipe->settings.isp_base, (int)pipe->type, (unsigned int)addr );
451 pipe->api.p_acamera_isp_dma_writer_bank0_base_write( pipe->settings.isp_base, addr );
452 empty_frame->primary.status = dma_buf_busy;
453 pipe->settings.last_address = addr;
454 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write( pipe->settings.isp_base, 1 );
455 /*if ( pipe->settings.enabled == 0 ) {
456 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write( pipe->settings.isp_base, 1 );
457 pipe->settings.enabled = 1;
458 DMA_PRINTF( ( "warning pipe is disabled, enabling" ) );
459 }*/
460 }
461 }
462
463 empty_frame->secondary.type = pipe->api.p_acamera_isp_dma_writer_format_read_uv( pipe->settings.isp_base );
464 if ( empty_frame->secondary.type != DMA_FORMAT_DISABLE ) {
465 empty_frame->secondary.width = pipe->api.p_acamera_isp_dma_writer_active_width_read_uv( pipe->settings.isp_base );
466 empty_frame->secondary.height = pipe->api.p_acamera_isp_dma_writer_active_height_read_uv( pipe->settings.isp_base );
467 empty_frame->secondary.line_offset = acamera_line_offset( empty_frame->secondary.width, _get_pixel_width( empty_frame->secondary.type ) );
468 uint32_t frame_size = empty_frame->secondary.line_offset * empty_frame->secondary.height;
469 if (empty_frame->secondary.type == DMA_FORMAT_NV12_UV || empty_frame->secondary.type == DMA_FORMAT_NV12_VU)
470 frame_size = frame_size / 2;
471 addr = empty_frame->secondary.address;
472 if ( pipe->settings.vflip ) {
473 addr += frame_size - empty_frame->secondary.line_offset;
474 pipe->api.p_acamera_isp_dma_writer_line_offset_write_uv( pipe->settings.isp_base, -(uint32_t)empty_frame->secondary.line_offset );
475 } else {
476 pipe->api.p_acamera_isp_dma_writer_line_offset_write_uv( pipe->settings.isp_base, empty_frame->secondary.line_offset );
477 }
478
479 addr += pipe->settings.write_offset;
480 if ( frame_size > empty_frame->secondary.size ) { //check frame buffer size
481 LOG( LOG_CRIT, "%s: frame_size greater than available buffer. ds %d vs %d ", TAG, (int)frame_size, (int)empty_frame->secondary.size );
482 result = edma_fail;
483 } else {
484 LOG( LOG_DEBUG, "ctx_id: %d, isp_base: %x, dma_pipe_type: %d, dma_writer_bank0_base_addr: 0x%08x.", (int)pipe->settings.ctx_id, (unsigned int)pipe->settings.isp_base, (int)pipe->type, (unsigned int)addr );
485 pipe->api.p_acamera_isp_dma_writer_bank0_base_write_uv( pipe->settings.isp_base, addr );
486 empty_frame->secondary.status = dma_buf_busy;
487 pipe->settings.last_address = addr;
488 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write_uv( pipe->settings.isp_base, 1 );
489 /*if ( pipe->settings.enabled == 0 ) {
490 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write_uv( pipe->settings.isp_base, 1 );
491 //pipe->settings.enabled = 1;
492 DMA_PRINTF( ( "warning pipe is disabled" ) );
493 }*/
494 }
495 } else {
496 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write_uv( pipe->settings.isp_base, 0 );
497 }
498
499 } else {
500 //no empty frames
501 //LOG( LOG_CRIT, "NO EMPTY FRAMES on dma_pipe_type: %d\n", (int)pipe->type );
502 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write( pipe->settings.isp_base, 0 );
503 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write_uv( pipe->settings.isp_base, 0 );
504 }
505 }
506 } else {
507 result = edma_fail;
508 }
509 return result;
510 }
511
dma_writer_pipe_set_fps(dma_pipe * pipe)512 dma_error dma_writer_pipe_set_fps(dma_pipe *pipe)
513 {
514 int frm_count = 0;
515 uint32_t inter_val = 0;
516 uint32_t c_fps = 0;
517 uint32_t t_fps = 0;
518
519 if (pipe == NULL || pipe->settings.p_ctx == NULL) {
520 LOG(LOG_ERR, "Error input param:p_ctx %p\n", pipe->settings.p_ctx);
521 return edma_invalid_pipe;
522 }
523
524 frm_count = pipe->settings.p_ctx->isp_frame_counter;
525 inter_val = pipe->settings.inter_val;
526 pipe->settings.back_tframe = NULL;
527 c_fps = pipe->settings.c_fps;
528 t_fps = pipe->settings.t_fps;
529
530 if ((pipe->settings.inqueue_tframe[1] == NULL)
531 || (inter_val == 0) || (inter_val == 1))
532 return edma_ok;
533
534 if (inter_val > 2) {
535 if (frm_count % inter_val != 0) {
536 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write( pipe->settings.isp_base, 0 );
537 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write_uv( pipe->settings.isp_base, 0 );
538 pipe->settings.back_tframe = pipe->settings.inqueue_tframe[1];
539 pipe->settings.inqueue_tframe[1] = NULL;
540 } else {
541 pipe->settings.back_tframe = NULL;
542 }
543 } else {
544 inter_val = c_fps / (c_fps - t_fps);
545 if (frm_count % inter_val == 0) {
546 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write( pipe->settings.isp_base, 0 );
547 pipe->api.p_acamera_isp_dma_writer_frame_write_on_write_uv( pipe->settings.isp_base, 0 );
548 pipe->settings.back_tframe = pipe->settings.inqueue_tframe[1];
549 pipe->settings.inqueue_tframe[1] = NULL;
550 } else {
551 pipe->settings.back_tframe = NULL;
552 }
553 }
554
555 return edma_ok;
556 }
557
dma_writer_pipe_process_interrupt(dma_pipe * pipe,uint32_t irq_event)558 dma_error dma_writer_pipe_process_interrupt( dma_pipe *pipe, uint32_t irq_event )
559 {
560 switch ( irq_event ) {
561 case ACAMERA_IRQ_FRAME_WRITER_FR:
562 if ( pipe->type == dma_fr ) {
563 dma_writer_pipe_update( pipe , false); // have to change last address and buffer ring
564 dma_writer_pipe_set_fps(pipe); //change the fps of fr path
565 }
566 break;
567 case ACAMERA_IRQ_FRAME_WRITER_DS:
568 if ( pipe->type == dma_ds1 || pipe->type == dma_ds2 ) {
569 dma_writer_pipe_update( pipe , false); // have to change last address and buffer ring
570 dma_writer_pipe_set_fps(pipe); //change the fps of ds1 path
571 }
572 break;
573 case ACAMERA_IRQ_FRAME_DROP_FR:
574 if ( pipe->type == dma_fr ) {
575 dma_writer_pipe_update( pipe , true); // have to change last address and buffer ring
576 dma_writer_pipe_set_fps(pipe); //change the fps of fr path
577 }
578 break;
579 case ACAMERA_IRQ_FRAME_DROP_DS:
580 if ( pipe->type == dma_ds1 || pipe->type == dma_ds2 ) {
581 dma_writer_pipe_update( pipe , true); // have to change last address and buffer ring
582 dma_writer_pipe_set_fps(pipe); //change the fps of ds1 path
583 }
584 break;
585 }
586 return 0;
587 }
588
589
dma_writer_process_interrupt(void * handle,uint32_t irq_event)590 dma_error dma_writer_process_interrupt( void *handle, uint32_t irq_event )
591 {
592 dma_error result = edma_ok;
593 uint32_t idx = 0;
594
595 dma_handle *p_dma = (dma_handle *)handle;
596 if ( !p_dma ) {
597 LOG( LOG_ERR, "p_dma is NULL of event: %u", (unsigned int)irq_event );
598 return edma_fail;
599 }
600
601 for ( idx = 0; idx < dma_max; idx++ ) {
602 if (p_dma->pipe[idx].state.initialized == 1)
603 dma_writer_pipe_process_interrupt( &p_dma->pipe[idx], irq_event );
604 }
605 return result;
606 }
607
608
dma_writer_return_metadata(void * handle,dma_type type)609 metadata_t *dma_writer_return_metadata( void *handle, dma_type type )
610 {
611 if ( handle != NULL ) {
612
613 dma_handle *p_dma = (dma_handle *)handle;
614
615 metadata_t *ret = &( p_dma->pipe[type].settings.curr_metadata );
616 return ret;
617 }
618 return 0;
619 }
620
dma_writer_pipe_get_next_empty_buffer(void * handle,dma_type type)621 dma_error dma_writer_pipe_get_next_empty_buffer( void *handle, dma_type type )
622 {
623 dma_error result = edma_ok;
624
625 if ( handle != NULL ) {
626 dma_handle *p_dma = (dma_handle *)handle;
627 dma_pipe *pipe = &p_dma->pipe[type];
628
629 return dma_writer_pipe_update(pipe, false);
630 } else {
631 result = edma_fail;
632 }
633 return result;
634 }