示例#1
0
static int fimc_open(struct file *filp)
{
	struct fimc_control *ctrl;
	struct s3c_platform_fimc *pdata;
	int ret;

	ctrl = video_get_drvdata(video_devdata(filp));
	pdata = to_fimc_plat(ctrl->dev);

	mutex_lock(&ctrl->lock);

	if (atomic_read(&ctrl->in_use)) {
		ret = -EBUSY;
		goto resource_busy;
	} else {
		atomic_inc(&ctrl->in_use);
	}

	if (pdata->clk_on)
		pdata->clk_on(to_platform_device(ctrl->dev), ctrl->clk);
#if defined(CONFIG_VIDEO_FIMC_FIFO)
	fimc_hwset_clksrc(ctrl,FIMC_SCLK);
	fimc_hwset_sclk_enable(ctrl);
#endif
	if (pdata->hw_ver == 0x40)
		fimc_hw_reset_camera(ctrl);

	/* Apply things to interface register */
	fimc_hwset_reset(ctrl);
	filp->private_data = ctrl;

	ctrl->fb.open_fifo = s3cfb_open_fifo;
	ctrl->fb.close_fifo = s3cfb_close_fifo;

	ret = s3cfb_direct_ioctl(ctrl->id, S3CFB_GET_LCD_WIDTH,
					(unsigned long)&ctrl->fb.lcd_hres);
	if (ret < 0)
		fimc_err("Fail: S3CFB_GET_LCD_WIDTH\n");

	ret = s3cfb_direct_ioctl(ctrl->id, S3CFB_GET_LCD_HEIGHT,
					(unsigned long)&ctrl->fb.lcd_vres);
	if (ret < 0)
		fimc_err("Fail: S3CFB_GET_LCD_HEIGHT\n");

	ctrl->mem.curr = ctrl->mem.base;
	ctrl->status = FIMC_STREAMOFF;

	mutex_unlock(&ctrl->lock);

	return 0;

resource_busy:
	mutex_unlock(&ctrl->lock);
	return ret;
}
示例#2
0
static int fimc_change_fifo_position(struct fimc_control *ctrl,
				     struct fimc_ctx *ctx) {
	struct v4l2_rect fimd_rect;
	struct s3cfb_user_window window;
	int ret = -1;

	memset(&fimd_rect, 0, sizeof(struct v4l2_rect));

	ret = fimc_fimd_rect(ctrl, ctx, &fimd_rect);
	if (ret < 0) {
		fimc_err("fimc_fimd_rect fail\n");
		return -EINVAL;
	}

	/* Update WIN position */
	window.x = fimd_rect.left;
	window.y = fimd_rect.top;
	ret = s3cfb_direct_ioctl(ctrl->id, S3CFB_WIN_POSITION,
			(unsigned long)&window);
	if (ret < 0) {
		fimc_err("direct_ioctl(S3CFB_WIN_POSITION) fail\n");
		return -EINVAL;
	}

	return 0;
}
示例#3
0
static int fimc_init_camera(struct fimc_control *ctrl)
{
	struct fimc_global *fimc = get_fimc_dev();
	struct s3c_platform_fimc *pdata;
	struct s3c_platform_camera *cam;
	struct v4l2_streamparm stream;
	int ret;

	pdata = to_fimc_plat(ctrl->dev);
	if (pdata->default_cam >= FIMC_MAXCAMS) {
		dev_err(ctrl->dev, "%s: invalid camera index\n", __func__);
		return -EINVAL;
	}

	if (!fimc->camera[pdata->default_cam]) {
		dev_err(ctrl->dev, "no external camera device\n");
		return -ENODEV;
	}

	/*
	 * ctrl->cam may not be null if already s_input called,
	 * otherwise, that should be default_cam if ctrl->cam is null.
	*/
	if (!ctrl->cam)
		ctrl->cam = fimc->camera[pdata->default_cam];

	cam = ctrl->cam;

	/* do nothing if already initialized */
	if (cam->initialized)
		return 0;

	/* 
	 * WriteBack mode doesn't need to set clock and power,
	 * but it needs to set source width, height depend on LCD resolution.
	*/
	if (cam->id == CAMERA_WB) {
		s3cfb_direct_ioctl(0, S3CFB_GET_LCD_WIDTH, (unsigned long)&cam->width);	
		s3cfb_direct_ioctl(0, S3CFB_GET_LCD_HEIGHT, (unsigned long)&cam->height);
		cam->window.width = cam->width;
		cam->window.height = cam->height;
		cam->initialized = 1;
		return 0;
	}
	
	/* set rate for mclk */
	if (cam->clk->set_rate) {
		clk_disable(cam->clk);
		cam->clk->set_rate(cam->clk, cam->clk_rate);
		clk_enable(cam->clk);
		dev_info(ctrl->dev, "clock for camera: %d\n", cam->clk_rate);
	}

	/* enable camera power if needed */
	if (cam->cam_power)
		cam->cam_power(1);
	
	/* camera s/w reset*/
	fimc_hwset_hw_reset();


	/* subdev call for init */
	ret = v4l2_subdev_call(cam->sd, core, init, 0);
	if (ret == -ENOIOCTLCMD) {
		dev_err(ctrl->dev, "%s: init subdev api not supported\n",
			__func__);
		return ret;
	}

	/*set resolution SVGA*/
	stream.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	stream.parm.capture.capturemode = 0;

	ret = v4l2_subdev_call(cam->sd, video, s_parm, &stream);
	if (ret == -ENOIOCTLCMD) {
		dev_err(ctrl->dev, "%s: init subdev api not supported\n",
			__func__);
		return ret;
	}

	if (cam->type == CAM_TYPE_MIPI) {
		/* 
		 * subdev call for sleep/wakeup:
		 * no error although no s_stream api support
		*/
		v4l2_subdev_call(cam->sd, video, s_stream, 0);
		s3c_csis_start(cam->mipi_lanes, cam->mipi_settle, \
				cam->mipi_align, cam->width, cam->height);
		v4l2_subdev_call(cam->sd, video, s_stream, 1);
	}

	cam->initialized = 1;

	return 0;
}
示例#4
0
static inline u32 fimc_irq_out_dma(struct fimc_control *ctrl)
{
	struct fimc_buf_set buf_set;
	u32 next = 0, wakeup = 1;
	int idx = ctrl->out->idx.active;
	int ret = -1, i;

	if (ctrl->status == FIMC_READY_OFF) {
		ctrl->out->idx.active = -1;
		ctrl->status = FIMC_STREAMOFF;
		return wakeup;
	}

	/* Attach done buffer to outgoing queue. */
	ret = fimc_attach_out_queue(ctrl, idx);
	if (ret < 0)
		fimc_err("Failed: fimc_attach_out_queue\n");

	if(ctrl->out->overlay.mode == FIMC_OVERLAY_DMA_AUTO) {
		ret = s3cfb_direct_ioctl(ctrl->id, S3CFB_SET_WIN_ADDR, \
				(unsigned long)ctrl->out->dst[idx].base[FIMC_ADDR_Y]);
		if (ret < 0) {
			fimc_err("direct_ioctl(S3CFB_SET_WIN_ADDR) fail\n");
			return -EINVAL;
		}

		if(ctrl->fb.is_enable == 0) {
			ret = s3cfb_direct_ioctl(ctrl->id, S3CFB_SET_WIN_ON, \
								(unsigned long)NULL);
			if (ret < 0) {
				fimc_err("direct_ioctl(S3CFB_SET_WIN_ON) fail\n");
				return -EINVAL;
			}

			ctrl->fb.is_enable = 1;
		}
	}

	/* Detach buffer from incomming queue. */
	ret =  fimc_detach_in_queue(ctrl, &next);
	if (ret == 0) {	/* There is a buffer in incomming queue. */
		fimc_outdev_set_src_addr(ctrl, ctrl->out->src[next].base);

		memset(&buf_set, 0x00, sizeof(buf_set));
		buf_set.base[FIMC_ADDR_Y] = ctrl->out->dst[next].base[FIMC_ADDR_Y];

		for (i = 0; i < FIMC_PHYBUFS; i++)
			fimc_hwset_output_address(ctrl, &buf_set, i);
		
		ret = fimc_outdev_start_camif(ctrl);
		if (ret < 0)
			fimc_err("Fail: fimc_start_camif\n");

		ctrl->out->idx.active = next;
		ctrl->status = FIMC_STREAMON;
	} else {	/* There is no buffer in incomming queue. */
		ctrl->out->idx.active = -1;
		ctrl->status = FIMC_STREAMON_IDLE;
	}

	return wakeup;
}
示例#5
0
文件: fimc_dev.c 项目: Arakmar/G3MOD
static int fimc_open(struct file *filp)
{
	struct fimc_control *ctrl;
	struct s3c_platform_fimc *pdata;
	unsigned long flags;
	int ret;
	u32 cfg;
	#ifdef VIEW_FUNCTION_CALL
	printk("[FIMC_DEV] %s(%d)\n", __func__, __LINE__);
#endif

	/* An ugly hack to make the i2c pins output low */
	if (unlikely(make_i2c_pin_low == 1)) {
	    cfg = readl(S5P64XX_GPD1DAT);
	    cfg &= ~(0x1 << 0);
	    writel(cfg, S5P64XX_GPD1DAT);
	    cfg = readl(S5P64XX_GPD1DAT);
	    cfg &= ~(0x1 << 1);
	    writel(cfg, S5P64XX_GPD1DAT);
	    make_i2c_pin_low = 0;
	}

	ctrl = video_get_drvdata(video_devdata(filp));

#ifdef S5P6442_POWER_GATING_CAM
	del_timer(&g_fimc_domain_timer);
//	fimc0 controller for Camera
	if(ctrl->id == CAM_ID){
	   spin_lock_irqsave(&fimc_domain_lock, flags);
	   gFIMC_CNT[CAM_ID]++;
	   s5p6442_idle_pm_gpiocfg(S5P6442_CAM_ID, S5P6442_ACTIVE_MODE); 
           s5p6442_pwrgate_config(S5P6442_CAM_ID, S5P6442_ACTIVE_MODE);
	   spin_unlock_irqrestore(&fimc_domain_lock, flags);
	}
//           gFIMC_CNT++;
//        }
#endif

#ifdef CONFIG_CPU_FREQ
	if(ctrl->id == CAM_ID){
	        set_dvfs_level(0);
	}
#endif /* CONFIG_CPU_FREQ */

	pdata = to_fimc_plat(ctrl->dev);

	mutex_lock(&ctrl->lock);

	if (atomic_read(&ctrl->in_use)) {
		ret = -EBUSY;
		goto resource_busy;
	} else {
		atomic_inc(&ctrl->in_use);
	}

	if (pdata->clk_on)
		pdata->clk_on(to_platform_device(ctrl->dev), ctrl->clk);

	/* Apply things to interface register */
	fimc_hwset_reset(ctrl);
	filp->private_data = ctrl;

	ctrl->fb.open_fifo = s3cfb_open_fifo;
	ctrl->fb.close_fifo = s3cfb_close_fifo;

	ret = s3cfb_direct_ioctl(ctrl->id, S3CFB_GET_LCD_WIDTH,
					(unsigned long)&ctrl->fb.lcd_hres);
	if (ret < 0)
		dev_err(ctrl->dev, "Fail: S3CFB_GET_LCD_WIDTH\n");

	ret = s3cfb_direct_ioctl(ctrl->id, S3CFB_GET_LCD_HEIGHT,
					(unsigned long)&ctrl->fb.lcd_vres);
	if (ret < 0)
		dev_err(ctrl->dev, "Fail: S3CFB_GET_LCD_HEIGHT\n");

	ctrl->status = FIMC_STREAMOFF;

#if 0
	/* To do : have to send ctrl to the fimd driver. */
	ret = s3cfb_direct_ioctl(ctrl->id, S3CFB_SET_SUSPEND_FIFO,
			(unsigned long)fimc_sleep);
	if (ret < 0)
		dev_err(ctrl->dev,
			"s3cfb_direct_ioctl(S3CFB_SET_SUSPEND_FIFO) fail\n");

	ret = s3cfb_direct_ioctl(ctrl->id, S3CFB_SET_RESUME_FIFO,
			(unsigned long)fimc_wakeup);
	if (ret < 0)
		dev_err(ctrl->dev,
			"s3cfb_direct_ioctl(S3CFB_SET_SUSPEND_FIFO) fail\n");
#endif
	mutex_unlock(&ctrl->lock);

	return 0;

resource_busy:
	mutex_unlock(&ctrl->lock);
	return ret;
}
示例#6
0
S3C_BC_ERROR S3C_BC_Register(void)
{
	S3C_BC_DEVINFO	*psDevInfo;
	int i;
	unsigned long addr;

	IMG_UINT32 pixelformat;
	struct fb_fix_screeninfo fix;
	struct fb_var_screeninfo var;

	s3cfb_direct_ioctl(FB_NUM, FBIOGET_FSCREENINFO, (unsigned long)&fix);
	s3cfb_direct_ioctl(FB_NUM, FBIOGET_VSCREENINFO, (unsigned long)&var);

	g_screen_w = var.xres;
	g_screen_h = var.yres;
	if ( g_screen_w >= g_screen_h )
		g_screen_h = g_screen_w;
	else
		g_screen_w = g_screen_h;

	if (16 == var.bits_per_pixel)
	{
		pixelformat = PVRSRV_PIXEL_FORMAT_RGB565;
		g_screen_stride = g_screen_w*2;
	}
	else
	{
		pixelformat = PVRSRV_PIXEL_FORMAT_ARGB8888;
		g_screen_stride = g_screen_w*4;
	}

	g_buffer_size = ((g_screen_h * g_screen_stride + S3C_BC_DEVICE_PHYS_PAGE_SIZE - 1) & ~(S3C_BC_DEVICE_PHYS_PAGE_SIZE-1));

	psDevInfo = GetAnchorPtr();

	if (!psDevInfo)
	{
		psDevInfo = (S3C_BC_DEVINFO *)BCAllocKernelMem(sizeof(S3C_BC_DEVINFO));

		if(!psDevInfo)
		{
			return (S3C_BC_ERROR_OUT_OF_MEMORY);/* failure */
		}

		SetAnchorPtr((void*)psDevInfo);

		psDevInfo->ulRefCount = 0;
		
		psDevInfo->ulDeviceID = S3C_BC_DEVICE_ID;
	
		if(BCGetLibFuncAddr ("PVRGetBufferClassJTable", &pfnGetPVRJTable) != S3C_BC_OK)
		{
			return (S3C_BC_ERROR_INIT_FAILURE);
		}

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


		psDevInfo->sBufferInfo.pixelformat        = pixelformat;
		psDevInfo->sBufferInfo.ui32Width          = g_screen_w;
		psDevInfo->sBufferInfo.ui32Height         = g_screen_h;
		psDevInfo->sBufferInfo.ui32ByteStride     = g_screen_stride;
		psDevInfo->sBufferInfo.ui32BufferDeviceID = S3C_BC_DEVICE_ID;
		psDevInfo->sBufferInfo.ui32Flags          = 0;
		psDevInfo->sBufferInfo.ui32BufferCount    = S3C_BC_DEVICE_BUFFER_COUNT;

		addr = S3C_BC_DEVICE_PHYS_ADDR_START;
		for(i = 0; i < S3C_BC_DEVICE_BUFFER_COUNT; i++, addr += g_buffer_size)
		{
			psDevInfo->sSystemBuffer[i].sSysAddr.uiAddr = (IMG_UINTPTR_T)addr;
		}

		psDevInfo->sBCJTable.ui32TableSize    = sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE);
		psDevInfo->sBCJTable.pfnOpenBCDevice  = OpenBCDevice;
		psDevInfo->sBCJTable.pfnCloseBCDevice = CloseBCDevice;
		psDevInfo->sBCJTable.pfnGetBCBuffer   = GetBCBuffer;
		psDevInfo->sBCJTable.pfnGetBCInfo     = GetBCInfo;
		psDevInfo->sBCJTable.pfnGetBufferAddr = GetBCBufferAddr;

		if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterBCDevice (&psDevInfo->sBCJTable,
										(IMG_UINT32*)&psDevInfo->ulDeviceID ) != PVRSRV_OK)
		{
			return (S3C_BC_ERROR_DEVICE_REGISTER_FAILED);
		}
	}

	psDevInfo->ulRefCount++;

	return (S3C_BC_OK);
}
示例#7
0
int init()
{
    IMG_UINT32 screen_w, screen_h;
    IMG_UINT32 pa_fb, va_fb;
    IMG_UINT32 byteSize;
    int	i;

    int rgb_format, bytes_per_pixel;

    struct fb_fix_screeninfo fix;
    struct fb_var_screeninfo var;


    s3cfb_direct_ioctl(FB_NUM, FBIOGET_FSCREENINFO, (unsigned long)&fix);
    s3cfb_direct_ioctl(FB_NUM, FBIOGET_VSCREENINFO, (unsigned long)&var);

    screen_w = var.xres;
    screen_h = var.yres;
    pa_fb = fix.smem_start;
    printk("PA FB = 0x%X, bits per pixel = %d\n", (unsigned int)fix.smem_start, (unsigned int)var.bits_per_pixel);
    va_fb = (unsigned long)phys_to_virt(pa_fb);

    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);

#if 1
    regs = (volatile unsigned int)ioremap(0xF8000000, 0x00100000);
#endif
    //spin_lock_init(g_psLCDInfo->psSwapChainLock);

    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->ui32NumFormats = S3C_DISPLAY_FORMAT_NUM;
        switch (var.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;
        }

        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;

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

        for (i=0; i<S3C_MAX_BACKBUFFERRS; i++)
        {
            g_psLCDInfo->asBackBuffers[i].byteSize = g_psLCDInfo->sSysBuffer.byteSize;
#if 1
            // modified by jamie (2010.04.09)
            // to use the frame buffer already allocated by LCD driver.
            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);

#else
            if(AllocLinearMemory(
                        g_psLCDInfo->asBackBuffers[i].byteSize,
                        (IMG_UINT32*)&(g_psLCDInfo->asBackBuffers[i].bufferVAddr),
                        &(g_psLCDInfo->asBackBuffers[i].bufferPAddr.uiAddr)))
                return 1;
#endif

            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=0;
        g_psLCDInfo->sDisplayInfo.ui32MaxSwapChains=1;
        g_psLCDInfo->sDisplayInfo.ui32MaxSwapChainBuffers=S3C_NUM_TOTAL_BUFFER;
        g_psLCDInfo->sDisplayInfo.ui32PhysicalWidthmm=var.width;	// width of lcd in mm
        g_psLCDInfo->sDisplayInfo.ui32PhysicalHeightmm=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;
        }

        //printk("deviceID:%d\n",(int)g_psLCDInfo->ui32DisplayID);

        // register flip command
        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;
        }

        LCDControllerBase = (volatile unsigned int *)ioremap(0xf8000000,1024);
    }

    return 0;

}