Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6b46ee7 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-vmware-next' into drm-core-next

* drm-vmware-next:
  drm/vmwgfx: Bump minor and driver date
  drm/vmwgfx: Save at least one screen layout
  drm/vmwgfx: Add modinfo version
  drm/vmwgfx: Add a parameter to get the max fb size
  drm/vmwgfx: Don't flush fb if we're in the suspended state.
  drm/vmwgfx: Prune modes based on available VRAM size
  drm/vmwgfx: Take the ttm lock around the dirty ioctl
  drm: vmwgfx: Add a struct drm_file parameter to the dirty framebuffer callback
  drm/vmwgfx: Add new-style PM hooks to improve hibernation behavior
  drm/vmwgfx: Fix ACPI S3 & S4 functionality.
  drm/vmwgfx: Really support other depths than 32
parents fb7ba211 8aea5287
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1854,7 +1854,8 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
	}

	if (fb->funcs->dirty) {
		ret = fb->funcs->dirty(fb, flags, r->color, clips, num_clips);
		ret = fb->funcs->dirty(fb, file_priv, flags, r->color,
				       clips, num_clips);
	} else {
		ret = -ENOSYS;
		goto out_err2;
+99 −13
Original line number Diff line number Diff line
@@ -597,6 +597,8 @@ static void vmw_lastclose(struct drm_device *dev)
static void vmw_master_init(struct vmw_master *vmaster)
{
	ttm_lock_init(&vmaster->lock);
	INIT_LIST_HEAD(&vmaster->fb_surf);
	mutex_init(&vmaster->fb_surf_mutex);
}

static int vmw_master_create(struct drm_device *dev,
@@ -608,7 +610,7 @@ static int vmw_master_create(struct drm_device *dev,
	if (unlikely(vmaster == NULL))
		return -ENOMEM;

	ttm_lock_init(&vmaster->lock);
	vmw_master_init(vmaster);
	ttm_lock_set_kill(&vmaster->lock, true, SIGTERM);
	master->driver_priv = vmaster;

@@ -699,6 +701,7 @@ static void vmw_master_drop(struct drm_device *dev,

	vmw_fp->locked_master = drm_master_get(file_priv->master);
	ret = ttm_vt_lock(&vmaster->lock, false, vmw_fp->tfile);
	vmw_kms_idle_workqueues(vmaster);

	if (unlikely((ret != 0))) {
		DRM_ERROR("Unable to lock TTM at VT switch.\n");
@@ -751,15 +754,16 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
		 * Buffer contents is moved to swappable memory.
		 */
		ttm_bo_swapout_all(&dev_priv->bdev);

		break;
	case PM_POST_HIBERNATION:
	case PM_POST_SUSPEND:
	case PM_POST_RESTORE:
		ttm_suspend_unlock(&vmaster->lock);

		break;
	case PM_RESTORE_PREPARE:
		break;
	case PM_POST_RESTORE:
		break;
	default:
		break;
	}
@@ -770,21 +774,98 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
 * These might not be needed with the virtual SVGA device.
 */

int vmw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
static int vmw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct drm_device *dev = pci_get_drvdata(pdev);
	struct vmw_private *dev_priv = vmw_priv(dev);

	if (dev_priv->num_3d_resources != 0) {
		DRM_INFO("Can't suspend or hibernate "
			 "while 3D resources are active.\n");
		return -EBUSY;
	}

	pci_save_state(pdev);
	pci_disable_device(pdev);
	pci_set_power_state(pdev, PCI_D3hot);
	return 0;
}

int vmw_pci_resume(struct pci_dev *pdev)
static int vmw_pci_resume(struct pci_dev *pdev)
{
	pci_set_power_state(pdev, PCI_D0);
	pci_restore_state(pdev);
	return pci_enable_device(pdev);
}

static int vmw_pm_suspend(struct device *kdev)
{
	struct pci_dev *pdev = to_pci_dev(kdev);
	struct pm_message dummy;

	dummy.event = 0;

	return vmw_pci_suspend(pdev, dummy);
}

static int vmw_pm_resume(struct device *kdev)
{
	struct pci_dev *pdev = to_pci_dev(kdev);

	return vmw_pci_resume(pdev);
}

static int vmw_pm_prepare(struct device *kdev)
{
	struct pci_dev *pdev = to_pci_dev(kdev);
	struct drm_device *dev = pci_get_drvdata(pdev);
	struct vmw_private *dev_priv = vmw_priv(dev);

	/**
	 * Release 3d reference held by fbdev and potentially
	 * stop fifo.
	 */
	dev_priv->suspended = true;
	if (dev_priv->enable_fb)
		vmw_3d_resource_dec(dev_priv);

	if (dev_priv->num_3d_resources != 0) {

		DRM_INFO("Can't suspend or hibernate "
			 "while 3D resources are active.\n");

		if (dev_priv->enable_fb)
			vmw_3d_resource_inc(dev_priv);
		dev_priv->suspended = false;
		return -EBUSY;
	}

	return 0;
}

static void vmw_pm_complete(struct device *kdev)
{
	struct pci_dev *pdev = to_pci_dev(kdev);
	struct drm_device *dev = pci_get_drvdata(pdev);
	struct vmw_private *dev_priv = vmw_priv(dev);

	/**
	 * Reclaim 3d reference held by fbdev and potentially
	 * start fifo.
	 */
	if (dev_priv->enable_fb)
		vmw_3d_resource_inc(dev_priv);

	dev_priv->suspended = false;
}

static const struct dev_pm_ops vmw_pm_ops = {
	.prepare = vmw_pm_prepare,
	.complete = vmw_pm_complete,
	.suspend = vmw_pm_suspend,
	.resume = vmw_pm_resume,
};

static struct drm_driver driver = {
	.driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
	DRIVER_MODESET,
@@ -824,8 +905,9 @@ static struct drm_driver driver = {
		 .id_table = vmw_pci_id_list,
		 .probe = vmw_probe,
		 .remove = vmw_remove,
		       .suspend = vmw_pci_suspend,
		       .resume = vmw_pci_resume
		 .driver = {
			 .pm = &vmw_pm_ops
		 }
	 },
	.name = VMWGFX_DRIVER_NAME,
	.desc = VMWGFX_DRIVER_DESC,
@@ -860,3 +942,7 @@ module_exit(vmwgfx_exit);
MODULE_AUTHOR("VMware Inc. and others");
MODULE_DESCRIPTION("Standalone drm driver for the VMware SVGA device");
MODULE_LICENSE("GPL and additional rights");
MODULE_VERSION(__stringify(VMWGFX_DRIVER_MAJOR) "."
	       __stringify(VMWGFX_DRIVER_MINOR) "."
	       __stringify(VMWGFX_DRIVER_PATCHLEVEL) "."
	       "0");
+9 −2
Original line number Diff line number Diff line
@@ -39,9 +39,9 @@
#include "ttm/ttm_execbuf_util.h"
#include "ttm/ttm_module.h"

#define VMWGFX_DRIVER_DATE "20100209"
#define VMWGFX_DRIVER_DATE "20100927"
#define VMWGFX_DRIVER_MAJOR 1
#define VMWGFX_DRIVER_MINOR 2
#define VMWGFX_DRIVER_MINOR 4
#define VMWGFX_DRIVER_PATCHLEVEL 0
#define VMWGFX_FILE_PAGE_OFFSET 0x00100000
#define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
@@ -151,6 +151,8 @@ struct vmw_overlay;

struct vmw_master {
	struct ttm_lock lock;
	struct mutex fb_surf_mutex;
	struct list_head fb_surf;
};

struct vmw_vga_topology_state {
@@ -286,6 +288,7 @@ struct vmw_private {
	struct vmw_master *active_master;
	struct vmw_master fbdev_master;
	struct notifier_block pm_nb;
	bool suspended;

	struct mutex release_mutex;
	uint32_t num_3d_resources;
@@ -518,6 +521,10 @@ 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);
void vmw_kms_idle_workqueues(struct vmw_master *vmaster);
bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
				uint32_t pitch,
				uint32_t height);
u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc);

/**
+10 −0
Original line number Diff line number Diff line
@@ -144,6 +144,13 @@ static int vmw_fb_check_var(struct fb_var_screeninfo *var,
		return -EINVAL;
	}

	if (!vmw_kms_validate_mode_vram(vmw_priv,
					info->fix.line_length,
					var->yoffset + var->yres)) {
		DRM_ERROR("Requested geom can not fit in framebuffer\n");
		return -EINVAL;
	}

	return 0;
}

@@ -205,6 +212,9 @@ static void vmw_fb_dirty_flush(struct vmw_fb_par *par)
		SVGAFifoCmdUpdate body;
	} *cmd;

	if (vmw_priv->suspended)
		return;

	spin_lock_irqsave(&par->dirty.lock, flags);
	if (!par->dirty.active) {
		spin_unlock_irqrestore(&par->dirty.lock, flags);
+3 −0
Original line number Diff line number Diff line
@@ -54,6 +54,9 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data,
	case DRM_VMW_PARAM_FIFO_CAPS:
		param->value = dev_priv->fifo.capabilities;
		break;
	case DRM_VMW_PARAM_MAX_FB_SIZE:
		param->value = dev_priv->vram_size;
		break;
	default:
		DRM_ERROR("Illegal vmwgfx get param request: %d\n",
			  param->param);
Loading