The CLKVAL field in VIDCON0 register controls the rate of RGB_VCLK signal. Table 32-5 defines the relationship
of RGB_VCLK and CLKVAL. The minimum value of CLKVAL is 1.
RGB_VCLK (Hz) =HCLK/ (CLKVAL+1), where CLKVAL >= 1
Table 32-5 Relation 16BPP Between VCLK and CLKVAL
(TFT, Frequency of Video Clock Source=60MHz)
CLKVAL 60MHz/X VCLK
2 60 MHz/3 20.0 MHz
3 60 MHz/4 15.0 MHz
: : :
63 60 MHz/64 937.5 kHz
of RGB_VCLK and CLKVAL. The minimum value of CLKVAL is 1.
RGB_VCLK (Hz) =HCLK/ (CLKVAL+1), where CLKVAL >= 1
Table 32-5 Relation 16BPP Between VCLK and CLKVAL
(TFT, Frequency of Video Clock Source=60MHz)
CLKVAL 60MHz/X VCLK
2 60 MHz/3 20.0 MHz
3 60 MHz/4 15.0 MHz
: : :
63 60 MHz/64 937.5 kHz
CLKSEL_F
Selects the video clock source.
0 = HCLK
1 = SCLK_FIMD
HCLK is the bus clock, whereas SCLK_FIMD is the special clock
for display controller.
For more information, refer to Chapter, ―02.03 CLOCK
CONTROLLER‖.
FIMD_RATIO [23:20]
DIVFIMD clock divider ratio,
SCLK_FIMD = MOUTFIMD
/ (FIMD_RATIO + 1)
MOUTFIMD 在手册居然不出现了,不知道哪里来的,只是看到代码里面有这么回事。
static BOOL
Disp_get_src_clock
(unsigned int CLKSrc,
unsigned int *pdwVCLKSrc)
{
DWORD dwTimeOut = 0;
volatile DWORD dwReadTemp = 0;
DWORD dwVCLKSrc = 0;
switch(CLKSrc)
{
case CLKSEL_F_HCLK:
dwVCLKSrc = g_pBSPArg->SystemClocks.HCLKDSYS_CLK;
DISP_INF((_T("[DISP:INF] VCLK Source = HCLK (%d Hz)\n\r"), dwVCLKSrc));
break;
case CLKSEL_F_LCDCLK:
Disp_set_syscon_clk_fimd();
// MPLL
#if MPLL_USE
// if we use Dout_MPLL then we can calculate Clock from SysClk Register
dwVCLKSrc = GET_MPLLCLK(g_pCMUCLKReg->PLL_CON.MPLL_CON);
DISP_INF((_T("[DISP:INF] MPLLout = (%d Hz)\n\r"), dwVCLKSrc));
dwVCLKSrc /= (((g_pCMUCLKReg->CLK_DIV.CLK_DIV1 & BW_DIV_FIMD_RATIO<<BP_DIV_FIMD_RATIO)>>BP_DIV_FIMD_RATIO) + 1);
#else
dwVCLKSrc = 54000000; // 54Mhz
#endif
DISP_INF((_T("[DISP:INF] VCLK Source = LCDCLK (%d Hz)\n\r"), dwVCLKSrc));
break;
case CLKSEL_F_EXT27M:
dwVCLKSrc = 27000000; // 27MHz
DISP_INF((_T("[DISP:INF] VCLK Source = EXT27M (%d Hz)\n\r"), dwVCLKSrc));
break;
default:
DISP_ERR((_T("[DISP:ERR] --Disp_get_vclk_direction_divider() : Unknown CLKSrc = %d\n\r"), CLKSrc));
return FALSE;
break;
}
*pdwVCLKSrc = dwVCLKSrc;
return TRUE;
}
static void
Disp_set_syscon_clk_fimd
(void)
{
DWORD dwTimeOut = 0;
volatile DWORD dwReadTemp = 0;
#if MPLL_USE
g_pCMUCLKReg->CLK_SRC.CLK_SRC_MASK0 = \
(g_pCMUCLKReg->CLK_SRC.CLK_SRC_MASK0 & \
~(BW_MUX_FIMD_MASK<<BP_MUX_FIMD_MASK)) | \
(MUX_OUT_OFF<<BP_MUX_FIMD_MASK); //MUX OFF
g_pCMUCLKReg->CLK_SRC.CLK_SRC1 =
(g_pCMUCLKReg->CLK_SRC.CLK_SRC1 & \
~(BW_MUX_FIMD_SEL<<BP_MUX_FIMD_SEL)) | \
(CLK_SCLKMPLL<<BP_MUX_FIMD_SEL);
g_pCMUCLKReg->CLK_DIV.CLK_DIV1 = \
(g_pCMUCLKReg->CLK_DIV.CLK_DIV1 & \
~(BW_DIV_FIMD_RATIO<<BP_DIV_FIMD_RATIO)) |
((MPLL_DIV_VALUE-1)<<BP_DIV_FIMD_RATIO); // MPLL/3
// Divider Status Check
dwTimeOut = 10000;
do
{
dwReadTemp = g_pCMUCLKReg->CLK_DIV_STAT.CLK_DIV_STAT0;
if(dwTimeOut-- == 0)
{
break;
}
}while(dwReadTemp & (DIV_STAT_ON_CHANGING<<BP_DIV_FIMD_STAT));
g_pCMUCLKReg->CLK_SRC.CLK_SRC_MASK0 = \
(g_pCMUCLKReg->CLK_SRC.CLK_SRC_MASK0 & \
~(BW_MUX_FIMD_MASK<<BP_MUX_FIMD_MASK)) |
(MUX_OUT_ON<<BP_MUX_FIMD_MASK); //MUX ON
DISP_INF((_T("[DISP:INF] CLK_SRC_MASK0 = 0x%08x\n\r"), g_pCMUCLKReg->CLK_SRC.CLK_SRC_MASK0));
DISP_INF((_T("[DISP:INF] CLK_SRC1 = 0x%08x\n\r"), g_pCMUCLKReg->CLK_SRC.CLK_SRC1));
DISP_INF((_T("[DISP:INF] CLK_DIV1 = 0x%08x\n\r"), g_pCMUCLKReg->CLK_DIV.CLK_DIV1));
#else
g_pCMUCLKReg->CLK_SRC2 = (g_pCMUCLKReg->CLK_SRC2 & ~BM_LCD_SEL) | CLKSEL_VCLK_54(LCD_SEL);
g_pCMUCLKReg->CLK_DIV3 = (g_pCMUCLKReg->CLK_DIV3 & ~BM_LCD_RATIO) | CLKDIV_LCD_RATIO(LCD_RATIO, 1);
#endif
}