📄 sdc.c
字号:
//------------------------------------------------------------------------------
//
// Copyright (C) 2004, 2006, Freescale Semiconductor, Inc. All Rights Reserved
// THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
// BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
// FREESCALE SEMICONDUCTOR, INC.
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// File: sdc.c
//
// Init IPU for SDC operations
//
//------------------------------------------------------------------------------
#include <windows.h>
#include <Winbase.h>
#include <ceddk.h>
#include "bsp.h"
#include "ipu.h"
#include "sdc.h"
//------------------------------------------------------------------------------
// External Functions
//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
// Defines
#define SDC_DMA_CHANNEL IPU_DMA_CHA_DMASDC_0_LSH // background
#define VF_DMA_CHANNEL IPU_DMA_CHA_DMASDC_1_LSH // foreground
#define GRAPHICS_DMA_CHANNEL IPU_DMA_CHA_DMASDC_1_LSH // foreground
#define FLOW_ARM 0
#define FLOW_ROT_VF 1
#define FLOW_ROT_PP 2
#define FLOW_VF 3
#define FLOW_PP 4
#define FLOW_SNOOP 5
#define FLOW_AUTO_REF 6
#define FLOW_AUTO_REF_SNOOP 7
#define SDC_ERROR DEBUGZONE(0)
#define DELAYTIMEOUT 20000
#define TVOUT_FS453 1
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
// Global Variables
PCSP_IPU_REGS g_pIPU;
UINT32 g_IPUClk;
PANEL_INFO g_PanelArray[numPanel] =
{
// Sharp Definitions
{
"Sharp QVGA Panel", // Name
IPU_PANEL_SHARP_TFT, // type
IPU_PIX_FMT_RGB565, // Pixel Format
240, // width
320, // height
1, // Vertical Sync width
8, // Vertical Start Width
80, // Vertical End Width
1, // Horizontal Sync Width
3, // Horizontal Start Width
10, // Horizontal End Width
{ // Display Interface signal polarities
FALSE, // Data mask enable
TRUE, // Clock Idle enable
FALSE, // Clock Select Enable
FALSE, // Vertical Sync Polarity
FALSE, // Output enable polarity(straight polarity for sharp signals)
TRUE, // Data Pol Inverse polarity.
TRUE, // Clock Pol Inverse polarity.
TRUE, // HSync Pol
}
},
//NEC VGA Panel definitions
{
"NEC VGA Panel", // Name
IPU_PANEL_NEC_TFT, // type
IPU_PIX_FMT_RGB666, // Pixel Format
640, // width
480, // height
1, // Vertical Sync width
0x22, // Vertical Start Width 34
40, // Vertical End Width
1, // Horizontal Sync Width
0x90, // Horizontal Start Width 144
0, // Horizontal End Width
{ //Display Interface signal polarities
FALSE, // Data mask enable
FALSE, // Clock Idle enable
FALSE, // Clock Select Enable
FALSE, // Vertical Sync Polarity
TRUE, // Output enable polarity(inverse polarity for VGA signals)
FALSE, // Data Pol Straight polarity.
FALSE, // Clock Pol Straight polarity.
FALSE, // HSync Pol
}
},
// NTSC TV mode definitions
{
"NTSC", // Name
IPU_TV_NTSC, // type
IPU_PIX_FMT_RGB565, // Pixel Format
640, // width
480, // height
6, // Vertical Sync width
20, // Vertical Start Width 34
20, // Vertical End Width
64, // Horizontal Sync Width
104, // Horizontal Start Width 144
103, // Horizontal End Width
{ //Display Interface signal polarities
FALSE, // Data mask enable
FALSE, // Clock Idle enable
FALSE, // Clock Select Enable
FALSE, // Vertical Sync Polarity
FALSE, // Output enable polarity(inverse polarity for VGA signals)
FALSE, // Data Pol Inverse polarity.
FALSE, // Clock Pol Inverse polarity.
FALSE, // HSync Pol
}
},
// PAL TV mode definitions
{
"PAL", // Name
IPU_TV_PAL, // type
IPU_PIX_FMT_RGB565, // Pixel Format
640, // width
480, // height
6, // Vertical Sync width
24, // Vertical Start Width 34
24, // Vertical End Width
64, // Horizontal Sync Width
180, // Horizontal Start Width 144
180, // Horizontal End Width
{ //Display Interface signal polarities
FALSE, // Data mask enable
FALSE, // Clock Idle enable
FALSE, // Clock Select Enable
FALSE, // Vertical Sync Polarity
FALSE, // Output enable polarity(inverse polarity for VGA signals)
FALSE, // Data Pol Inverse polarity.
FALSE, // Clock Pol Inverse polarity.
FALSE, // HSync Pol
}
},
// New Panel definitions go here
// Put other Panel info here in future expasion
};
//------------------------------------------------------------------------------
// Local Variables
static HANDLE ipu_mutex;
static BOOL need_map = TRUE;
static HANDLE g_hSDCBGIntrEvent = NULL;
static HANDLE g_hSDCFGIntrEvent = NULL;
static HANDLE g_hSDCIntrThread = NULL;
static const UINT32 m_RefreshRate = 60;
static UINT8 g_iSDCFGNextBuffer = 0;
static PANEL_INFO *g_pCurrentPanel;
static UINT32 g_SDCFGBuf_Saved = 0;
//------------------------------------------------------------------------------
// Local Functions
static void _init_dma(int width, int height, int bpp, BOOL vFlip, const channel);
static void SetSrcBuffer(int channel, PHYSICAL_ADDRESS *pAddr, DISP_BUF_TYPE bufNum);
//------------------------------------------------------------------------------
//
// Function: InitializeSDC
//
// This function initializes SDC related bits in IPU common registers, the
// IPU SDC registers and IDMAC registers for SDC operation.
//
// Parameters:
// width
// [in] width of the display
// height
// [in] height of the display
// bpp
// [in] bits per pixel of the display
//
// Returns:
// TRUE if successful.
//------------------------------------------------------------------------------
UINT32 InitializeSDC(PANEL_INFO *currentPanel, int bpp)
{
UINT32 ret = FALSE, temp = 0, m_PixelClock = 0, m_PixelDivider;
PHYSICAL_ADDRESS phyAddr;
IPU_DI_SIGNAL_CFG m_SignalPol; // variable to contain Polling information
m_SignalPol = currentPanel -> SIG_POL;
if (need_map == TRUE)
{
phyAddr.QuadPart = CSP_BASE_REG_PA_IPU;
// Map peripheral physical address to virtual address
g_pIPU = (PCSP_IPU_REGS)MmMapIoSpace(phyAddr, sizeof(CSP_IPU_REGS), FALSE);
// Check if virtual mapping failed
if (g_pIPU == NULL)
{
DEBUGMSG(SDC_ERROR,
(TEXT("%s(): MmMapIoSpace failed!\r\n"), __WFUNCTION__));
return ret;
}
// Turn on clock for IPU
DDKClockSetGatingMode(DDK_CLOCK_GATE_INDEX_IPU, DDK_CLOCK_GATE_MODE_ENABLED_ALL);
need_map = FALSE;
}
// Create event for IPU interrupt for SDC BG EOF
g_hSDCBGIntrEvent = CreateEvent(NULL, FALSE, FALSE, IPU_SDC_BG_INTR_EVENT);
if (g_hSDCBGIntrEvent == NULL)
{
DEBUGMSG(SDC_ERROR,
(TEXT("%s: CreateEvent for IPU Interrupt failed\r\n"), __WFUNCTION__));
return ret;
}
// Create event for IPU interrupt for SDC FG EOF
g_hSDCFGIntrEvent = CreateEvent(NULL, FALSE, FALSE, IPU_SDC_FG_INTR_EVENT);
if (g_hSDCFGIntrEvent == NULL)
{
DEBUGMSG(SDC_ERROR,
(TEXT("%s: CreateEvent for IPU Interrupt failed\r\n"), __WFUNCTION__));
return ret;
}
//----- General configuration
// Set little endian
INSREG32BF(&g_pIPU->IPU_CONF,
IPU_IPU_CONF_PXL_ENDIAN, IPU_LITTLE_ENDIAN);
//----- Display interface configuration
switch(currentPanel -> TYPE)
{
case IPU_PANEL_SHARP_TFT:
//... SDC_COM_CONF
OUTREG32( &g_pIPU->SDC_COM_CONF,
//.. SDC mode
CSP_BITFVAL(IPU_SDC_COM_CONF_SDC_MODE, IPU_SDC_MODE_TFT_COLOR)|
//.. sharp pannel enable
CSP_BITFVAL(IPU_SDC_COM_CONF_SHARP, 0x1)|
//.. dual mode enable
CSP_BITFVAL(IPU_SDC_COM_CONF_DUAL_MODE, 0));
//... SDC_SHARP_CONF_1
OUTREG32( &g_pIPU->SDC_SHARP_CONF_1,
//..cls rise delay
CSP_BITFVAL( IPU_SDC_SHARP_CONF_1_CLS_RISE_DELAY, 0x2)|
//..ps fall delay
CSP_BITFVAL( IPU_SDC_SHARP_CONF_1_PS_FALL_DELAY, 0x1)|
//..rev toggle delay
CSP_BITFVAL( IPU_SDC_SHARP_CONF_1_REV_TOGGLE_DELAY, 0xfd));
//... SDC_SHARP_CONF_2
OUTREG32(&g_pIPU->SDC_SHARP_CONF_2,
//..cls fall delay
CSP_BITFVAL( IPU_SDC_SHARP_CONF_2_CLS_FALL_DELAY, 0xf4)|
//..ps rise delay
CSP_BITFVAL( IPU_SDC_SHARP_CONF_2_PS_RISE_DELAY, 0xf5));
break;
// NEC VGA Driver
case IPU_PANEL_NEC_TFT:
case IPU_TV_NTSC:
case IPU_TV_PAL:
OUTREG32( &g_pIPU->SDC_COM_CONF,
//.. SDC mode
CSP_BITFVAL(IPU_SDC_COM_CONF_SDC_MODE, IPU_SDC_MODE_TFT_COLOR));
break;
default:
DEBUGMSG(SDC_ERROR,
(TEXT("Error configuring IPU SDC. Panel Type is not supported.\r\n Exiting Initialization\r\n")));
return FALSE;
}
switch (currentPanel -> TYPE)
{
case IPU_PANEL_SHARP_TFT:
case IPU_PANEL_NEC_TFT:
//... SDC_HOR_CONF
OUTREG32( &g_pIPU->SDC_HOR_CONF,
//.. display width for tearing and Vsync calculation
CSP_BITFVAL(IPU_SDC_HOR_CONF_SCREEN_WIDTH, (UINT32) (currentPanel -> WIDTH + currentPanel -> HSTARTWIDTH + currentPanel -> HENDWIDTH) ) |
//.. horizontal synchronization pulse
CSP_BITFVAL(IPU_SDC_HOR_CONF_H_SYNC_WIDTH, currentPanel -> HSYNCWIDTH - 1));
//... SDC_VER_CONF
OUTREG32( &g_pIPU->SDC_VER_CONF,
//..line/pixel resolution
CSP_BITFVAL(IPU_SDC_VER_CONF_V_SYNC_WIDTH_L, 0x1)|
//..display height for tearing and Vsync calculation
CSP_BITFVAL(IPU_SDC_VER_CONF_SCREEN_HEIGHT, (UINT32) (currentPanel -> HEIGHT + currentPanel -> VSTARTWIDTH + currentPanel -> VENDWIDTH) ) |
//..vsync size
CSP_BITFVAL(IPU_SDC_VER_CONF_V_SYNC_WIDTH, currentPanel -> VSYNCWIDTH));
break;
case IPU_TV_NTSC:
case IPU_TV_PAL:
//... SDC_HOR_CONF
OUTREG32( &g_pIPU->SDC_HOR_CONF,
//.. display width for tearing and Vsync calculation
CSP_BITFVAL(IPU_SDC_HOR_CONF_SCREEN_WIDTH, (UINT32) (currentPanel -> WIDTH + currentPanel -> HSTARTWIDTH + currentPanel -> HENDWIDTH - 1) ) |
//.. horizontal synchronization pulse
CSP_BITFVAL(IPU_SDC_HOR_CONF_H_SYNC_WIDTH, currentPanel -> HSYNCWIDTH - 1));
//... SDC_VER_CONF
OUTREG32( &g_pIPU->SDC_VER_CONF,
//..line/pixel resolution
CSP_BITFVAL(IPU_SDC_VER_CONF_V_SYNC_WIDTH_L, 0x1)|
//..display height for tearing and Vsync calculation
CSP_BITFVAL(IPU_SDC_VER_CONF_SCREEN_HEIGHT, (UINT32) (currentPanel -> HEIGHT + currentPanel -> VSTARTWIDTH + currentPanel -> VENDWIDTH - 1) ) |
//..vsync size
CSP_BITFVAL(IPU_SDC_VER_CONF_V_SYNC_WIDTH, currentPanel -> VSYNCWIDTH - 1));
break;
}
temp = INREG32(&g_pIPU->DI_DISP_IF_CONF) & 0x78FFFFFF;
//... DI_DISP_IF_CONF
OUTREG32(&g_pIPU->DI_DISP_IF_CONF,
//..data mask
CSP_BITFVAL( IPU_DI_DISP_IF_CONF_DISP3_DATAMASK, m_SignalPol.DATAMASK_EN )|
// select interface display clock
CSP_BITFVAL( IPU_DI_DISP_IF_CONF_DISP3_CLK_SEL, m_SignalPol.CLKSEL_EN)|
// display clock idle enable
CSP_BITFVAL( IPU_DI_DISP_IF_CONF_DISP3_CLK_IDLE, m_SignalPol.CLKIDLE_EN) |
// Old value
temp);
temp = INREG32(&g_pIPU->DI_DISP_SIG_POL) & 0xE0FFFFFF;
//... DI_DISP_SIG_POL
OUTREG32(&g_pIPU->DI_DISP_SIG_POL,
//..1: inverse data polarity
CSP_BITFVAL( IPU_DI_DISP_SIG_POL_D3_DATA_POL, m_SignalPol.DATA_POL)|
//..display interface clock polarity
CSP_BITFVAL( IPU_DI_DISP_SIG_POL_D3_CLK_POL, m_SignalPol.CLK_POL)|
//..1: active high horizontal signal polarity
CSP_BITFVAL( IPU_DI_DISP_SIG_POL_D3_HSYNC_POL, m_SignalPol.HSYNC_POL)|
//..1: active high vertical signal polarity
CSP_BITFVAL( IPU_DI_DISP_SIG_POL_D3_VSYNC_POL, m_SignalPol.VSYNC_POL)|
// output enable polarity
CSP_BITFVAL( IPU_DI_DISP_SIG_POL_D3_DRDY_SHARP_POL, m_SignalPol.ENABLE_POL) |
// old value
temp);
// DI_CLK = HSP_CLK * HSP_CLOCK_PER
// ==> HSP_CLOCK_PER = 1
// these are 7 bit fields iiiffff
// where i = integer part and f = fractional part of the value
OUTREG32(&g_pIPU->DI_HSP_CLK_PER,
CSP_BITFVAL( IPU_DI_HSP_CLK_PER_HSP_CLK_PERIOD_1, 1 << 4) |
CSP_BITFVAL( IPU_DI_HSP_CLK_PER_HSP_CLK_PERIOD_2, 1 << 4));
// DI_DISP3_TIME_CONF = DI_CLK / DISP3_IF_CLK_PER_WR = 133 MHz / 20 = 6.65MHz
m_PixelClock = (currentPanel -> WIDTH + currentPanel -> HSTARTWIDTH + currentPanel -> HSYNCWIDTH + currentPanel -> HENDWIDTH) * \
(currentPanel -> HEIGHT + currentPanel -> VSTARTWIDTH + currentPanel -> VSYNCWIDTH + currentPanel -> VENDWIDTH) * 60;
DDKClockGetFreq(DDK_CLOCK_SIGNAL_IPU, &g_IPUClk);
m_PixelDivider = (g_IPUClk << 4) / m_PixelClock; // g_IPUClk is 0x3F6B5A0
if (m_PixelDivider < 0x40) // Divider less than 4
{
DEBUGMSG(SDC_ERROR,
(TEXT("InitPanel() - Pixel clock divider less than 1\r\n")));
m_PixelDivider = 0x40;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -