diff options
Diffstat (limited to 'drivers/gpu/drm/bochs')
-rw-r--r-- | drivers/gpu/drm/bochs/bochs.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/bochs/bochs_drv.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/bochs/bochs_fbdev.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/bochs/bochs_hw.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/bochs/bochs_kms.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/bochs/bochs_mm.c | 24 |
6 files changed, 75 insertions, 17 deletions
diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h index 7eb52dd44b01..71f2687fc3cc 100644 --- a/drivers/gpu/drm/bochs/bochs.h +++ b/drivers/gpu/drm/bochs/bochs.h @@ -7,6 +7,8 @@ #include <drm/drm_crtc_helper.h> #include <drm/drm_fb_helper.h> +#include <drm/drm_gem.h> + #include <ttm/ttm_bo_driver.h> #include <ttm/ttm_page_alloc.h> @@ -99,7 +101,7 @@ struct bochs_bo { struct ttm_placement placement; struct ttm_bo_kmap_obj kmap; struct drm_gem_object gem; - u32 placements[3]; + struct ttm_place placements[3]; int pin_count; }; diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c index 9738e9b14708..98837bde2d25 100644 --- a/drivers/gpu/drm/bochs/bochs_drv.c +++ b/drivers/gpu/drm/bochs/bochs_drv.c @@ -82,6 +82,7 @@ static struct drm_driver bochs_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET, .load = bochs_load, .unload = bochs_unload, + .set_busid = drm_pci_set_busid, .fops = &bochs_fops, .name = "bochs-drm", .desc = "bochs dispi vga interface (qemu stdvga)", diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c index fe95d31cd110..61dbf09dff5d 100644 --- a/drivers/gpu/drm/bochs/bochs_fbdev.c +++ b/drivers/gpu/drm/bochs/bochs_fbdev.c @@ -9,6 +9,17 @@ /* ---------------------------------------------------------------------- */ +static int bochsfb_mmap(struct fb_info *info, + struct vm_area_struct *vma) +{ + struct drm_fb_helper *fb_helper = info->par; + struct bochs_device *bochs = + container_of(fb_helper, struct bochs_device, fb.helper); + struct bochs_bo *bo = gem_to_bochs_bo(bochs->fb.gfb.obj); + + return ttm_fbdev_mmap(vma, &bo->bo); +} + static struct fb_ops bochsfb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, @@ -19,6 +30,7 @@ static struct fb_ops bochsfb_ops = { .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, + .fb_mmap = bochsfb_mmap, }; static int bochsfb_create_object(struct bochs_device *bochs, @@ -123,11 +135,9 @@ static int bochsfb_create(struct drm_fb_helper *helper, 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); + drm_vma_offset_remove(&bo->bo.bdev->vma_manager, &bo->bo.vma_node); + info->fix.smem_start = 0; info->fix.smem_len = size; -#endif ret = fb_alloc_cmap(&info->cmap, 256, 0); if (ret) { diff --git a/drivers/gpu/drm/bochs/bochs_hw.c b/drivers/gpu/drm/bochs/bochs_hw.c index dbe619e6aab4..460389702d31 100644 --- a/drivers/gpu/drm/bochs/bochs_hw.c +++ b/drivers/gpu/drm/bochs/bochs_hw.c @@ -51,11 +51,10 @@ int bochs_hw_init(struct drm_device *dev, uint32_t flags) { struct bochs_device *bochs = dev->dev_private; struct pci_dev *pdev = dev->pdev; - unsigned long addr, size, mem, ioaddr, iosize; + unsigned long addr, size, mem, ioaddr, iosize, qext_size; u16 id; - if (/* (ent->driver_data == BOCHS_QEMU_STDVGA) && */ - (pdev->resource[2].flags & IORESOURCE_MEM)) { + if (pdev->resource[2].flags & IORESOURCE_MEM) { /* mmio bar with vga and bochs registers present */ if (pci_request_region(pdev, 2, "bochs-drm") != 0) { DRM_ERROR("Cannot request mmio region\n"); @@ -116,6 +115,24 @@ int bochs_hw_init(struct drm_device *dev, uint32_t flags) size / 1024, addr, bochs->ioports ? "ioports" : "mmio", ioaddr); + + if (bochs->mmio && pdev->revision >= 2) { + qext_size = readl(bochs->mmio + 0x600); + if (qext_size < 4 || qext_size > iosize) + goto noext; + DRM_DEBUG("Found qemu ext regs, size %ld\n", qext_size); + if (qext_size >= 8) { +#ifdef __BIG_ENDIAN + writel(0xbebebebe, bochs->mmio + 0x604); +#else + writel(0x1e1e1e1e, bochs->mmio + 0x604); +#endif + DRM_DEBUG(" qext endian: 0x%x\n", + readl(bochs->mmio + 0x604)); + } + } + +noext: return 0; } diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 6b7efcf363d6..85f0f8cf1fb8 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -6,6 +6,7 @@ */ #include "bochs.h" +#include <drm/drm_plane_helper.h> static int defx = 1024; static int defy = 768; @@ -108,11 +109,32 @@ static void bochs_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, { } +static int bochs_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t page_flip_flags) +{ + struct bochs_device *bochs = + container_of(crtc, struct bochs_device, crtc); + struct drm_framebuffer *old_fb = crtc->primary->fb; + unsigned long irqflags; + + crtc->primary->fb = fb; + bochs_crtc_mode_set_base(crtc, 0, 0, old_fb); + if (event) { + spin_lock_irqsave(&bochs->dev->event_lock, irqflags); + drm_send_vblank_event(bochs->dev, -1, event); + spin_unlock_irqrestore(&bochs->dev->event_lock, irqflags); + } + return 0; +} + /* These provide the minimum set of functions required to handle a CRTC */ static const struct drm_crtc_funcs bochs_crtc_funcs = { .gamma_set = bochs_crtc_gamma_set, .set_config = drm_crtc_helper_set_config, .destroy = drm_crtc_cleanup, + .page_flip = bochs_crtc_page_flip, }; static const struct drm_crtc_helper_funcs bochs_helper_funcs = { diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c index 1728a1b0b813..66286ff518d4 100644 --- a/drivers/gpu/drm/bochs/bochs_mm.c +++ b/drivers/gpu/drm/bochs/bochs_mm.c @@ -257,20 +257,26 @@ void bochs_mm_fini(struct bochs_device *bochs) static void bochs_ttm_placement(struct bochs_bo *bo, int domain) { + unsigned i; u32 c = 0; - bo->placement.fpfn = 0; - bo->placement.lpfn = 0; bo->placement.placement = bo->placements; bo->placement.busy_placement = bo->placements; if (domain & TTM_PL_FLAG_VRAM) { - bo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED + bo->placements[c++].flags = TTM_PL_FLAG_WC + | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM; } if (domain & TTM_PL_FLAG_SYSTEM) { - bo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; + bo->placements[c++].flags = TTM_PL_MASK_CACHING + | TTM_PL_FLAG_SYSTEM; } if (!c) { - bo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; + bo->placements[c++].flags = TTM_PL_MASK_CACHING + | TTM_PL_FLAG_SYSTEM; + } + for (i = 0; i < c; ++i) { + bo->placements[i].fpfn = 0; + bo->placements[i].lpfn = 0; } bo->placement.num_placement = c; bo->placement.num_busy_placement = c; @@ -294,7 +300,7 @@ int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag, u64 *gpu_addr) bochs_ttm_placement(bo, pl_flag); for (i = 0; i < bo->placement.num_placement; i++) - bo->placements[i] |= TTM_PL_FLAG_NO_EVICT; + bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false); if (ret) return ret; @@ -319,7 +325,7 @@ int bochs_bo_unpin(struct bochs_bo *bo) return 0; for (i = 0; i < bo->placement.num_placement; i++) - bo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT; + bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false); if (ret) return ret; @@ -333,7 +339,7 @@ int bochs_mmap(struct file *filp, struct vm_area_struct *vma) struct bochs_device *bochs; if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) - return drm_mmap(filp, vma); + return -EINVAL; file_priv = filp->private_data; bochs = file_priv->minor->dev->dev_private; @@ -371,7 +377,7 @@ static int bochs_bo_create(struct drm_device *dev, int size, int align, ret = ttm_bo_init(&bochs->ttm.bdev, &bochsbo->bo, size, ttm_bo_type_device, &bochsbo->placement, align >> PAGE_SHIFT, false, NULL, acc_size, - NULL, bochs_bo_ttm_destroy); + NULL, NULL, bochs_bo_ttm_destroy); if (ret) return ret; |