Esempio n. 1
0
static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
{
    struct omapfb_info *ofbi = FB2OFB(fbi);
    struct omapfb2_device *fbdev = ofbi->fbdev;
    struct omap_dss_device *display = fb2display(fbi);
    struct omapfb2_mem_region *rg;
    int r = 0, i;
    size_t size;

    if (mi->type != OMAPFB_MEMTYPE_SDRAM)
        return -EINVAL;

    size = PAGE_ALIGN(mi->size);

    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 (rg->size == size && rg->type == mi->type)
        goto out;

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

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

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

    return r;
}
Esempio n. 2
0
static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
{
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;
	struct omapfb2_mem_region *rg;
	int r = 0, i;
	size_t size;

	if (mi->type > OMAPFB_MEMTYPE_MAX)
		return -EINVAL;

	size = PAGE_ALIGN(mi->size);

	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++) {
			if (ofbi2->overlays[j]->info.enabled) {
				r = -EBUSY;
				goto out;
			}
		}
	}

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

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

	return r;
}
Esempio n. 3
0
static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
{
	struct omapfb_info *ofbi = FB2OFB(fbi);

	if (ofbi->num_overlays != 1) {
		memset(pi, 0, sizeof(*pi));
	} else {
		struct omap_overlay *ovl;
		struct omap_overlay_info *ovli;

		ovl = ofbi->overlays[0];
		ovli = &ovl->info;

		pi->pos_x = ovli->pos_x;
		pi->pos_y = ovli->pos_y;
		pi->enabled = ovli->enabled;
		pi->channel_out = 0; /* xxx */
		pi->mirror = 0;
		pi->mem_idx = get_mem_idx(ofbi);
		pi->out_width = ovli->out_width;
		pi->out_height = ovli->out_height;
	}

	return 0;
}
Esempio n. 4
0
static int omapfb_detach_framebuffer(struct fb_info *fbi,
		struct omap_overlay *ovl)
{
	int i;
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;

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

	if (i == ofbi->num_overlays) {
		dev_err(fbdev->dev, "cannot detach fb, overlay not attached\n");
		return -EINVAL;
	}

	ovl->enable(ovl, 0);

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

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

	ofbi->num_overlays--;

	return 0;
}
Esempio n. 5
0
static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
{
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;
	struct omapfb2_mem_region *rg;
	int r, i;
	size_t size;

	if (mi->type > OMAPFB_MEMTYPE_MAX)
		return -EINVAL;

	size = PAGE_ALIGN(mi->size);

	rg = &ofbi->region;

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

	if (rg->size != size || rg->type != mi->type) {
		r = omapfb_realloc_fbmem(fbi, size, mi->type);
		if (r) {
			dev_err(fbdev->dev, "realloc fbmem failed\n");
			return r;
		}
	}

	return 0;
}
Esempio n. 6
0
static int omapfb_get_update_mode(struct fb_info *fbi,
		enum omapfb_update_mode *mode)
{
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;
	struct omap_display *display = fb2display(fbi);
	enum omap_dss_update_mode m;

	if (!display || !display->get_update_mode)
		return -EINVAL;

	omapfb_lock(fbdev);
	m = display->get_update_mode(display);
	omapfb_unlock(fbdev);

	switch (m) {
	case OMAP_DSS_UPDATE_DISABLED:
		*mode = OMAPFB_UPDATE_DISABLED;
		break;
	case OMAP_DSS_UPDATE_AUTO:
		*mode = OMAPFB_AUTO_UPDATE;
		break;
	case OMAP_DSS_UPDATE_MANUAL:
		*mode = OMAPFB_MANUAL_UPDATE;
		break;
	default:
		BUG();
	}

	return 0;
}
Esempio n. 7
0
static int omapfb_set_update_mode(struct fb_info *fbi,
				   enum omapfb_update_mode mode)
{
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;
	struct omap_display *display = fb2display(fbi);
	enum omap_dss_update_mode um;
	int r;

	if (!display || !display->set_update_mode)
		return -EINVAL;

	switch (mode) {
	case OMAPFB_UPDATE_DISABLED:
		um = OMAP_DSS_UPDATE_DISABLED;
		break;

	case OMAPFB_AUTO_UPDATE:
		um = OMAP_DSS_UPDATE_AUTO;
		break;

	case OMAPFB_MANUAL_UPDATE:
		um = OMAP_DSS_UPDATE_MANUAL;
		break;

	default:
		return -EINVAL;
	}

	omapfb_lock(fbdev);
	r = display->set_update_mode(display, um);
	omapfb_unlock(fbdev);

	return r;
}
Esempio n. 8
0
static 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;
	struct omap_display *display = fb2display(fbi);
	int dw, dh;

	if (!display)
		return 0;

	if (w == 0 || h == 0)
		return 0;

	display->get_resolution(display, &dw, &dh);

	if (x + w > dw || y + h > dh)
		return -EINVAL;

	omapfb_lock(fbdev);
	display->update(display, x, y, w, h);
	omapfb_unlock(fbdev);

	return 0;
}
Esempio n. 9
0
static int omapfb_get_color_key(struct fb_info *fbi,
		struct omapfb_color_key *ck)
{
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;
	struct omap_overlay_manager *mgr = NULL;
	int r = 0;
	int i;

	omapfb_lock(fbdev);

	for (i = 0; i < ofbi->num_overlays; i++) {
		if (ofbi->overlays[i]->manager) {
			mgr = ofbi->overlays[i]->manager;
			break;
		}
	}

	if (!mgr) {
		r = -EINVAL;
		goto err;
	}

	*ck = omapfb_color_keys[mgr->id];
err:
	omapfb_unlock(fbdev);

	return r;
}
Esempio n. 10
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;
}
Esempio n. 11
0
/*
 * Presents the flip in the display with the DSS2 overlay API
 * in: psSwapChain, aPhyAddr
 */
static void OMAPLFBFlipNoLock(OMAPLFB_SWAPCHAIN *psSwapChain,
	unsigned long aPhyAddr)
{
	OMAPLFB_DEVINFO	*psDevInfo = (OMAPLFB_DEVINFO *)psSwapChain->pvDevInfo;
	struct fb_info * framebuffer = psDevInfo->psLINFBInfo;
	struct omapfb_info *ofbi = FB2OFB(framebuffer);
	int i;

	unsigned long fb_offset =
		aPhyAddr - psDevInfo->sSystemBuffer.sSysAddr.uiAddr;
    int overlay_offset = 0; 
	struct omap_overlay* overlay;
	struct omap_overlay_info overlay_info;

	fb_offset = aPhyAddr - psDevInfo->sSystemBuffer.sSysAddr.uiAddr;

	for(i = 0; i < ofbi->num_overlays ; i++)
	{
		struct omap_dss_device *display = NULL;

		int deltaY = 0;
        int deltaX = 0;
		overlay = ofbi->overlays[i];
		overlay->get_overlay_info( overlay, &overlay_info );

		/* If the overlay is not enabled don't update it */
		if(!overlay_info.enabled)
			continue;
        deltaY = overlay_info.pos_y;
        deltaX = overlay_info.pos_x;

        overlay_offset =  (framebuffer->var.bits_per_pixel >= 24 ? 4 : 2) * (overlay_info.screen_width * deltaY + deltaX);

		overlay_info.paddr = framebuffer->fix.smem_start + fb_offset + overlay_offset;
		overlay_info.vaddr = framebuffer->screen_base + fb_offset;
		overlay->set_overlay_info(overlay, &overlay_info);
		
		if(overlay->manager)
		{
			if (overlay->manager->device)
			{
				overlay->manager->apply(overlay->manager);
				if(overlay->manager->device->update)
				{
					overlay->manager->device->update(
					overlay->manager->device, 0, 0,
					overlay_info.width,
					overlay_info.height);
				}
			}
		}

		if (display && display->update &&
			display->get_update_mode(display) ==
			OMAP_DSS_UPDATE_MANUAL)
			display->update(display, 0, 0, overlay_info.width,
				overlay_info.height);

	}
}
Esempio n. 12
0
void set_fb_fix(struct fb_info *fbi)
{
	struct fb_fix_screeninfo *fix = &fbi->fix;
	struct fb_var_screeninfo *var = &fbi->var;
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_mem_region *rg = &ofbi->region;

	DBG("set_fb_fix\n");

	/* used by open/write in fbmem.c */
	fbi->screen_base = (char __iomem *)omapfb_get_region_vaddr(ofbi);

	DBG("changing rotation to %d\n", var->rotate);

	/* used by mmap in fbmem.c */
	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
		switch (var->nonstd) {
		case OMAPFB_COLOR_YUV422:
		case OMAPFB_COLOR_YUY422:
			fix->line_length =
				(OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 2;
			break;
		default:
			fix->line_length =
				(OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 3;
			break;
		}
	} else
Esempio n. 13
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;
}
Esempio n. 14
0
static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
{
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;
	struct omap_display *display = fb2display(fbi);
	struct omap_overlay *ovl;
	int r = 0;

	DBG("omapfb_setup_plane\n");

	omapfb_lock(fbdev);

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

	/* XXX uses only the first overlay */
	ovl = ofbi->overlays[0];

	if (pi->enabled && !ofbi->region.size) {
		/*
		 * This plane's memory was freed, can't enable it
		 * until it's reallocated.
		 */
		r = -EINVAL;
		goto out;
	}

	if (pi->enabled) {
		r = omapfb_setup_overlay(fbi, ovl, pi->pos_x, pi->pos_y,
				pi->out_width, pi->out_height);
		if (r)
			goto out;
	}

	ovl->enable(ovl, pi->enabled);

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

	if (display) {
		int w, h;

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

		display->get_resolution(display, &w, &h);

		if (display->update)
			display->update(display, 0, 0, w, h);
	}

out:
	omapfb_unlock(fbdev);
	if (r)
		dev_err(fbdev->dev, "setup_plane failed\n");
	return r;
}
Esempio n. 15
0
static ssize_t show_mirror(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct omapfb_info *ofbi = FB2OFB(fbi);

	return snprintf(buf, PAGE_SIZE, "%d\n", ofbi->mirror);
}
Esempio n. 16
0
/* Interrupt service routine. */
static void omapfb_isr(void *arg, unsigned int irqstatus)
{
	struct fb_info *fbi = (struct fb_info *) arg;
	struct omapfb_info *ofbi = FB2OFB(fbi);

	++ofbi->vsync_cnt;
	wake_up_interruptible(&ofbi->vsync_wait);
}
Esempio n. 17
0
static ssize_t show_phys(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct fb_info *fbi = dev_get_drvdata(dev);
	struct omapfb_info *ofbi = FB2OFB(fbi);

	return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr);
}
Esempio n. 18
0
static int omapfb_attach_framebuffer(struct fb_info *fbi,
		struct omap_overlay *ovl)
{
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;
	int i, t;
	int r;

	if (ofbi->num_overlays >= OMAPFB_MAX_OVL_PER_FB) {
		dev_err(fbdev->dev, "fb has max number of overlays already\n");
		return -EINVAL;
	}

	for (i = 0; i < ofbi->num_overlays; i++) {
		if (ofbi->overlays[i] == ovl) {
			dev_err(fbdev->dev, "fb already attached to overlay\n");
			return -EINVAL;
		}
	}

	for (i = 0; i < fbdev->num_fbs; i++) {
		struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]);
		for (t = 0; t < ofbi2->num_overlays; t++) {
			if (ofbi2->overlays[t] == ovl) {
				dev_err(fbdev->dev, "overlay already in use\n");
				return -EINVAL;
			}
		}
	}

	ofbi->overlays[ofbi->num_overlays++] = ovl;

/*
	if (ovl->manager && ovl->manager->display)
		omapfb_adjust_fb(fbi, ovl, 0, 0);
*/
	r = omapfb_apply_changes(fbi, 1);
	if (r)
		return r;

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

	return 0;
}
Esempio n. 19
0
void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr)
{
	OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)psSwapChain->pvDevInfo;
	struct fb_info *framebuffer = psDevInfo->psLINFBInfo;
	struct omapfb_info *ofbi = FB2OFB(framebuffer);
	struct omapfb2_device *fbdev = ofbi->fbdev;

	omapfb_lock(fbdev);
	OMAPLFBFlipNoLock(psSwapChain, aPhyAddr);
	omapfb_unlock(fbdev);
}
Esempio n. 20
0
static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
{
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_mem_region *rg;

	rg = &ofbi->region;
	memset(mi, 0, sizeof(*mi));

	mi->size = rg->size;
	mi->type = rg->type;

	return 0;
}
Esempio n. 21
0
/*
 * Present frame and synchronize with the display to prevent tearing
 * On DSI panels the sync function is used to handle FRAMEDONE IRQ
 * On DPI panels the wait_for_vsync is used to handle VSYNC IRQ
 * in: psDevInfo
 */
void OMAPLFBPresentSync(OMAPLFB_DEVINFO *psDevInfo,
	OMAPLFB_FLIP_ITEM *psFlipItem)
{
	struct fb_info *framebuffer = psDevInfo->psLINFBInfo;
	struct omapfb_info *ofbi = FB2OFB(framebuffer);
	struct omap_dss_device *display;
	struct omapfb2_device *fbdev = ofbi->fbdev;
	struct omap_dss_driver *driver;
	struct omap_overlay_manager *manager;
	int err = 1;

	omapfb_lock(fbdev);

// [email protected] Backup the Display device for using later [START]
#if defined(CONFIG_MACH_LGE_OMAP3)
	Prev_disp = display = fb2display(framebuffer);
#else
	display = fb2display(framebuffer);
#endif	
// [email protected] Backup the Display device for using later [END]
	/* The framebuffer doesn't have a display attached, just bail out */
	if (!display) {
		omapfb_unlock(fbdev);
		return;
	}

	driver = display->driver;
	manager = display->manager;

	if (driver && driver->sync &&
		driver->get_update_mode(display) == OMAP_DSS_UPDATE_MANUAL) {
		/* Wait first for the DSI bus to be released then update */
		err = driver->sync(display);
		OMAPLFBFlipNoLock(psDevInfo->psSwapChain,
			(unsigned long)psFlipItem->sSysAddr->uiAddr);
	} else if (manager && manager->wait_for_vsync) {
		/*
		 * Update the video pipelines registers then wait until the
		 * frame is shown with a VSYNC
		 */
		OMAPLFBFlipNoLock(psDevInfo->psSwapChain,
			(unsigned long)psFlipItem->sSysAddr->uiAddr);
		err = manager->wait_for_vsync(manager);
	}

	if (err)
		WARNING_PRINTK("Unable to sync with display %u!",
			psDevInfo->uDeviceID);

	omapfb_unlock(fbdev);
}
Esempio n. 22
0
/*
 * Presents the flip in the display with the DSS2 overlay API
 * in: psSwapChain, aPhyAddr
 */
static void OMAPLFBFlipNoLock(OMAPLFB_SWAPCHAIN *psSwapChain,
	unsigned long aPhyAddr)
{
	OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)psSwapChain->pvDevInfo;
	struct fb_info * framebuffer = psDevInfo->psLINFBInfo;
	struct omapfb_info *ofbi = FB2OFB(framebuffer);
	unsigned long fb_offset;
	int i;

	fb_offset = aPhyAddr - psDevInfo->sSystemBuffer.sSysAddr.uiAddr;

	for(i = 0; i < ofbi->num_overlays ; i++)
	{
		struct omap_dss_device *display = NULL;
		struct omap_dss_driver *driver = NULL;
		struct omap_overlay_manager *manager;
		struct omap_overlay *overlay;
		struct omap_overlay_info overlay_info;

		overlay = ofbi->overlays[i];
		manager = overlay->manager;
		overlay->get_overlay_info( overlay, &overlay_info );

		overlay_info.paddr = framebuffer->fix.smem_start + fb_offset;
		overlay_info.vaddr = framebuffer->screen_base + fb_offset;
		overlay->set_overlay_info(overlay, &overlay_info);

		if (manager) {
			display = manager->device;
			/* No display attached to this overlay, don't update */
			if (!display)
				continue;
			driver = display->driver;
			manager->set_manager_info(manager, &manager->info);
			manager->apply(manager);
		}

		if (dss_ovl_manually_updated(overlay)) {
			if (driver->sched_update)
				driver->sched_update(display, 0, 0,
							overlay_info.width,
							overlay_info.height);
			else if (driver->update)
				driver->update(display, 0, 0,
							overlay_info.width,
							overlay_info.height);

		}

	}
}
Esempio n. 23
0
static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
{
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omapfb2_device *fbdev = ofbi->fbdev;
	struct omap_overlay *ovl;
	struct omap_overlay_info info;
	int r = 0;

	DBG("omapfb_setup_plane\n");

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

	/* XXX uses only the first overlay */
	ovl = ofbi->overlays[0];

	if (pi->enabled && !ofbi->region.size) {
		/*
		 * This plane's memory was freed, can't enable it
		 * until it's reallocated.
		 */
		r = -EINVAL;
		goto out;
	}

	ovl->get_overlay_info(ovl, &info);

	info.pos_x = pi->pos_x;
	info.pos_y = pi->pos_y;
	info.out_width = pi->out_width;
	info.out_height = pi->out_height;
	info.enabled = pi->enabled;

	r = ovl->set_overlay_info(ovl, &info);
	if (r)
		goto out;

	if (ovl->manager) {
		r = ovl->manager->apply(ovl->manager);
		if (r)
			goto out;
	}

out:
	if (r)
		dev_err(fbdev->dev, "setup_plane failed\n");
	return r;
}
Esempio n. 24
0
static int omapfb_wait_for_go(struct fb_info *fbi)
{
	struct omapfb_info *ofbi = FB2OFB(fbi);
	int r = 0;
	int i;

	for (i = 0; i < ofbi->num_overlays; ++i) {
		struct omap_overlay *ovl = ofbi->overlays[i];
		r = ovl->wait_for_go(ovl);
		if (r)
			break;
	}

	return r;
}
Esempio n. 25
0
static struct omapfb_info *get_overlay_fb(struct omapfb2_device *fbdev,
		struct omap_overlay *ovl)
{
	int i, t;

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

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

	return NULL;
}
Esempio n. 26
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;
}
Esempio n. 27
0
static int omapfb_wait_for_vsync(struct fb_info *fbi)
{
	wait_queue_t wqt;
	unsigned long cnt, timeout = HZ/5;
	int ret;
	void *handle = NULL;
	u32 mask = 0;
	struct omapfb_info *ofbi = FB2OFB(fbi);
	struct omap_display *display = fb2display(fbi);

	mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN |
			DISPC_IRQ_EVSYNC_ODD;

	handle = omap_dispc_register_isr(omapfb_isr, fbi, mask);
	if (!handle)
		return -EINVAL;

	init_waitqueue_entry(&wqt, current);

	cnt = ofbi->vsync_cnt;
	ret = wait_event_interruptible_timeout(ofbi->vsync_wait,
			cnt != ofbi->vsync_cnt, timeout);
	/*
	 * If the GFX is on TV, then wait for another VSYNC
	 * to compensate for Interlaced scan
	 */
	if (display->type == OMAP_DISPLAY_TYPE_VENC) {
		if (ret > 0) {
			cnt = ofbi->vsync_cnt;
			ret = wait_event_interruptible_timeout(
					ofbi->vsync_wait,
					cnt != ofbi->vsync_cnt,
					timeout);
		}
	}
	omap_dispc_unregister_isr(handle);

	if (ret < 0)
		return ret;
	if (ret == 0)
		return -ETIMEDOUT;

	return 0;
}
Esempio n. 28
0
void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr)
{
struct omap_overlay* overlay;
	struct omap_overlay_info overlay_info;
	struct fb_info * framebuffer;
	OMAPLFB_DEVINFO	*psDevInfo;
	struct omapfb_info *ofbi;
	struct omapfb2_device *fbdev;
	int i;
	unsigned long fb_offset;

	psDevInfo = (OMAPLFB_DEVINFO *) psSwapChain->pvDevInfo;
	framebuffer = psDevInfo->psLINFBInfo;
	ofbi = FB2OFB(framebuffer);
	fb_offset = aPhyAddr - psDevInfo->sSystemBuffer.sSysAddr.uiAddr;
	fbdev = ofbi->fbdev;

	omapfb_lock(fbdev);

	for(i = 0; i < ofbi->num_overlays ; i++)
	{
		overlay = ofbi->overlays[i];
		overlay->get_overlay_info( overlay, &overlay_info );
		/* If the overlay is not enabled don't update it */
		if(!overlay_info.enabled)
			continue;

		overlay_info.paddr = framebuffer->fix.smem_start + fb_offset;
		overlay_info.vaddr = framebuffer->screen_base + fb_offset;
		overlay->set_overlay_info(overlay, &overlay_info);
		overlay->manager->apply(overlay->manager);

		if(overlay->manager->device->update)
		{
			overlay->manager->device->update(
				overlay->manager->device, 0, 0,
				overlay_info.width,
				overlay_info.height);
		}
	}

	omapfb_unlock(fbdev);

}
Esempio n. 29
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;
}
Esempio n. 30
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);
	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;
}