int s3c_displayclass_init(void)
{
	IMG_UINT32 screen_w, screen_h;
	IMG_UINT32 pa_fb, va_fb, fb_size;
	IMG_UINT32 num_of_fb, num_of_backbuffer;
	IMG_UINT32 byteSize;
	struct fb_info *psLINFBInfo = 0;

	int	i;
	int rgb_format, bytes_per_pixel, bits_per_pixel;

	if(InitDev(&psLINFBInfo) == S3C_FALSE)
	{
		return 0;
	}
	
	pa_fb = psLINFBInfo->fix.smem_start;
	va_fb = (unsigned long)phys_to_virt(psLINFBInfo->fix.smem_start);
	screen_w = psLINFBInfo->var.xres;
	//screen_h = psLINFBInfo->var.yres;
	//framebuffer HEIGHT set to 640 to suit the framebuffer size must 4K-aligned
	screen_h = 640;
	bits_per_pixel = psLINFBInfo->var.bits_per_pixel;
	fb_size = psLINFBInfo->fix.smem_len;

	switch (bits_per_pixel)
	{
	case 16:
		rgb_format = PVRSRV_PIXEL_FORMAT_RGB565;
		bytes_per_pixel = 2;
		break;
	case 32:
		rgb_format = PVRSRV_PIXEL_FORMAT_ARGB8888;
		bytes_per_pixel = 4;
		break;
	default:
		rgb_format = PVRSRV_PIXEL_FORMAT_ARGB8888;
		bytes_per_pixel = 4;
		break;
	}

	printk("PA FB = 0x%X, bits per pixel = %d\n", (unsigned int)pa_fb, (unsigned int)bits_per_pixel);
	printk("screen width=%d height=%d va=0x%x pa=0x%x\n", (int)screen_w, (int)screen_h, (unsigned int)va_fb, (unsigned int)pa_fb);
	printk("xres_virtual = %d, yres_virtual = %d, xoffset = %d, yoffset = %d\n", psLINFBInfo->var.xres_virtual,  psLINFBInfo->var.yres_virtual,  psLINFBInfo->var.xoffset,  psLINFBInfo->var.yoffset);
	printk("fb_size=%d\n", (int)fb_size);
	
	num_of_fb = fb_size / (screen_w * screen_h * bytes_per_pixel);
	if(num_of_fb > S3C_MAX_BUFFERS)
	{
		printk("too many frame buffers\n");
		return 0;
	}
	num_of_backbuffer = num_of_fb - 1;
	
	if (g_psLCDInfo == NULL)
	{
		PFN_CMD_PROC	pfnCmdProcList[DC_S3C_LCD_COMMAND_COUNT];
		IMG_UINT32	aui32SyncCountList[DC_S3C_LCD_COMMAND_COUNT][2];

		g_psLCDInfo = (S3C_LCD_DEVINFO*)kmalloc(sizeof(S3C_LCD_DEVINFO),GFP_KERNEL);

		g_psLCDInfo->psFBInfo = psLINFBInfo;
		g_psLCDInfo->ui32NumFrameBuffers = num_of_fb;

		g_psLCDInfo->ui32NumFormats = S3C_DISPLAY_FORMAT_NUM;

		g_psLCDInfo->asDisplayForamtList[0].pixelformat = rgb_format;
		g_psLCDInfo->ui32NumDims = S3C_DISPLAY_DIM_NUM;
		g_psLCDInfo->asDisplayDimList[0].ui32ByteStride = (bytes_per_pixel) * screen_w;

		//g_psLCDInfo->asDisplayDimList[0].ui32Height = screen_h;
		//our LCD real height is 600 so here set to 600
		g_psLCDInfo->asDisplayDimList[0].ui32Height = 600;

		g_psLCDInfo->asDisplayDimList[0].ui32Width = screen_w;

		g_psLCDInfo->sSysBuffer.bufferPAddr.uiAddr = pa_fb;
		g_psLCDInfo->sSysBuffer.bufferVAddr = (IMG_CPU_VIRTADDR)va_fb;
		g_psLCDInfo->sSysBuffer.yoffset = 0;
		byteSize = screen_w * screen_h * bytes_per_pixel;
		g_psLCDInfo->sSysBuffer.byteSize = (IMG_UINT32)byteSize;

		for (i=0 ; i < num_of_backbuffer; i++)
		{
			g_psLCDInfo->asBackBuffers[i].byteSize = g_psLCDInfo->sSysBuffer.byteSize;
			g_psLCDInfo->asBackBuffers[i].bufferPAddr.uiAddr = pa_fb + byteSize * (i+1);
			g_psLCDInfo->asBackBuffers[i].bufferVAddr = (IMG_CPU_VIRTADDR)phys_to_virt(g_psLCDInfo->asBackBuffers[i].bufferPAddr.uiAddr);
			g_psLCDInfo->asBackBuffers[i].yoffset = screen_h * (i + 1);
		
			printk("Back frameBuffer[%d].VAddr=%p PAddr=%p size=%d\n",
				i, 
				(void*)g_psLCDInfo->asBackBuffers[i].bufferVAddr,
				(void*)g_psLCDInfo->asBackBuffers[i].bufferPAddr.uiAddr,
				(int)g_psLCDInfo->asBackBuffers[i].byteSize);
		}

		g_psLCDInfo->bFlushCommands = S3C_FALSE;
		g_psLCDInfo->psSwapChain = NULL;

		PVRGetDisplayClassJTable(&(g_psLCDInfo->sPVRJTable));

		g_psLCDInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE);
		g_psLCDInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice;
		g_psLCDInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice;
		g_psLCDInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats;
		g_psLCDInfo->sDCJTable.pfnEnumDCDims = EnumDCDims;
		g_psLCDInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer;
		g_psLCDInfo->sDCJTable.pfnGetDCInfo = GetDCInfo;
		g_psLCDInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr;
		g_psLCDInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain;
		g_psLCDInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain;
		g_psLCDInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect;
		g_psLCDInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect;
		g_psLCDInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey;
		g_psLCDInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey;
		g_psLCDInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers;
		g_psLCDInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer;
		g_psLCDInfo->sDCJTable.pfnSwapToDCSystem = SwapToDCSystem;
		g_psLCDInfo->sDCJTable.pfnSetDCState = S3CSetState;

		g_psLCDInfo->sDisplayInfo.ui32MinSwapInterval=0;
		g_psLCDInfo->sDisplayInfo.ui32MaxSwapInterval=1;
		g_psLCDInfo->sDisplayInfo.ui32MaxSwapChains=1;
		g_psLCDInfo->sDisplayInfo.ui32MaxSwapChainBuffers = num_of_fb;
		g_psLCDInfo->sDisplayInfo.ui32PhysicalWidthmm= psLINFBInfo->var.width;// width of lcd in mm 
		g_psLCDInfo->sDisplayInfo.ui32PhysicalHeightmm= psLINFBInfo->var.height;// height of lcd in mm 

		strncpy(g_psLCDInfo->sDisplayInfo.szDisplayName, "s3c_lcd", MAX_DISPLAY_NAME_SIZE);

		if(g_psLCDInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice	(&(g_psLCDInfo->sDCJTable),
			(IMG_UINT32 *)(&(g_psLCDInfo->ui32DisplayID))) != PVRSRV_OK)
		{
			return 1;
		}

		pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip;
		aui32SyncCountList[DC_FLIP_COMMAND][0] = 0;
		aui32SyncCountList[DC_FLIP_COMMAND][1] = 2;

		if (g_psLCDInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(g_psLCDInfo->ui32DisplayID,
			&pfnCmdProcList[0], aui32SyncCountList, DC_S3C_LCD_COMMAND_COUNT)
			!= PVRSRV_OK)
		{
			printk("failing register commmand proc list deviceID:%d\n",(int)g_psLCDInfo->ui32DisplayID);
			return PVRSRV_ERROR_CANT_REGISTER_CALLBACK;
		}

		if(CreateVsyncWorkQueue(g_psLCDInfo) == S3C_FALSE)
		{
			printk("fail to CreateVsyncWorkQueue\n");
			return 1;
		}
	}

	return 0;

}
OMAP_ERROR OMAPLFBInit(void)
{
	OMAPLFB_DEVINFO		*psDevInfo;

	psDevInfo = GetAnchorPtr();
	
	if (psDevInfo == NULL)
	{
		PFN_CMD_PROC	 		pfnCmdProcList[OMAPLFB_COMMAND_COUNT];
		IMG_UINT32				aui32SyncCountList[OMAPLFB_COMMAND_COUNT][2];
		
		psDevInfo = (OMAPLFB_DEVINFO *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_DEVINFO));

		if(!psDevInfo)
		{
			return (OMAP_ERROR_OUT_OF_MEMORY);
		}

		
		memset(psDevInfo, 0, sizeof(OMAPLFB_DEVINFO));

		
		SetAnchorPtr((void*)psDevInfo);

		
		psDevInfo->ulRefCount = 0;

		
		if(InitDev(psDevInfo) != OMAP_OK)
		{
			return (OMAP_ERROR_INIT_FAILURE);
		}

		if(OMAPLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &pfnGetPVRJTable) != OMAP_OK)
		{
			return (OMAP_ERROR_INIT_FAILURE);
		}

		
		if(!(*pfnGetPVRJTable)(&psDevInfo->sPVRJTable))
		{
			return (OMAP_ERROR_INIT_FAILURE);
		}

		spin_lock_init(&psDevInfo->sSwapChainLock);

		psDevInfo->psSwapChain = 0;
		psDevInfo->bFlushCommands = OMAP_FALSE;
		psDevInfo->bDeviceSuspended = OMAP_FALSE;

		psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = (IMG_UINT32)(psDevInfo->sFBInfo.ulFBSize / psDevInfo->sFBInfo.ulRoundedBufferSize);
		if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers == 0)
		{
			psDevInfo->sDisplayInfo.ui32MaxSwapChains = 0;
			psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 0;
		}
		else
		{
			psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1;
			psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 3;
		}
		psDevInfo->sDisplayInfo.ui32MinSwapInterval = 0;

		strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE);
	
		psDevInfo->sDisplayFormat.pixelformat = psDevInfo->sFBInfo.ePixelFormat;
		psDevInfo->sDisplayDim.ui32Width      = (IMG_UINT32)psDevInfo->sFBInfo.ulWidth;
		psDevInfo->sDisplayDim.ui32Height     = (IMG_UINT32)psDevInfo->sFBInfo.ulHeight;
		psDevInfo->sDisplayDim.ui32ByteStride = (IMG_UINT32)psDevInfo->sFBInfo.ulByteStride;

		DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
			": Maximum number of swap chain buffers: %lu\n",
			psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers));

		psDevInfo->sSystemBuffer.sSysAddr = psDevInfo->sFBInfo.sSysAddr;
		psDevInfo->sSystemBuffer.sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr;
		psDevInfo->sSystemBuffer.ulBufferSize = psDevInfo->sFBInfo.ulRoundedBufferSize;

		

		psDevInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE);
		psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice;
		psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice;
		psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats;
		psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims;
		psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer;
		psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo;
		psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr;
		psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain;
		psDevInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain;
		psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect;
		psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect;
		psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey;
		psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey;
		psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers;
		psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer;
		psDevInfo->sDCJTable.pfnSwapToDCSystem = SwapToDCSystem;
		psDevInfo->sDCJTable.pfnSetDCState = SetDCState;

		
		if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice (
			&psDevInfo->sDCJTable,
			&psDevInfo->ulDeviceID ) != PVRSRV_OK)
		{
			return (OMAP_ERROR_DEVICE_REGISTER_FAILED);
		}
		
		
		pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip;

		
		aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; 
		aui32SyncCountList[DC_FLIP_COMMAND][1] = 2; 

		



		if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList (psDevInfo->ulDeviceID,
																&pfnCmdProcList[0],
																aui32SyncCountList,
																OMAPLFB_COMMAND_COUNT) != PVRSRV_OK)
		{
			printk(KERN_WARNING DRIVER_PREFIX ": Can't register callback\n");
			return (OMAP_ERROR_CANT_REGISTER_CALLBACK);
		}

	}

	
	psDevInfo->ulRefCount++;

	
	return (OMAP_OK);
	
	}
Пример #3
0
int s3c_displayclass_init(void)
{
	IMG_UINT32 screen_w, screen_h;
	IMG_UINT32 va_fb, fb_size;
#if defined(S3C_DC_IS_PHYS_DISCONTIG)
	IMG_SYS_PHYADDR *parr_addr = IMG_NULL;
	IMG_UINT32 page_count;
#else
	IMG_SYS_PHYADDR pa_fb;
#endif

	IMG_UINT32 num_of_fb, num_of_backbuffer;
	IMG_UINT32 byteSize;

	struct fb_info *psLINFBInfo = 0;

	int	i;
	int rgb_format, bytes_per_pixel, bits_per_pixel;

	if(InitDev(&psLINFBInfo) == S3C_FALSE)
	{
		goto err_out;
	}

	va_fb = (unsigned long)psLINFBInfo->screen_base;
	screen_w = psLINFBInfo->var.xres;
	screen_h = psLINFBInfo->var.yres;
	bits_per_pixel = psLINFBInfo->var.bits_per_pixel;
	fb_size = psLINFBInfo->fix.smem_len;

	switch (bits_per_pixel)
	{
	case 16:
		rgb_format = PVRSRV_PIXEL_FORMAT_RGB565;
		bytes_per_pixel = 2;
		break;
	case 32:
		rgb_format = PVRSRV_PIXEL_FORMAT_ARGB8888;
		bytes_per_pixel = 4;
		break;
	default:
		rgb_format = PVRSRV_PIXEL_FORMAT_ARGB8888;
		bytes_per_pixel = 4;
		break;
	}

	byteSize = screen_w * screen_h * bytes_per_pixel;
	num_of_fb = fb_size / (screen_w * screen_h * bytes_per_pixel);

	if(num_of_fb > S3C_MAX_BUFFERS)
	{
		printk("too many frame buffers\n");
		return 0;
	}
	num_of_backbuffer = num_of_fb - 1;

#if defined(S3C_DC_IS_PHYS_DISCONTIG)
	if (GetPhysAddrFromLCDInfo(psLINFBInfo,  &page_count, &parr_addr) == IMG_FALSE)
	{
		printk("PVR s3c_lcd cannot get physical address list form lcd info\n");
		goto err_out;
	}
	printk("PA FB = 0x%X, bits per pixel = %d\n", (unsigned int)parr_addr[0].uiAddr, (unsigned int)bits_per_pixel);
#else
	pa_fb.uiAddr = psLINFBInfo->fix.smem_start;
	printk("PA FB = 0x%X, bits per pixel = %d\n", (unsigned int)pa_fb.uiAddr, (unsigned int)bits_per_pixel);
#endif

	printk("screen width=%d height=%d va=0x%x", (int)screen_w, (int)screen_h, (unsigned int)va_fb);
	printk("xres_virtual = %d, yres_virtual = %d, xoffset = %d, yoffset = %d\n", psLINFBInfo->var.xres_virtual,  psLINFBInfo->var.yres_virtual,  psLINFBInfo->var.xoffset,  psLINFBInfo->var.yoffset);
	printk("fb_size=%d\n", (int)fb_size);

	if (g_psLCDInfo == NULL)
	{
		PFN_CMD_PROC	pfnCmdProcList[DC_S3C_LCD_COMMAND_COUNT];
		IMG_UINT32	aui32SyncCountList[DC_S3C_LCD_COMMAND_COUNT][2];

		g_psLCDInfo = (S3C_LCD_DEVINFO*)kmalloc(sizeof(S3C_LCD_DEVINFO),GFP_KERNEL);
		if(!g_psLCDInfo)
		{
			printk("Fail to get memory for g_psLCDInfo\n");
			goto err_out;
		}
		memset(g_psLCDInfo, 0, sizeof(S3C_LCD_DEVINFO));

		g_psLCDInfo->psFBInfo = psLINFBInfo;
		g_psLCDInfo->ui32NumFrameBuffers = num_of_fb;

		g_psLCDInfo->ui32NumFormats = S3C_DISPLAY_FORMAT_NUM;

		g_psLCDInfo->asDisplayForamtList[0].pixelformat = rgb_format;
		g_psLCDInfo->ui32NumDims = S3C_DISPLAY_DIM_NUM;
		g_psLCDInfo->asDisplayDimList[0].ui32ByteStride = (bytes_per_pixel) * screen_w;
		g_psLCDInfo->asDisplayDimList[0].ui32Height = screen_h;
		g_psLCDInfo->asDisplayDimList[0].ui32Width = screen_w;
#if defined(S3C_DC_IS_PHYS_DISCONTIG)
		g_psLCDInfo->sSysBuffer.pbufferPAddrs = parr_addr;
#else
		g_psLCDInfo->sSysBuffer.bufferPAddr.uiAddr = pa_fb.uiAddr;
#endif
		g_psLCDInfo->sSysBuffer.bufferVAddr = (IMG_CPU_VIRTADDR)va_fb;
		g_psLCDInfo->sSysBuffer.yoffset = 0;
		g_psLCDInfo->sSysBuffer.byteSize = (IMG_UINT32)byteSize;

		for (i=0 ; i < num_of_backbuffer; i++)
		{
			g_psLCDInfo->asBackBuffers[i].byteSize = g_psLCDInfo->sSysBuffer.byteSize;
#if defined(S3C_DC_IS_PHYS_DISCONTIG)
			g_psLCDInfo->asBackBuffers[i].pbufferPAddrs = parr_addr + byteSize * (i+1) / PAGE_SIZE;
#else
			g_psLCDInfo->asBackBuffers[i].bufferPAddr.uiAddr = pa_fb.uiAddr + byteSize * (i+1);
#endif
			g_psLCDInfo->asBackBuffers[i].bufferVAddr = (IMG_CPU_VIRTADDR)(va_fb +  byteSize * (i+1));
			g_psLCDInfo->asBackBuffers[i].yoffset = screen_h * (i + 1);
		
			printk("Back frameBuffer[%d].VAddr=%p PAddr=%p size=%d\n",
				i, 
				(void*)g_psLCDInfo->asBackBuffers[i].bufferVAddr,
#if defined(S3C_DC_IS_PHYS_DISCONTIG)
				(void*)g_psLCDInfo->asBackBuffers[i].pbufferPAddrs[0].uiAddr,
#else
				(void*)g_psLCDInfo->asBackBuffers[i].bufferPAddr.uiAddr,
#endif
				(int)g_psLCDInfo->asBackBuffers[i].byteSize);
		}

		g_psLCDInfo->bFlushCommands = S3C_FALSE;
		g_psLCDInfo->psSwapChain = NULL;

		PVRGetDisplayClassJTable(&(g_psLCDInfo->sPVRJTable));

		g_psLCDInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE);
		g_psLCDInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice;
		g_psLCDInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice;
		g_psLCDInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats;
		g_psLCDInfo->sDCJTable.pfnEnumDCDims = EnumDCDims;
		g_psLCDInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer;
		g_psLCDInfo->sDCJTable.pfnGetDCInfo = GetDCInfo;
		g_psLCDInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr;
		g_psLCDInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain;
		g_psLCDInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain;
		g_psLCDInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect;
		g_psLCDInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect;
		g_psLCDInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey;
		g_psLCDInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey;
		g_psLCDInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers;
		g_psLCDInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer;
		g_psLCDInfo->sDCJTable.pfnSetDCState = S3CSetState;

		g_psLCDInfo->sDisplayInfo.ui32MinSwapInterval=0;
		g_psLCDInfo->sDisplayInfo.ui32MaxSwapInterval=1;
		g_psLCDInfo->sDisplayInfo.ui32MaxSwapChains=1;
		g_psLCDInfo->sDisplayInfo.ui32MaxSwapChainBuffers = num_of_fb;
		g_psLCDInfo->sDisplayInfo.ui32PhysicalWidthmm= psLINFBInfo->var.width;// width of lcd in mm 
		g_psLCDInfo->sDisplayInfo.ui32PhysicalHeightmm= psLINFBInfo->var.height;// height of lcd in mm 

		strncpy(g_psLCDInfo->sDisplayInfo.szDisplayName, "s3c_lcd", MAX_DISPLAY_NAME_SIZE);

		if(g_psLCDInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice	(&(g_psLCDInfo->sDCJTable),
			(IMG_UINT32 *)(&(g_psLCDInfo->ui32DisplayID))) != PVRSRV_OK)
		{
			goto err_out;
		}

		pfnCmdProcList[DC_FLIP_COMMAND] = (PFN_CMD_PROC)ProcessFlip;
		aui32SyncCountList[DC_FLIP_COMMAND][0] = 0;
		aui32SyncCountList[DC_FLIP_COMMAND][1] = 2;

		if (g_psLCDInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(g_psLCDInfo->ui32DisplayID,
			&pfnCmdProcList[0], aui32SyncCountList, DC_S3C_LCD_COMMAND_COUNT)
			!= PVRSRV_OK)
		{
			printk("failing register commmand proc list deviceID:%d\n",(int)g_psLCDInfo->ui32DisplayID);
			return PVRSRV_ERROR_CANT_REGISTER_CALLBACK;
		}

		if(CreateVsyncWorkQueue(g_psLCDInfo) == S3C_FALSE)
		{
			printk("fail to CreateVsyncWorkQueue\n");
			goto err_out;
		}
	}

#if defined(S3C_DC_IS_PHYS_DISCONTIG)
	g_psLCDInfo->pbufferPAddrs = parr_addr;
#endif
	return 0;

err_out:
#if defined(S3C_DC_IS_PHYS_DISCONTIG)
	if (parr_addr != NULL)
		kfree(parr_addr);
#endif
	printk("fail to init s3c lcd for pvr driver\n");
	return 1;
}