⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setcrtctiming.c

📁 X-scale 27x 平台
💻 C
字号:
//
// Copyright (c) Chrontel Inc.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Chrontel end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:  
  SetCrtcTiming.c

Abstract:  
   set up LCD register for CRTC timing.

Revision:
   12/01/02 Roger Yu, Create file.  
     

Notes: 
--*/

#include "chrontel.h"

//extern REG_MAP  Xsl_MapReg[REGCAT_SIZE];
#define LCD_PCD_MASK    0x000000FF

//
#define CCCR_L_MASK     0x0000000F
const static unsigned freqL[]={ 99533, 117965, 132710, 147456, 165888 };

// return -1 if clock unable to set.
ULONG FindBestClock(ULONG clk, int isDPCmode, unsigned *ppcd, unsigned *lval)
{
	unsigned i;
	unsigned j;
    volatile PCLKMAN_REGS clkman;
	ULONG pcd=0;

    clkman = (volatile PCLKMAN_REGS)Xsl_MapReg[CLKREG].mapaddr;
    j = clkman->cccr & CCCR_L_MASK;

	*lval = j;   // we don't touch lval;

	j = freqL[ j-1];   // j is the LCLK value

	clk+=clk;    // 2*clk*(pcd+1)
    i =clk;
	while (i<j) {
		i+=clk;
		pcd++;
	}
	if ((pcd>0) && ((j+clk-i)<(i-j))) pcd--;

	if ((pcd==0) && (isDPCmode)) return -1;   // can't set PCLK, DPC need pcd>=1

	if (pcd>255) pcd=255;    // pcd is 0~255

	if (ppcd!=NULL) *ppcd = pcd;
    
    i = ((j<<10)/(pcd+1)) >>11;    // PCLK=LCLK/2/(pcd+1)
	return i;
}


int SetCrtcTiming( PDISPTIMING dt)
{
   volatile SA2lcdregs* lcd;
   unsigned pcd =0;
   unsigned lval=1;
   unsigned vaval = 0;
   unsigned dt_clk, dt_l;

   volatile PCLKMAN_REGS clkman;

   if (dt->dwSize != sizeof(DISPTIMING)) return -1;
	   
   lcd =(volatile SA2lcdregs*)Xsl_MapReg[LCDREG].mapaddr;
   clkman = (volatile PCLKMAN_REGS)Xsl_MapReg[CLKREG].mapaddr;
		// set the CCCR register L field
   lval = CCCR_L_MASK & clkman->cccr;

   // the msb4 is for required L value
   dt_l = dt->dwDotClock >> 28;
   dt_clk = dt->dwDotClock & 0x0FFFFFFF;

   if (-1==FindBestClock(dt_clk, dt->flFlags.bClockDouble, &pcd, &lval)) return -1;

   if (dt->flFlags.bClockDouble) pcd |= LCD_DPC;
//   lcd->LCCR3 = (lcd->LCCR3 & ~(LCD_DPC | LCD_PCD_MASK)) | pcd;

   lcd->LCCR1 = LCD_PPL(dt->dwHActive-1) + 
	            LCD_HSW(dt->dwHSyncWidth -1) +
				LCD_BLW(dt->dwHFrontPorch -1) +
				LCD_ELW(dt->dwHBackPorch -1);
   vaval = dt->dwVActive;
   if (dt->flFlags.bLineDouble) vaval <<=1;  // double-lines
   lcd->LCCR2 = LCD_LPP(vaval-1) + 
	            LCD_VSW(dt->dwVSyncWidth -1) +
				LCD_BFW(dt->dwVFrontPorch) +
				LCD_EFW(dt->dwVBackPorch);

   if (dt->flFlags.bHSyncPolarity) pcd |= LCD_HSP;
   if (dt->flFlags.bVSyncPolarity) pcd |= LCD_VSP;
   if (dt->flFlags.bBlankPolarity) pcd |= LCD_OEP;

   lcd->LCCR3 &= ~(LCD_HSP | LCD_VSP | LCD_OEP | LCD_DPC | LCD_PCD_MASK);
   lcd->LCCR3 |= pcd;

   return 0;
   

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -