2 #include <cyg/hal/hal_io.h> // I/O macros
3 #include <cyg/hal/drv_api.h> // cyg_interrupt
4 #include <cyg/hal/hal_platform_ints.h>
5 #include <cyg/kernel/diag.h>
7 #include "video_config.h"
8 #include "video_dct_p5p.h"
9 #include "video_utils_p5p.h"
11 #if (MAX_NUM_MACRO_BLOCKS_PER_CALL > 10)
12 # error "MAX_NUM_MACRO_BLOCKS_PER_CALL must not be greater than 10 on P5P"
15 #if (VIDEO_DCT_USE_INTRAM == 0)
16 #include <cyg/utils/mmu.h>
19 static cyg_uint32 dct_in_progress;
21 #if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
23 static cyg_interrupt dct_interrupt;
24 static cyg_handle_t dct_interrupt_handle;
26 //! DCT driver interrupt service routine (ISR)
27 static cyg_uint32 dct_isr( cyg_vector_t vector, cyg_addrword_t data )
29 cyg_drv_interrupt_mask(vector);
30 cyg_drv_interrupt_acknowledge(vector);
32 return CYG_ISR_CALL_DSR; // request DSR
35 //! DCT driver deffered service routine (DSR)
36 static void dct_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
40 RTMON_USTOP( VIDEO_VLIB_DCT_COMPUTE_UEVENT );
42 switch( dct_read_reg( DCT_STATUS ) )
44 case DCT_STATUS_END_OK:
45 itack = DCT_ITACK_END_OK;
48 case DCT_STATUS_ERROR:
49 diag_printf("[DCT] DMA access failure\n");
50 itack = DCT_ITACK_ERROR;
58 dct_write_reg( DCT_ITACK, itack );
60 cyg_drv_interrupt_unmask(vector);
62 #endif // VIDEO_DCT_INTERRUPT_ENABLE
65 C_RESULT video_dct_p5p_init(void)
69 HAL_READ_UINT32( PARROT5_SYS + _SYS_CEN, value);
70 HAL_WRITE_UINT32( PARROT5_SYS + _SYS_CEN, (value | SYS_CEN_CAMIFCLK) );
72 #if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
73 diag_printf("Configuring DCT with interrupt acknowledge\n");
74 cyg_drv_interrupt_create( CYGNUM_HAL_INTERRUPT_DCT,
79 &dct_interrupt_handle,
82 cyg_drv_interrupt_attach(dct_interrupt_handle);
84 cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_DCT);
86 dct_write_reg( DCT_ITEN , DCT_ITEN_END_OK | DCT_ITEN_ERROR );
88 dct_write_reg ( DCT_ITEN, 0 );
89 #endif // VIDEO_DCT_INTERRUPT_ENABLE
96 #ifdef HAS_FDCT_COMPUTE
98 int16_t* video_fdct_compute(int16_t* in, int16_t* out, int32_t num_macro_blocks)
101 #if (VIDEO_DCT_INTERRUPT_ENABLE == 0)
102 cyg_uint32 itack = 0;
105 num_macro_blocks *= 6;
107 #if (VIDEO_DCT_USE_INTRAM == 0)
108 // arm_mmu_clean_dcache_range((CYG_ADDRESS)in, num_macro_blocks*MCU_BLOCK_SIZE*2 );
109 // arm_mmu_invalidate_cache_range((CYG_ADDRESS)in, num_macro_blocks*MCU_BLOCK_SIZE*2 );
111 // arm_mmu_clean_dcache_range((CYG_ADDRESS)out, num_macro_blocks*MCU_BLOCK_SIZE*2 );
112 // arm_mmu_invalidate_cache_range((CYG_ADDRESS)out, num_macro_blocks*MCU_BLOCK_SIZE*2 );
114 arm_mmu_flush_dcache();
117 #if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
121 if( dct_in_progress > 0 )
123 RTMON_USTART( VIDEO_VLIB_DCT_WAIT_UEVENT );
125 // Check if we have to wait for a previous run to complete
126 while( dct_read_reg( DCT_STATUS ) == 0 );
128 RTMON_USTOP( VIDEO_VLIB_DCT_WAIT_UEVENT );
131 switch( dct_read_reg( DCT_STATUS ) )
133 case DCT_STATUS_END_OK:
134 // diag_printf("DCT_STATUS_END_OK\n");
135 itack = DCT_ITACK_END_OK;
138 case DCT_STATUS_ERROR:
139 diag_printf("[DCT] DMA access failure\n");
140 itack = DCT_ITACK_ERROR;
149 dct_write_reg( DCT_ITACK, itack ); // Acknowledge previous run
151 #endif // VIDEO_DCT_INTERRUPT_ENABLE
153 ctrl |= ((num_macro_blocks - 1) & 0x3F ) << 1;
154 ctrl |= DCT_CTRLMODE_FDCT;
156 dct_write_reg ( DCT_ORIG_Y_ADDR , arm_mmu_v2p( (cyg_addrword_t)in ) );
157 dct_write_reg ( DCT_ORIG_CU_ADDR, 0 );
158 dct_write_reg ( DCT_ORIG_CV_ADDR, 0 );
160 dct_write_reg ( DCT_DEST_Y_ADDR , arm_mmu_v2p( (cyg_addrword_t)out ) );
161 dct_write_reg ( DCT_DEST_CU_ADDR, 0 );
162 dct_write_reg ( DCT_DEST_CV_ADDR, 0 );
164 dct_write_reg ( DCT_LINEOFFSET, 0 );
166 dct_write_reg ( DCT_CONTROL, ctrl );
168 #if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
169 cyg_drv_dsr_unlock();
171 RTMON_USTART( VIDEO_VLIB_DCT_COMPUTE_UEVENT );
176 return out + MCU_BLOCK_SIZE*num_macro_blocks;
179 #endif // HAS_FDCT_COMPUTE
181 #ifdef HAS_IDCT_COMPUTE
183 int16_t* video_idct_compute(int16_t* in, int16_t* out, int32_t num_macro_blocks)
186 #if (VIDEO_DCT_INTERRUPT_ENABLE == 0)
187 cyg_uint32 itack = 0;
190 #if (VIDEO_DCT_USE_INTRAM == 0)
191 arm_mmu_flush_dcache();
194 num_macro_blocks *= 6;
196 #if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
200 if( dct_in_progress > 0 )
202 // Check if we have to wait for a previous run to complete
203 while( dct_read_reg( DCT_STATUS ) == 0 );
206 switch( dct_read_reg( DCT_STATUS ) )
208 case DCT_STATUS_END_OK:
209 // diag_printf("DCT_STATUS_END_OK\n");
210 itack = DCT_ITACK_END_OK;
213 case DCT_STATUS_ERROR:
214 diag_printf("[DCT] DMA access failure\n");
215 itack = DCT_ITACK_ERROR;
224 dct_write_reg( DCT_ITACK, itack ); // Acknowledge previous run
226 #endif // VIDEO_DCT_INTERRUPT_ENABLE
228 ctrl |= ((num_macro_blocks - 1) & 0x3F ) << 1;
229 ctrl |= DCT_CTRLMODE_IDCT;
231 dct_write_reg ( DCT_ORIG_Y_ADDR , arm_mmu_v2p( (cyg_addrword_t)in ) );
232 dct_write_reg ( DCT_ORIG_CU_ADDR, 0 );
233 dct_write_reg ( DCT_ORIG_CV_ADDR, 0 );
235 dct_write_reg ( DCT_DEST_Y_ADDR , arm_mmu_v2p( (cyg_addrword_t)out ) );
236 dct_write_reg ( DCT_DEST_CU_ADDR, 0 );
237 dct_write_reg ( DCT_DEST_CV_ADDR, 0 );
239 dct_write_reg ( DCT_LINEOFFSET, 0 );
241 dct_write_reg ( DCT_CONTROL, ctrl );
243 #if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
244 cyg_drv_dsr_unlock();
246 RTMON_USTART( VIDEO_VLIB_DCT_COMPUTE_UEVENT );
251 return out + MCU_BLOCK_SIZE*num_macro_blocks;
254 #endif // HAS_IDCT_COMPUTE