Skip to content

Commit

Permalink
Merge branch 'drm-vmware-fixes' into drm-testing
Browse files Browse the repository at this point in the history
* drm-vmware-fixes:
  drm/vmwgfx: Remove some leftover debug messages.
  drm/vmwgfx: Print warnings in kernel log about bo pinning that fails.
  drm/vmwgfx: Unpause overlay on update.
  drm/vmwgfx: Some modesetting cleanups and fixes.
  drm/vmwgfx: Don't use SVGA_REG_ENABLE in modesetting code.
  drm/vmwgfx: Remove duplicate member from struct vmw_legacy_display_unit.
  drm/vmwgfx: Reserve first part of VRAM for framebuffer.
  drm/vmwgfx: Support older hardware.
  drm/vmwgfx: Get connector status from detection function.
  drm/vmwgfx: Add kernel throttling support. Bump minor.
  drm/vmwgfx: Make sure to unpin old and pin new framebuffer.
  drm/vmwgfx: Fix single framebuffer detection.
  drm/vmwgfx: Assume larger framebuffer max size.
  • Loading branch information
Dave Airlie committed Jun 1, 2010
2 parents 4abe438 + 1ca14e7 commit c09a350
Show file tree
Hide file tree
Showing 11 changed files with 433 additions and 149 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/vmwgfx/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ ccflags-y := -Iinclude/drm
vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
vmwgfx_fb.o vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_buffer.o \
vmwgfx_fifo.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \
vmwgfx_overlay.o
vmwgfx_overlay.o vmwgfx_fence.o

obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
17 changes: 9 additions & 8 deletions drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,15 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
goto out_err3;
}

/* Need mmio memory to check for fifo pitchlock cap. */
if (!(dev_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) &&
!(dev_priv->capabilities & SVGA_CAP_PITCHLOCK) &&
!vmw_fifo_have_pitchlock(dev_priv)) {
ret = -ENOSYS;
DRM_ERROR("Hardware has no pitchlock\n");
goto out_err4;
}

dev_priv->tdev = ttm_object_device_init
(dev_priv->mem_global_ref.object, 12);

Expand Down Expand Up @@ -399,8 +408,6 @@ static int vmw_driver_unload(struct drm_device *dev)
{
struct vmw_private *dev_priv = vmw_priv(dev);

DRM_INFO(VMWGFX_DRIVER_NAME " unload.\n");

unregister_pm_notifier(&dev_priv->pm_nb);

vmw_fb_close(dev_priv);
Expand Down Expand Up @@ -546,7 +553,6 @@ static int vmw_master_create(struct drm_device *dev,
{
struct vmw_master *vmaster;

DRM_INFO("Master create.\n");
vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL);
if (unlikely(vmaster == NULL))
return -ENOMEM;
Expand All @@ -563,7 +569,6 @@ static void vmw_master_destroy(struct drm_device *dev,
{
struct vmw_master *vmaster = vmw_master(master);

DRM_INFO("Master destroy.\n");
master->driver_priv = NULL;
kfree(vmaster);
}
Expand All @@ -579,8 +584,6 @@ static int vmw_master_set(struct drm_device *dev,
struct vmw_master *vmaster = vmw_master(file_priv->master);
int ret = 0;

DRM_INFO("Master set.\n");

if (active) {
BUG_ON(active != &dev_priv->fbdev_master);
ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile);
Expand Down Expand Up @@ -622,8 +625,6 @@ static void vmw_master_drop(struct drm_device *dev,
struct vmw_master *vmaster = vmw_master(file_priv->master);
int ret;

DRM_INFO("Master drop.\n");

/**
* Make sure the master doesn't disappear while we have
* it locked.
Expand Down
32 changes: 31 additions & 1 deletion drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

#define VMWGFX_DRIVER_DATE "20100209"
#define VMWGFX_DRIVER_MAJOR 1
#define VMWGFX_DRIVER_MINOR 0
#define VMWGFX_DRIVER_MINOR 1
#define VMWGFX_DRIVER_PATCHLEVEL 0
#define VMWGFX_FILE_PAGE_OFFSET 0x00100000
#define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
Expand Down Expand Up @@ -102,6 +102,13 @@ struct vmw_surface {
struct vmw_cursor_snooper snooper;
};

struct vmw_fence_queue {
struct list_head head;
struct timespec lag;
struct timespec lag_time;
spinlock_t lock;
};

struct vmw_fifo_state {
unsigned long reserved_size;
__le32 *dynamic_buffer;
Expand All @@ -115,6 +122,7 @@ struct vmw_fifo_state {
uint32_t capabilities;
struct mutex fifo_mutex;
struct rw_semaphore rwsem;
struct vmw_fence_queue fence_queue;
};

struct vmw_relocation {
Expand Down Expand Up @@ -179,6 +187,7 @@ struct vmw_private {
uint32_t vga_red_mask;
uint32_t vga_blue_mask;
uint32_t vga_green_mask;
uint32_t vga_pitchlock;

/*
* Framebuffer info.
Expand Down Expand Up @@ -393,6 +402,7 @@ extern int vmw_fifo_send_fence(struct vmw_private *dev_priv,
extern void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason);
extern int vmw_fifo_mmap(struct file *filp, struct vm_area_struct *vma);
extern bool vmw_fifo_have_3d(struct vmw_private *dev_priv);
extern bool vmw_fifo_have_pitchlock(struct vmw_private *dev_priv);

/**
* TTM glue - vmwgfx_ttm_glue.c
Expand Down Expand Up @@ -441,6 +451,23 @@ extern int vmw_fallback_wait(struct vmw_private *dev_priv,
uint32_t sequence,
bool interruptible,
unsigned long timeout);
extern void vmw_update_sequence(struct vmw_private *dev_priv,
struct vmw_fifo_state *fifo_state);


/**
* Rudimentary fence objects currently used only for throttling -
* vmwgfx_fence.c
*/

extern void vmw_fence_queue_init(struct vmw_fence_queue *queue);
extern void vmw_fence_queue_takedown(struct vmw_fence_queue *queue);
extern int vmw_fence_push(struct vmw_fence_queue *queue,
uint32_t sequence);
extern int vmw_fence_pull(struct vmw_fence_queue *queue,
uint32_t signaled_sequence);
extern int vmw_wait_lag(struct vmw_private *dev_priv,
struct vmw_fence_queue *queue, uint32_t us);

/**
* Kernel framebuffer - vmwgfx_fb.c
Expand All @@ -466,6 +493,9 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
struct ttm_object_file *tfile,
struct ttm_buffer_object *bo,
SVGA3dCmdHeader *header);
void vmw_kms_write_svga(struct vmw_private *vmw_priv,
unsigned width, unsigned height, unsigned pitch,
unsigned bbp, unsigned depth);

/**
* Overlay control - vmwgfx_overlay.c
Expand Down
9 changes: 9 additions & 0 deletions drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,15 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
goto out_err;

vmw_apply_relocations(sw_context);

if (arg->throttle_us) {
ret = vmw_wait_lag(dev_priv, &dev_priv->fifo.fence_queue,
arg->throttle_us);

if (unlikely(ret != 0))
goto out_err;
}

vmw_fifo_commit(dev_priv, arg->command_size);

ret = vmw_fifo_send_fence(dev_priv, &sequence);
Expand Down
81 changes: 28 additions & 53 deletions drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,14 @@ static int vmw_fb_check_var(struct fb_var_screeninfo *var,
return -EINVAL;
}

/* without multimon its hard to resize */
if (!(vmw_priv->capabilities & SVGA_CAP_MULTIMON) &&
(var->xres != par->max_width ||
var->yres != par->max_height)) {
DRM_ERROR("Tried to resize, but we don't have multimon\n");
if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) &&
(var->xoffset != 0 || var->yoffset != 0)) {
DRM_ERROR("Can not handle panning without display topology\n");
return -EINVAL;
}

if (var->xres > par->max_width ||
var->yres > par->max_height) {
if ((var->xoffset + var->xres) > par->max_width ||
(var->yoffset + var->yres) > par->max_height) {
DRM_ERROR("Requested geom can not fit in framebuffer\n");
return -EINVAL;
}
Expand All @@ -154,8 +152,7 @@ static int vmw_fb_set_par(struct fb_info *info)
struct vmw_fb_par *par = info->par;
struct vmw_private *vmw_priv = par->vmw_priv;

if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) {
vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
if (vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) {
vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0);
Expand All @@ -164,32 +161,31 @@ static int vmw_fb_set_par(struct fb_info *info)
vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);

vmw_write(vmw_priv, SVGA_REG_ENABLE, 1);
vmw_write(vmw_priv, SVGA_REG_WIDTH, par->max_width);
vmw_write(vmw_priv, SVGA_REG_HEIGHT, par->max_height);
vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, par->bpp);
vmw_write(vmw_priv, SVGA_REG_DEPTH, par->depth);
vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000);
vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00);
vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff);
vmw_kms_write_svga(vmw_priv, info->var.xres, info->var.yres,
info->fix.line_length,
par->bpp, par->depth);

/* TODO check if pitch and offset changes */

vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, info->var.xoffset);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, info->var.yoffset);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, info->var.xres);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
} else {
vmw_write(vmw_priv, SVGA_REG_WIDTH, info->var.xres);
vmw_write(vmw_priv, SVGA_REG_HEIGHT, info->var.yres);
vmw_kms_write_svga(vmw_priv, info->var.xres, info->var.yres,
info->fix.line_length,
par->bpp, par->depth);

/* TODO check if pitch and offset changes */
}

/* This is really helpful since if this fails the user
* can probably not see anything on the screen.
*/
WARN_ON(vmw_read(vmw_priv, SVGA_REG_FB_OFFSET) != 0);

return 0;
}

Expand Down Expand Up @@ -416,48 +412,23 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
unsigned fb_bbp, fb_depth, fb_offset, fb_pitch, fb_size;
int ret;

/* XXX These shouldn't be hardcoded. */
initial_width = 800;
initial_height = 600;

fb_bbp = 32;
fb_depth = 24;

if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) {
fb_width = min(vmw_priv->fb_max_width, (unsigned)2048);
fb_height = min(vmw_priv->fb_max_height, (unsigned)2048);
} else {
fb_width = min(vmw_priv->fb_max_width, initial_width);
fb_height = min(vmw_priv->fb_max_height, initial_height);
}
/* XXX As shouldn't these be as well. */
fb_width = min(vmw_priv->fb_max_width, (unsigned)2048);
fb_height = min(vmw_priv->fb_max_height, (unsigned)2048);

initial_width = min(fb_width, initial_width);
initial_height = min(fb_height, initial_height);

vmw_write(vmw_priv, SVGA_REG_WIDTH, fb_width);
vmw_write(vmw_priv, SVGA_REG_HEIGHT, fb_height);
vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, fb_bbp);
vmw_write(vmw_priv, SVGA_REG_DEPTH, fb_depth);
vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000);
vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00);
vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff);

fb_size = vmw_read(vmw_priv, SVGA_REG_FB_SIZE);
fb_pitch = fb_width * fb_bbp / 8;
fb_size = fb_pitch * fb_height;
fb_offset = vmw_read(vmw_priv, SVGA_REG_FB_OFFSET);
fb_pitch = vmw_read(vmw_priv, SVGA_REG_BYTES_PER_LINE);

DRM_DEBUG("width %u\n", vmw_read(vmw_priv, SVGA_REG_MAX_WIDTH));
DRM_DEBUG("height %u\n", vmw_read(vmw_priv, SVGA_REG_MAX_HEIGHT));
DRM_DEBUG("width %u\n", vmw_read(vmw_priv, SVGA_REG_WIDTH));
DRM_DEBUG("height %u\n", vmw_read(vmw_priv, SVGA_REG_HEIGHT));
DRM_DEBUG("bpp %u\n", vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL));
DRM_DEBUG("depth %u\n", vmw_read(vmw_priv, SVGA_REG_DEPTH));
DRM_DEBUG("bpl %u\n", vmw_read(vmw_priv, SVGA_REG_BYTES_PER_LINE));
DRM_DEBUG("r mask %08x\n", vmw_read(vmw_priv, SVGA_REG_RED_MASK));
DRM_DEBUG("g mask %08x\n", vmw_read(vmw_priv, SVGA_REG_GREEN_MASK));
DRM_DEBUG("b mask %08x\n", vmw_read(vmw_priv, SVGA_REG_BLUE_MASK));
DRM_DEBUG("fb_offset 0x%08x\n", fb_offset);
DRM_DEBUG("fb_pitch %u\n", fb_pitch);
DRM_DEBUG("fb_size %u kiB\n", fb_size / 1024);

info = framebuffer_alloc(sizeof(*par), device);
if (!info)
Expand Down Expand Up @@ -659,6 +630,10 @@ int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv,
goto err_unlock;

ret = ttm_bo_validate(bo, &ne_placement, false, false, false);

/* Could probably bug on */
WARN_ON(bo->offset != 0);

ttm_bo_unreserve(bo);
err_unlock:
ttm_write_unlock(&vmw_priv->active_master->lock);
Expand Down
Loading

0 comments on commit c09a350

Please sign in to comment.