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

📄 dispdrvr.c

📁 PXA270芯片显示驱动源码
💻 C
📖 第 1 页 / 共 3 页
字号:

    v_pOSTRegs = (volatile unsigned int *)VirtualAllocCopyPhysical(sizeof(XLLP_OST_T),"DispDrvrInitialize : v_pOSTRegs",(PVOID)(BULVERDE_BASE_REG_PA_OST));
    if (!v_pOSTRegs)
    {
        Cleanup();
        return FALSE;
    }

    v_pLcdRegs = (volatile LCDRegs *)VirtualAllocCopyPhysical(sizeof(LCDRegs),"DispDrvrInitialize : v_pLcdRegs",(PVOID)(BULVERDE_BASE_REG_PA_LCD));
    if (!v_pLcdRegs)
    {
        Cleanup();
        return FALSE;
    }

    v_pClkRegs = (volatile XLLP_CLKMGR_T *)VirtualAllocCopyPhysical(sizeof(XLLP_CLKMGR_T),"DispDrvrInitialize : v_pClkRegs",(PVOID)(BULVERDE_BASE_REG_PA_CLKMGR));
    if (!v_pClkRegs)
    {
        Cleanup();
        return FALSE;
    }
    
    v_pGPIORegs = (volatile XLLP_GPIO_T *)VirtualAllocCopyPhysical(sizeof(XLLP_GPIO_T),"DispDrvrInitialize : v_pGPIORegs",(PVOID)(BULVERDE_BASE_REG_PA_GPIO));
    if (!v_pGPIORegs)
    {
        Cleanup();
        return FALSE;
    }

    frameDescriptorCh0fd1  = (volatile LCD_FRAME_DESCRIPTOR *)(DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_VIRTUAL);
    frameDescriptorCh0fd2  = (volatile LCD_FRAME_DESCRIPTOR *)(DMA_CHANNEL_0_ALT_FRAME_DESCRIPTOR_BASE_VIRTUAL);
    frameDescriptorCh1     = (volatile LCD_FRAME_DESCRIPTOR *)(DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_VIRTUAL);
    frameDescriptorPalette = (volatile LCD_FRAME_DESCRIPTOR *)(PALETTE_FRAME_DESCRIPTOR_BASE_VIRTUAL);
    v_pPaletteBuffer       = (volatile LCD_PALETTE *)(PALETTE_BUFFER_BASE_VIRTUAL);

    // Enter into Kernel mode to enable us to modify the section descriptor
    // so that we may set the bufferable bit.  This enables write coalescing
    // for frame buffer writes when using the section mapped address.
    // 
    // GAPI uses the section mapped address always.  


    // Now configure the frame buffer's section descriptor.
    // The function GetDescriptorAddress shows how to obtain the correct descriptor address.
    // This descriptor is one of two descriptors that map the the frame buffer.
    // The first descriptor found maps the cached virtual address, while the second
    // descriptor found maps the uncached virtual address.  We want to modify the 
    // second descriptor, that which maps the uncached virtual address since the uncached virtual 
    // address is the address we've chosen to use throughout the codebase.
    //
    // NOTE:
    // The section descriptor covers a 1MB section.  If the frame buffer ever exceeds 1MB
    // in size, you'll need to modify additional section descriptors.
    //
    
    // DDraw requires that the frame buffer pointer be in the shared memory space so
    // is can be shared between processes.
    {
        PVOID  pPhysAddr;
        size_t offset;
        size_t size;

        pPhysAddr  = (PVOID)(FRAME_BUFFER_0_BASE_PHYSICAL);
        size       = frameBufferSize * NUM_FRAME_BUFFERS;
        offset     = (unsigned)pPhysAddr & (0x1000 - 1);
        size      += (offset ? 0x1000 : 0);
        pPhysAddr  = (PVOID)((unsigned)pPhysAddr - offset);

        if (size >= 1024*1024*2)
        {
            gFrameBuffer = (PBYTE)VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS);
        }
        else
        {
            gFrameBuffer = (PBYTE)VirtualAlloc(NULL, 1024*1024*2, MEM_RESERVE, PAGE_NOACCESS);
        }

        if (!VirtualCopy(gFrameBuffer, (LPVOID)((unsigned long)pPhysAddr >> 8), size, (PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL)))
        {
            gFrameBuffer = NULL;
        }
        else
        {
            gFrameBuffer += offset;
        }
    }

    if (!gFrameBuffer)
    {
        Cleanup();
        return FALSE;
    }    

    if (bDoRotation)
    {
        // if rotating the display, the actual frame buffer should be configured as bufferable for max write performance into the frame buffer.
        VirtualSetAttributes(gFrameBuffer, frameBufferSize*NUM_FRAME_BUFFERS, 4, 4, NULL);
    }
    else
    {
        // if not rotating the dispay, we can draw directly into the frame buffer, and use write-through cache mode to improve frame buffer throughput
        VirtualSetAttributes(gFrameBuffer, frameBufferSize*NUM_FRAME_BUFFERS, 8, 8, NULL);
    }

    gBlankFrameBuffer = (PBYTE) VirtualAlloc(0, frameBufferSize, MEM_RESERVE | MEM_COMMIT,PAGE_READWRITE);
    if (!gBlankFrameBuffer)
    {
        Cleanup();
        return FALSE;
    }

    return TRUE;
}

// Free all the global memory resources
void Cleanup(void)
{
    DMA_ADAPTER_OBJECT Adapter;
    PHYSICAL_ADDRESS   PhysAddr;

    if (v_pDMAC)
    {
        VirtualFree((PVOID)v_pDMAC,0,MEM_RELEASE);
        v_pDMAC = NULL;
    }

    if (v_pI2C)
    {
        VirtualFree((PVOID)v_pI2C,0,MEM_RELEASE);
        v_pI2C = NULL;
    }

    if (v_pOSTRegs)
    {
        VirtualFree((PVOID)v_pOSTRegs,0,MEM_RELEASE);
        v_pOSTRegs = NULL;
    }

    if (v_pLcdRegs)
    {
        VirtualFree((PVOID)v_pLcdRegs,0,MEM_RELEASE);
        v_pLcdRegs = NULL;
    }
	//end
    if (v_pClkRegs)
    {
        VirtualFree((PVOID)v_pClkRegs,0,MEM_RELEASE);
        v_pLcdRegs = NULL;
    }

    if (v_pGPIORegs)
    {
        VirtualFree((PVOID)v_pGPIORegs,0,MEM_RELEASE);
        v_pGPIORegs = NULL;
    }

    if (gFrameBuffer)
    {
        VirtualFree((PVOID)gFrameBuffer,0,MEM_RELEASE);
        gFrameBuffer = NULL;
    }

    if (gBlankFrameBuffer)
    {
        VirtualFree((PVOID)gBlankFrameBuffer,0,MEM_RELEASE);
        gBlankFrameBuffer = NULL;
    }

    if (frameDescriptorCh2_YCbCr_Y)
    {
        VirtualFree((PVOID)frameDescriptorCh2_YCbCr_Y,0,MEM_RELEASE);
        frameDescriptorCh2_YCbCr_Y = NULL;
    }

    if (frameDescriptorCh3_YCbCr_Cb)
    {
        VirtualFree((PVOID)frameDescriptorCh3_YCbCr_Cb,0,MEM_RELEASE);
        frameDescriptorCh3_YCbCr_Cb = NULL;
    }

    if (frameDescriptorCh4_YCbCr_Cr)
    {
        VirtualFree((PVOID)frameDescriptorCh4_YCbCr_Cr,0,MEM_RELEASE);
        frameDescriptorCh4_YCbCr_Cr = NULL;
    }

    Adapter.ObjectSize    = sizeof (DMA_ADAPTER_OBJECT);
    Adapter.InterfaceType = Internal;
    Adapter.BusNumber     = 0;

    PhysAddr.HighPart = 0;
    PhysAddr.LowPart  = g_DisplayBasePhysical;

    HalFreeCommonBuffer(&Adapter, DISPLAY_BUFFER_SIZE, PhysAddr, (void *)g_DisplayBaseVirtual, FALSE);
}

void DispDrvrPowerHandler(BOOL    bOff)
{

    if(bOff) 
    {
        // Copy the active frame buffer into a temporary buffer
        // because we are going to write over the active frame buffer
        // with a blank all black display.  When we restore the display
        // when we wake up, we want to be able to copy the original 
        // frame buffer back in.
        CopyFrameBuffer(TRUE);

        // Turn the display to black
        // and allow a few frames to display
        ClearFrameBuffer(FALSE);

        XllpLCDSuspend(&XllpLCD, Suspend_Graceful);
    }
    else
    {
        // Copy the original frame buffer back in.
        CopyFrameBuffer(FALSE);

        XllpLCDResume(&XllpLCD);
    }
}

void CopyFrameBuffer(BOOL gDirection)
{
    DWORD i;

    unsigned * cfbp = (unsigned *)gBlankFrameBuffer;
    unsigned * fbp  = (unsigned *)gFrameBuffer + (activeFrameBuffer * frameBufferSize);


    for(i = 0; i < (DispDrvr_cxScreen * DispDrvr_cyScreen * (bpp / 8) / 4); i++) 
    {
        if (gDirection)
        {
          *cfbp++ = *fbp++; 
        }
        else 
        {
          *fbp++ = *cfbp++; 
        }
    }    
}

void ClearFrameBuffer(BOOL color)
{
    DWORD i;

    unsigned * fbp = (unsigned *)gFrameBuffer + (activeFrameBuffer * frameBufferSize);

    for(i = 0; i < (DispDrvr_cxScreen * DispDrvr_cyScreen * (bpp / 8) / 4); i++) 
    {
        if (color)
        {
            *fbp++ = 0xFFFFFFFF;    // Ones turn it white
        }
        else       
        {
            *fbp++ = 0x00000000;    // Zeros turn it black
        }
    }
}

//**********************************************************************
//
//DispDrvrContrastControl:
//
//    Modify the contrast according to the Cmd parameter.
// Not supported
//

BOOL DispDrvrContrastControl(int Cmd,DWORD *pValue)
{
    // currently does not support changing contrast in software. 
    return TRUE;
}

void DirtyRectDumpPortraitLoop_C(BYTE    *pDstBuf, BYTE  *pSrcBuf, DWORD    yTop, DWORD yBottom,
                                 DWORD srcWidthB, DWORD    bytesPerRow, DWORD bytesPerPixel,
                                 DWORD srcMarginWidth, DWORD dstMarginWidth) 
{
    DWORD row;
    DWORD i;
    DWORD j;

    if ( bytesPerPixel != 2 )
    {
        //not 16-bit
        for (i = 0; i < srcWidthB / bytesPerPixel; i++)
        {
            for (row = yTop; row < yBottom; row++)
            {
                for (j = 0; j < bytesPerPixel; j++)
                {
                    *pDstBuf++ = *(pSrcBuf + j);
                }

                pSrcBuf -= bytesPerRow;
            }

            pDstBuf += dstMarginWidth;
            pSrcBuf += srcMarginWidth + 2;
        }
    }
    else
    {
        WORD * pwDst;
        WORD * pwSrc;
        int    rowLen;

        //16-bit
        srcWidthB >>= 1;

        pwDst = (WORD *)pDstBuf;
        pwSrc = (WORD *)pSrcBuf;

        //first row for pwSrc, then column for pwDst
        rowLen = yBottom - yTop;

#ifndef _OPT_ASM        
        bytesPerRow    >>= 1;
        dstMarginWidth >>= 1;
        srcMarginWidth >>= 1;

        for (i = 0; i < srcWidthB; i++)
        {
            for (row = 0; row < (rowLen >> 2); row++)
            {
                *pwDst++  = *pwSrc;
                pwSrc    -= bytesPerRow;
                
                *pwDst++  = *pwSrc;
                pwSrc    -= bytesPerRow;
                
                *pwDst++  = *pwSrc;
                pwSrc    -= bytesPerRow;
                
                *pwDst++  = *pwSrc;
                pwSrc    -= bytesPerRow;
            }

            for (row = 0; row < (rowLen & 0x3); row++)
            {
                *pwDst++  = *pwSrc;
                pwSrc    -= bytesPerRow;
            }

            pwDst += dstMarginWidth;
            pwSrc += srcMarginWidth + 1;
        }
#else 
        dirtyRectDump_core_ASM(pwSrc, pwDst, rowLen, srcWidthB, bytesPerRow, srcMarginWidth, dstMarginWidth);
#endif
    }
}    

void DispDrvrDirtyRectDump(LPCRECT prc)
{
    BYTE  * pDstBuf;
    BYTE  * pSrcBuf;
    DWORD   xLeft;
    DWORD   yTop;
    DWORD   xRight;
    DWORD   yBottom;

⌨️ 快捷键说明

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