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

📄 xllp_lcd.c

📁 Intel PXA270底层设备驱动代码
💻 C
📖 第 1 页 / 共 4 页
字号:
void LCDClearStatusReg(P_XLLP_LCD_T pXllpLCD)
{
	volatile LCDRegs *p_LCDRegs;
	p_LCDRegs = (LCDRegs *) pXllpLCD->LCDC;

	// Clear the status registers by writing 1's to each bit.
	p_LCDRegs->LCSR0 =	( LCD_LDD | LCD_SOF0| LCD_BER | LCD_ABC	| LCD_IU0	|
						  LCD_IU1 |	LCD_OU  | LCD_QD  | LCD_EOF0| LCD_BS0	| 
						  LCD_SINT|	LCD_RD_ST | LCD_CMD_INTR );

	p_LCDRegs->LCSR1 =	( LCD_SOF1|	LCD_SOF2| LCD_SOF3| LCD_SOF4| LCD_SOF5	| LCD_SOF6	|
						  LCD_EOF1| LCD_EOF2| LCD_EOF3| LCD_EOF4| LCD_EOF5	| LCD_EOF6	|
						  LCD_BS1 | LCD_BS2	| LCD_BS3 |	LCD_BS4 | LCD_BS5	| LCD_BS6	|
									LCD_IU2 | LCD_IU3 | LCD_IU4 | LCD_IU5	| LCD_IU6 );

}

void LCDSetupGPIOs(P_XLLP_LCD_T pXllpLCD)
{
    volatile unsigned int APB_Temp;
	volatile XLLP_GPIO_T *p_GPIORegs;

	p_GPIORegs = (XLLP_GPIO_T *) pXllpLCD->GPIO;

//	XllpLock(XLLP_RESOURCE_GPDR0);
	if (pXllpLCD->DisplayType != LS022Q8DD06)
	{
		p_GPIORegs->GPDR0 = (p_GPIORegs->GPDR0 & ~XLLP_GPIO_BIT_L_VSYNC) | (XLLP_GPIO_BIT_PWM_OUT0 | XLLP_GPIO_BIT_L_CS);
	}
//	XllpUnlock(XLLP_RESOURCE_GPDR0);

//	XllpLock(XLLP_RESOURCE_GPDR1);
	p_GPIORegs->GPDR1 |= ( XLLP_GPIO_BIT_L_DD0 | XLLP_GPIO_BIT_L_DD1 | XLLP_GPIO_BIT_L_DD2 | XLLP_GPIO_BIT_L_DD3 | XLLP_GPIO_BIT_L_DD4 | XLLP_GPIO_BIT_L_DD5);

	// Set GPIO 38 and 40 as outputs
	#if defined XLLP_GPIO_BIT_SSPTXD3 && XLLP_GPIO_BIT_SSPCLK3
		if (pXllpLCD->DisplayType == LS022Q8DD06)
		{
			p_GPIORegs->GPDR1 |= (XLLP_GPIO_BIT_SSPTXD3 | XLLP_GPIO_BIT_SSPCLK3);
		}
	#endif
//	XllpUnlock(XLLP_RESOURCE_GPDR1);

//	XllpLock(XLLP_RESOURCE_GPDR2);
	if (pXllpLCD->DisplayType != LS022Q8DD06)
	{
		p_GPIORegs->GPDR2 |= (	XLLP_GPIO_BIT_L_DD6 | XLLP_GPIO_BIT_L_DD7 | XLLP_GPIO_BIT_L_DD8 | XLLP_GPIO_BIT_L_DD9 | XLLP_GPIO_BIT_L_DD10 | 
							XLLP_GPIO_BIT_L_DD11 | XLLP_GPIO_BIT_L_DD12 | XLLP_GPIO_BIT_L_DD13 | XLLP_GPIO_BIT_L_DD14 | XLLP_GPIO_BIT_L_DD15 |
							XLLP_GPIO_BIT_L_FCLK | XLLP_GPIO_BIT_L_LCLK | XLLP_GPIO_BIT_L_PCLK | XLLP_GPIO_BIT_L_BIAS | XLLP_GPIO_BIT_L_DD16 | 
							XLLP_GPIO_BIT_L_DD17);
	} else 
	{
		p_GPIORegs->GPDR2 |= (	XLLP_GPIO_BIT_L_DD6 | XLLP_GPIO_BIT_L_DD7 | XLLP_GPIO_BIT_L_DD8 | XLLP_GPIO_BIT_L_DD9 | XLLP_GPIO_BIT_L_DD10 | 
							XLLP_GPIO_BIT_L_DD11 | XLLP_GPIO_BIT_L_DD12 | XLLP_GPIO_BIT_L_DD13 | XLLP_GPIO_BIT_L_DD14 | XLLP_GPIO_BIT_L_DD15 |
							XLLP_GPIO_BIT_L_FCLK | XLLP_GPIO_BIT_L_LCLK | XLLP_GPIO_BIT_L_PCLK | XLLP_GPIO_BIT_L_BIAS );

		#if defined XLLP_GPIO_BIT_SSPRXD3
			// Set GPIO 89 as input		
			p_GPIORegs->GPDR2 &= ~(XLLP_GPIO_BIT_SSPRXD3);
		#endif
	}
//	XllpUnlock(XLLP_RESOURCE_GPDR2);

	if (pXllpLCD->DisplayType != LS022Q8DD06)
	{
		// Program the GAFR0_L to select alternate function 1 for GPIO 14.
//		XllpLock(XLLP_RESOURCE_GAFR0_L);
		p_GPIORegs->GAFR0_L = (p_GPIORegs->GAFR0_L & ~XLLP_GPIO_AF_BIT_L_VSYNC_MASK) | (XLLP_GPIO_AF_BIT_L_VSYNC);
//		XllpUnlock(XLLP_RESOURCE_GAFR0_L);

		// Program the GAFR0_U to select alternate function 2 for GPIO 19.
//		XllpLock(XLLP_RESOURCE_GAFR0_U);
		p_GPIORegs->GAFR0_U = (p_GPIORegs->GAFR0_U & ~XLLP_GPIO_AF_BIT_L_CS_MASK) | (XLLP_GPIO_AF_BIT_L_CS);
//		XllpUnlock(XLLP_RESOURCE_GAFR0_U);
	}

	if (pXllpLCD->DisplayType == LS022Q8DD06)
	{
		#if defined XLLP_GPIO_AF_BIT_SSPTXD3_MASK && XLLP_GPIO_AF_BIT_SSPCLK3_MASK && XLLP_GPIO_AF_BIT_SSPTXD3 && XLLP_GPIO_AF_BIT_SSPCLK3
			// Program the GAFR1_L to select alternate function 1 for GPIO 38, 40.
//			XllpLock(XLLP_RESOURCE_GAFR1_L);
			p_GPIORegs->GAFR1_L = (p_GPIORegs->GAFR1_L & ~(XLLP_GPIO_AF_BIT_SSPTXD3_MASK | XLLP_GPIO_AF_BIT_SSPCLK3_MASK)) | 
					(XLLP_GPIO_AF_BIT_SSPTXD3 | XLLP_GPIO_AF_BIT_SSPCLK3);
//			XllpUnlock(XLLP_RESOURCE_GAFR1_L);
		#endif
	}

	// Program the GAFR1_U to select alternate function 2 for GPIO 58 through 63.
//	XllpLock(XLLP_RESOURCE_GAFR1_U);
	p_GPIORegs->GAFR1_U = (p_GPIORegs->GAFR1_U & ~(XLLP_GPIO_AF_BIT_L_DD0_MASK | XLLP_GPIO_AF_BIT_L_DD1_MASK | XLLP_GPIO_AF_BIT_L_DD2_MASK|
												   XLLP_GPIO_AF_BIT_L_DD3_MASK | XLLP_GPIO_AF_BIT_L_DD4_MASK | XLLP_GPIO_AF_BIT_L_DD5_MASK)) | 
												  (XLLP_GPIO_AF_BIT_L_DD0 | XLLP_GPIO_AF_BIT_L_DD1 | XLLP_GPIO_AF_BIT_L_DD2 | 
												   XLLP_GPIO_AF_BIT_L_DD3 | XLLP_GPIO_AF_BIT_L_DD4 | XLLP_GPIO_AF_BIT_L_DD5 );
//	XllpUnlock(XLLP_RESOURCE_GAFR1_U);

	// Program the GAFR2_L to select alternate function 2 for GPIO 64 through 77.
//	XllpLock(XLLP_RESOURCE_GAFR2_L);
	p_GPIORegs->GAFR2_L = (p_GPIORegs->GAFR2_L & ~(XLLP_GPIO_AF_BIT_L_DD6_MASK	| XLLP_GPIO_AF_BIT_L_DD7_MASK	| XLLP_GPIO_AF_BIT_L_DD8_MASK	|
												   XLLP_GPIO_AF_BIT_L_DD9_MASK	| XLLP_GPIO_AF_BIT_L_DD10_MASK	| XLLP_GPIO_AF_BIT_L_DD11_MASK	|
												   XLLP_GPIO_AF_BIT_L_DD12_MASK | XLLP_GPIO_AF_BIT_L_DD13_MASK	| XLLP_GPIO_AF_BIT_L_DD14_MASK	|
												   XLLP_GPIO_AF_BIT_L_DD15_MASK | XLLP_GPIO_AF_BIT_L_FCLK_RD_MASK | XLLP_GPIO_AF_BIT_L_LCLK_A0_MASK |
												   XLLP_GPIO_AF_BIT_L_PCLK_WR_MASK | XLLP_GPIO_AF_BIT_L_BIAS_MASK)) |
												  (XLLP_GPIO_AF_BIT_L_DD6	| XLLP_GPIO_AF_BIT_L_DD7	| XLLP_GPIO_AF_BIT_L_DD8	| 
												   XLLP_GPIO_AF_BIT_L_DD9 	| XLLP_GPIO_AF_BIT_L_DD10	| XLLP_GPIO_AF_BIT_L_DD11	| 
												   XLLP_GPIO_AF_BIT_L_DD12	| XLLP_GPIO_AF_BIT_L_DD13	| XLLP_GPIO_AF_BIT_L_DD14	| 
												   XLLP_GPIO_AF_BIT_L_DD15	| XLLP_GPIO_AF_BIT_L_FCLK_RD| XLLP_GPIO_AF_BIT_L_LCLK_A0|
												   XLLP_GPIO_AF_BIT_L_PCLK_WR	| XLLP_GPIO_AF_BIT_L_BIAS ); 
	if (pXllpLCD->DisplayType == LS022Q8DD06)
	{
		p_GPIORegs->GAFR2_L = (p_GPIORegs->GAFR2_L & ~XLLP_GPIO_AF_BIT_L_BIAS_MASK); 
	}

//	XllpUnlock(XLLP_RESOURCE_GAFR2_L);


	if (pXllpLCD->DisplayType != LS022Q8DD06)
	{
		// Program the GAFR2_U to select alternate function 2 for GPIO 86, 87.
//		XllpLock(XLLP_RESOURCE_GAFR2_U);
		p_GPIORegs->GAFR2_U = (p_GPIORegs->GAFR2_U & ~(XLLP_GPIO_AF_BIT_L_DD16_MASK | XLLP_GPIO_AF_BIT_L_DD17_MASK))  | (XLLP_GPIO_AF_BIT_L_DD16 | XLLP_GPIO_AF_BIT_L_DD17); 
//		XllpUnlock(XLLP_RESOURCE_GAFR2_U);
	}
		
	if (pXllpLCD->DisplayType == LS022Q8DD06)
	{
//		XllpLock(XLLP_RESOURCE_GAFR2_U);
		#if defined XLLP_GPIO_AF_BIT_SSPRXD3_MASK && XLLP_GPIO_AF_BIT_SSPRXD3
			p_GPIORegs->GAFR2_U = (p_GPIORegs->GAFR2_U & ~XLLP_GPIO_AF_BIT_SSPRXD3_MASK)  | XLLP_GPIO_AF_BIT_SSPRXD3; 
		#endif
//		XllpUnlock(XLLP_RESOURCE_GAFR2_U);
	}

	if (pXllpLCD->DisplayType != LS022Q8DD06)
	{
//		XllpLock(XLLP_RESOURCE_GPSR0);
		// Turn on the backlight...
		p_GPIORegs->GPSR0 = XLLP_GPIO_BIT_PWM_OUT0;
//		XllpUnlock(XLLP_RESOURCE_GPSR0);
	}

	if (pXllpLCD->DisplayType == LS022Q8DD06)
	{
		p_GPIORegs->GPCR2 = XLLP_GPIO_BIT_L_BIAS;
	}

    //
    // Ensure GPIO writes that have posted complete
    //
    APB_Temp = p_GPIORegs->GAFR0_L;

}

void LCDEnableController(P_XLLP_LCD_T pXllpLCD)
{
	volatile LCDRegs *p_LCDRegs;

	p_LCDRegs = (LCDRegs *) pXllpLCD->LCDC;

	p_LCDRegs->LCCR0 |= LCD_ENB;
}

#ifndef NO_NH040609_OVERLAY2_YUVHWFIX
typedef enum
    {
     WFS_ALL
    ,WFS_ANY
    } WFS_TYPE;

static int WaitForState(volatile unsigned int (*pStatusReg), unsigned int mask, WFS_TYPE wait_type, unsigned int max_ms)
// Wait a max # milliseconds for a register to match a given state (any or all bits)
// Returns number of milliseconds of max_ms remaining (ie. >= 0 = got match, < 0 = no match) 
    {
    int matched = 0;
    int sleep_quantum = (max_ms/100); // milliseconds
    int sleep_time_left = max_ms;

    if (sleep_quantum == 0)
        sleep_quantum = 1;
    while (1)
        {
        matched = (wait_type == WFS_ALL) ? ((*pStatusReg & mask) == mask)
                                         : ((*pStatusReg & mask) != 0);
        if (matched)
            {
            if (sleep_time_left < 0)
                sleep_time_left = 0;
            break;
            }
        if (sleep_time_left < 0)
            break;
        SPINSLEEP(sleep_quantum);
        sleep_time_left -= sleep_quantum;
        }
    return(sleep_time_left);
    } // WaitForState
#endif /* NH040609_OVERLAY2_YUVHWFIX */

#ifndef NO_NH040609_OVERLAY2_YUVHWFIX
// The enable and disable routines have been changed to implement workaround(s) for 
// controller(/hardware) problems (lockup an fade-to-white) described in Tibet sighting 49219
// when enabling and disabling YUV 4:2:0 mode.
// The basic functional changes are...
// 1. When enabling overlay2, set the enable bit (LCD_O2EN) and wait for input FIFO underrun to occur 
//    BEFORE setting the registers that point to the DMA descriptors for CH2,3&4 (FDADRx).
// 2. When disabling overlay2, after clearing LCD_O2EN wait for DMA branch status (LCD_BSx) to occur
//    before restoring the baseframe pixel format.
//    DMA branch status is detected by setting branch registers (FBRx) and waiting for LCD_BSx status.

XLLP_STATUS_T XllpLCD_Overlay2_Enable(P_XLLP_LCD_T pXllpLCD, P_XLLP_OVERLAY_T pXllpOverlay)
    {
    XLLP_STATUS_T status = 0;
    volatile LCDRegs *p_LCDRegs;
    unsigned int StatMask = 0; 

    p_LCDRegs = (LCDRegs *) pXllpLCD->LCDC; 

    if ((p_LCDRegs->OVL2C1) & LCD_O2EN)
        {
        LOGMSG(1,(TEXT("XllpLCD_Overlay2_Enable: Already enabled\r\n")));
 //       return(status);
        }

	// Change baseframe pixel format to reduce memory bus bandwidth
	XllpLCDSuspend(pXllpLCD, Suspend_Graceful);
	pXllpOverlay->TmpBPP = pXllpLCD->BPP;
	if (pXllpOverlay->DegradeBaseFrame)
		pXllpLCD->BPP = BPP_1;
	pXllpLCD->PixelDataFormat = PDFOR_11;
	XllpLCDResume(pXllpLCD);

    // Setup frame descriptors
    // CH2
    pXllpLCD->frameDescriptorCh2_YCbCr_Y->PHYSADDR  = LCD_FDADR(pXllpLCD->_DMA_CHANNEL_2_Y_FRAME_DESCRIPTOR_BASE_PHYSICAL);  // self
    pXllpLCD->frameDescriptorCh2_YCbCr_Y->FDADR     = pXllpLCD->frameDescriptorCh2_YCbCr_Y->PHYSADDR;                        // next = self
    pXllpLCD->frameDescriptorCh2_YCbCr_Y->FSADR     = LCD_FSADR(pXllpLCD->_OVERLAY2_Y_CHANNEL_BASE_PHYSICAL);                // frame buffer
    pXllpLCD->frameDescriptorCh2_YCbCr_Y->FIDR      = LCD_FIDR(0);
    pXllpLCD->frameDescriptorCh2_YCbCr_Y->LDCMD     = LCD_Len(pXllpOverlay->ch2_size);
    // CH3
    pXllpLCD->frameDescriptorCh3_YCbCr_Cb->PHYSADDR = LCD_FDADR(pXllpLCD->_DMA_CHANNEL_3_Cb_FRAME_DESCRIPTOR_BASE_PHYSICAL); // self
    pXllpLCD->frameDescriptorCh3_YCbCr_Cb->FDADR    = pXllpLCD->frameDescriptorCh3_YCbCr_Cb->PHYSADDR;                       // next = self
    pXllpLCD->frameDescriptorCh3_YCbCr_Cb->FSADR    = LCD_FSADR(pXllpLCD->_OVERLAY2_Cb_CHANNEL_BASE_PHYSICAL);               // frame buffer
    pXllpLCD->frameDescriptorCh3_YCbCr_Cb->FIDR     = LCD_FIDR(0);
    pXllpLCD->frameDescriptorCh3_YCbCr_Cb->LDCMD    = LCD_Len(pXllpOverlay->ch3_size);
    // CH4
    pXllpLCD->frameDescriptorCh4_YCbCr_Cr->PHYSADDR = LCD_FDADR(pXllpLCD->_DMA_CHANNEL_4_Cr_FRAME_DESCRIPTOR_BASE_PHYSICAL); // self
    pXllpLCD->frameDescriptorCh4_YCbCr_Cr->FDADR    = pXllpLCD->frameDescriptorCh4_YCbCr_Cr->PHYSADDR;                       // next = self
    pXllpLCD->frameDescriptorCh4_YCbCr_Cr->FSADR    = LCD_FSADR(pXllpLCD->_OVERLAY2_Cr_CHANNEL_BASE_PHYSICAL);               // frame buffer
    pXllpLCD->frameDescriptorCh4_YCbCr_Cr->FIDR     = LCD_FIDR(0);
    pXllpLCD->frameDescriptorCh4_YCbCr_Cr->LDCMD    = LCD_Len(pXllpOverlay->ch4_size);

	// Set the physical address of the frame buffer
#if 1
    pXllpLCD->frameDescriptorCh2_YCbCr_Y->FSADR =  LCD_FSADR(pXllpLCD->_OVERLAY2_Y_CHANNEL_BASE_PHYSICAL);
    pXllpLCD->frameDescriptorCh3_YCbCr_Cb->FSADR =  LCD_FSADR(pXllpLCD->_OVERLAY2_Y_CHANNEL_BASE_PHYSICAL+pXllpOverlay->ch2_size);
    pXllpLCD->frameDescriptorCh4_YCbCr_Cr->FSADR =  LCD_FSADR(pXllpLCD->_OVERLAY2_Y_CHANNEL_BASE_PHYSICAL+
									pXllpOverlay->ch2_size + pXllpOverlay->ch3_size);
#endif

    // FBRx is cleared and is not used.
    p_LCDRegs->FBR2 = 0;
    p_LCDRegs->FBR3 = 0;
    p_LCDRegs->FBR4 = 0;

    StatMask = LCD_IU2;
    if (pXllpOverlay->Format != FORMAT_RGB)
        StatMask |= (LCD_IU3 | LCD_IU4);

    p_LCDRegs->LCSR1 = StatMask; // clear
    DBGMSG(1, (TEXT("AT XllpLCD_Overlay2_Enable x=%d, y=%d\r\n"), pXllpOverlay->X_Position,pXllpOverlay->Y_Position));
    p_LCDRegs->OVL2C2 = (LCD_FOR(pXllpOverlay->Format) | LCD_O2YPOS(pXllpOverlay->Y_Position) | LCD_O2XPOS(pXllpOverlay->X_Position));
//=========================================================
    p_LCDRegs->OVL2C1 = (LCD_O2EN | (LCD_BPP2(pXllpOverlay->OverlayBPP) | LCD_LPO2(pXllpOverlay->OverlayHeight-1) | LCD_PPL2(pXllpOverlay->OverlayWidth-1)));
//=========================================================
    // Wait for the hardware to signal input FIFOx underrun
    // before setting the FDADRx regs (and hence enabling DMA).
    // This is a key part of the hardware workaround described in Tibet sighting 49219.
    // Note that that IUx doesn't happen the first time after reset or resume.
    // The underrun apparently does occur in the controller but the controller doesn't set IUx.
    // According HW eng, the 50ms delay introduced by waiting for IUx should be sufficient 
    // to avoid the hardware problem.
    // Note also that this may only needed for YUV modes but also works for RGB modes and
    // implementing it for all modes produces less convoluted code.
    if (WaitForState(&(p_LCDRegs->LCSR1),StatMask,WFS_ALL,OVERLAY_DELAY_ENABLE) < 0)
        DBGMSG(1,(TEXT("XllpLCD_Overlay2_Enable(F=%d): No IUx (LCSR1=x%08x)\r\n"),
                  pXllpOverlay->Format, p_LCDRegs->LCSR1));
    else
        DBGMSG(1,(TEXT("XllpLCD_Overlay2_Enable(F=%d): Got IUx (LCSR1=x%08x)\r\n"),
                  pXllpOverlay->Format, p_LCDRegs->LCSR1));

    // Load the FDADRx regs with the physical address of the frame descriptors
    // Testing indicates that this is what actually enables DMA transfers.
    // If FDADRx isn't set (even if already set to the desired value) the DMA doesn't start.
    p_LCDRegs->FDADR2 = LCD_FDADR(pXllpLCD->frameDescriptorCh2_YCbCr_Y->PHYSADDR);
    if (pXllpOverlay->Format != FORMAT_RGB)
        {
        p_LCDRegs->FDADR3 = LCD_FDADR(pXllpLCD->frameDescriptorCh3_YCbCr_Cb->PHYSADDR);
        p_LCDRegs->FDADR4 = LCD_FDADR(pXllpLCD->frameDescriptorCh4_YCbCr_Cr->PHYSADDR);
        }
    p_LCDRegs->LCSR1 = StatMask; // clear
    return(status);
    } // XllpLCD_Overlay2_Enable

void XllpLCD_Overlay2_Disable(P_XLLP_LCD_T pXllpLCD, P_XLLP_OVERLAY_T pXllpOverlay)
    {
    volatile LCDRegs *p_LCDRegs;
    unsigned int OVL2C1;
    unsigned int OVL2C2;
    unsigned int OL2Format;
    unsigned int StatMask = 0; 

    p_LCDRegs = (LCDRegs *) pXllpLCD->LCDC; 

    OVL2C1 = p_LCDRegs->OVL2C1;
    if (!(OVL2C1 & LCD_O2EN))
        {
        LOGMSG(1,(TEXT("XllpLCD_Overlay2_Disable: Not enabled\r\n")));
        return;
        }
    OVL2C2 = p_LCDRegs->OVL2C2;
    OL2Format = (OVL2C2 >> 20) & 7;
    StatMask = LCD_BS2;
    if (OL2Format != FORMAT_RGB)
        StatMask |= (LCD_BS3 | LCD_BS4);
    p_LCDRegs->LCSR1 = StatMask;
//=========================================================

⌨️ 快捷键说明

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