📄 sdc.c
字号:
//
// Returns:
// none.
//------------------------------------------------------------------------------
void EnableSDC(void)
{
UINT32 iOldVal, iNewVal, iMask, iBitval;
DWORD dwBytesTransferred;
// Configure IOMUX to request IPU SDC pins
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD1, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD2, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD4, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD5, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD6, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD7, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD8, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD9, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD10, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD11, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD12, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD13, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD14, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD15, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD16, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD17, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_VSYNC3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_HSYNC, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_FPSHIFT, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_DRDY0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_D3_REV, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_CONTRAST, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_D3_SPL, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_D3_CLS, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
// Enable DI and SDC
// Call to IPU Base to turn on SDC_EN in IPU_CONF reg.
// This will also turn on IPU clocks if no other IPU
// modules have already turned them on.
if (!DeviceIoControl(g_hIPUBase, // file handle to the driver
IPU_IOCTL_ENABLE_SDC, // I/O control code
NULL, // in buffer
0, // in buffer size
NULL, // out buffer
0, // out buffer size
&dwBytesTransferred, // number of bytes returned
NULL)) // ignored (=NULL)
{
DEBUGMSG (SDC_ERROR,
(TEXT("%s: Failed to enable SDC!\r\n"), __WFUNCTION__));
}
// Call to IPU Base to turn on DI_EN in IPU_CONF reg.
// This will also turn on IPU clocks if no other IPU
// modules have already turned them on.
if (!DeviceIoControl(g_hIPUBase, // file handle to the driver
IPU_IOCTL_ENABLE_DI, // I/O control code
NULL, // in buffer
0, // in buffer size
NULL, // out buffer
0, // out buffer size
&dwBytesTransferred, // number of bytes returned
NULL)) // ignored (=NULL)
{
DEBUGMSG (SDC_ERROR,
(TEXT("%s: Failed to enable DI!\r\n"), __WFUNCTION__));
}
// Enable DMA SDC Channel 1
// Compute bitmask and shifted bit value for IPU Conf register
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMASDC_0);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMASDC_0, IPU_ENABLE);
// Use interlocked function to Enable DMA SDC Channel 1.
do
{
iOldVal = INREG32(&g_pIPU->IDMAC_CHA_EN);
iNewVal = (iOldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange(&g_pIPU->IDMAC_CHA_EN,
iOldVal, iNewVal) != iOldVal);
// Enable SDC background
// Set BG_EN = 1 (Background is enabled)
INSREG32BF(&g_pIPU->SDC_COM_CONF,
IPU_SDC_COM_CONF_BG_EN, IPU_ENABLE);
// Set DMA SDC Channel 0 as ready
SETREG32(&g_pIPU->IPU_CHA_BUF0_RDY,
CSP_BITFVAL(IPU_DMA_CHA_DMASDC_0, IPU_DMA_CHA_READY));
}
//------------------------------------------------------------------------------
//
// Function: DisableSDC
//
// This function disables SDC
//
// Parameters:
// none
//
// Returns:
// none.
//------------------------------------------------------------------------------
void DisableSDC(void)
{
UINT32 uTempReg1, uTempReg2, uCount = 0;
UINT32 oldVal, newVal, iMask, iBitval;
DWORD dwBytesTransferred;
// Compute bitmask and shifted bit value for SDC_COM_CONF reg.
iMask = CSP_BITFMASK(IPU_SDC_COM_CONF_BG_EN);
iBitval = CSP_BITFVAL(IPU_SDC_COM_CONF_BG_EN, IPU_DISABLE);
// Use interlocked function to Disable SDC FG and BG.
do
{
oldVal = INREG32(&g_pIPU->SDC_COM_CONF);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange(&g_pIPU->SDC_COM_CONF,
oldVal, newVal) != oldVal);
// Can we do this, or perhaps not because a system
// level call is required (WaitForSingleObject)?
// DisplayPlaneWaitForNotBusy(DisplayPlane_0);
// initalize ... for the first time through
uTempReg1 = INREG32(&g_pIPU->IDMAC_CHA_BUSY);
uTempReg2 = INREG32(&g_pIPU->IPU_CHA_BUF0_RDY);
// We can't disable tasks until the active channel
// has completed its current frames. Make sure
// that buffers aren't set as ready (indicating that
// they are yet to start) and that channels are
// not busy (indicating that channels are still running).
while ((uTempReg1 & (1 << GRAPHICS_DMA_CHANNEL)) || (uTempReg2 & (1 << GRAPHICS_DMA_CHANNEL)))
{
if (uCount <= DELAYTIMEOUT)
{
uCount++;
//.. need to check after the sleep delay
uTempReg1 = INREG32(&g_pIPU->IDMAC_CHA_BUSY);
uTempReg2 = INREG32(&g_pIPU->IPU_CHA_BUF0_RDY);
}
else
{
//.. there is something wrong ....break out
return;
}
}
// Compute bitmask and shifted bit value for idmac register
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMASDC_0);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMASDC_0, IPU_DISABLE);
// Use interlocked function to Disable DMA SDC Channel 0.
do
{
oldVal = INREG32(&g_pIPU->IDMAC_CHA_EN);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange(&g_pIPU->IDMAC_CHA_EN,
oldVal, newVal) != oldVal);
// Call to IPU Base to turn off SDC_EN in IPU_CONF reg.
// This will also shut off IPU clocks if no other IPU
// modules are enabled.
if (!DeviceIoControl(g_hIPUBase, // file handle to the driver
IPU_IOCTL_DISABLE_SDC, // I/O control code
NULL, // in buffer
0, // in buffer size
NULL, // out buffer
0, // out buffer size
&dwBytesTransferred, // number of bytes returned
NULL)) // ignored (=NULL)
{
DEBUGMSG (SDC_ERROR,
(TEXT("%s: Failed to disable SDC!\r\n"), __WFUNCTION__));
}
// Call to IPU Base to turn off DI_EN in IPU_CONF reg.
// This will also shut off IPU clocks if no other IPU
// modules are enabled.
if (!DeviceIoControl(g_hIPUBase, // file handle to the driver
IPU_IOCTL_DISABLE_DI, // I/O control code
NULL, // in buffer
0, // in buffer size
NULL, // out buffer
0, // out buffer size
&dwBytesTransferred, // number of bytes returned
NULL)) // ignored (=NULL)
{
DEBUGMSG (SDC_ERROR,
(TEXT("%s: Failed to disable DI!\r\n"), __WFUNCTION__));
}
// Configure IOMUX to release IPU SDC pins
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD0, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD1, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD2, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD3, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD4, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD5, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD6, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD7, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD8, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD9, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD10, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD11, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD12, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD13, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD14, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD15, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD16, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_LD17, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_VSYNC3, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_HSYNC, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_FPSHIFT, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_DRDY0, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_D3_REV, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_CONTRAST, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_D3_SPL, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_D3_CLS, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
}
//------------------------------------------------------------------------------
//
// Function: BackgroundSetSrcBuffer
//
// This function sets the source buffer for the main background display window.
//
// Parameters:
// pAddr
// [in] Address of buffer to set as source for main background
// display window.
//
// Returns:
// none.
//------------------------------------------------------------------------------
void BackgroundSetSrcBuffer(PHYSICAL_ADDRESS *pAddr)
{
SetSrcBuffer(SDC_DMA_CHANNEL, pAddr, eBUF_0);
}
//------------------------------------------------------------------------------
//
// Function: _init_dma
//
// Init the IPU DMA module
//
// Parameters:
// None.
//
// Returns:
// None.
//------------------------------------------------------------------------------
static void _init_dma(int width, int height, int bpp, int stride, BOOL vFlip, const channel)
{
UINT32 bpp_code, npb_code, sat_code, bam_code, ofs[4], wid[4];
UINT32 ima_addr = 0;
UINT32 oldVal, newVal;
//=================================
// Configure First 132 bit word
//=================================
// Software-controlled access to IMA registers
// IMA registers may only be accessed if IMA_ADDR is
// set to 0.
// Set IPU_IMA_ADDR (IPU Internal Memory Access Address)
newVal = CSP_BITFVAL( IPU_IPU_IMA_ADDR_MEM_NU, IPU_IMA_ADDR_MEM_NU_CPM) |
CSP_BITFVAL( IPU_IPU_IMA_ADDR_ROW_NU, (2 * channel))|
CSP_BITFVAL( IPU_IPU_IMA_ADDR_WORD_NU, 0);
while (1)
{
oldVal = INREG32(&g_pIPU->IPU_IMA_ADDR);
if (oldVal == 0)
{
// Try to set IPU_IMA registers.
if (InterlockedTestExchange(&g_pIPU->IPU_IMA_ADDR,
oldVal, newVal) == oldVal)
{
// Successfully set IMA_ADDR.
break;
}
}
// IPU_IMA controlled by another process.
// Surrender CPU and then try again.
Sleep(0);
}
//...0th 32 bit word
// XV [9:0], YV [19:10], XB [31:20]
OUTREG32(&g_pIPU->IPU_IMA_DATA,
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_XV, 0)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_YV, 0)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_XB, 0));
//...1st 32 bit word
// YB [11:0], SCE [12], RESERVED [13], NSB [14], LNPB [20:15], SX [30:21],
// SY~ [31]
// - Set NSB
OUTREG32(&g_pIPU->IPU_IMA_DATA,
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_YB, 0)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SCE, 0)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_NSB, 1)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_LNPB, 0)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SX, 0)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_LOW_SY, 0));
//...2nd 32 bit word
// ~SY [8:0], NS [18:9], SM [28:10] SDX~ [31:29]
OUTREG32(&g_pIPU->IPU_IMA_DATA,
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_HIGH_SY, 0)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_NS, 0)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SM, 0)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_LOW_SDX, 0));
//...3rd 32 bit word
// ~SDX [1:0], SDY [6:2], SDRX [7], SDRY [8], SCRQ [9], RESERVED [11:10]
// - FW [23:12], FH~ [31:24]
// - Set FW & FH
OUTREG32(&g_pIPU->IPU_IMA_DATA,
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_HIGH_SDX, 0)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SDY, 0)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SDRX, 0)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SDRY, 0)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SCRQ, 0)|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_FW, (width - 1))|
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_LOW_FH, (height - 1)));
//...4th 32 bit word
// ~FH [3:0]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -