void *radeon_gem_prime_vmap(struct drm_gem_object *obj) { struct radeon_bo *bo = gem_to_radeon_bo(obj); int ret; ret = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->dma_buf_vmap); if (ret) return ERR_PTR(ret); return bo->dma_buf_vmap.virtual; }
int nouveau_bo_map(struct nouveau_bo *nvbo) { int ret; ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0); if (ret) return ret; ret = ttm_bo_kmap(&nvbo->bo, 0, nvbo->bo.mem.num_pages, &nvbo->kmap); ttm_bo_unreserve(&nvbo->bo); return ret; }
/* cirrus is different - we will force move buffers out of VRAM */ static int cirrus_crtc_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y, int atomic) { struct cirrus_device *cdev = crtc->dev->dev_private; struct drm_gem_object *obj; struct cirrus_framebuffer *cirrus_fb; struct cirrus_bo *bo; int ret; u64 gpu_addr; /* push the previous fb to system ram */ if (!atomic && fb) { cirrus_fb = to_cirrus_framebuffer(fb); obj = cirrus_fb->obj; bo = gem_to_cirrus_bo(obj); ret = cirrus_bo_reserve(bo, false); if (ret) return ret; cirrus_bo_push_sysram(bo); cirrus_bo_unreserve(bo); } cirrus_fb = to_cirrus_framebuffer(crtc->primary->fb); obj = cirrus_fb->obj; bo = gem_to_cirrus_bo(obj); ret = cirrus_bo_reserve(bo, false); if (ret) return ret; ret = cirrus_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); if (ret) { cirrus_bo_unreserve(bo); return ret; } if (&cdev->mode_info.gfbdev->gfb == cirrus_fb) { /* if pushing console in kmap it */ ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); if (ret) DRM_ERROR("failed to kmap fbcon\n"); } cirrus_bo_unreserve(bo); cirrus_set_start_address(crtc, (u32)gpu_addr); return 0; }
/** * vmw_dummy_query_bo_create - create a bo to hold a dummy query result * * @dev_priv: A device private structure. * * This function creates a small buffer object that holds the query * result for dummy queries emitted as query barriers. * The function will then map the first page and initialize a pending * occlusion query result structure, Finally it will unmap the buffer. * No interruptible waits are done within this function. * * Returns an error if bo creation or initialization fails. */ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv) { int ret; struct vmw_dma_buffer *vbo; struct ttm_bo_kmap_obj map; volatile SVGA3dQueryResult *result; bool dummy; /* * Create the vbo as pinned, so that a tryreserve will * immediately succeed. This is because we're the only * user of the bo currently. */ vbo = kzalloc(sizeof(*vbo), GFP_KERNEL); if (!vbo) return -ENOMEM; ret = vmw_dmabuf_init(dev_priv, vbo, PAGE_SIZE, &vmw_sys_ne_placement, false, &vmw_dmabuf_bo_free); if (unlikely(ret != 0)) return ret; ret = ttm_bo_reserve(&vbo->base, false, true, NULL); BUG_ON(ret != 0); vmw_bo_pin_reserved(vbo, true); ret = ttm_bo_kmap(&vbo->base, 0, 1, &map); if (likely(ret == 0)) { result = ttm_kmap_obj_virtual(&map, &dummy); result->totalSize = sizeof(*result); result->state = SVGA3D_QUERYSTATE_PENDING; result->result32 = 0xff; ttm_bo_kunmap(&map); } vmw_bo_pin_reserved(vbo, false); ttm_bo_unreserve(&vbo->base); if (unlikely(ret != 0)) { DRM_ERROR("Dummy query buffer map failed.\n"); vmw_dmabuf_unreference(&vbo); } else dev_priv->dummy_query_bo = vbo; return ret; }
static int vbox_crtc_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y, int atomic) { struct vbox_private *vbox = crtc->dev->dev_private; struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); struct drm_gem_object *obj; struct vbox_framebuffer *vbox_fb; struct vbox_bo *bo; int ret; u64 gpu_addr; LogFunc(("vboxvideo: %d: fb=%p, vbox_crtc=%p\n", __LINE__, fb, vbox_crtc)); vbox_fb = to_vbox_framebuffer(CRTC_FB(crtc)); obj = vbox_fb->obj; bo = gem_to_vbox_bo(obj); ret = vbox_bo_reserve(bo, false); if (ret) return ret; ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); if (ret) { vbox_bo_unreserve(bo); return ret; } if (&vbox->fbdev->afb == vbox_fb) { /* if pushing console in kmap it */ ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); if (ret) DRM_ERROR("failed to kmap fbcon\n"); } vbox_bo_unreserve(bo); /* vbox_set_start_address_crt1(crtc, (u32)gpu_addr); */ vbox_crtc->offFB = gpu_addr; LogFunc(("vboxvideo: %d: vbox_fb=%p, obj=%p, bo=%p, gpu_addr=%u\n", __LINE__, vbox_fb, obj, bo, (unsigned)gpu_addr)); return 0; }
int virtio_gpu_object_kmap(struct virtio_gpu_object *bo, void **ptr) { bool is_iomem; int r; if (bo->vmap) { if (ptr) *ptr = bo->vmap; return 0; } r = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->kmap); if (r) return r; bo->vmap = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem); if (ptr) *ptr = bo->vmap; return 0; }
int radeon_bo_kmap(struct radeon_bo *bo, void **ptr) { bool is_iomem; int r; if (bo->kptr) { if (ptr) { *ptr = bo->kptr; } return 0; } r = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->kmap); if (r) { return r; } bo->kptr = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem); if (ptr) { *ptr = bo->kptr; } radeon_bo_check_tiling(bo, 0, 0); return 0; }
static void *nouveau_gem_prime_vmap(struct dma_buf *dma_buf) { struct nouveau_bo *nvbo = dma_buf->priv; struct drm_device *dev = nvbo->gem->dev; int ret; mutex_lock(&dev->struct_mutex); if (nvbo->vmapping_count) { nvbo->vmapping_count++; goto out_unlock; } ret = ttm_bo_kmap(&nvbo->bo, 0, nvbo->bo.num_pages, &nvbo->dma_buf_vmap); if (ret) { mutex_unlock(&dev->struct_mutex); return ERR_PTR(ret); } nvbo->vmapping_count = 1; out_unlock: mutex_unlock(&dev->struct_mutex); return nvbo->dma_buf_vmap.virtual; }
static void *radeon_gem_prime_vmap(struct dma_buf *dma_buf) { struct radeon_bo *bo = dma_buf->priv; struct drm_device *dev = bo->rdev->ddev; int ret; mutex_lock(&dev->struct_mutex); if (bo->vmapping_count) { bo->vmapping_count++; goto out_unlock; } ret = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->dma_buf_vmap); if (ret) { mutex_unlock(&dev->struct_mutex); return ERR_PTR(ret); } bo->vmapping_count = 1; out_unlock: mutex_unlock(&dev->struct_mutex); return bo->dma_buf_vmap.virtual; }
/* allocate cursor cache and pin at start of VRAM */ int vbox_cursor_init(struct drm_device *dev) { struct vbox_private *vbox = dev->dev_private; int size; int ret; struct drm_gem_object *obj; struct vbox_bo *bo; uint64_t gpu_addr; size = (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE) * AST_DEFAULT_HWC_NUM; ret = vbox_gem_create(dev, size, true, &obj); if (ret) return ret; bo = gem_to_vbox_bo(obj); ret = vbox_bo_reserve(bo, false); if (unlikely(ret != 0)) goto fail; ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); vbox_bo_unreserve(bo); if (ret) goto fail; /* kmap the object */ ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &vbox->cache_kmap); if (ret) goto fail; vbox->cursor_cache = obj; vbox->cursor_cache_gpu_addr = gpu_addr; DRM_DEBUG_KMS("pinned cursor cache at %llx\n", vbox->cursor_cache_gpu_addr); return 0; fail: return ret; }
ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp, const char __user *wbuf, char __user *rbuf, size_t count, loff_t *f_pos, bool write) { struct ttm_buffer_object *bo; struct ttm_bo_driver *driver; struct ttm_bo_kmap_obj map; unsigned long dev_offset = (*f_pos >> PAGE_SHIFT); unsigned long kmap_offset; unsigned long kmap_end; unsigned long kmap_num; size_t io_size; unsigned int page_offset; char *virtual; int ret; bool no_wait = false; bool dummy; read_lock(&bdev->vm_lock); bo = ttm_bo_vm_lookup_rb(bdev, dev_offset, 1); if (likely(bo != NULL)) ttm_bo_reference(bo); read_unlock(&bdev->vm_lock); if (unlikely(bo == NULL)) return -EFAULT; driver = bo->bdev->driver; if (unlikely(!driver->verify_access)) { ret = -EPERM; goto out_unref; } ret = driver->verify_access(bo, filp); if (unlikely(ret != 0)) goto out_unref; kmap_offset = dev_offset - bo->vm_node->start; if (unlikely(kmap_offset >= bo->num_pages)) { ret = -EFBIG; goto out_unref; } page_offset = *f_pos & ~PAGE_MASK; io_size = bo->num_pages - kmap_offset; io_size = (io_size << PAGE_SHIFT) - page_offset; if (count < io_size) io_size = count; kmap_end = (*f_pos + count - 1) >> PAGE_SHIFT; kmap_num = kmap_end - kmap_offset + 1; ret = ttm_bo_reserve(bo, true, no_wait, false, 0); switch (ret) { case 0: break; case -EBUSY: ret = -EAGAIN; goto out_unref; default: goto out_unref; } ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map); if (unlikely(ret != 0)) { ttm_bo_unreserve(bo); goto out_unref; } virtual = ttm_kmap_obj_virtual(&map, &dummy); virtual += page_offset; if (write) ret = copy_from_user(virtual, wbuf, io_size); else
static int bochsfb_create(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { struct bochs_device *bochs = container_of(helper, struct bochs_device, fb.helper); struct drm_device *dev = bochs->dev; struct fb_info *info; struct drm_framebuffer *fb; struct drm_mode_fb_cmd2 mode_cmd; struct device *device = &dev->pdev->dev; struct drm_gem_object *gobj = NULL; struct bochs_bo *bo = NULL; int size, ret; if (sizes->surface_bpp != 32) return -EINVAL; mode_cmd.width = sizes->surface_width; mode_cmd.height = sizes->surface_height; mode_cmd.pitches[0] = mode_cmd.width * ((sizes->surface_bpp + 7) / 8); mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); size = mode_cmd.pitches[0] * mode_cmd.height; /* alloc, pin & map bo */ ret = bochsfb_create_object(bochs, &mode_cmd, &gobj); if (ret) { DRM_ERROR("failed to create fbcon backing object %d\n", ret); return ret; } bo = gem_to_bochs_bo(gobj); ret = ttm_bo_reserve(&bo->bo, true, false, false, 0); if (ret) return ret; ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL); if (ret) { DRM_ERROR("failed to pin fbcon\n"); ttm_bo_unreserve(&bo->bo); return ret; } ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); if (ret) { DRM_ERROR("failed to kmap fbcon\n"); ttm_bo_unreserve(&bo->bo); return ret; } ttm_bo_unreserve(&bo->bo); /* init fb device */ info = framebuffer_alloc(0, device); if (info == NULL) return -ENOMEM; info->par = &bochs->fb.helper; ret = bochs_framebuffer_init(bochs->dev, &bochs->fb.gfb, &mode_cmd, gobj); if (ret) return ret; bochs->fb.size = size; /* setup helper */ fb = &bochs->fb.gfb.base; bochs->fb.helper.fb = fb; bochs->fb.helper.fbdev = info; strcpy(info->fix.id, "bochsdrmfb"); info->flags = FBINFO_DEFAULT; info->fbops = &bochsfb_ops; drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(info, &bochs->fb.helper, sizes->fb_width, sizes->fb_height); info->screen_base = bo->kmap.virtual; info->screen_size = size; #if 0 /* FIXME: get this right for mmap(/dev/fb0) */ info->fix.smem_start = bochs_bo_mmap_offset(bo); info->fix.smem_len = size; #endif ret = fb_alloc_cmap(&info->cmap, 256, 0); if (ret) { DRM_ERROR("%s: can't allocate color map\n", info->fix.id); return -ENOMEM; } return 0; }
int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, uint32_t width, uint32_t height) { struct vmw_private *dev_priv = vmw_priv(crtc->dev); struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; struct vmw_display_unit *du = vmw_crtc_to_du(crtc); struct vmw_surface *surface = NULL; struct vmw_dma_buffer *dmabuf = NULL; int ret; if (handle) { ret = vmw_user_surface_lookup_handle(dev_priv, tfile, handle, &surface); if (!ret) { if (!surface->snooper.image) { DRM_ERROR("surface not suitable for cursor\n"); return -EINVAL; } } else { ret = vmw_user_dmabuf_lookup(tfile, handle, &dmabuf); if (ret) { DRM_ERROR("failed to find surface or dmabuf: %i\n", ret); return -EINVAL; } } } /* takedown old cursor */ if (du->cursor_surface) { du->cursor_surface->snooper.crtc = NULL; vmw_surface_unreference(&du->cursor_surface); } if (du->cursor_dmabuf) vmw_dmabuf_unreference(&du->cursor_dmabuf); /* setup new image */ if (surface) { /* vmw_user_surface_lookup takes one reference */ du->cursor_surface = surface; du->cursor_surface->snooper.crtc = crtc; du->cursor_age = du->cursor_surface->snooper.age; vmw_cursor_update_image(dev_priv, surface->snooper.image, 64, 64, du->hotspot_x, du->hotspot_y); } else if (dmabuf) { struct ttm_bo_kmap_obj map; unsigned long kmap_offset; unsigned long kmap_num; void *virtual; bool dummy; /* vmw_user_surface_lookup takes one reference */ du->cursor_dmabuf = dmabuf; kmap_offset = 0; kmap_num = (64*64*4) >> PAGE_SHIFT; ret = ttm_bo_reserve(&dmabuf->base, true, false, false, 0); if (unlikely(ret != 0)) { DRM_ERROR("reserve failed\n"); return -EINVAL; } ret = ttm_bo_kmap(&dmabuf->base, kmap_offset, kmap_num, &map); if (unlikely(ret != 0)) goto err_unreserve; virtual = ttm_kmap_obj_virtual(&map, &dummy); vmw_cursor_update_image(dev_priv, virtual, 64, 64, du->hotspot_x, du->hotspot_y); ttm_bo_kunmap(&map); err_unreserve: ttm_bo_unreserve(&dmabuf->base); } else {
static int bochsfb_create(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { struct bochs_device *bochs = container_of(helper, struct bochs_device, fb.helper); struct fb_info *info; struct drm_framebuffer *fb; struct drm_mode_fb_cmd2 mode_cmd; struct drm_gem_object *gobj = NULL; struct bochs_bo *bo = NULL; int size, ret; if (sizes->surface_bpp != 32) return -EINVAL; mode_cmd.width = sizes->surface_width; mode_cmd.height = sizes->surface_height; mode_cmd.pitches[0] = mode_cmd.width * ((sizes->surface_bpp + 7) / 8); mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); size = mode_cmd.pitches[0] * mode_cmd.height; /* alloc, pin & map bo */ ret = bochsfb_create_object(bochs, &mode_cmd, &gobj); if (ret) { DRM_ERROR("failed to create fbcon backing object %d\n", ret); return ret; } bo = gem_to_bochs_bo(gobj); ret = ttm_bo_reserve(&bo->bo, true, false, false, NULL); if (ret) return ret; ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL); if (ret) { DRM_ERROR("failed to pin fbcon\n"); ttm_bo_unreserve(&bo->bo); return ret; } ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); if (ret) { DRM_ERROR("failed to kmap fbcon\n"); ttm_bo_unreserve(&bo->bo); return ret; } ttm_bo_unreserve(&bo->bo); /* init fb device */ info = drm_fb_helper_alloc_fbi(helper); if (IS_ERR(info)) return PTR_ERR(info); info->par = &bochs->fb.helper; ret = bochs_framebuffer_init(bochs->dev, &bochs->fb.gfb, &mode_cmd, gobj); if (ret) { drm_fb_helper_release_fbi(helper); return ret; } bochs->fb.size = size; /* setup helper */ fb = &bochs->fb.gfb.base; bochs->fb.helper.fb = fb; strcpy(info->fix.id, "bochsdrmfb"); info->flags = FBINFO_DEFAULT; info->fbops = &bochsfb_ops; drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(info, &bochs->fb.helper, sizes->fb_width, sizes->fb_height); info->screen_base = bo->kmap.virtual; info->screen_size = size; drm_vma_offset_remove(&bo->bo.bdev->vma_manager, &bo->bo.vma_node); info->fix.smem_start = 0; info->fix.smem_len = size; return 0; }
int vsp_init(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; struct ttm_bo_device *bdev = &dev_priv->bdev; struct vsp_private *vsp_priv; bool is_iomem; int ret; unsigned int context_size; VSP_DEBUG("init vsp private data structure\n"); vsp_priv = kmalloc(sizeof(struct vsp_private), GFP_KERNEL); if (vsp_priv == NULL) return -1; memset(vsp_priv, 0, sizeof(*vsp_priv)); /* get device --> drm_device --> drm_psb_private --> vsp_priv * for psb_vsp_pmstate_show: vsp_pmpolicy * if not pci_set_drvdata, can't get drm_device from device */ /* pci_set_drvdata(dev->pdev, dev); */ if (device_create_file(&dev->pdev->dev, &dev_attr_vsp_pmstate)) DRM_ERROR("TOPAZ: could not create sysfs file\n"); vsp_priv->sysfs_pmstate = sysfs_get_dirent( dev->pdev->dev.kobj.sd, NULL, "vsp_pmstate"); vsp_priv->vsp_cmd_num = 0; vsp_priv->fw_loaded = VSP_FW_NONE; vsp_priv->current_sequence = 0; vsp_priv->vsp_state = VSP_STATE_DOWN; vsp_priv->dev = dev; vsp_priv->coded_buf = NULL; vsp_priv->context_num = 0; atomic_set(&dev_priv->vsp_mmu_invaldc, 0); dev_priv->vsp_private = vsp_priv; vsp_priv->cmd_queue_sz = VSP_CMD_QUEUE_SIZE * sizeof(struct vss_command_t); #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) ret = ttm_buffer_object_create(bdev, vsp_priv->cmd_queue_sz, ttm_bo_type_kernel, DRM_PSB_FLAG_MEM_MMU | TTM_PL_FLAG_NO_EVICT, 0, 0, 0, NULL, &vsp_priv->cmd_queue_bo); #else ret = ttm_buffer_object_create(bdev, vsp_priv->cmd_queue_sz, ttm_bo_type_kernel, DRM_PSB_FLAG_MEM_MMU | TTM_PL_FLAG_NO_EVICT, 0, 0, NULL, &vsp_priv->cmd_queue_bo); #endif if (ret != 0) { DRM_ERROR("VSP: failed to allocate VSP cmd queue\n"); goto out_clean; } vsp_priv->ack_queue_sz = VSP_ACK_QUEUE_SIZE * sizeof(struct vss_response_t); #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) ret = ttm_buffer_object_create(bdev, vsp_priv->ack_queue_sz, ttm_bo_type_kernel, DRM_PSB_FLAG_MEM_MMU | TTM_PL_FLAG_NO_EVICT, 0, 0, 0, NULL, &vsp_priv->ack_queue_bo); #else ret = ttm_buffer_object_create(bdev, vsp_priv->ack_queue_sz, ttm_bo_type_kernel, DRM_PSB_FLAG_MEM_MMU | TTM_PL_FLAG_NO_EVICT, 0, 0, NULL, &vsp_priv->ack_queue_bo); #endif if (ret != 0) { DRM_ERROR("VSP: failed to allocate VSP cmd ack queue\n"); goto out_clean; } /* Create setting buffer */ #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) ret = ttm_buffer_object_create(bdev, sizeof(struct vsp_settings_t), ttm_bo_type_kernel, DRM_PSB_FLAG_MEM_MMU | TTM_PL_FLAG_NO_EVICT, 0, 0, 0, NULL, &vsp_priv->setting_bo); #else ret = ttm_buffer_object_create(bdev, sizeof(struct vsp_settings_t), ttm_bo_type_kernel, DRM_PSB_FLAG_MEM_MMU | TTM_PL_FLAG_NO_EVICT, 0, 0, NULL, &vsp_priv->setting_bo); #endif if (ret != 0) { DRM_ERROR("VSP: failed to allocate VSP setting buffer\n"); goto out_clean; } /* map cmd queue */ ret = ttm_bo_kmap(vsp_priv->cmd_queue_bo, 0, vsp_priv->cmd_queue_bo->num_pages, &vsp_priv->cmd_kmap); if (ret) { DRM_ERROR("drm_bo_kmap failed: %d\n", ret); ttm_bo_unref(&vsp_priv->cmd_queue_bo); ttm_bo_kunmap(&vsp_priv->cmd_kmap); goto out_clean; } vsp_priv->cmd_queue = ttm_kmap_obj_virtual(&vsp_priv->cmd_kmap, &is_iomem); /* map ack queue */ ret = ttm_bo_kmap(vsp_priv->ack_queue_bo, 0, vsp_priv->ack_queue_bo->num_pages, &vsp_priv->ack_kmap); if (ret) { DRM_ERROR("drm_bo_kmap failed: %d\n", ret); ttm_bo_unref(&vsp_priv->ack_queue_bo); ttm_bo_kunmap(&vsp_priv->ack_kmap); goto out_clean; } vsp_priv->ack_queue = ttm_kmap_obj_virtual(&vsp_priv->ack_kmap, &is_iomem); /* map vsp setting */ ret = ttm_bo_kmap(vsp_priv->setting_bo, 0, vsp_priv->setting_bo->num_pages, &vsp_priv->setting_kmap); if (ret) { DRM_ERROR("drm_bo_kmap setting_bo failed: %d\n", ret); ttm_bo_unref(&vsp_priv->setting_bo); ttm_bo_kunmap(&vsp_priv->setting_kmap); goto out_clean; } vsp_priv->setting = ttm_kmap_obj_virtual(&vsp_priv->setting_kmap, &is_iomem); vsp_priv->vp8_filp[0] = NULL; vsp_priv->vp8_filp[1] = NULL; vsp_priv->context_vp8_num = 0; vsp_priv->vp8_cmd_num = 0; spin_lock_init(&vsp_priv->lock); mutex_init(&vsp_priv->vsp_mutex); INIT_DELAYED_WORK(&vsp_priv->vsp_suspend_wq, &psb_powerdown_vsp); INIT_DELAYED_WORK(&vsp_priv->vsp_irq_wq, &vsp_irq_task); return 0; out_clean: vsp_deinit(dev); return -1; }
static int hibmc_drm_fb_create(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { struct hibmc_fbdev *hi_fbdev = container_of(helper, struct hibmc_fbdev, helper); struct hibmc_drm_private *priv = helper->dev->dev_private; struct fb_info *info; struct drm_mode_fb_cmd2 mode_cmd; struct drm_gem_object *gobj = NULL; int ret = 0; int ret1; size_t size; unsigned int bytes_per_pixel; struct hibmc_bo *bo = NULL; DRM_DEBUG_DRIVER("surface width(%d), height(%d) and bpp(%d)\n", sizes->surface_width, sizes->surface_height, sizes->surface_bpp); bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8); mode_cmd.width = sizes->surface_width; mode_cmd.height = sizes->surface_height; mode_cmd.pitches[0] = mode_cmd.width * bytes_per_pixel; mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); size = PAGE_ALIGN(mode_cmd.pitches[0] * mode_cmd.height); ret = hibmcfb_create_object(priv, &mode_cmd, &gobj); if (ret) { DRM_ERROR("failed to create fbcon backing object: %d\n", ret); return -ENOMEM; } bo = gem_to_hibmc_bo(gobj); ret = ttm_bo_reserve(&bo->bo, true, false, NULL); if (ret) { DRM_ERROR("failed to reserve ttm_bo: %d\n", ret); goto out_unref_gem; } ret = hibmc_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL); if (ret) { DRM_ERROR("failed to pin fbcon: %d\n", ret); goto out_unreserve_ttm_bo; } ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); if (ret) { DRM_ERROR("failed to kmap fbcon: %d\n", ret); goto out_unpin_bo; } ttm_bo_unreserve(&bo->bo); info = drm_fb_helper_alloc_fbi(helper); if (IS_ERR(info)) { ret = PTR_ERR(info); DRM_ERROR("failed to allocate fbi: %d\n", ret); goto out_release_fbi; } info->par = hi_fbdev; hi_fbdev->fb = hibmc_framebuffer_init(priv->dev, &mode_cmd, gobj); if (IS_ERR(hi_fbdev->fb)) { ret = PTR_ERR(hi_fbdev->fb); hi_fbdev->fb = NULL; DRM_ERROR("failed to initialize framebuffer: %d\n", ret); goto out_release_fbi; } priv->fbdev->size = size; hi_fbdev->helper.fb = &hi_fbdev->fb->fb; strcpy(info->fix.id, "hibmcdrmfb"); info->fbops = &hibmc_drm_fb_ops; drm_fb_helper_fill_fix(info, hi_fbdev->fb->fb.pitches[0], hi_fbdev->fb->fb.format->depth); drm_fb_helper_fill_var(info, &priv->fbdev->helper, sizes->fb_width, sizes->fb_height); info->screen_base = bo->kmap.virtual; info->screen_size = size; info->fix.smem_start = bo->bo.mem.bus.offset + bo->bo.mem.bus.base; info->fix.smem_len = size; return 0; out_release_fbi: ret1 = ttm_bo_reserve(&bo->bo, true, false, NULL); if (ret1) { DRM_ERROR("failed to rsv ttm_bo when release fbi: %d\n", ret1); goto out_unref_gem; } ttm_bo_kunmap(&bo->kmap); out_unpin_bo: hibmc_bo_unpin(bo); out_unreserve_ttm_bo: ttm_bo_unreserve(&bo->bo); out_unref_gem: drm_gem_object_put_unlocked(gobj); return ret; }
static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, uint32_t width, uint32_t height, int32_t hot_x, int32_t hot_y) { struct vbox_private *vbox = crtc->dev->dev_private; struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); struct drm_gem_object *obj; struct vbox_bo *bo; int ret, rc; struct ttm_bo_kmap_obj uobj_map; u8 *src; u8 *dst = NULL; size_t cbData, cbMask; bool src_isiomem; if (!handle) { /* Hide cursor. */ VBoxHGSMIUpdatePointerShape(&vbox->Ctx, 0, 0, 0, 0, 0, NULL, 0); return 0; } if ( width > VBOX_MAX_CURSOR_WIDTH || height > VBOX_MAX_CURSOR_HEIGHT || width == 0 || hot_x > width || height == 0 || hot_y > height) return -EINVAL; obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); if (obj) { bo = gem_to_vbox_bo(obj); ret = vbox_bo_reserve(bo, false); if (!ret) { /* The mask must be calculated based on the alpha channel, one bit * per ARGB word, and must be 32-bit padded. */ cbMask = ((width + 7) / 8 * height + 3) & ~3; cbData = width * height * 4 + cbMask; dst = kmalloc(cbData, GFP_KERNEL); if (dst) { ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &uobj_map); if (!ret) { src = ttm_kmap_obj_virtual(&uobj_map, &src_isiomem); if (!src_isiomem) { uint32_t fFlags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE | VBOX_MOUSE_POINTER_ALPHA; copy_cursor_image(src, dst, width, height, cbMask); rc = VBoxHGSMIUpdatePointerShape(&vbox->Ctx, fFlags, hot_x, hot_y, width, height, dst, cbData); ret = RTErrConvertToErrno(rc); } else DRM_ERROR("src cursor bo should be in main memory\n"); ttm_bo_kunmap(&uobj_map); } kfree(dst); } vbox_bo_unreserve(bo); } drm_gem_object_unreference_unlocked(obj); } else { DRM_ERROR("Cannot find cursor object %x for crtc\n", handle); ret = -ENOENT; } return ret; }