// SPDX-License-Identifier: GPL-2.0-only /* * linux/drivers/video/omap2/omapfb-ioctl.c * * Copyright (C) 2008 Nokia Corporation * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> * * Some code and ideas taken from drivers/video/omap/ driver * by Imre Deak.
*/
if (ofbi->num_overlays == 0) {
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);
} elseif (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) {
r = ovl->disable(ovl); if (r) goto undo;
}
if (pi->enabled) {
r = omapfb_setup_overlay(fbi, ovl, pi->pos_x, pi->pos_y,
pi->out_width, pi->out_height); if (r) goto undo;
} else { struct omap_overlay_info info;
r = ovl->set_overlay_info(ovl, &info); if (r) goto undo;
}
if (ovl->manager) {
r = ovl->manager->apply(ovl->manager); if (r) goto undo;
}
if (pi->enabled) {
r = ovl->enable(ovl); if (r) goto undo;
}
/* 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);
} elseif (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);
for (i = 0; i < sizeof(supported_modes) * 8; i++) { if (!(supported_modes & (1 << i))) continue; /* * It's possible that the FB doesn't support a mode * that is supported by the overlay, so call the * following here.
*/ if (dss_mode_to_fb_mode(1 << i, &var) < 0) continue;
mode_idx--; if (mode_idx < 0) break;
}
if (i == sizeof(supported_modes) * 8) return -ENOENT;
switch (cmd) { case OMAPFB_SYNC_GFX:
DBG("ioctl SYNC_GFX\n"); if (!display || !display->driver->sync) { /* DSS1 never returns an error here, so we neither */ /*r = -EINVAL;*/ break;
}
r = display->driver->sync(display); break;
case OMAPFB_UPDATE_WINDOW_OLD:
DBG("ioctl UPDATE_WINDOW_OLD\n"); if (!display || !display->driver->update) {
r = -EINVAL; break;
}
if (copy_from_user(&p.uwnd_o,
(void __user *)arg, sizeof(p.uwnd_o))) {
r = -EFAULT; break;
}
r = omapfb_update_window(fbi, p.uwnd_o.x, p.uwnd_o.y,
p.uwnd_o.width, p.uwnd_o.height); break;
case OMAPFB_UPDATE_WINDOW:
DBG("ioctl UPDATE_WINDOW\n"); if (!display || !display->driver->update) {
r = -EINVAL; break;
}
if (copy_from_user(&p.uwnd, (void __user *)arg, sizeof(p.uwnd))) {
r = -EFAULT; break;
}
r = omapfb_update_window(fbi, p.uwnd.x, p.uwnd.y,
p.uwnd.width, p.uwnd.height); break;
case OMAPFB_SETUP_PLANE:
DBG("ioctl SETUP_PLANE\n"); if (copy_from_user(&p.plane_info, (void __user *)arg, sizeof(p.plane_info)))
r = -EFAULT; else
r = omapfb_setup_plane(fbi, &p.plane_info); break;
case OMAPFB_QUERY_PLANE:
DBG("ioctl QUERY_PLANE\n");
r = omapfb_query_plane(fbi, &p.plane_info); if (r < 0) break; if (copy_to_user((void __user *)arg, &p.plane_info, sizeof(p.plane_info)))
r = -EFAULT; break;
case OMAPFB_SETUP_MEM:
DBG("ioctl SETUP_MEM\n"); if (copy_from_user(&p.mem_info, (void __user *)arg, sizeof(p.mem_info)))
r = -EFAULT; else
r = omapfb_setup_mem(fbi, &p.mem_info); break;
case OMAPFB_QUERY_MEM:
DBG("ioctl QUERY_MEM\n");
r = omapfb_query_mem(fbi, &p.mem_info); if (r < 0) break; if (copy_to_user((void __user *)arg, &p.mem_info, sizeof(p.mem_info)))
r = -EFAULT; break;
case OMAPFB_GET_CAPS:
DBG("ioctl GET_CAPS\n"); if (!display) {
r = -EINVAL; break;
}
memset(&p.caps, 0, sizeof(p.caps)); if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
p.caps.ctrl |= OMAPFB_CAPS_MANUAL_UPDATE; if (display->caps & OMAP_DSS_DISPLAY_CAP_TEAR_ELIM)
p.caps.ctrl |= OMAPFB_CAPS_TEARSYNC;
if (copy_to_user((void __user *)arg, &p.caps, sizeof(p.caps)))
r = -EFAULT; break;
case OMAPFB_GET_OVERLAY_COLORMODE:
DBG("ioctl GET_OVERLAY_COLORMODE\n"); if (copy_from_user(&p.ovl_colormode, (void __user *)arg, sizeof(p.ovl_colormode))) {
r = -EFAULT; break;
}
r = omapfb_get_ovl_colormode(fbdev, &p.ovl_colormode); if (r < 0) break; if (copy_to_user((void __user *)arg, &p.ovl_colormode, sizeof(p.ovl_colormode)))
r = -EFAULT; break;
case OMAPFB_SET_UPDATE_MODE:
DBG("ioctl SET_UPDATE_MODE\n"); if (get_user(p.update_mode, (int __user *)arg))
r = -EFAULT; else
r = omapfb_set_update_mode(fbi, p.update_mode); break;
case OMAPFB_GET_UPDATE_MODE:
DBG("ioctl GET_UPDATE_MODE\n");
r = omapfb_get_update_mode(fbi, &p.update_mode); if (r) break; if (put_user(p.update_mode,
(enum omapfb_update_mode __user *)arg))
r = -EFAULT; break;
case OMAPFB_SET_COLOR_KEY:
DBG("ioctl SET_COLOR_KEY\n"); if (copy_from_user(&p.color_key, (void __user *)arg, sizeof(p.color_key)))
r = -EFAULT; else
r = omapfb_set_color_key(fbi, &p.color_key); break;
case OMAPFB_GET_COLOR_KEY:
DBG("ioctl GET_COLOR_KEY\n");
r = omapfb_get_color_key(fbi, &p.color_key); if (r) break; if (copy_to_user((void __user *)arg, &p.color_key, sizeof(p.color_key)))
r = -EFAULT; break;
case FBIO_WAITFORVSYNC: if (get_user(p.crt, (__u32 __user *)arg)) {
r = -EFAULT; break;
} if (p.crt != 0) {
r = -ENODEV; break;
}
fallthrough;
case OMAPFB_WAITFORVSYNC:
DBG("ioctl WAITFORVSYNC\n");
if (!display) {
r = -EINVAL; break;
}
mgr = omapdss_find_mgr_from_display(display); if (!mgr) {
r = -EINVAL; break;
}
r = mgr->wait_for_vsync(mgr); break;
case OMAPFB_WAITFORGO:
DBG("ioctl WAITFORGO\n"); if (!display) {
r = -EINVAL; break;
}
r = omapfb_wait_for_go(fbi); break;
/* LCD and CTRL tests do the same thing for backward
* compatibility */ case OMAPFB_LCD_TEST:
DBG("ioctl LCD_TEST\n"); if (get_user(p.test_num, (int __user *)arg)) {
r = -EFAULT; break;
} if (!display || !display->driver->run_test) {
r = -EINVAL; break;
}
r = display->driver->run_test(display, p.test_num);
break;
case OMAPFB_CTRL_TEST:
DBG("ioctl CTRL_TEST\n"); if (get_user(p.test_num, (int __user *)arg)) {
r = -EFAULT; break;
} if (!display || !display->driver->run_test) {
r = -EINVAL; break;
}
r = display->driver->run_test(display, p.test_num);
break;
case OMAPFB_MEMORY_READ:
DBG("ioctl MEMORY_READ\n");
if (copy_from_user(&p.memory_read, (void __user *)arg, sizeof(p.memory_read))) {
r = -EFAULT; break;
}
r = omapfb_memory_read(fbi, &p.memory_read);
break;
case OMAPFB_GET_VRAM_INFO: {
DBG("ioctl GET_VRAM_INFO\n");
/* * We don't have the ability to get this vram info anymore. * Fill in something that should keep the applications working.
*/
p.vram_info.total = SZ_1M * 64;
p.vram_info.free = SZ_1M * 64;
p.vram_info.largest_free_block = SZ_1M * 64;
if (copy_to_user((void __user *)arg, &p.vram_info, sizeof(p.vram_info)))
r = -EFAULT; break;
}
case OMAPFB_SET_TEARSYNC: {
DBG("ioctl SET_TEARSYNC\n");
if (copy_from_user(&p.tearsync_info, (void __user *)arg, sizeof(p.tearsync_info))) {
r = -EFAULT; break;
}
if (!display || !display->driver->enable_te) {
r = -ENODEV; break;
}
r = display->driver->enable_te(display,
!!p.tearsync_info.enabled);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.