diff options
Diffstat (limited to 'drivers/gpu/drm/bochs')
-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 |
3 files changed, 56 insertions, 7 deletions
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 = { |