23#define READ_ONCE(x) (*(const volatile typeof(x) *)(&x))
24#define WRITE_ONCE(x, val) (*(volatile typeof(x) *)(&x) = (val))
48static int (*s_SetDMA_func)(
void *);
49static void *s_SetDMA_arg;
56static u32 s_BitsBuffered;
57static u32 s_LocalBits;
98extern s32 _mpeg_dmac_handler(s32 channel,
void *arg,
void *addr);
100#define RGBA32_BLOCK_SIZE (16 * 16 * 4)
102#define IPU_CMD_BUSY (1ull << 63)
104#define IPU_CTRL_BUSY (1 << 31)
105#define IPU_CTRL_RST (1 << 30)
106#define IPU_CTRL_MP1 (1 << 23)
107#define IPU_CTRL_ECD (1 << 14)
110#define IPU_COMMAND_BCLR 0x00000000
111#define IPU_COMMAND_IDEC 0x10000000
112#define IPU_COMMAND_BDEC 0x20000000
113#define IPU_COMMAND_VDEC 0x30000000
114#define IPU_COMMAND_VDEC_MBAI 0x00000000
115#define IPU_COMMAND_VDEC_MBTYPE 0x04000000
116#define IPU_COMMAND_VDEC_MCODE 0x08000000
117#define IPU_COMMAND_VDEC_DMV 0x0C000000
118#define IPU_COMMAND_FDEC 0x40000000
119#define IPU_COMMAND_SETIQ 0x50000000
120#define IPU_COMMAND_SETVQ 0x60000000
121#define IPU_COMMAND_CSC 0x70000000
122#define IPU_COMMAND_PACK 0x80000000
123#define IPU_COMMAND_SETTH 0x90000000
126void _MPEG_Initialize(
_MPEGContext *mc,
int (*data_cb)(
void *),
void *cb_user,
int *eof_flag)
140 s_SetDMA_func = data_cb;
141 s_SetDMA_arg = cb_user;
145 memset(&sema, 0,
sizeof(sema));
149 s_Sema = CreateSema(&sema);
150 s_CSCID = AddDmacHandler2(3, _mpeg_dmac_handler, 0, &s_CSCParam);
155void _MPEG_Destroy(
void)
157 while (READ_ONCE(s_CSCFlag) != 0)
159 RemoveDmacHandler(3, s_CSCID);
163void _ipu_suspend(
void)
209void _MPEG_Suspend(
void)
211 while (READ_ONCE(s_CSCFlag) != 0)
217void _ipu_resume(
void)
219 if (s_IPUState.d3_qwc != 0) {
224 u32 qw_to_reinsert = (s_IPUState.ipu_bp >> 16 & 3) + (s_IPUState.ipu_bp >> 8 & 0xf);
225 u32 actual_qwc = s_IPUState.d4_qwc + qw_to_reinsert;
226 if (actual_qwc != 0) {
227 *
R_EE_IPU_CMD = IPU_COMMAND_BCLR | (s_IPUState.ipu_bp & 0x7f);
231 *
R_EE_D4_MADR = s_IPUState.d4_madr - (qw_to_reinsert * 16);
237void _MPEG_Resume(
void)
242s32 _mpeg_dmac_handler(s32 channel,
void *arg,
void *addr)
249 if (cp->blocks == 0) {
252 WRITE_ONCE(s_CSCFlag, 0);
256 u32 mbc = cp->blocks;
263 cp->dest += mbc * RGBA32_BLOCK_SIZE;
264 cp->blocks = cp->blocks - mbc;
275int _MPEG_CSCImage(
void *source,
void *dest,
int mbcount)
289 s_CSCParam.dest = (u32)dest + mbc * RGBA32_BLOCK_SIZE;
290 s_CSCParam.blocks = mbcount - mbc;
299 WRITE_ONCE(s_CSCFlag, 1);
305static int _ipu_bits_in_fifo()
312 ifc = (bp_reg >> 8) & 0xf;
313 fp = (bp_reg >> 16) & 0x3;
315 return (ifc << 7) + (fp << 7) - bp;
318static int _ipu_needs_bits()
320 return _ipu_bits_in_fifo() < 32;
323static int _req_data()
326 if (s_SetDMA_func(s_SetDMA_arg) == 0) {
328 s_LocalBits = _MPEG_CODE_SEQ_END;
342 while ((ctrl & IPU_CTRL_ECD) == 0) {
343 if (_ipu_needs_bits()) {
356 if ((ctrl & IPU_CTRL_BUSY) == 0) {
365u32 _ipu_sync_data(
void)
371 while ((ctrl & IPU_CTRL_ECD) == 0) {
372 if (_ipu_needs_bits()) {
374 return _MPEG_CODE_SEQ_END;
381 return _MPEG_CODE_SEQ_END;
385 if ((cmd & IPU_CMD_BUSY) == 0) {
397unsigned int _ipu_get_bits(
unsigned int bits)
402 if (s_BitsBuffered < bits) {
404 s_LocalBits = _ipu_sync_data();
408 s_BitsBuffered = s_BitsBuffered - bits;
409 ret = s_LocalBits >> ((32 - bits) & 0x1f);
410 s_LocalBits = s_LocalBits << (bits & 0x1f);
416unsigned int _MPEG_GetBits(
unsigned int bits)
418 return _ipu_get_bits(bits);
421unsigned int _ipu_show_bits(
unsigned int bits)
423 if (s_BitsBuffered < bits) {
426 s_LocalBits = _ipu_sync_data();
430 return s_LocalBits >> ((32 - bits) & 0x1f);
433unsigned int _MPEG_ShowBits(
unsigned int bits)
435 return _ipu_show_bits(bits);
438void _ipu_align_bits(
void)
447void _MPEG_AlignBits(
void)
452unsigned int _MPEG_NextStartCode(
void)
455 while (_MPEG_ShowBits(24) != 1) {
459 return _MPEG_ShowBits(32);
462void _MPEG_SetDefQM(
int arg0)
473 q = (qword_t *)s_QmIntra;
474 for (i = 0; i < 4; i++) {
479 :
"d"(&q[i]),
"d"(A_EE_IPU_in_FIFO)
487 q = (qword_t *)s_QmNonIntra;
488 for (i = 0; i < 4; i++) {
493 :
"d"(&q[i]),
"d"(A_EE_IPU_in_FIFO)
504void _MPEG_SetQM(
int iqm)
511int _MPEG_GetMBAI(
void)
516 *
R_EE_IPU_CMD = IPU_COMMAND_VDEC | IPU_COMMAND_VDEC_MBAI;
517 ret = _ipu_sync_data() & 0xffff;
543int _MPEG_GetMBType(
void)
546 *
R_EE_IPU_CMD = IPU_COMMAND_VDEC | IPU_COMMAND_VDEC_MBTYPE;
547 u32 ret = _ipu_sync_data();
556int _MPEG_GetMotionCode(
void)
562 *
R_EE_IPU_CMD = IPU_COMMAND_VDEC | IPU_COMMAND_VDEC_MCODE;
563 ret = _ipu_sync_data();
576int _MPEG_GetDMVector(
void)
581 *
R_EE_IPU_CMD = IPU_COMMAND_VDEC | IPU_COMMAND_VDEC_DMV;
582 ret = _ipu_sync_data() & 0xffff;
588void _MPEG_SetIDCP(
void)
590 unsigned int var1 = _MPEG_GetBits(2);
594void _MPEG_SetQSTIVFAS(
void)
596 unsigned int qst = _MPEG_GetBits(1);
597 unsigned int ivf = _MPEG_GetBits(1);
598 unsigned int as = _MPEG_GetBits(1);
602void _MPEG_SetPCT(
unsigned int arg0)
608void _MPEG_BDEC(
int mbi,
int dcr,
int dt,
int qsc,
void *spaddr)
610 *
R_EE_D3_MADR = ((u32)spaddr & ~0xf0000000) | 0x80000000;
614 *
R_EE_IPU_CMD = IPU_COMMAND_BDEC | mbi << 27 | dcr << 26 | dt << 25 | qsc << 16;
617int _MPEG_WaitBDEC(
void)
623 if ((*s_pEOF != 0)) {
657 const u32 mbwidth = width *
sizeof(*mb);
661 if (n_motions <= 0) {
672 q = UNCACHED_SEG(s_DMAPack);
673 for (i = 0; i < n_motions; i++) {
674 DMATAG_REF(q, 0x30, (u32)motions[i].m_pSrc, 0, 0, 0);
676 DMATAG_REF(q, 0x30, (u32)motions[i].m_pSrc + mbwidth, 0, 0, 0);
679 motions[i].m_pSrc = (
unsigned char *)mb;
684 motions[i].MC_Luma = NULL;