📄 mae_hal.c
字号:
//#include "mae-driver.h"
#include "au1200_lcd.h"
#include "au1200.h"
#include "mae_fe.h"
#include "mae_hal.h"
#include "queue.h"
#define MAE_GLOBAL
#include "mae_global.h"
#include <windows.h>
static UINT32 OM_STEADY_STATE=5;
uint32 g_StreamType;
int mae_exists(void)
{
unsigned long val=0;
val = au_readl(MAEFE_MOCOMP0);
//DPRINTF(MSG_INIT, (TEXT("mae_exists MAEFE_MOCOMP0= %x MAEFE_MOCOMP0_DEFAULT=%x\n"), val, MAEFE_MOCOMP0_DEFAULT));
if (val != MAEFE_MOCOMP0_DEFAULT) {
return 0;
}
val = au_readl(MAEFE_MOCOMP1);
//DPRINTF(MSG_INIT, (TEXT("mae_exists MAEFE_MOCOMP1= %x MAEFE_MOCOMP1_DEFAULT=%x\n"), val, MAEFE_MOCOMP1_DEFAULT));
if (val != MAEFE_MOCOMP1_DEFAULT) {
return 0;
}
return TRUE;
}
#if 0
void au_writel(u32 val, int reg)
{
*(volatile u32 *)(reg) = val;
}
u32 au_readl(unsigned long port)
{
return (*(volatile u32 *)port);
}
#endif
void print_registers()
{
// au_readl(MAEBE_INTSTAT);
DPRINTF(MSG_INFO, (TEXT("fe_status %x be_status %x \n"),au_readl(MAEFE_INTSTAT),au_readl(MAEBE_INTSTAT)));
DPRINTF(MSG_INFO, (TEXT("LCD_INTSTATUS %x \n"),au_readl(LCD_INTSTATUS)));
//DPRINTF(MSG_INFO, (TEXT("IC0_CFG0SET %x, IC0_CFG1CLR %x, IC0_CFG2SET %x \n"),au_readl(IC0_CFG0SET),au_readl(IC0_CFG1CLR),au_readl(IC0_CFG2SET)));
//DPRINTF(MSG_INFO, (TEXT("IC0_MASKSET %x \n"),au_readl(IC0_MASKSET)));
DPRINTF(MSG_INFO, (TEXT("MAEFE_INTENABLE %x ,MAEBE_INTENABLE %x, LCD_INTENABLE %x \n"),au_readl(MAEFE_INTENABLE),au_readl(MAEBE_INTENABLE),au_readl(LCD_INTENABLE)));
}
void setup_interrupts(void)
{
// clear the interrupt status bits to prevent spurious ones at init
// MAE BOTH interrupt is a simple AND of FE and BE, it cannot be cleared
// these are peripheral bits, not controller bits
au_writel(MAEFE_INTSTAT_DONE, MAEFE_INTSTAT);
au_writel(MAEBE_INTSTAT_DONE, MAEBE_INTSTAT);
au_writel(LCD_INTSTATUS_SS, LCD_INTSTATUS);
// configure the interrupt controller
// FE gives a High Level intr
au_writel((1<<FE_INTR_CTRL_NUMBER), IC0_CFG0SET);
au_writel((1<<FE_INTR_CTRL_NUMBER), IC0_CFG1CLR);
au_writel((1<<FE_INTR_CTRL_NUMBER), IC0_CFG2SET);
// BE gives a High Level intr
au_writel((1<<BE_INTR_CTRL_NUMBER), IC0_CFG0SET);
au_writel((1<<BE_INTR_CTRL_NUMBER), IC0_CFG1CLR);
au_writel((1<<BE_INTR_CTRL_NUMBER), IC0_CFG2SET);
// FEBE gives a High Level intr
au_writel((1<<FEBE_INTR_CTRL_NUMBER), IC0_CFG0SET);
au_writel((1<<FEBE_INTR_CTRL_NUMBER), IC0_CFG1CLR);
au_writel((1<<FEBE_INTR_CTRL_NUMBER), IC0_CFG2SET);
// LCD Vsync-start gives a High Level intr
au_writel((1<<AU1200_LCD_INT), IC0_CFG0SET);
au_writel((1<<AU1200_LCD_INT), IC0_CFG1CLR);
au_writel((1<<AU1200_LCD_INT), IC0_CFG2SET);
// enable the intr controller
au_writel((1<<FE_INTR_CTRL_NUMBER), IC0_MASKSET);
au_writel((1<<BE_INTR_CTRL_NUMBER), IC0_MASKSET);
au_writel((1<<FEBE_INTR_CTRL_NUMBER), IC0_MASKSET);
au_writel((1<<AU1200_LCD_INT), IC0_MASKSET);
// now enable the peripheral interrupt bits
// again, the MAE BOTH intr is not configurable, it is
// a simple AND of FE and BE.
au_writel(MAEFE_INTENABLE_EN, MAEFE_INTENABLE);
au_writel(MAEBE_INTENABLE_EN, MAEBE_INTENABLE);
au_writel(LCD_INTSTATUS_SS, LCD_INTENABLE);
DPRINTF(MSG_INFO, (TEXT("setup_interrupts: printing registers \n")));
print_registers();
}
void teardown_interrupts(void)
{
unsigned int mask;
mask = mask_interrupts((1<<AU1200_MAE_BOTH_INT)
| (1<<AU1200_MAE_FE_INT)
| (1<<AU1200_MAE_BE_INT)
| (1 << AU1200_LCD_INT) );
// clear the intr controller
au_writel((1<<FE_INTR_CTRL_NUMBER)
| (1<<BE_INTR_CTRL_NUMBER)
| (1<<FEBE_INTR_CTRL_NUMBER), IC0_MASKCLR);
au_writel((1<<AU1200_LCD_INT), IC0_MASKCLR);
// clear the interrupt status bits to prevent spurious ones at init
// MAE BOTH interrupt is a simple AND of FE and BE, it cannot be cleared
// these are peripheral bits, not controller bits
au_writel(MAEFE_INTSTAT_DONE, MAEFE_INTSTAT);
au_writel(MAEBE_INTSTAT_DONE, MAEBE_INTSTAT);
au_writel(LCD_INTSTATUS_SS, LCD_INTSTATUS);
}
// this routine assumes that MAE is not currently running
unsigned char prime_fe_hw(void)
{
UINT32 fe_armed = 0;
UINT32 be_armed = 0;
DPRINTF(MSG_FE, (TEXT("prime_fe_hw() - state 0x%x\n"),pmms->state));
// this function should only be run when MAE is idle/empty or when the
// front end is filling the back end buffers (and the be is not enabled yet)
if ((!pmms->state) || (pmms->state & MAE_FREEZE))
{
my_fe_armed=fe_armed = run_fe_hw();
#ifdef DUMP_FE
DPRINTF(MSG_TIME, (TEXT("@prime@\n")));
dump_fe();
#endif
if (fe_armed && (pmms->state & ENABLE_BE))
my_be_armed=be_armed = run_be_hw();
kickstart_hw(fe_armed, be_armed);
return TRUE;
}
return FALSE;
}
void update_operating_mode(PMAEQ_T el)
{
// if the pipeline start-up process has been completed
if (pmms->operating_mode_status >= OM_STEADY_STATE)
return;
// update one tick on the pipeline propogation
pmms->operating_mode_status++;
if (pmms->operating_mode_status == pmms->pipeline_be_delay)
el->state_change |= (ENABLE_BE | ENABLE_LCD);
if (pmms->operating_mode_status == pmms->pipeline_discard_delay)
el->state_change |= ENABLE_DISCARD;
}
// This function (prime_fe_hw_async) gets called only when the MAE Wait Q is empty
unsigned char prime_fe_hw_async(PMAEQ_T el)
{
UINT32 fe_armed = 0;
UINT32 be_armed = 0;
DPRINTF(MSG_FUNCTION, (TEXT("prime_fe_hw_async() - state 0x%x\n"),pmms->state));
update_operating_mode(el);
if ((!pmms->state) || (pmms->state & MAE_FREEZE))
{
my_fe_armed = fe_armed = run_fe_hw();
#ifdef DUMP_FE
DPRINTF(MSG_TIME, (TEXT("@prime async@\n")));
dump_fe();
#endif
if (fe_armed && (pmms->state & ENABLE_BE))
my_be_armed = be_armed = run_be_hw();
DPRINTF(MSG_FE, (TEXT("prime_fe_hw_async- kickstart_hw: - State 0x%x fe_armed %d be_armed %d\n"),pmms->state, fe_armed, be_armed));
// printk("Prime_fe_hw - kickstart_hw: - State %x fe_armed %d be_armed %d\n", pmms->state, fe_armed, be_armed);
kickstart_hw(fe_armed, be_armed);
return TRUE;
}
unmask_interrupts(gbl_mask | (1 << AU1200_LCD_INT));
return FALSE;
}
// This function (prime_be_hw_async) gets called only when the MAE Wait Q is empty
unsigned char prime_be_hw_async(PMAEQ_T el)
{
UINT32 fe_armed = 0;
UINT32 be_armed = 0;
DPRINTF(MSG_BE, (TEXT("prime_be_hw_async() - state 0x%x\n"),pmms->state));
update_operating_mode(el);
if ((!pmms->state) || (pmms->state & MAE_FREEZE))
{
be_armed = run_be_hw();
DPRINTF(MSG_BE, (TEXT("prime_be_hw_async- kickstart_hw: - State 0x%x fe_armed %d be_armed %d\n"),pmms->state, fe_armed, be_armed));
// printk("Prime_be_hw - kickstart_hw: - State %x fe_armed %d be_armed %d\n", pmms->state, fe_armed, be_armed);
kickstart_hw(fe_armed, be_armed);
return TRUE;
}
//printk("could not prime be hw %d, %d\n", pmms->state, MAE_FREEZE);
DPRINTF(MSG_BE, (TEXT("could not prime be hw pmms->state 0x%x, MAE_FREEZE %x\n"),pmms->state, MAE_FREEZE));
unmask_interrupts(gbl_mask | (1 << AU1200_LCD_INT));
return FALSE;
}
UINT32 submit_besw(void)
{
UINT32 status = HEALTH_OK;
PMAEQ_T el;
UINT32 mask;
EnterCS(g_CriticalSection);
DPRINTF(MSG_FUNCTION, (TEXT("submit_besw: Entry \n") ));
// mask interrupts while we touch the MAE memory area
mask = mask_interrupts(gbl_mask | (1 << AU1200_LCD_INT));
gblBEOnly = 1;
// pull from the sw list
DLCL_POP(MAEQ_T, &pmms->sw_proc, el);
if (el)
{
// trim the memory usage to what was submitted
if (el->desc_size > DEFAULT_BUFSIZE)
{
// overused memory! this should not happen.
status = HEALTH_SUBMIT_ERROR;
//printk("submit_besw: We are consuming more buffer memory than allocated!!!\n");
DPRINTF(MSG_BE, (TEXT("submit_besw: We are consuming more buffer memory than allocated!! \n")));
} else
{
el->y = gblYUVBuffer;
el->u = (PUINT32)((UINT32)el->y + (el->encoded_picture_height*el->encoded_picture_linesize));
el->v = (PUINT32)((UINT32)el->u + (el->encoded_picture_height*el->encoded_picture_linesize)/4);
el->pyuvq = gblYUVq;
gblYUVq = NULL;
// put it on the BE processing list
DLCL_APPEND(MAEQ_T, &pmms->be_proc, el);
status = HEALTH_OK;
}
} else
{
//printk("submit_besw: Invalid MAEQ entry - we should never get here!!!\n");
DPRINTF(MSG_BE, (TEXT("submit_besw: Invalid MAEQ entry - we should never get here!!!!! \n")));
status = HEALTH_SUBMIT_ERROR;
unmask_interrupts(mask);
LeaveCS(g_CriticalSection);
return status;
}
// If the MAE wait queue is empty, we need to kickstart the hardware
// Otherwise the interrupt handler should automatically submit the next frame
if(!(pmms->state & MAE_RUNNING))
{
prime_be_hw_async(el);
unmask_interrupts(mask);
} else
{
el->update_mode_flag = 1;
unmask_interrupts(mask);
}
DPRINTF(MSG_FUNCTION, (TEXT("submit_besw: Exit \n") ));
LeaveCS(g_CriticalSection);
return status;
}
// KK - rev2
void compute_reg_values(PMAEQ_T pmaeq, UINT32 ulInterlaced, UINT32 bottom_field)
{
UINT32 val, regmask = 0;
reg_info *preg_values2;
UINT32 width, height, y_size, uv_size;
UINT32 offset;
UINT32 val2;
PYUVQ_T b_pyuvq = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -