Merge remote branch 'korg/drm-fixes' into drm-vmware-next
necessary for some of the vmware fixes to be pushed in. Conflicts: drivers/gpu/drm/drm_gem.c drivers/gpu/drm/i915/intel_fb.c include/drm/drmP.h
This commit is contained in:
@@ -148,13 +148,16 @@ static struct pci_device_id vmw_pci_id_list[] = {
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
static char *vmw_devname = "vmwgfx";
|
||||
static int enable_fbdev;
|
||||
|
||||
static int vmw_probe(struct pci_dev *, const struct pci_device_id *);
|
||||
static void vmw_master_init(struct vmw_master *);
|
||||
static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
|
||||
void *ptr);
|
||||
|
||||
MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev");
|
||||
module_param_named(enable_fbdev, enable_fbdev, int, 0600);
|
||||
|
||||
static void vmw_print_capabilities(uint32_t capabilities)
|
||||
{
|
||||
DRM_INFO("Capabilities:\n");
|
||||
@@ -192,8 +195,6 @@ static int vmw_request_device(struct vmw_private *dev_priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
vmw_kms_save_vga(dev_priv);
|
||||
|
||||
ret = vmw_fifo_init(dev_priv, &dev_priv->fifo);
|
||||
if (unlikely(ret != 0)) {
|
||||
DRM_ERROR("Unable to initialize FIFO.\n");
|
||||
@@ -206,9 +207,35 @@ static int vmw_request_device(struct vmw_private *dev_priv)
|
||||
static void vmw_release_device(struct vmw_private *dev_priv)
|
||||
{
|
||||
vmw_fifo_release(dev_priv, &dev_priv->fifo);
|
||||
vmw_kms_restore_vga(dev_priv);
|
||||
}
|
||||
|
||||
int vmw_3d_resource_inc(struct vmw_private *dev_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&dev_priv->release_mutex);
|
||||
if (unlikely(dev_priv->num_3d_resources++ == 0)) {
|
||||
ret = vmw_request_device(dev_priv);
|
||||
if (unlikely(ret != 0))
|
||||
--dev_priv->num_3d_resources;
|
||||
}
|
||||
mutex_unlock(&dev_priv->release_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void vmw_3d_resource_dec(struct vmw_private *dev_priv)
|
||||
{
|
||||
int32_t n3d;
|
||||
|
||||
mutex_lock(&dev_priv->release_mutex);
|
||||
if (unlikely(--dev_priv->num_3d_resources == 0))
|
||||
vmw_release_device(dev_priv);
|
||||
n3d = (int32_t) dev_priv->num_3d_resources;
|
||||
mutex_unlock(&dev_priv->release_mutex);
|
||||
|
||||
BUG_ON(n3d < 0);
|
||||
}
|
||||
|
||||
static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
|
||||
{
|
||||
@@ -228,6 +255,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
|
||||
dev_priv->last_read_sequence = (uint32_t) -100;
|
||||
mutex_init(&dev_priv->hw_mutex);
|
||||
mutex_init(&dev_priv->cmdbuf_mutex);
|
||||
mutex_init(&dev_priv->release_mutex);
|
||||
rwlock_init(&dev_priv->resource_lock);
|
||||
idr_init(&dev_priv->context_idr);
|
||||
idr_init(&dev_priv->surface_idr);
|
||||
@@ -244,6 +272,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
|
||||
dev_priv->vram_start = pci_resource_start(dev->pdev, 1);
|
||||
dev_priv->mmio_start = pci_resource_start(dev->pdev, 2);
|
||||
|
||||
dev_priv->enable_fb = enable_fbdev;
|
||||
|
||||
mutex_lock(&dev_priv->hw_mutex);
|
||||
|
||||
vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
|
||||
@@ -343,17 +373,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
|
||||
|
||||
dev->dev_private = dev_priv;
|
||||
|
||||
if (!dev->devname)
|
||||
dev->devname = vmw_devname;
|
||||
|
||||
if (dev_priv->capabilities & SVGA_CAP_IRQMASK) {
|
||||
ret = drm_irq_install(dev);
|
||||
if (unlikely(ret != 0)) {
|
||||
DRM_ERROR("Failed installing irq: %d\n", ret);
|
||||
goto out_no_irq;
|
||||
}
|
||||
}
|
||||
|
||||
ret = pci_request_regions(dev->pdev, "vmwgfx probe");
|
||||
dev_priv->stealth = (ret != 0);
|
||||
if (dev_priv->stealth) {
|
||||
@@ -369,26 +388,52 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
|
||||
goto out_no_device;
|
||||
}
|
||||
}
|
||||
ret = vmw_request_device(dev_priv);
|
||||
ret = vmw_kms_init(dev_priv);
|
||||
if (unlikely(ret != 0))
|
||||
goto out_no_device;
|
||||
vmw_kms_init(dev_priv);
|
||||
goto out_no_kms;
|
||||
vmw_overlay_init(dev_priv);
|
||||
vmw_fb_init(dev_priv);
|
||||
if (dev_priv->enable_fb) {
|
||||
ret = vmw_3d_resource_inc(dev_priv);
|
||||
if (unlikely(ret != 0))
|
||||
goto out_no_fifo;
|
||||
vmw_kms_save_vga(dev_priv);
|
||||
vmw_fb_init(dev_priv);
|
||||
DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ?
|
||||
"Detected device 3D availability.\n" :
|
||||
"Detected no device 3D availability.\n");
|
||||
} else {
|
||||
DRM_INFO("Delayed 3D detection since we're not "
|
||||
"running the device in SVGA mode yet.\n");
|
||||
}
|
||||
|
||||
if (dev_priv->capabilities & SVGA_CAP_IRQMASK) {
|
||||
ret = drm_irq_install(dev);
|
||||
if (unlikely(ret != 0)) {
|
||||
DRM_ERROR("Failed installing irq: %d\n", ret);
|
||||
goto out_no_irq;
|
||||
}
|
||||
}
|
||||
|
||||
dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier;
|
||||
register_pm_notifier(&dev_priv->pm_nb);
|
||||
|
||||
DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? "Have 3D\n" : "No 3D\n");
|
||||
|
||||
return 0;
|
||||
|
||||
out_no_device:
|
||||
if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
|
||||
drm_irq_uninstall(dev_priv->dev);
|
||||
if (dev->devname == vmw_devname)
|
||||
dev->devname = NULL;
|
||||
out_no_irq:
|
||||
if (dev_priv->enable_fb) {
|
||||
vmw_fb_close(dev_priv);
|
||||
vmw_kms_restore_vga(dev_priv);
|
||||
vmw_3d_resource_dec(dev_priv);
|
||||
}
|
||||
out_no_fifo:
|
||||
vmw_overlay_close(dev_priv);
|
||||
vmw_kms_close(dev_priv);
|
||||
out_no_kms:
|
||||
if (dev_priv->stealth)
|
||||
pci_release_region(dev->pdev, 2);
|
||||
else
|
||||
pci_release_regions(dev->pdev);
|
||||
out_no_device:
|
||||
ttm_object_device_release(&dev_priv->tdev);
|
||||
out_err4:
|
||||
iounmap(dev_priv->mmio_virt);
|
||||
@@ -415,19 +460,20 @@ static int vmw_driver_unload(struct drm_device *dev)
|
||||
|
||||
unregister_pm_notifier(&dev_priv->pm_nb);
|
||||
|
||||
vmw_fb_close(dev_priv);
|
||||
if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
|
||||
drm_irq_uninstall(dev_priv->dev);
|
||||
if (dev_priv->enable_fb) {
|
||||
vmw_fb_close(dev_priv);
|
||||
vmw_kms_restore_vga(dev_priv);
|
||||
vmw_3d_resource_dec(dev_priv);
|
||||
}
|
||||
vmw_kms_close(dev_priv);
|
||||
vmw_overlay_close(dev_priv);
|
||||
vmw_release_device(dev_priv);
|
||||
if (dev_priv->stealth)
|
||||
pci_release_region(dev->pdev, 2);
|
||||
else
|
||||
pci_release_regions(dev->pdev);
|
||||
|
||||
if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
|
||||
drm_irq_uninstall(dev_priv->dev);
|
||||
if (dev->devname == vmw_devname)
|
||||
dev->devname = NULL;
|
||||
ttm_object_device_release(&dev_priv->tdev);
|
||||
iounmap(dev_priv->mmio_virt);
|
||||
drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start,
|
||||
@@ -500,7 +546,7 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd,
|
||||
struct drm_ioctl_desc *ioctl =
|
||||
&vmw_ioctls[nr - DRM_COMMAND_BASE];
|
||||
|
||||
if (unlikely(ioctl->cmd != cmd)) {
|
||||
if (unlikely(ioctl->cmd_drv != cmd)) {
|
||||
DRM_ERROR("Invalid command format, ioctl %d\n",
|
||||
nr - DRM_COMMAND_BASE);
|
||||
return -EINVAL;
|
||||
@@ -589,6 +635,16 @@ static int vmw_master_set(struct drm_device *dev,
|
||||
struct vmw_master *vmaster = vmw_master(file_priv->master);
|
||||
int ret = 0;
|
||||
|
||||
if (!dev_priv->enable_fb) {
|
||||
ret = vmw_3d_resource_inc(dev_priv);
|
||||
if (unlikely(ret != 0))
|
||||
return ret;
|
||||
vmw_kms_save_vga(dev_priv);
|
||||
mutex_lock(&dev_priv->hw_mutex);
|
||||
vmw_write(dev_priv, SVGA_REG_TRACES, 0);
|
||||
mutex_unlock(&dev_priv->hw_mutex);
|
||||
}
|
||||
|
||||
if (active) {
|
||||
BUG_ON(active != &dev_priv->fbdev_master);
|
||||
ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile);
|
||||
@@ -617,7 +673,13 @@ static int vmw_master_set(struct drm_device *dev,
|
||||
return 0;
|
||||
|
||||
out_no_active_lock:
|
||||
vmw_release_device(dev_priv);
|
||||
if (!dev_priv->enable_fb) {
|
||||
mutex_lock(&dev_priv->hw_mutex);
|
||||
vmw_write(dev_priv, SVGA_REG_TRACES, 1);
|
||||
mutex_unlock(&dev_priv->hw_mutex);
|
||||
vmw_kms_restore_vga(dev_priv);
|
||||
vmw_3d_resource_dec(dev_priv);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -645,11 +707,23 @@ static void vmw_master_drop(struct drm_device *dev,
|
||||
|
||||
ttm_lock_set_kill(&vmaster->lock, true, SIGTERM);
|
||||
|
||||
if (!dev_priv->enable_fb) {
|
||||
ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM);
|
||||
if (unlikely(ret != 0))
|
||||
DRM_ERROR("Unable to clean VRAM on master drop.\n");
|
||||
mutex_lock(&dev_priv->hw_mutex);
|
||||
vmw_write(dev_priv, SVGA_REG_TRACES, 1);
|
||||
mutex_unlock(&dev_priv->hw_mutex);
|
||||
vmw_kms_restore_vga(dev_priv);
|
||||
vmw_3d_resource_dec(dev_priv);
|
||||
}
|
||||
|
||||
dev_priv->active_master = &dev_priv->fbdev_master;
|
||||
ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM);
|
||||
ttm_vt_unlock(&dev_priv->fbdev_master.lock);
|
||||
|
||||
vmw_fb_on(dev_priv);
|
||||
if (dev_priv->enable_fb)
|
||||
vmw_fb_on(dev_priv);
|
||||
}
|
||||
|
||||
|
||||
@@ -722,6 +796,7 @@ static struct drm_driver driver = {
|
||||
.irq_postinstall = vmw_irq_postinstall,
|
||||
.irq_uninstall = vmw_irq_uninstall,
|
||||
.irq_handler = vmw_irq_handler,
|
||||
.get_vblank_counter = vmw_get_vblank_counter,
|
||||
.reclaim_buffers_locked = NULL,
|
||||
.ioctls = vmw_ioctls,
|
||||
.num_ioctls = DRM_ARRAY_SIZE(vmw_ioctls),
|
||||
|
@@ -277,6 +277,7 @@ struct vmw_private {
|
||||
|
||||
bool stealth;
|
||||
bool is_opened;
|
||||
bool enable_fb;
|
||||
|
||||
/**
|
||||
* Master management.
|
||||
@@ -285,6 +286,9 @@ struct vmw_private {
|
||||
struct vmw_master *active_master;
|
||||
struct vmw_master fbdev_master;
|
||||
struct notifier_block pm_nb;
|
||||
|
||||
struct mutex release_mutex;
|
||||
uint32_t num_3d_resources;
|
||||
};
|
||||
|
||||
static inline struct vmw_private *vmw_priv(struct drm_device *dev)
|
||||
@@ -319,6 +323,9 @@ static inline uint32_t vmw_read(struct vmw_private *dev_priv,
|
||||
return val;
|
||||
}
|
||||
|
||||
int vmw_3d_resource_inc(struct vmw_private *dev_priv);
|
||||
void vmw_3d_resource_dec(struct vmw_private *dev_priv);
|
||||
|
||||
/**
|
||||
* GMR utilities - vmwgfx_gmr.c
|
||||
*/
|
||||
@@ -511,6 +518,7 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv,
|
||||
unsigned bbp, unsigned depth);
|
||||
int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc);
|
||||
|
||||
/**
|
||||
* Overlay control - vmwgfx_overlay.c
|
||||
|
@@ -615,6 +615,11 @@ int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv,
|
||||
if (unlikely(ret != 0))
|
||||
goto err_unlock;
|
||||
|
||||
if (bo->mem.mem_type == TTM_PL_VRAM &&
|
||||
bo->mem.mm_node->start < bo->num_pages)
|
||||
(void) ttm_bo_validate(bo, &vmw_sys_placement, false,
|
||||
false, false);
|
||||
|
||||
ret = ttm_bo_validate(bo, &ne_placement, false, false, false);
|
||||
|
||||
/* Could probably bug on */
|
||||
|
@@ -106,6 +106,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
|
||||
mutex_lock(&dev_priv->hw_mutex);
|
||||
dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE);
|
||||
dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE);
|
||||
dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES);
|
||||
vmw_write(dev_priv, SVGA_REG_ENABLE, 1);
|
||||
|
||||
min = 4;
|
||||
@@ -175,6 +176,8 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
|
||||
dev_priv->config_done_state);
|
||||
vmw_write(dev_priv, SVGA_REG_ENABLE,
|
||||
dev_priv->enable_state);
|
||||
vmw_write(dev_priv, SVGA_REG_TRACES,
|
||||
dev_priv->traces_state);
|
||||
|
||||
mutex_unlock(&dev_priv->hw_mutex);
|
||||
vmw_fence_queue_takedown(&fifo->fence_queue);
|
||||
|
@@ -898,7 +898,19 @@ int vmw_kms_save_vga(struct vmw_private *vmw_priv)
|
||||
save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH);
|
||||
save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT);
|
||||
vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
|
||||
if (i == 0 && vmw_priv->num_displays == 1 &&
|
||||
save->width == 0 && save->height == 0) {
|
||||
|
||||
/*
|
||||
* It should be fairly safe to assume that these
|
||||
* values are uninitialized.
|
||||
*/
|
||||
|
||||
save->width = vmw_priv->vga_width - save->pos_x;
|
||||
save->height = vmw_priv->vga_height - save->pos_y;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -984,3 +996,8 @@ out_unlock:
|
||||
ttm_read_unlock(&vmaster->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "vmwgfx_kms.h"
|
||||
|
||||
#define VMWGFX_LDU_NUM_DU 8
|
||||
|
||||
#define vmw_crtc_to_ldu(x) \
|
||||
container_of(x, struct vmw_legacy_display_unit, base.crtc)
|
||||
#define vmw_encoder_to_ldu(x) \
|
||||
@@ -536,6 +538,10 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
|
||||
|
||||
int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = dev_priv->dev;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (dev_priv->ldu_priv) {
|
||||
DRM_INFO("ldu system already on\n");
|
||||
return -EINVAL;
|
||||
@@ -553,23 +559,24 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv)
|
||||
|
||||
drm_mode_create_dirty_info_property(dev_priv->dev);
|
||||
|
||||
vmw_ldu_init(dev_priv, 0);
|
||||
/* for old hardware without multimon only enable one display */
|
||||
if (dev_priv->capabilities & SVGA_CAP_MULTIMON) {
|
||||
vmw_ldu_init(dev_priv, 1);
|
||||
vmw_ldu_init(dev_priv, 2);
|
||||
vmw_ldu_init(dev_priv, 3);
|
||||
vmw_ldu_init(dev_priv, 4);
|
||||
vmw_ldu_init(dev_priv, 5);
|
||||
vmw_ldu_init(dev_priv, 6);
|
||||
vmw_ldu_init(dev_priv, 7);
|
||||
for (i = 0; i < VMWGFX_LDU_NUM_DU; ++i)
|
||||
vmw_ldu_init(dev_priv, i);
|
||||
ret = drm_vblank_init(dev, VMWGFX_LDU_NUM_DU);
|
||||
} else {
|
||||
/* for old hardware without multimon only enable one display */
|
||||
vmw_ldu_init(dev_priv, 0);
|
||||
ret = drm_vblank_init(dev, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = dev_priv->dev;
|
||||
|
||||
drm_vblank_cleanup(dev);
|
||||
if (!dev_priv->ldu_priv)
|
||||
return -ENOSYS;
|
||||
|
||||
|
@@ -211,6 +211,7 @@ static void vmw_hw_context_destroy(struct vmw_resource *res)
|
||||
cmd->body.cid = cpu_to_le32(res->id);
|
||||
|
||||
vmw_fifo_commit(dev_priv, sizeof(*cmd));
|
||||
vmw_3d_resource_dec(dev_priv);
|
||||
}
|
||||
|
||||
static int vmw_context_init(struct vmw_private *dev_priv,
|
||||
@@ -247,6 +248,7 @@ static int vmw_context_init(struct vmw_private *dev_priv,
|
||||
cmd->body.cid = cpu_to_le32(res->id);
|
||||
|
||||
vmw_fifo_commit(dev_priv, sizeof(*cmd));
|
||||
(void) vmw_3d_resource_inc(dev_priv);
|
||||
vmw_resource_activate(res, vmw_hw_context_destroy);
|
||||
return 0;
|
||||
}
|
||||
@@ -406,6 +408,7 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res)
|
||||
cmd->body.sid = cpu_to_le32(res->id);
|
||||
|
||||
vmw_fifo_commit(dev_priv, sizeof(*cmd));
|
||||
vmw_3d_resource_dec(dev_priv);
|
||||
}
|
||||
|
||||
void vmw_surface_res_free(struct vmw_resource *res)
|
||||
@@ -473,6 +476,7 @@ int vmw_surface_init(struct vmw_private *dev_priv,
|
||||
}
|
||||
|
||||
vmw_fifo_commit(dev_priv, submit_size);
|
||||
(void) vmw_3d_resource_inc(dev_priv);
|
||||
vmw_resource_activate(res, vmw_hw_surface_destroy);
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user