⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mae_hal.c

📁 AU1200嵌入式处理器媒体加速引擎(mae)的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:

//#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 + -