📄 drvgop.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.c
/// @version Rev.86 #67800
/// @brief Graphics Output Path
/// @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 "drvuart.h"
#include "drvsys.h"
#include "drvmiu.h"
#include "drvgop.h"
#include "drvge.h"
#include "drvtimer.h"
#include "drvscaler.h"
#include "drvAnalog_inline.h"
#include "drvAnalog_DataType.h"
#include "drvMode.h"
#include "memtype.h"
#include "panel.h"
#include <stdio.h>
#include <string.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 u16GOP_PDOffset
#if 0
// Addy 20070928
#if (PANEL_WIDTH == 480)
#define GOP_PD_SHIFT 1
#else
#define GOP_PD_SHIFT 0
#endif
#define GOP_PD_SHIFT2 0
#endif
// Addy 20071031
#define GOP_PD_SHIFT (4 - ((PANEL_HSTART%4)&0x03))
#define GOP_PD_SHIFT2 (3 - ((PANEL_HSTART%4)&0x03) )
#define GOPD_CLK (0x002D + (CHIP_REG_BASE))
/// 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 U8 Gwin_Current = GWIN_OSD_DEFAULT;
static U8 Gwin_Prev = GWIN_OSD_DEFAULT;
static BOOLEAN gop_gwin_frwr, gop_dwin_frwr;
static BOOLEAN Gwin_H_Dup, Gwin_V_Dup;
static U32 goptimeout;
static U16 u16GOP_PDOffset ;
#define PALETTE_ENTRY_NUM 32
code GOPPALETTE PaletteEntry[PALETTE_ENTRY_NUM] =
{
// R, G, B
{ 0x08, 0x08, 0x08 }, // black 0
{ 0xff, 0x00, 0x00 }, // red 1
{ 0x00, 0xff, 0x00 }, // green 2
{ 0xff, 0xff, 0x00 }, // yellow 3
{ 0x00, 0x00, 0xff }, // blue 4
{ 0xff, 0x00, 0xff }, // magenta 5
{ 0x00, 0xff, 0xff }, // cyan 6
{ 0xff, 0xff, 0xff }, // white 7
{ 0x00, 0x00, 0x00 }, // transparent 8
{ 0x7f, 0x00, 0x00 }, // half red 9
{ 0x00, 0x7f, 0x00 }, // half green 10
{ 0x7f, 0x7f, 0x00 }, // half yellow 11
{ 0x00, 0x00, 0x7f }, // half blue 12
{ 0x7f, 0x00, 0x7f }, // half magenta 13
{ 0x00, 0x7f, 0x7f }, // half cyan 14
{ 0x7f, 0x7f, 0x7f }, // gray 15
{ 0x0f, 0x0f, 0x0f },
{ 0xff, 0x00, 0x00 },
{ 0x00, 0xff, 0x00 },
{ 0xff, 0xff, 0x00 },
{ 0x00, 0x00, 0xff },
{ 0xff, 0x00, 0xff },
{ 0x00, 0xff, 0xff },
{ 0xff, 0xff, 0xff },
{ 0x00, 0x00, 0x00 }, // Transparent 24
{ 0x7f, 0x00, 0x00 },
{ 0x00, 0x7f, 0x00 },
{ 0x7f, 0x7f, 0x00 },
{ 0x00, 0x00, 0x7f },
{ 0x7f, 0x00, 0x7f },
{ 0x00, 0x7f, 0x7f },
{ 0x7f, 0x7f, 0x7f },
};
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)
// Addy 20071031 for paralleltask.c usage
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 u8lo \b IN low 8 bits (1 byte) value to write
///@param u8hi \b IN high 8 bits (1 byte) value to write
/******************************************************************************/
static void GOP_Write16Reg2(U8 u8addr, U8 u8lo, U8 u8hi)
{
// GOP_DEBUGINFO(printf("GOP_Write16Reg2[%bx] = (%bx, %bx)\r\n", u8addr, u8lo, u8hi));
XBYTE[u8addr + GOP_REG_BASE] = u8lo; // LSB
XBYTE[u8addr + GOP_REG_BASE + 1] = u8hi; // MSB
#if (CHECK_WRITTEN_VALUE)
{
U8 lo, hi;
// WaitForDataFifoEmpty();
lo = XBYTE[u8addr + GOP_REG_BASE];
hi = XBYTE[u8addr + GOP_REG_BASE + 1];
if (lo != u8lo || hi != u8hi)
{
printf("RegError! %d addr:%bx %02bx%02bx (read) != %02bx%02bx (written)\r\n",
(int)__LINE__, u8addr, lo, hi, u8lo, u8hi);
}
}
#endif
}
/******************************************************************************/
///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 &= 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
}
/********************************************************************************/
/// Pack several small fragments into a larger area for frame buffer
/// @param fbId \b IN Frame buffer id
/// @param addr \b OUT Buffer address for the fbId
/********************************************************************************/
static void GOP_GWIN_REARRANGE_SDRAM(U8 fbId, U32 *addr)
{
U8 index;
U32 lastAddr, curStartAdr, size2move, moveSize, gapSize, count;
GOP_GWIN_INFO gWin;
GOP_DEBUGINFO(printf("GOP_GWIN_REARRANGE_SDRAM(fbId=%bx, addr=%lx)\r\n",fbId, *addr));
index = gwinMap[GWIN_OSD_DEFAULT]; // gId is the prev valid winId
lastAddr = (GWIN_KEEP_INIT_OSDWIN == 0) ? GOP_GWIN_RB_BASE_ADR : gwinFB[index].addr + gwinFB[index].size;
while (gwinFB[index].next != GWIN_SDRAM_NULL)
{
index = gwinFB[index].next;
curStartAdr = gwinFB[index].addr;
size2move = gwinFB[index].size;
if (curStartAdr > lastAddr)
{
gapSize = curStartAdr - lastAddr;
moveSize = count = 0;
while (moveSize < size2move)
{
count = (moveSize + gapSize > size2move) ? (size2move - moveSize) : gapSize;
#if 0
#if(DRAM_DMATYPE == DRAM_GE_DMA)
MDrv_GE_DMA(curStartAdr + moveSize, lastAddr + moveSize, count, MIU_SDRAM2SDRAM);
#else
MDrv_MIU_W1_DRAM2DRAMCopy(curStartAdr + moveSize, lastAddr + moveSize, count, MIU_SDRAM2SDRAM);
#endif
#else
MDrv_MIU_Copy(curStartAdr + moveSize, lastAddr + moveSize, count, MIU_SDRAM2SDRAM);
#endif
GOP_DEBUGINFO(printf("\tMDrv_GE_DMA(%lx, %lx, %lx)", curStartAdr + moveSize, lastAddr + moveSize, count));
moveSize += count;
}
for (curStartAdr = 0; (U8)curStartAdr < MAX_GWIN_SUPPORT; curStartAdr++)
{
if (gwinMap[(U8)curStartAdr] == index) {
MDrv_GOP_GWIN_GetWinInfo( (U8)curStartAdr, &gWin);
gWin.u32DRAMRBlkStart = lastAddr;
MDrv_GOP_GWIN_SetWinInfo( (U8)curStartAdr, &gWin);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -