Beispiel #1
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;
}
Beispiel #2
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 old_info;
	struct omapfb2_mem_region *old_rg, *new_rg;
	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];

	old_rg = ofbi->region;
	new_rg = get_mem_region(ofbi, pi->mem_idx);
	if (!new_rg) {
		r = -EINVAL;
		goto out;
	}

	/* Take the locks in a specific order to keep lockdep happy */
	if (old_rg->id < new_rg->id) {
		omapfb_get_mem_region(old_rg);
		omapfb_get_mem_region(new_rg);
	} else if (new_rg->id < old_rg->id) {
		omapfb_get_mem_region(new_rg);
		omapfb_get_mem_region(old_rg);
	} else
		omapfb_get_mem_region(old_rg);

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

	ovl->get_overlay_info(ovl, &old_info);

	if (old_rg != new_rg) {
		ofbi->region = new_rg;
		set_fb_fix(fbi);
	}

	if (pi->enabled) {
		struct omap_overlay_info info;

		r = omapfb_setup_overlay(fbi, ovl, pi->pos_x, pi->pos_y,
			pi->out_width, pi->out_height);
		if (r)
			goto undo;

		ovl->get_overlay_info(ovl, &info);

		if (!info.enabled) {
			info.enabled = pi->enabled;
			r = ovl->set_overlay_info(ovl, &info);
			if (r)
				goto undo;
		}
	} else {
		struct omap_overlay_info info;

		ovl->get_overlay_info(ovl, &info);

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

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

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

	/* Release the locks in a specific order to keep lockdep happy */
	if (old_rg->id > new_rg->id) {
		omapfb_put_mem_region(old_rg);
		omapfb_put_mem_region(new_rg);
	} else if (new_rg->id > old_rg->id) {
		omapfb_put_mem_region(new_rg);
		omapfb_put_mem_region(old_rg);
	} else
		omapfb_put_mem_region(old_rg);

	return 0;

 undo:
	if (old_rg != new_rg) {
		ofbi->region = old_rg;
		set_fb_fix(fbi);
	}

	ovl->set_overlay_info(ovl, &old_info);
 put_mem:
	/* Release the locks in a specific order to keep lockdep happy */
	if (old_rg->id > new_rg->id) {
		omapfb_put_mem_region(old_rg);
		omapfb_put_mem_region(new_rg);
	} else if (new_rg->id > old_rg->id) {
		omapfb_put_mem_region(new_rg);
		omapfb_put_mem_region(old_rg);
	} else
		omapfb_put_mem_region(old_rg);
 out:
	dev_err(fbdev->dev, "setup_plane failed\n");

	return r;
}