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

📄 xllp_lcd.c

📁 Intel PXA270底层设备驱动代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    p_LCDRegs->OVL2C1 &= ~LCD_O2EN; // Clear the enable bit
//=========================================================
    // Wait for DMA branch taken status (BSx bits to be set).
    // This is per HW Eng. workaround described in Tibet sighting 49219.
    // Note that testing indicates the loading of FBRx avoids the hardware problem.
    // Not loading FBRx and just waiting for 50ms does not avoid the problem.

    p_LCDRegs->FBR2 = LCD_FDADR(pXllpLCD->frameDescriptorCh2_YCbCr_Y->FDADR) | (LCD_BRA | LCD_BINT);
    if (OL2Format != FORMAT_RGB)
        {
        p_LCDRegs->FBR3 = LCD_FDADR(pXllpLCD->frameDescriptorCh3_YCbCr_Cb->FDADR) | (LCD_BRA | LCD_BINT);
        p_LCDRegs->FBR4 = LCD_FDADR(pXllpLCD->frameDescriptorCh4_YCbCr_Cr->FDADR) | (LCD_BRA | LCD_BINT);
        }
    if (WaitForState(&(p_LCDRegs->LCSR1),StatMask,WFS_ALL,OVERLAY_DELAY_DISABLE) < 0)
        LOGMSG(1,(TEXT("XllpLCD_Overlay2_Disable(F=%d): No BSx (LCSR1=x%08x)\r\n"),
                  OL2Format, p_LCDRegs->LCSR1));
    else
        DBGMSG(1,(TEXT("XllpLCD_Overlay2_Disable(F=%d): Got BSx (LCSR1=x%08x)\r\n"),
                  OL2Format, p_LCDRegs->LCSR1));

    // Restore BaseFrame Pixel Format
	XllpLCDSuspend(pXllpLCD, Suspend_Graceful);
	pXllpLCD->PixelDataFormat = PDFOR_00;
	pXllpLCD->BPP = pXllpOverlay->TmpBPP;
	XllpLCDResume(pXllpLCD);

    return;
    } // XllpLCD_Overlay2_Disable

#else /* NH040609_OVERLAY2_YUVHWFIX old code */
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;

	p_LCDRegs = (LCDRegs *) pXllpLCD->LCDC;	

	// Set the physical address of the frame descriptor
	pXllpLCD->frameDescriptorCh2_YCbCr_Y->FDADR =  LCD_FDADR(pXllpLCD->_DMA_CHANNEL_2_Y_FRAME_DESCRIPTOR_BASE_PHYSICAL);
	pXllpLCD->frameDescriptorCh3_YCbCr_Cb->FDADR = LCD_FDADR(pXllpLCD->_DMA_CHANNEL_3_Cb_FRAME_DESCRIPTOR_BASE_PHYSICAL);
	pXllpLCD->frameDescriptorCh4_YCbCr_Cr->FDADR = LCD_FDADR(pXllpLCD->_DMA_CHANNEL_4_Cr_FRAME_DESCRIPTOR_BASE_PHYSICAL);

	// Set the physical address of the frame buffer
	pXllpLCD->frameDescriptorCh2_YCbCr_Y->FSADR =  LCD_FSADR(pXllpLCD->_OVERLAY2_Y_CHANNEL_BASE_PHYSICAL);
	pXllpLCD->frameDescriptorCh3_YCbCr_Cb->FSADR = LCD_FSADR(pXllpLCD->_OVERLAY2_Cb_CHANNEL_BASE_PHYSICAL);
	pXllpLCD->frameDescriptorCh4_YCbCr_Cr->FSADR = LCD_FSADR(pXllpLCD->_OVERLAY2_Cr_CHANNEL_BASE_PHYSICAL);
	
	// Clear the frame ID
	pXllpLCD->frameDescriptorCh2_YCbCr_Y->FIDR  = LCD_FIDR(0);
	pXllpLCD->frameDescriptorCh3_YCbCr_Cb->FIDR  = LCD_FIDR(0);
	pXllpLCD->frameDescriptorCh4_YCbCr_Cr->FIDR  = LCD_FIDR(0);

	// Set the DMA transfer size (calculated already by XllpLCD_DMALength())
	pXllpLCD->frameDescriptorCh2_YCbCr_Y->LDCMD = LCD_Len(pXllpOverlay->ch2_size);
	pXllpLCD->frameDescriptorCh3_YCbCr_Cb->LDCMD = LCD_Len(pXllpOverlay->ch3_size);
	pXllpLCD->frameDescriptorCh4_YCbCr_Cr->LDCMD = LCD_Len(pXllpOverlay->ch4_size);

	// Store the physical address of each frame descriptor in the frame descriptor
	pXllpLCD->frameDescriptorCh2_YCbCr_Y->PHYSADDR = pXllpLCD->frameDescriptorCh2_YCbCr_Y->FDADR;
	pXllpLCD->frameDescriptorCh3_YCbCr_Cb->PHYSADDR = pXllpLCD->frameDescriptorCh3_YCbCr_Cb->FDADR;
	pXllpLCD->frameDescriptorCh4_YCbCr_Cr->PHYSADDR = pXllpLCD->frameDescriptorCh4_YCbCr_Cr->FDADR;
	
	// FBRx is cleared and is not used.
	p_LCDRegs->FBR2 = 0;
	p_LCDRegs->FBR3 = 0;
	p_LCDRegs->FBR4 = 0;

	// Load the contents of FDADRx with the physical address of this frame descriptor
	p_LCDRegs->FDADR2 = LCD_FDADR(pXllpLCD->frameDescriptorCh2_YCbCr_Y->FDADR);
	p_LCDRegs->FDADR3 = LCD_FDADR(pXllpLCD->frameDescriptorCh3_YCbCr_Cb->FDADR);
	p_LCDRegs->FDADR4 = LCD_FDADR(pXllpLCD->frameDescriptorCh4_YCbCr_Cr->FDADR);
	

	// Reinit the LCD controller so that the pixel data format can be updated for use with overlays
	XllpLCDSuspend(pXllpLCD, Suspend_Graceful);

	pXllpOverlay->TmpBPP = pXllpLCD->BPP;
	if (pXllpOverlay->DegradeBaseFrame)
	{
		pXllpLCD->BPP = BPP_1;
	}
	
	pXllpLCD->PixelDataFormat = PDFOR_11;

	// Configure the overlay registers and enable the overlay
	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));

	XllpLCDResume(pXllpLCD);

	return status;
}

void XllpLCD_Overlay2_Disable(P_XLLP_LCD_T pXllpLCD, P_XLLP_OVERLAY_T pXllpOverlay)
{
	volatile LCDRegs *p_LCDRegs;
	
	p_LCDRegs = (LCDRegs *) pXllpLCD->LCDC;	

    // Reinit the LCD controller so that the pixel data format can be updated for use without overlays
	XllpLCDSuspend(pXllpLCD, Suspend_Graceful);

	pXllpLCD->PixelDataFormat = PDFOR_00;

	// Undo the degraded base frame - always.
	pXllpLCD->BPP = pXllpOverlay->TmpBPP;

	p_LCDRegs->OVL2C1 &= 0x00FFFFFF; // Clear the enable bit, and clear the reserved bits 30:24.
	XllpLCDResume(pXllpLCD);
}
#endif /* NH040609_OVERLAY2_YUVHWFIX */

void XllpLCD_DMALength(P_XLLP_OVERLAY_T pXllpOverlay)
{
	unsigned int pixels = pXllpOverlay->OverlayHeight * pXllpOverlay->OverlayWidth;
	unsigned int DMALength = 0;

	// Determine the DMA transfer length
	// each DMA transfer length for YUV formatted data must be multiples of 32-bits and adjusted accordingly
	if (pXllpOverlay->Format == FORMAT_RGB)
	{
		switch(pXllpOverlay->OverlayBPP)
		{
			case O_BPP_4:
				DMALength = pixels >> 1;
				break;
			case O_BPP_8:
				DMALength = pixels;
				break;
			case O_BPP_16:
				DMALength = pixels << 1;
				break;
			case O_BPP_18:
				DMALength = pixels << 2;
				break;
			case O_BPP_18_PACKED:
				break;
			case O_BPP_19:
				DMALength = pixels << 2;
				break;
			case O_BPP_19_PACKED:
				break;
			case O_BPP_24:
				DMALength = pixels << 2;
				break;
			case O_BPP_25:
				DMALength = pixels << 2;
				break;
		default:
			break;
		}
		pXllpOverlay->ch2_size = DMALength;
		pXllpOverlay->ch3_size = 0;
		pXllpOverlay->ch4_size = 0;
	}
	if (pXllpOverlay->Format == FORMAT_PACKED_444)
	{
		pXllpOverlay->ch2_size = (pixels << 2);
		pXllpOverlay->ch3_size = 0;
		pXllpOverlay->ch4_size = 0;
	} 
	else if (pXllpOverlay->Format == FORMAT_PLANAR_444) 
	{
		// calculate the number of bits in the frame (pixels << 3)
		// mod by 32 to determine the remainder
		// subtract from 32 to determine how many bits to add to the length to make it a multiple of 32 bits
		// add this value to the number of bits in the frame
		// convert this value back to bytes
		DMALength = pixels;
		if ((DMALength % 4) > 0)
		{
			DMALength = (((32 - ((pixels << 3) % 32)) + (pixels << 3)) >> 3);  // 24 bits total
		}
		pXllpOverlay->ch2_size = DMALength;
		pXllpOverlay->ch3_size = DMALength;
		pXllpOverlay->ch4_size = DMALength;
	}
	else if (pXllpOverlay->Format == FORMAT_PLANAR_422)
	{																			
		DMALength = pixels;
		if ((DMALength % 4) > 0)
		{
			DMALength = (((32 - ((pixels << 3) % 32)) + (pixels << 3)) >> 3);	// 16 bits total
		}
		pXllpOverlay->ch2_size = DMALength;

		DMALength = pixels >> 1;
		if (((pixels << 2) % 32) > 0)
		{
			DMALength = (((32 - ((pixels << 2) % 32)) + (pixels << 2)) >> 3);
		}
		pXllpOverlay->ch3_size = DMALength;
		pXllpOverlay->ch4_size = DMALength;
	}
	else if (pXllpOverlay->Format == FORMAT_PLANAR_420)
	{
		DMALength = pixels;
		if ((DMALength % 4) > 0)
		{
			DMALength = (((32 - ((pixels << 3) % 32)) + (pixels << 3)) >> 3);	// 12 bits total
		}
		pXllpOverlay->ch2_size = DMALength;

		DMALength = pixels >> 2;
		if (((pixels << 1) % 32) > 0)
		{
			DMALength = (((32 - ((pixels << 1) % 32)) + (pixels << 1)) >> 3);
		}
		pXllpOverlay->ch3_size = DMALength;
		pXllpOverlay->ch4_size = DMALength;
	}
}
			


#ifndef NO_NH040609_OVERLAY2_YUVHWFIX

XLLP_STATUS_T XllpLCD_Overlay1_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->OVL1C1) & LCD_O2EN)
        {
        LOGMSG(1,(TEXT("XllpLCD_Overlay1_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
    // CH1
    pXllpLCD->frameDescriptorCh1->PHYSADDR  = LCD_FDADR(pXllpLCD->_DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_PHYSICAL);  // self
    pXllpLCD->frameDescriptorCh1->FDADR     = pXllpLCD->frameDescriptorCh1->PHYSADDR;                        // next = self
    pXllpLCD->frameDescriptorCh1->FSADR     = LCD_FSADR(pXllpLCD->_OVERLAY1_CHANNEL_BASE_PHYSICAL);                // frame buffer
    pXllpLCD->frameDescriptorCh1->FIDR      =  LCD_FIDR(0);
    pXllpLCD->frameDescriptorCh1->LDCMD     = LCD_Len(pXllpOverlay->ch1_size);

    // FBRx is cleared and is not used.
    p_LCDRegs->FBR1 = 0;

    p_LCDRegs->OVL1C2 = (LCD_O2YPOS(pXllpOverlay->Y_Position) | LCD_O2XPOS(pXllpOverlay->X_Position));
//=========================================================
    p_LCDRegs->OVL1C1 = (LCD_O2EN | (LCD_BPP2(pXllpOverlay->OverlayBPP) | LCD_LPO2(pXllpOverlay->OverlayHeight-1) | LCD_PPL2(pXllpOverlay->OverlayWidth-1)));
//=========================================================

    // 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->FDADR1 = LCD_FDADR(pXllpLCD->frameDescriptorCh1->PHYSADDR);

    return(status);
} // XllpLCD_Overlay2_Enable

void XllpLCD_Overlay1_Disable(P_XLLP_LCD_T pXllpLCD, P_XLLP_OVERLAY_T pXllpOverlay)
    {
    volatile LCDRegs *p_LCDRegs;
    unsigned int OVL1C1;
    unsigned int OVL1C2;
    unsigned int StatMask = LCD_BS1; 

    p_LCDRegs = (LCDRegs *) pXllpLCD->LCDC; 

    OVL1C1 = p_LCDRegs->OVL1C1;
    if (!(OVL1C1 & LCD_O2EN))
        {
        LOGMSG(1,(TEXT("XllpLCD_Overlay1_Disable: Not enabled\r\n")));
        return;
        }
    OVL1C2 = p_LCDRegs->OVL1C2;

//=========================================================
    p_LCDRegs->OVL1C1 &= ~LCD_O2EN; // Clear the enable bit
//=========================================================

    p_LCDRegs->FBR1 = LCD_FDADR(pXllpLCD->frameDescriptorCh1->FDADR) | (LCD_BRA | LCD_BINT);

    // Wait for DMA branch taken status (BSx bits to be set).
    // This is per HW Eng. workaround described in Tibet sighting 49219.
    // Note that testing indicates the loading of FBRx avoids the hardware problem.
    // Not loading FBRx and just waiting for 50ms does not avoid the problem.

    if (WaitForState(&(p_LCDRegs->LCSR1),StatMask,WFS_ALL,OVERLAY_DELAY_DISABLE) < 0)
        LOGMSG(1,(TEXT("XllpLCD_Overlay1_Disable: No BSx (LCSR1=x%08x)\r\n"),
                  p_LCDRegs->LCSR1));
    else
        DBGMSG(1,(TEXT("XllpLCD_Overlay1_Disable: Got BSx (LCSR1=x%08x)\r\n"),
                  p_LCDRegs->LCSR1));


    // Restore BaseFrame Pixel Format
    XllpLCDSuspend(pXllpLCD, Suspend_Graceful);
    pXllpLCD->PixelDataFormat = PDFOR_00;
    pXllpLCD->BPP = pXllpOverlay->TmpBPP;
    XllpLCDResume(pXllpLCD);

    return;
} // XllpLCD_Overlay2_Disable

#else

XLLP_STATUS_T XllpLCD_Overlay1_Enable(P_XLLP_LCD_T pXllpLCD, P_XLLP_OVERLAY_T pXllpOverlay)
{
	return 0;
}

void XllpLCD_Overlay1_Disable(P_XLLP_LCD_T pXllpLCD, P_XLLP_OVERLAY_T pXllpOverlay)
{
	return;
}
#endif



⌨️ 快捷键说明

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