コード例 #1
0
static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
			    int rotate, unsigned int num)
{
	unsigned int x;

	if (rotate == FB_ROTATE_UR) {
		for (x = 0;
		     x < num && image->dx + image->width <= info->var.xres;
		     x++) {
			info->fbops->fb_imageblit(info, image);
			image->dx += image->width + 8;
		}
	} else if (rotate == FB_ROTATE_UD) {
		for (x = 0; x < num && image->dx >= 0; x++) {
			info->fbops->fb_imageblit(info, image);
			image->dx -= image->width + 8;
		}
	} else if (rotate == FB_ROTATE_CW) {
		for (x = 0;
		     x < num && image->dy + image->height <= info->var.yres;
		     x++) {
			info->fbops->fb_imageblit(info, image);
			image->dy += image->height + 8;
		}
	} else if (rotate == FB_ROTATE_CCW) {
		for (x = 0; x < num && image->dy >= 0; x++) {
			info->fbops->fb_imageblit(info, image);
			image->dy -= image->height + 8;
		}
	}
	unlock_fb_info(info);
}
コード例 #2
0
static
PVRSRV_ERROR DC_FBDEV_DimQuery(IMG_HANDLE hDeviceData,
							   IMG_UINT32 ui32NumDims,
							   PVRSRV_SURFACE_DIMS *psDim,
							   IMG_UINT32 *pui32Supported)
{
	DC_FBDEV_DEVICE *psDeviceData = hDeviceData;
	struct fb_var_screeninfo *psVar = &psDeviceData->psLINFBInfo->var;
	int i;

	if(!lock_fb_info(psDeviceData->psLINFBInfo))
		return PVRSRV_ERROR_RETRY;

	for(i = 0; i < ui32NumDims; i++)
	{
		pui32Supported[i] = 0;

		if(psDim[i].ui32Width  == psVar->xres &&
		   psDim[i].ui32Height == psVar->yres)
			pui32Supported[i]++;
	}

	unlock_fb_info(psDeviceData->psLINFBInfo);
	return PVRSRV_OK;
}
コード例 #3
0
static ssize_t store_size(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct omapfb_info *ofbi = FB2OFB(fbi);
	unsigned long size;
	int r;
	int i;

	size = PAGE_ALIGN(simple_strtoul(buf, NULL, 0));

	if (!lock_fb_info(fbi))
		return -ENODEV;

	for (i = 0; i < ofbi->num_overlays; i++) {
		if (ofbi->overlays[i]->info.enabled) {
			r = -EBUSY;
			goto out;
		}
	}

	if (size != ofbi->region.size) {
		r = omapfb_realloc_fbmem(fbi, size, ofbi->region.type);
		if (r) {
			dev_err(dev, "realloc fbmem failed\n");
			goto out;
		}
	}

	r = count;
out:
	unlock_fb_info(fbi);

	return r;
}
コード例 #4
0
static ssize_t show_overlays(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;
	ssize_t l = 0;
	int t;

	if (!lock_fb_info(fbi))
		return -ENODEV;
	omapfb_lock(fbdev);

	for (t = 0; t < ofbi->num_overlays; t++) {
		struct omap_overlay *ovl = ofbi->overlays[t];
		int ovlnum;

		for (ovlnum = 0; ovlnum < fbdev->num_overlays; ++ovlnum)
			if (ovl == fbdev->overlays[ovlnum])
				break;

		l += snprintf(buf + l, PAGE_SIZE - l, "%s%d",
				t == 0 ? "" : ",", ovlnum);
	}

	l += snprintf(buf + l, PAGE_SIZE - l, "\n");

	omapfb_unlock(fbdev);
	unlock_fb_info(fbi);

	return l;
}
コード例 #5
0
ファイル: fbcmap.c プロジェクト: 020gzh/linux
int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
{
	int rc, size = cmap->len * sizeof(u16);
	struct fb_cmap umap;

	if (size < 0 || size < cmap->len)
		return -E2BIG;

	memset(&umap, 0, sizeof(struct fb_cmap));
	rc = fb_alloc_cmap_gfp(&umap, cmap->len, cmap->transp != NULL,
				GFP_KERNEL);
	if (rc)
		return rc;
	if (copy_from_user(umap.red, cmap->red, size) ||
	    copy_from_user(umap.green, cmap->green, size) ||
	    copy_from_user(umap.blue, cmap->blue, size) ||
	    (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) {
		rc = -EFAULT;
		goto out;
	}
	umap.start = cmap->start;
	if (!lock_fb_info(info)) {
		rc = -ENODEV;
		goto out;
	}

	rc = fb_set_cmap(&umap, info);
	unlock_fb_info(info);
out:
	fb_dealloc_cmap(&umap);
	return rc;
}
コード例 #6
0
int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
{
	int rc, size = cmap->len * sizeof(u16);
	struct fb_cmap umap;

	memset(&umap, 0, sizeof(struct fb_cmap));
	rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL);
	if (rc)
		return rc;
	if (copy_from_user(umap.red, cmap->red, size) ||
	    copy_from_user(umap.green, cmap->green, size) ||
	    copy_from_user(umap.blue, cmap->blue, size) ||
	    (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) {
		rc = -EFAULT;
		goto out;
	}
	umap.start = cmap->start;
	if (!lock_fb_info(info)) {
		rc = -ENODEV;
		goto out;
	}
	if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
				!info->fbops->fb_setcmap)) {
		rc = -EINVAL;
		goto out1;
	}
	rc = fb_set_cmap(&umap, info);
out1:
	unlock_fb_info(info);
out:
	fb_dealloc_cmap(&umap);
	return rc;
}
コード例 #7
0
static void blank_framebuffer(int getref)
{
	struct device *fbdev = NULL;
	struct fb_info *fb_info;
	struct s3c_fb_win *win;
	struct s3c_fb *sfb;
	struct s3c_fb_platdata *pd;

	fbdev = get_fb_dev();
	if (!fbdev)
		return;

	fb_info = get_fb_info(fbdev);
	if (!fb_info)
		return;

	/*
	 * hold a reference to the dsim device, to prevent it from going into
	 * power management during tui session
	 */
	win = fb_info->par;
	sfb = win->parent;
	pd = sfb->pdata;

	/* Re-enable the clocks */
	//enable_clocks(fbdev->parent,
		//	disp_clock_name, ARRAY_SIZE(disp_clock_name), 1);
	//enable_clocks(NULL, other_clock_name, ARRAY_SIZE(other_clock_name), 1);

#if defined(CONFIG_SOC_EXYNOS5420)
	pm_runtime_get_sync(pd->dsim1_device);
#endif
	if (getref)
		pm_runtime_get_sync(sfb->dev);

	/* blank the framebuffer */
	lock_fb_info(fb_info);
	console_lock();
	fb_info->flags |= FBINFO_MISC_USEREVENT;
	fb_blank(fb_info, FB_BLANK_POWERDOWN);
	fb_info->flags &= ~FBINFO_MISC_USEREVENT;
	console_unlock();
	unlock_fb_info(fb_info);

#if defined(CONFIG_SOC_EXYNOS5420)
	/*
	 * part of the init of dsim device is not done in the TEE.  So do it
	 * here
	 */
	gpio_request_one(EXYNOS5420_GPF1(6),
			GPIOF_OUT_INIT_HIGH, "GPIO_MIPI_18V_EN");
	usleep_range(5000, 6000);
	gpio_free(EXYNOS5420_GPF1(6));
#endif

}
コード例 #8
0
ファイル: sprdfb_main.c プロジェクト: ShinySide/SM-G361H
static void sprdfb_shutdown(struct platform_device *pdev)
{
	struct sprdfb_device *dev = platform_get_drvdata(pdev);
	struct fb_info *fb = dev->fb;

	if (!lock_fb_info(fb))
		return;

	sprdfb_power(dev, 0);
	unlock_fb_info(fb);
}
コード例 #9
0
static void sprdfb_early_suspend (struct early_suspend* es)
{
	struct sprdfb_device *dev = container_of(es, struct sprdfb_device, early_suspend);
	struct fb_info *fb = dev->fb;
	printk("sprdfb: [%s]\n",__FUNCTION__);

	fb_set_suspend(fb, FBINFO_STATE_SUSPENDED);

	if (!lock_fb_info(fb)) {
		return ;
	}
	dev->ctrl->suspend(dev);
	unlock_fb_info(fb);
}
コード例 #10
0
ファイル: sprdfb_main.c プロジェクト: ShinySide/SM-G361H
static void sprdfb_late_resume (struct early_suspend* es)
{
	struct sprdfb_device *dev = container_of(es, struct sprdfb_device, early_suspend);
	struct fb_info *fb = dev->fb;
	pr_debug("sprdfb: [%s]\n",__FUNCTION__);

	if (!lock_fb_info(fb)) {
		return ;
	}
	dev->ctrl->resume(dev);
	unlock_fb_info(fb);

	fb_set_suspend(fb, FBINFO_STATE_RUNNING);
}
コード例 #11
0
/* This function is exported for SGX driver use */
int omapfb_update_window(struct fb_info *fbi,
		u32 x, u32 y, u32 w, u32 h)
{
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;
	int r;

	if (!lock_fb_info(fbi))
		return -ENODEV;
	omapfb_lock(fbdev);

	r = omapfb_update_window_nolock(fbi, x, y, w, h);

	omapfb_unlock(fbdev);
	unlock_fb_info(fbi);

	return r;
}
コード例 #12
0
static ssize_t store_rotate_type(struct device *dev,
		struct device_attribute *attr,
		const char *buf, size_t count)
{
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_mem_region *rg;
	int rot_type;
	int r;

	r = kstrtoint(buf, 0, &rot_type);
	if (r)
		return r;

	if (rot_type != OMAP_DSS_ROT_DMA && rot_type != OMAP_DSS_ROT_VRFB)
		return -EINVAL;

	if (!lock_fb_info(fbi))
		return -ENODEV;

	r = 0;
	if (rot_type == ofbi->rotation_type)
		goto out;

	rg = omapfb_get_mem_region(ofbi->region);

	if (rg->size) {
		r = -EBUSY;
		goto put_region;
	}

	ofbi->rotation_type = rot_type;

	/*
	 * Since the VRAM for this FB is not allocated at the moment we don't
	 * need to do any further parameter checking at this point.
	 */
put_region:
	omapfb_put_mem_region(rg);
out:
	unlock_fb_info(fbi);

	return r ? r : count;
}
コード例 #13
0
static void __exit DC_FBDEV_exit(void)
{
	DC_FBDEV_DEVICE *psDeviceData = gpsDeviceData;
	struct fb_info *psLINFBInfo = psDeviceData->psLINFBInfo;

	lock_fb_info(psLINFBInfo);
	console_lock();

    if(psLINFBInfo->fbops->fb_release)
	   psLINFBInfo->fbops->fb_release(psLINFBInfo, 0);

	module_put(psLINFBInfo->fbops->owner);

	console_unlock();
	unlock_fb_info(psLINFBInfo);

	DCUnregisterDevice(psDeviceData->hSrvHandle);
	kfree(psDeviceData);
}
コード例 #14
0
ファイル: omapfb-sysfs.c プロジェクト: 119-org/hi3518-osdrv
static ssize_t store_mirror(struct device *dev,
		struct device_attribute *attr,
		const char *buf, size_t count)
{
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct omapfb_info *ofbi = FB2OFB(fbi);
	int mirror;
	int r;
	struct fb_var_screeninfo new_var;

	r = kstrtoint(buf, 0, &mirror);
	if (r)
		return r;

	mirror = !!mirror;

	if (!lock_fb_info(fbi))
		return -ENODEV;

	ofbi->mirror = mirror;

	omapfb_get_mem_region(ofbi->region);

	memcpy(&new_var, &fbi->var, sizeof(new_var));
	r = check_fb_var(fbi, &new_var);
	if (r)
		goto out;
	memcpy(&fbi->var, &new_var, sizeof(fbi->var));

	set_fb_fix(fbi);

	r = omapfb_apply_changes(fbi, 0);
	if (r)
		goto out;

	r = count;
out:
	omapfb_put_mem_region(ofbi->region);

	unlock_fb_info(fbi);

	return r;
}
コード例 #15
0
static ssize_t show_overlays_rotate(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct omapfb_info *ofbi = FB2OFB(fbi);
	ssize_t l = 0;
	int t;

	lock_fb_info(fbi);

	for (t = 0; t < ofbi->num_overlays; t++) {
		l += snprintf(buf + l, PAGE_SIZE - l, "%s%d",
				t == 0 ? "" : ",", ofbi->rotation[t]);
	}

	l += snprintf(buf + l, PAGE_SIZE - l, "\n");

	unlock_fb_info(fbi);

	return l;
}
コード例 #16
0
static void blank_framebuffer(int getref)
{
	struct device *fbdev = NULL;
	struct fb_info *fb_info;
	struct s3c_fb_win *win;
	struct s3c_fb *sfb;

	fbdev = get_fb_dev();
	if (!fbdev)
		return;

	fb_info = get_fb_info(fbdev);
	if (!fb_info)
		return;

	/*
	 * hold a reference to the dsim device, to prevent it from going into
	 * power management during tui session
	 */
	win = fb_info->par;
	sfb = win->parent;

	if (getref)
		pm_runtime_get_sync(sfb->dev);

	/* blank the framebuffer */
	lock_fb_info(fb_info);
	console_lock();
	fb_info->flags |= FBINFO_MISC_USEREVENT;
	pr_info("%s call fb_blank\n", __func__);
	fb_blank(fb_info, FB_BLANK_POWERDOWN);
	fb_info->flags &= ~FBINFO_MISC_USEREVENT;
	console_unlock();
	unlock_fb_info(fb_info);
	pr_info("%s call s3c_fb_deactivate_vsync\n", __func__);
	s3c_fb_deactivate_vsync(sfb);

}
コード例 #17
0
static ssize_t store_mirror(struct device *dev,
		struct device_attribute *attr,
		const char *buf, size_t count)
{
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct omapfb_info *ofbi = FB2OFB(fbi);
	bool mirror;
	int r;
	struct fb_var_screeninfo new_var;

	mirror = simple_strtoul(buf, NULL, 0);

	if (mirror != 0 && mirror != 1)
		return -EINVAL;

	if (!lock_fb_info(fbi))
		return -ENODEV;

	ofbi->mirror = mirror;

	memcpy(&new_var, &fbi->var, sizeof(new_var));
	r = check_fb_var(fbi, &new_var);
	if (r)
		goto out;
	memcpy(&fbi->var, &new_var, sizeof(fbi->var));

	set_fb_fix(fbi);

	r = omapfb_apply_changes(fbi, 0);
	if (r)
		goto out;

	r = count;
out:
	unlock_fb_info(fbi);

	return r;
}
コード例 #18
0
static ssize_t store_rotate_type(struct device *dev,
		struct device_attribute *attr,
		const char *buf, size_t count)
{
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct omapfb_info *ofbi = FB2OFB(fbi);
	enum omap_dss_rotation_type rot_type;
	int r;

	rot_type = simple_strtoul(buf, NULL, 0);

	if (rot_type != OMAP_DSS_ROT_DMA && rot_type != OMAP_DSS_ROT_VRFB)
		return -EINVAL;

	if (!lock_fb_info(fbi))
		return -ENODEV;

	r = 0;
	if (rot_type == ofbi->rotation_type)
		goto out;

	if (ofbi->region.size) {
		r = -EBUSY;
		goto out;
	}

	ofbi->rotation_type = rot_type;

	/*
	 * Since the VRAM for this FB is not allocated at the moment we don't
	 * need to do any further parameter checking at this point.
	 */
out:
	unlock_fb_info(fbi);

	return r ? r : count;
}
コード例 #19
0
static
PVRSRV_ERROR DC_FBDEV_PanelQuery(IMG_HANDLE hDeviceData,
								 IMG_UINT32 ui32PanelsArraySize,
								 IMG_UINT32 *pui32NumPanels,
								 PVRSRV_PANEL_INFO *psPanelInfo)
{
	DC_FBDEV_DEVICE *psDeviceData = hDeviceData;
	struct fb_var_screeninfo *psVar = &psDeviceData->psLINFBInfo->var;
	struct fb_var_screeninfo sVar = { .pixclock = 0 };

	if(!lock_fb_info(psDeviceData->psLINFBInfo))
		return PVRSRV_ERROR_RETRY;

	*pui32NumPanels = 1;

	psPanelInfo[0].sSurfaceInfo.sFormat.ePixFormat = psDeviceData->ePixFormat;
	psPanelInfo[0].sSurfaceInfo.sDims.ui32Width    = psVar->xres;
	psPanelInfo[0].sSurfaceInfo.sDims.ui32Height   = psVar->yres;
	psPanelInfo[0].sSurfaceInfo.sFormat.eMemLayout = PVRSRV_SURFACE_MEMLAYOUT_STRIDED;
	psPanelInfo[0].sSurfaceInfo.sFormat.u.sFBCLayout.eFBCompressionMode = FB_COMPRESSION_NONE;

	/* Conformant fbdev drivers should have `var' and mode in sync by now,
	 * but some don't (like drmfb), so try a couple of different ways to
	 * get the info before falling back to the default.
	 */
	if(psVar->xres > 0 && psVar->yres > 0 && psVar->pixclock > 0)
		sVar = *psVar;
	else if(psDeviceData->psLINFBInfo->mode)
		fb_videomode_to_var(&sVar, psDeviceData->psLINFBInfo->mode);

	/* Override the refresh rate when defined. */
#ifdef DC_FBDEV_REFRESH
	psPanelInfo[0].ui32RefreshRate = DC_FBDEV_REFRESH;
#else
	if(sVar.xres > 0 && sVar.yres > 0 && sVar.pixclock > 0)
	{
		psPanelInfo[0].ui32RefreshRate = 1000000000LU /
			((sVar.upper_margin + sVar.lower_margin +
			  sVar.yres + sVar.vsync_len) *
			 (sVar.left_margin  + sVar.right_margin +
			  sVar.xres + sVar.hsync_len) *
			 (sVar.pixclock / 1000));
	}
	else
		psPanelInfo[0].ui32RefreshRate = FALLBACK_REFRESH_RATE;
#endif

	/* MTK: fixme */
	if (psPanelInfo[0].ui32RefreshRate == 0)
		psPanelInfo[0].ui32RefreshRate = FALLBACK_REFRESH_RATE;

	psPanelInfo[0].ui32XDpi =
		((int)sVar.width > 0) ? (254000 / sVar.width * psVar->xres / 10000) : FALLBACK_DPI;

	psPanelInfo[0].ui32YDpi	=
		((int)sVar.height > 0) ? 254000 / sVar.height * psVar->yres / 10000 : FALLBACK_DPI;

	unlock_fb_info(psDeviceData->psLINFBInfo);
	return PVRSRV_OK;
}

static
PVRSRV_ERROR DC_FBDEV_FormatQuery(IMG_HANDLE hDeviceData,
								  IMG_UINT32 ui32NumFormats,
								  PVRSRV_SURFACE_FORMAT *pasFormat,
								  IMG_UINT32 *pui32Supported)
{
	DC_FBDEV_DEVICE *psDeviceData = hDeviceData;
	int i;

	for(i = 0; i < ui32NumFormats; i++)
	{
		pui32Supported[i] = 0;

		if(pasFormat[i].ePixFormat == psDeviceData->ePixFormat)
			pui32Supported[i]++;
	}

	return PVRSRV_OK;
}
コード例 #20
0
static PVRSRV_ERROR
DC_FBDEV_ContextConfigureCheck(IMG_HANDLE hDisplayContext,
							   IMG_UINT32 ui32PipeCount,
							   PVRSRV_SURFACE_CONFIG_INFO *pasSurfAttrib,
							   IMG_HANDLE *ahBuffers)
{
	DC_FBDEV_CONTEXT *psDeviceContext = hDisplayContext;
	DC_FBDEV_DEVICE *psDeviceData = psDeviceContext->psDeviceData;
	struct fb_var_screeninfo *psVar = &psDeviceData->psLINFBInfo->var;
	DC_FBDEV_BUFFER *psBuffer;
	PVRSRV_ERROR eError;

	if(ui32PipeCount != 1)
	{
		eError = PVRSRV_ERROR_DC_TOO_MANY_PIPES;
		goto err_out;
	}

	if(!ahBuffers)
	{
		eError = PVRSRV_ERROR_DC_INVALID_CONFIG;
		goto err_out;
	}

	if(!lock_fb_info(psDeviceData->psLINFBInfo))
	{
		eError = PVRSRV_ERROR_RETRY;
		goto err_out;
	}

	psBuffer = ahBuffers[0];

	if(pasSurfAttrib[0].sCrop.sDims.ui32Width  != psVar->xres ||
	   pasSurfAttrib[0].sCrop.sDims.ui32Height != psVar->yres ||
	   pasSurfAttrib[0].sCrop.i32XOffset != 0 ||
	   pasSurfAttrib[0].sCrop.i32YOffset != 0)
	{
		eError = PVRSRV_ERROR_DC_INVALID_CROP_RECT;
		goto err_unlock;
	}

	if(pasSurfAttrib[0].sDisplay.sDims.ui32Width !=
	   pasSurfAttrib[0].sCrop.sDims.ui32Width ||
	   pasSurfAttrib[0].sDisplay.sDims.ui32Height !=
	   pasSurfAttrib[0].sCrop.sDims.ui32Height ||
	   pasSurfAttrib[0].sDisplay.i32XOffset !=
	   pasSurfAttrib[0].sCrop.i32XOffset ||
	   pasSurfAttrib[0].sDisplay.i32YOffset !=
	   pasSurfAttrib[0].sCrop.i32YOffset)
	{
		eError = PVRSRV_ERROR_DC_INVALID_DISPLAY_RECT;
		goto err_unlock;
	}

	if(psBuffer->ui32Width  != psVar->xres &&
	   psBuffer->ui32Height != psVar->yres)
	{
		eError = PVRSRV_ERROR_DC_INVALID_BUFFER_DIMS;
		goto err_unlock;
	}

	eError = PVRSRV_OK;
err_unlock:
	unlock_fb_info(psDeviceData->psLINFBInfo);
err_out:
	return eError;
}
コード例 #21
0
static
void DC_FBDEV_ContextConfigure(IMG_HANDLE hDisplayContext,
								   IMG_UINT32 ui32PipeCount,
								   PVRSRV_SURFACE_CONFIG_INFO *pasSurfAttrib,
								   IMG_HANDLE *ahBuffers,
								   IMG_UINT32 ui32DisplayPeriod,
								   IMG_HANDLE hConfigData)
{
	DC_FBDEV_CONTEXT *psDeviceContext = hDisplayContext;
	DC_FBDEV_DEVICE *psDeviceData = psDeviceContext->psDeviceData;
	struct fb_var_screeninfo sVar = psDeviceData->psLINFBInfo->var;
	int err;

	PVR_UNREFERENCED_PARAMETER(ui32PipeCount);
	PVR_UNREFERENCED_PARAMETER(pasSurfAttrib);
	PVR_UNREFERENCED_PARAMETER(ui32DisplayPeriod);

	if(psDeviceContext->hLastConfigData)
		DCDisplayConfigurationRetired(psDeviceContext->hLastConfigData);

	sVar.yoffset = 0;

	if(ui32PipeCount == 0)
	{
		/* If the pipe count is zero, we're tearing down. Don't record
		 * any new configurations, but still allow the display to pan
		 * back to buffer 0.
		 */
		psDeviceContext->hLastConfigData = IMG_NULL;

		/*
			We still need to "retire" this NULL flip as that signals back to
			the DC core that we've finished doing what we need to do
			and it can destroy the display context
		*/
		DCDisplayConfigurationRetired(hConfigData);
	}
	else
	{
		BUG_ON(ahBuffers == IMG_NULL);

		if(psDeviceData->bCanFlip)
		{
			DC_FBDEV_BUFFER *psBuffer = ahBuffers[0];
			sVar.yoffset = sVar.yres * psBuffer->ui32BufferID;
		}

		psDeviceContext->hLastConfigData = hConfigData;
	}

	/* MTK: set BGRA */
	sVar.bits_per_pixel = 32;
	sVar.transp.offset  = 24;
	sVar.transp.length  = 8;
	sVar.red.offset     = 16;
	sVar.red.length     = 8;
	sVar.green.offset   = 8;
	sVar.green.length   = 8;
	sVar.blue.offset    = 0;
	sVar.blue.length    = 8;

	if(lock_fb_info(psDeviceData->psLINFBInfo))
	{
		console_lock();

		/* If we're supposed to be able to flip, but the yres_virtual
		 * has been changed to an unsupported (smaller) value, we need
		 * to change it back (this is a workaround for some Linux fbdev
		 * drivers that seem to lose any modifications to yres_virtual
		 * after a blank.)
		 */
		if(psDeviceData->bCanFlip &&
		   sVar.yres_virtual < sVar.yres * NUM_PREFERRED_BUFFERS)
		{
			sVar.activate = FB_ACTIVATE_NOW;
			sVar.yres_virtual = sVar.yres * NUM_PREFERRED_BUFFERS;

			err = fb_set_var(psDeviceData->psLINFBInfo, &sVar);
			if(err)
				pr_err("fb_set_var failed (err=%d)\n", err);
		}
		else
		{
			err = fb_pan_display(psDeviceData->psLINFBInfo, &sVar);
			if(err)
				pr_err("fb_pan_display failed (err=%d)\n", err);
		}

		console_unlock();
		unlock_fb_info(psDeviceData->psLINFBInfo);
	}
}
コード例 #22
0
static int __init DC_FBDEV_init(void)
{
	static DC_DEVICE_FUNCTIONS sDCFunctions =
	{
		.pfnGetInfo					= DC_FBDEV_GetInfo,
		.pfnPanelQueryCount			= DC_FBDEV_PanelQueryCount,
		.pfnPanelQuery				= DC_FBDEV_PanelQuery,
		.pfnFormatQuery				= DC_FBDEV_FormatQuery,
		.pfnDimQuery				= DC_FBDEV_DimQuery,
		.pfnSetBlank				= IMG_NULL,
		.pfnSetVSyncReporting		= IMG_NULL,
		.pfnLastVSyncQuery			= IMG_NULL,
		.pfnContextCreate			= DC_FBDEV_ContextCreate,
		.pfnContextDestroy			= DC_FBDEV_ContextDestroy,
		.pfnContextConfigure		= DC_FBDEV_ContextConfigure,
		.pfnContextConfigureCheck	= DC_FBDEV_ContextConfigureCheck,
		.pfnBufferAlloc				= DC_FBDEV_BufferAlloc,
		.pfnBufferAcquire			= DC_FBDEV_BufferAcquire,
		.pfnBufferRelease			= DC_FBDEV_BufferRelease,
		.pfnBufferFree				= DC_FBDEV_BufferFree,
	};

	struct fb_info *psLINFBInfo;
	IMG_PIXFMT ePixFormat;
	int err = -ENODEV;

	psLINFBInfo = registered_fb[0];
	if(!psLINFBInfo)
	{
		pr_err("No Linux framebuffer (fbdev) device is registered!\n"
			   "Check you have a framebuffer driver compiled into your "
			   "kernel\nand that it is enabled on the cmdline.\n");
		goto err_out;
	}

	if(!lock_fb_info(psLINFBInfo))
		goto err_out;

	console_lock();

	/* Filter out broken FB devices */
	if(!psLINFBInfo->fix.smem_len || !psLINFBInfo->fix.line_length)
	{
		pr_err("The fbdev device detected had a zero smem_len or "
			   "line_length,\nwhich suggests it is a broken driver.\n");
		goto err_unlock;
	}

	if(psLINFBInfo->fix.type != FB_TYPE_PACKED_PIXELS ||
	   psLINFBInfo->fix.visual != FB_VISUAL_TRUECOLOR)
	{
		pr_err("The fbdev device detected is not truecolor with packed "
			   "pixels.\n");
		goto err_unlock;
	}

	if(psLINFBInfo->var.bits_per_pixel == 32)
	{
		if(psLINFBInfo->var.red.length   != 8  ||
		   psLINFBInfo->var.green.length != 8  ||
		   psLINFBInfo->var.blue.length  != 8  /*||
		   psLINFBInfo->var.red.offset   != 16 ||
		   psLINFBInfo->var.green.offset != 8  ||
		   psLINFBInfo->var.blue.offset  != 0 */) // MTK: supports RGBA
		{
			pr_err("The fbdev device detected uses an unrecognized "
				   "32bit pixel format (%u/%u/%u, %u/%u/%u)\n",
				   psLINFBInfo->var.red.length,
				   psLINFBInfo->var.green.length,
				   psLINFBInfo->var.blue.length,
				   psLINFBInfo->var.red.offset,
				   psLINFBInfo->var.green.offset,
				   psLINFBInfo->var.blue.offset);
			goto err_unlock;
		}

		 // MTK: supports RGBA
		if(psLINFBInfo->var.red.offset   == 0 ||
		   psLINFBInfo->var.green.offset == 8  ||
		   psLINFBInfo->var.blue.offset  == 16 )
		{
			ePixFormat = IMG_PIXFMT_R8G8B8A8_UNORM;
		}
		else
		{
#if defined(DC_FBDEV_FORCE_XRGB8888)
		ePixFormat = IMG_PIXFMT_B8G8R8X8_UNORM;
#else
		ePixFormat = IMG_PIXFMT_B8G8R8A8_UNORM;
#endif
	}
	}
	else if(psLINFBInfo->var.bits_per_pixel == 16)
	{
		if(psLINFBInfo->var.red.length   != 5  ||
		   psLINFBInfo->var.green.length != 6  ||
		   psLINFBInfo->var.blue.length  != 5  ||
		   psLINFBInfo->var.red.offset   != 11 ||
		   psLINFBInfo->var.green.offset != 5  ||
		   psLINFBInfo->var.blue.offset  != 0)
		{
			pr_err("The fbdev device detected uses an unrecognized "
				   "16bit pixel format (%u/%u/%u, %u/%u/%u)\n",
				   psLINFBInfo->var.red.length,
				   psLINFBInfo->var.green.length,
				   psLINFBInfo->var.blue.length,
				   psLINFBInfo->var.red.offset,
				   psLINFBInfo->var.green.offset,
				   psLINFBInfo->var.blue.offset);
			goto err_unlock;
		}
		ePixFormat = IMG_PIXFMT_B5G6R5_UNORM;
	}
	else
	{
		pr_err("The fbdev device detected uses an unsupported "
			   "bpp (%u).\n", psLINFBInfo->var.bits_per_pixel);
		goto err_unlock;
	}

	if(!try_module_get(psLINFBInfo->fbops->owner))
	{
		pr_err("try_module_get() failed");
		goto err_unlock;
	}

	if(psLINFBInfo->fbops->fb_open &&
	   psLINFBInfo->fbops->fb_open(psLINFBInfo, 0) != 0)
	{
		pr_err("fb_open() failed");
		goto err_module_put;
	}

	gpsDeviceData = kmalloc(sizeof(DC_FBDEV_DEVICE), GFP_KERNEL);
	if(!gpsDeviceData)
		goto err_module_put;

	gpsDeviceData->psLINFBInfo = psLINFBInfo;
	gpsDeviceData->ePixFormat = ePixFormat;

	if(DCRegisterDevice(&sDCFunctions,
						MAX_COMMANDS_IN_FLIGHT,
						gpsDeviceData,
						&gpsDeviceData->hSrvHandle) != PVRSRV_OK)
		goto err_kfree;

	gpsDeviceData->bCanFlip = DC_FBDEV_FlipPossible(psLINFBInfo);

	pr_info("Found usable fbdev device (%s):\n"
			"range (physical) = 0x%lx-0x%lx\n"
			"size (bytes)     = 0x%x\n"
			"xres x yres      = %ux%u\n"
			"xres x yres (v)  = %ux%u\n"
			"img pix fmt      = %u\n"
			"flipping?        = %d\n",
			psLINFBInfo->fix.id,
			psLINFBInfo->fix.smem_start,
			psLINFBInfo->fix.smem_start + psLINFBInfo->fix.smem_len,
			psLINFBInfo->fix.smem_len,
			psLINFBInfo->var.xres, psLINFBInfo->var.yres,
			psLINFBInfo->var.xres_virtual, psLINFBInfo->var.yres_virtual,
			ePixFormat, gpsDeviceData->bCanFlip);
	err = 0;
err_unlock:
	console_unlock();
	unlock_fb_info(psLINFBInfo);
err_out:
	return err;
err_kfree:
	kfree(gpsDeviceData);
err_module_put:
	module_put(psLINFBInfo->fbops->owner);
	goto err_unlock;
}
コード例 #23
0
static ssize_t store_size(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;
	struct omap_dss_device *display = fb2display(fbi);
	struct omapfb2_mem_region *rg;
	unsigned long size;
	int r;
	int i;

	r = kstrtoul(buf, 0, &size);
	if (r)
		return r;

	size = PAGE_ALIGN(size);

	if (!lock_fb_info(fbi))
		return -ENODEV;

	if (display && display->driver->sync)
		display->driver->sync(display);

	rg = ofbi->region;

	down_write_nested(&rg->lock, rg->id);
	atomic_inc(&rg->lock_count);

	if (atomic_read(&rg->map_count)) {
		r = -EBUSY;
		goto out;
	}

	for (i = 0; i < fbdev->num_fbs; i++) {
		struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]);
		int j;

		if (ofbi2->region != rg)
			continue;

		for (j = 0; j < ofbi2->num_overlays; j++) {
			struct omap_overlay *ovl;
			ovl = ofbi2->overlays[j];
			if (ovl->is_enabled(ovl)) {
				r = -EBUSY;
				goto out;
			}
		}
	}

	if (size != ofbi->region->size) {
		r = omapfb_realloc_fbmem(fbi, size, ofbi->region->type);
		if (r) {
			dev_err(dev, "realloc fbmem failed\n");
			goto out;
		}
	}

	r = count;
out:
	atomic_dec(&rg->lock_count);
	up_write(&rg->lock);

	unlock_fb_info(fbi);

	return r;
}
コード例 #24
0
static ssize_t store_overlays_rotate(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct omapfb_info *ofbi = FB2OFB(fbi);
	int num_ovls = 0, r, i;
	int len;
	bool changed = false;
	u8 rotation[OMAPFB_MAX_OVL_PER_FB];

	len = strlen(buf);
	if (buf[len - 1] == '\n')
		len = len - 1;

	if (!lock_fb_info(fbi))
		return -ENODEV;

	if (len > 0) {
		char *p = (char *)buf;

		while (p < buf + len) {
			int rot;

			if (num_ovls == ofbi->num_overlays) {
				r = -EINVAL;
				goto out;
			}

			rot = simple_strtoul(p, &p, 0);
			if (rot < 0 || rot > 3) {
				r = -EINVAL;
				goto out;
			}

			if (ofbi->rotation[num_ovls] != rot)
				changed = true;

			rotation[num_ovls++] = rot;

			p++;
		}
	}

	if (num_ovls != ofbi->num_overlays) {
		r = -EINVAL;
		goto out;
	}

	if (changed) {
		for (i = 0; i < num_ovls; ++i)
			ofbi->rotation[i] = rotation[i];

		omapfb_get_mem_region(ofbi->region);

		r = omapfb_apply_changes(fbi, 0);

		omapfb_put_mem_region(ofbi->region);

		if (r)
			goto out;

		/* FIXME error handling? */
	}

	r = count;
out:
	unlock_fb_info(fbi);

	return r;
}
コード例 #25
0
static ssize_t store_overlays(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;
	struct omap_overlay *ovls[OMAPFB_MAX_OVL_PER_FB];
	struct omap_overlay *ovl;
	int num_ovls, r, i;
	int len;
	bool added = false;

	num_ovls = 0;

	len = strlen(buf);
	if (buf[len - 1] == '\n')
		len = len - 1;

	if (!lock_fb_info(fbi))
		return -ENODEV;
	omapfb_lock(fbdev);

	if (len > 0) {
		char *p = (char *)buf;
		int ovlnum;

		while (p < buf + len) {
			int found;
			if (num_ovls == OMAPFB_MAX_OVL_PER_FB) {
				r = -EINVAL;
				goto out;
			}

			ovlnum = simple_strtoul(p, &p, 0);
			if (ovlnum > fbdev->num_overlays) {
				r = -EINVAL;
				goto out;
			}

			found = 0;
			for (i = 0; i < num_ovls; ++i) {
				if (ovls[i] == fbdev->overlays[ovlnum]) {
					found = 1;
					break;
				}
			}

			if (!found)
				ovls[num_ovls++] = fbdev->overlays[ovlnum];

			p++;
		}
	}

	for (i = 0; i < num_ovls; ++i) {
		struct omapfb_info *ofbi2 = get_overlay_fb(fbdev, ovls[i]);
		if (ofbi2 && ofbi2 != ofbi) {
			dev_err(fbdev->dev, "overlay already in use\n");
			r = -EINVAL;
			goto out;
		}
	}

	/* detach unused overlays */
	for (i = 0; i < ofbi->num_overlays; ++i) {
		int t, found;

		ovl = ofbi->overlays[i];

		found = 0;

		for (t = 0; t < num_ovls; ++t) {
			if (ovl == ovls[t]) {
				found = 1;
				break;
			}
		}

		if (found)
			continue;

		DBG("detaching %d\n", ofbi->overlays[i]->id);

		omapfb_get_mem_region(ofbi->region);

		omapfb_overlay_enable(ovl, 0);

		if (ovl->manager)
			ovl->manager->apply(ovl->manager);

		omapfb_put_mem_region(ofbi->region);

		for (t = i + 1; t < ofbi->num_overlays; t++) {
			ofbi->rotation[t-1] = ofbi->rotation[t];
			ofbi->overlays[t-1] = ofbi->overlays[t];
		}

		ofbi->num_overlays--;
		i--;
	}

	for (i = 0; i < num_ovls; ++i) {
		int t, found;

		ovl = ovls[i];

		found = 0;

		for (t = 0; t < ofbi->num_overlays; ++t) {
			if (ovl == ofbi->overlays[t]) {
				found = 1;
				break;
			}
		}

		if (found)
			continue;
		ofbi->rotation[ofbi->num_overlays] = 0;
		ofbi->overlays[ofbi->num_overlays++] = ovl;

		added = true;
	}

	if (added) {
		omapfb_get_mem_region(ofbi->region);

		r = omapfb_apply_changes(fbi, 0);

		omapfb_put_mem_region(ofbi->region);

		if (r)
			goto out;
	}

	r = count;
out:
	omapfb_unlock(fbdev);
	unlock_fb_info(fbi);

	return r;
}