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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
/* * 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); } }
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
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; }
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; }
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); }
/* 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); }
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); }
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; }
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); }
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; }
/* * 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); }
/* * 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); } } }
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; }
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; }
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; }
/* 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; }
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; }
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); }
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; }
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; }