📄 drvgop_bloader.c
字号:
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006-2007 MStar Semiconductor, Inc.
// All rights reserved.
//
// Unless otherwise stipulated in writing, any and all information contained
// herein regardless in any format shall remain the sole proprietary of
// MStar Semiconductor Inc. and be kept in strict confidence
// (¨MStar Confidential Information〃) by the recipient.
// Any unauthorized act including without limitation unauthorized disclosure,
// copying, use, reproduction, sale, distribution, modification, disassembling,
// reverse engineering and compiling of the contents of MStar Confidential
// Information is unlawful and strictly prohibited. MStar hereby reserves the
// rights to any and all damages, losses, costs and expenses resulting therefrom.
//
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// @file drvgop_BLoader.c
/// @version Rev.7 #58042
/// @brief Graphics Output Path (Simplified for bootloader)
/// @author MStarSemi Inc.
///
/// GOP (Graphics Output Path) support two types of windows.
/// - Graphic window is used to copy data from its frame buffer for output.
/// The data in the frame buffer is usually rendered by Graphics Engine (GE).
/// - Dump window is used to capture data from Scaler or VOP to DRAM.
///
/// Features:
/// - 1 programmable Dump Window
/// (DWIN: dump image window data to DRAM, full size support)
/// - 4 independent programmable Graphic Window
/// (GWIN: Graphic window data from DRAM, full size support)
/// - GWIN priority: GWIN0 > GWIN1 > GWIN2 > GWIN3,
/// always read higher priority window data from DRAM when GWINs overlap.
/// - 2 GWIN transparent color key , respectively to two data formats (RGB555, PalleteRGB)
/// - GWIN horizontal, vertical duplicate support
/// - GWIN horizontal, vertical auto-scroll mode.
///
///
/// @par Pixel Formats
/// @code
/// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
/// FM0 0 R4 R3 R2 R1 R0 G4 G3 G2 G1 G0 B4 B3 B2 B1 B0
/// FM1 1 X X B1 B0 F/B FG4 FG3 FG2 FG1 FG0 BG4 BG3 BG2 BG1 BG0
///
/// Bit 15: palette mode select 1: palette index mode
/// 0: RGB mode
///
/// {A1, A0} blending format select (ignore when GOP access)
///
/// {b1, B0} 00: BG, FG no blink
/// 01: BG blink , FG no blink
/// 10: FG blink , BG no blink
/// 11: BG, FG blink
/// FM0 is always foreground color
///
/// F/B 1: FG
/// 0: BG
/// @endcode
///////////////////////////////////////////////////////////////////////////////
/******************************************************************************/
/* Header Files */
/* ****************************************************************************/
#define DRV_GOP_C
#include "datatype.h"
#include "hwreg.h"
#include "sysinfo.h"
#include "debug.h"
#include "drvsys.h"
#include "drvgop.h"
#include "drvge.h"
#include "drvscaler.h"
#include "memtype.h"
#include <stdio.h>
#define GOP_GWIN_INIT_DELAY (10)
#define GOP_GWIN_RESET_DELAY (17)
/********************************************************************************/
/* Local */
/* ******************************************************************************/
//#define GOP_DEBUGINFO(x) x;
#define GOP_DEBUGINFO(x)
#define GWIN_OSD_DEFAULT MAX_GWIN_SUPPORT
#define GWIN_SDRAM_NULL 0x30
#define GWIN_SDRAM_PG_UNIT 0x00000010 // 16-byte page-unit for gwin_sdram
#define GOP_REG_WORD_MASK 0xffff
#define GOP_REG_HW_MASK 0xff00
#define GOP_REG_LW_MASK 0x00ff
#define CHECK_WRITTEN_VALUE 0 // readback written register for comparison
#define GOP_PD_OFFSET 52
#define GOP_PD_SHIFT 3
/// GWIN id 0 ~ (MAX_GWIN_SUPPORT - 1)
typedef U8 GWINID;
typedef U8 Gwin_Map;
static Gwin_Map gwinMap[MAX_GWIN_SUPPORT*MAX_GOP_SUPPORT+1];
static Gwin_FB_Attr gwinFB[MAX_GWIN_FB_SUPPORT+1];
static BOOLEAN gop_gwin_frwr, gop_dwin_frwr;
static BOOLEAN Gwin_H_Dup, Gwin_V_Dup;
static U32 goptimeout;
static U32 gopSdramFree = GOP_GWIN_RB_BASE_LEN;
static U8 current_bank;
/******************************************************************************/
///Read 2 bytes data from GOP register
///@param u8addr \b IN register address
///@param *pu16ret \b IN pointer to a 16-bit return data buffer (2 bytes)
/******************************************************************************/
static void GOP_Read16Reg(U8 u8addr, U16* pu16ret)
{
GOP_DEBUGINFO(printf("GOP_Read16Reg[%bx]\r\n", u8addr));
// *pu16ret->u8Num[1] = XBYTE[u8addr + GOP_REG_BASE]; // LSB
// *pu16ret->u8Num[0] = XBYTE[u8addr + GOP_REG_BASE + 1]; // MSB
*pu16ret = XBYTE[u8addr + GOP_REG_BASE] | (XBYTE[u8addr + GOP_REG_BASE + 1] << 8); // LSB
}
/********************************************************************************/
/* Local Function Prototypes */
/********************************************************************************/
//#define GOP_Set_Reg(reg, val) do { XBYTE[reg] = (val); } while (0)
//#define GOP_Get_Reg(reg) XBYTE[reg]
/******************************************************************************/
///Write 2 bytes data to GOP register
///@param u8addr \b IN register address
///@param u16val \b IN 16 bits (2 bytes) value to write
///@param mask \b IN bits not in mask are kept
/******************************************************************************/
static void GOP_Write16Reg(U8 u8addr, U16 u16val, U16 mask)
{
U16 u16tmp;
GOP_DEBUGINFO(printf("GOP_Write16Reg[%bx] = %x\n", u8addr, u16val));
#if 1
if(mask!=0xffff) {
GOP_Read16Reg((U16)u8addr, &u16tmp);
u16tmp &= ~mask;
u16val = u16val | u16tmp;
}
#endif
XBYTE[u8addr + GOP_REG_BASE] = VARBYTE(u16val, 1);
XBYTE[u8addr + GOP_REG_BASE + 1] = VARBYTE(u16val, 0);
#if (CHECK_WRITTEN_VALUE)
{
U8 lo, hi;
// WaitForDataFifoEmpty();
lo = XBYTE[u8addr + GOP_REG_BASE];
hi = XBYTE[u8addr + GOP_REG_BASE + 1];
if (lo != VARBYTE(u16val, 1) || hi != VARBYTE(u16val, 0))
{
printf("RegError! %d addr:%bx %02bx%02bx (read) != %02bx%02bx (written)\r\n",
(int)__LINE__, u8addr, lo, hi, VARBYTE(u16val, 1), VARBYTE(u16val, 0));
}
}
#endif
}
/******************************************************************************/
///Write 4 bytes data to GOP register
///@param u8addr \b IN register address
///@param u32val \b IN 32 bits (4 bytes) value to write
/******************************************************************************/
static void GOP_Write32Reg(U8 u8addr, U32 u32val)
{
GOP_DEBUGINFO(printf("GOP_Write32Reg[%bx] = %lx\n", u8addr, u32val));
XBYTE[u8addr + GOP_REG_BASE] = VARBYTE(u32val, 3); // LSB
XBYTE[u8addr + GOP_REG_BASE + 1] = VARBYTE(u32val, 2); //
#if (CHECK_WRITTEN_VALUE)
{
U8 lo, hi;
// WaitForDataFifoEmpty();
lo = XBYTE[u8addr + GOP_REG_BASE];
hi = XBYTE[u8addr + GOP_REG_BASE + 1];
if (lo != VARBYTE(u32val, 3) || hi != VARBYTE(u32val, 2))
{
printf("RegError! %d addr:%bx %02bx%02bx (read) != %02bx%02bx (written)\r\n",
(int)__LINE__, u8addr, lo, hi, VARBYTE(u32val, 3), VARBYTE(u32val, 2));
}
}
#endif
XBYTE[u8addr + GOP_REG_BASE + 2] = VARBYTE(u32val, 1); //
XBYTE[u8addr + GOP_REG_BASE + 3] = VARBYTE(u32val, 0); // MSB
#if (CHECK_WRITTEN_VALUE)
{
U8 lo, hi;
// WaitForDataFifoEmpty();
lo = XBYTE[u8addr + GOP_REG_BASE + 2];
hi = XBYTE[u8addr + GOP_REG_BASE + 3];
if (lo != VARBYTE(u32val, 1) || hi != VARBYTE(u32val, 0))
{
printf("RegError! %d addr:%bx %02bx%02bx (read) != %02bx%02bx (written)\r\n",
(int)__LINE__, u8addr, lo, hi, VARBYTE(u32val, 1), VARBYTE(u32val, 0));
}
}
#endif
}
/********************************************************************************/
/* Functions */
/********************************************************************************/
/********************************************************************************/
/// Confirm modification of GOP register.
/// Basically MCU will wait to H sync for register update.
/// If timeout, use force write automatically.
/********************************************************************************/
static void GOP_GWIN_UpdateReg()
{
U16 reg_val;
goptimeout = 0;
if(gop_gwin_frwr)
{
GOP_Write16Reg(GOP_BAK_SEL, GOP_VAL_FWR, GOP_REG_HW_MASK);
GOP_Write16Reg(GOP_BAK_SEL, 0x0000, GOP_REG_HW_MASK);
}
else
{
GOP_Write16Reg(GOP_BAK_SEL, GOP_VAL_WR, GOP_REG_HW_MASK);
GOP_Write16Reg(GOP_BAK_SEL, 0x0000, GOP_REG_HW_MASK);
if(current_bank <= 2)
{
do
{
GOP_Read16Reg(GOP_BAK_SEL, ®_val);
goptimeout++;
}
while( (reg_val&(0x1000 ))&&(goptimeout<=GOP_TIMEOUT_CNT) );
}
else
{
printf("Bank incorrect. UpdateReg failed.\r\n");
}
// Perform force write if wr timeout.
if(goptimeout > GOP_TIMEOUT_CNT)
{
printf("Perform fwr if wr timeout!!\r\n");
GOP_Write16Reg(GOP_BAK_SEL, GOP_VAL_FWR, GOP_REG_HW_MASK);
GOP_Write16Reg(GOP_BAK_SEL, 0x0000, GOP_REG_HW_MASK);
}
}
}
/********************************************************************************/
/// Initialize the GOP,
/// Must be called after MDrv_GE_Init()
/********************************************************************************/
void MDrv_GOP_Init()
{
U8 i;
gop_gwin_frwr = TRUE;
gop_dwin_frwr = FALSE;
Gwin_H_Dup = FALSE;
Gwin_V_Dup = FALSE;
current_bank = 0;
// Need switch bank to GWIN0 ??
GOP_Write16Reg(GOP_BAK_SEL, 0x0000, GOP_REG_WORD_MASK);
#if 0 // ECO workaround.
GOP_Set_Reg(GOP_VSRIUSYNC, GOP_Get_Reg(GOP_VSRIUSYNC) | 0x02);
GOP_Set_Reg(GOP_PERFFIX, GOP_Get_Reg(GOP_PERFFIX) | 0x03);
GOP_Set_Reg(GOP_VSYNCSWITCH, GOP_Get_Reg(GOP_VSYNCSWITCH) | 0x01);
GOP_Set_Reg(GOP_BUFCHEAT, GOP_Get_Reg(GOP_BUFCHEAT) | 0x03);
#endif
GOP_Write16Reg(GOP_MIU_RD_TSH, GOP_BUF_MIU_RD_TH_H_WORKING, GOP_REG_WORD_MASK);
GOP_GWIN_UpdateReg();
MDrv_Timer_Delayms(GOP_GWIN_INIT_DELAY);
GOP_Write16Reg(GOP_GWIN_EN, 0x10, GOP_REG_WORD_MASK); // soft reset
GOP_Write16Reg(GOP_GWIN_EN, 0x00, GOP_REG_WORD_MASK); // soft reset
// Need switch bank to DWIN ??
GOP_Write16Reg(GOP_BAK_SEL, 0x0002, GOP_REG_WORD_MASK);
GOP_Write16Reg(GOP_DW_CTL0_EN, 0x32, GOP_REG_WORD_MASK);
GOP_Write16Reg(GOP_BAK_SEL, 0x0000, GOP_REG_WORD_MASK);
#if(PANEL_TYPE_SEL==PNL_DAC_CRT)
#if(CRT_INTERLACE_OUT)
MDrv_GOP_GWIN_EnableProgressive(FALSE);
#endif
#endif
MDrv_GOP_GWIN_EnableProgressive(true);
MDrv_GOP_DstPlane_Set(0, E_GOP_DST_OP); // Set OP as GOP destination (for FPGA)
GOP_Write16Reg(GOP_PDATA_WR, 0x0000, 0x0008); // Enable YUV output
GOP_Write16Reg(GOP_PDATA_WR, ((U16)GOP_PD_SHIFT << 8), 0xff00); // Set GOP shift
GOP_Write16Reg(GOP_PSHIFT, ((U16)0x00FF), 0x00FF); // Set GOP shift
GOP_GWIN_UpdateReg();
// enable blink capability - for ttx usage
GOP_Write16Reg(GOP_BLINK, 0x0098, GOP_REG_WORD_MASK);
//MDrv_GOP_GWIN_SetPalette();
MDrv_GOP_GWIN_Init();
/* Clear non-common fields for better initialization */
i = 0;
while(i<4) {
GOP_Write16Reg(GOP_GWIN_DRAM_HSTR(i), 0, GOP_REG_WORD_MASK);
GOP_Write16Reg(GOP_GWIN_VSTOP_L(i), 0, GOP_REG_WORD_MASK);
GOP_Write16Reg(GOP_GWIN_VSTOP_H(i), 0, GOP_REG_WORD_MASK);
GOP_Write16Reg(GOP_GWIN_HSTOP_L(i), 0, GOP_REG_WORD_MASK);
i++;
}
GOP_Write16Reg(GOP_GWIN_ALPHA01, 0, GOP_REG_WORD_MASK);
GOP_Write16Reg(GOP_GWIN_ALPHA23, 0, GOP_REG_WORD_MASK);
gop_gwin_frwr = FALSE;
}
/********************************************************************************/
/// Enable GWIN for display
/// @param u8win \b IN GWIN id
/// @param bEnable \b IN
/// - # TRUE Show GWIN
/// - # FALSE Hide GWIN
/********************************************************************************/
void MDrv_GOP_GWIN_Enable(U8 u8win, BOOLEAN bEnable)
{
U16 regval;
U8 fbId;
GOP_DEBUGINFO( printf("MDrv_GOP_GWIN_Enable(gId=%bd) == %bx\n",u8win, bEnable));
if (u8win >= MAX_GWIN_SUPPORT )
{
msWarning(ERR_GWIN_ID_OUT_OF_RANGE);
return;
}
fbId = gwinMap[u8win];
if ((fbId == GWIN_ID_INVALID) || (gwinFB[fbId].allocated== FALSE))
{
msWarning(ERR_GWIN_ID_NOT_ALLOCATED);
GOP_DEBUGINFO( printf("MDrv_GOP_GWIN_Enable: gId=%bd not allocated\n",u8win));
return;
}
gwinFB[fbId].enable = bEnable;
GOP_Read16Reg(GOP_GWIN_EN, ®val);
if(bEnable)
{
regval &= ~0x0010; // Clear software reset
regval |= (1 << u8win);
}
else
{
regval &= ~(1 << u8win);
}
#if (PANEL_ATCON || PANEL_DTCON)
regval |= BIT6;
#endif
GOP_Write16Reg(GOP_GWIN_EN, regval, GOP_REG_WORD_MASK);
GOP_GWIN_UpdateReg();
}
/********************************************************************************/
/// Set GWIN display mode
/// @param bEnable \b IN
/// - # TRUE Interlaced (read out the DRAM graphic data by FIELD)
/// - # FALSE Progressive (not care FIELD)
/// @internal please verify the register document and the code
/********************************************************************************/
void MDrv_GOP_GWIN_EnableProgressive(BOOLEAN bEnable)
{
U16 regval;
GOP_Read16Reg(GOP_GWIN_EN, ®val);
if(bEnable)
regval |= 0x100;
else
regval &= ~0x100;
// GOP_Set_Reg(GOP_GWIN_MD_DUP, regval);
GOP_Write16Reg(GOP_GWIN_EN, regval, GOP_REG_WORD_MASK);
GOP_GWIN_UpdateReg();
}
/********************************************************************************/
/// Set transparent color for the GWIN in ARGB8888 format
/// @param clr \b IN transparent color
/// @param mask \b IN mask for trs color
/********************************************************************************/
void MDrv_GOP_GWIN_SetTransClr_8888(U32 clr, U32 mask)
{
U16 regval;
regval = (U16)(clr&0xffff);
GOP_Write16Reg(GOP_TRS_CLR_L, regval, GOP_REG_WORD_MASK);
regval = (U16)((clr>>16&0xff))|(U16)((mask&0xff)<<8) ;
GOP_Write16Reg(GOP_TRS_CLR_H, regval, GOP_REG_WORD_MASK);
regval = (U16)((mask >> 8) & 0xffff) ;
GOP_Write16Reg(GOP_TRS_MASK, regval, GOP_REG_WORD_MASK);
GOP_GWIN_UpdateReg();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -