diff options
Diffstat (limited to 'drivers/gpu/drm')
39 files changed, 346 insertions, 137 deletions
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index d0c4574ef49..36164806b9d 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -193,6 +193,9 @@ static const struct file_operations ast_fops = {  	.mmap = ast_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.read = drm_read,  }; diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 7282c081fb5..a712cafcfa1 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -841,7 +841,7 @@ int ast_cursor_init(struct drm_device *dev)  	ast->cursor_cache = obj;  	ast->cursor_cache_gpu_addr = gpu_addr; -	DRM_ERROR("pinned cursor cache at %llx\n", ast->cursor_cache_gpu_addr); +	DRM_DEBUG_KMS("pinned cursor cache at %llx\n", ast->cursor_cache_gpu_addr);  	return 0;  fail:  	return ret; diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index 7053140c659..b83a2d7ddd1 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c @@ -74,6 +74,9 @@ static const struct file_operations cirrus_driver_fops = {  	.unlocked_ioctl = drm_ioctl,  	.mmap = cirrus_mmap,  	.poll = drm_poll, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.fasync = drm_fasync,  };  static struct drm_driver driver = { diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 7f5096763b7..59a26e577b5 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig @@ -36,6 +36,6 @@ config DRM_EXYNOS_VIDI  config DRM_EXYNOS_G2D  	bool "Exynos DRM G2D" -	depends on DRM_EXYNOS +	depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_G2D  	help  	  Choose this option if you want to use Exynos G2D for DRM. diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index 613bf8a5d9b..ae13febe0ea 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c @@ -163,6 +163,12 @@ static void exynos_gem_dmabuf_kunmap(struct dma_buf *dma_buf,  	/* TODO */  } +static int exynos_gem_dmabuf_mmap(struct dma_buf *dma_buf, +	struct vm_area_struct *vma) +{ +	return -ENOTTY; +} +  static struct dma_buf_ops exynos_dmabuf_ops = {  	.map_dma_buf		= exynos_gem_map_dma_buf,  	.unmap_dma_buf		= exynos_gem_unmap_dma_buf, @@ -170,6 +176,7 @@ static struct dma_buf_ops exynos_dmabuf_ops = {  	.kmap_atomic		= exynos_gem_dmabuf_kmap_atomic,  	.kunmap			= exynos_gem_dmabuf_kunmap,  	.kunmap_atomic		= exynos_gem_dmabuf_kunmap_atomic, +	.mmap			= exynos_gem_dmabuf_mmap,  	.release		= exynos_dmabuf_release,  }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index ebacec6f1e4..d0707193745 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -160,7 +160,6 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)  	if (!file_priv)  		return -ENOMEM; -	drm_prime_init_file_private(&file->prime);  	file->driver_priv = file_priv;  	return exynos_drm_subdrv_open(dev, file); @@ -184,7 +183,6 @@ static void exynos_drm_preclose(struct drm_device *dev,  			e->base.destroy(&e->base);  		}  	} -	drm_prime_destroy_file_private(&file->prime);  	spin_unlock_irqrestore(&dev->event_lock, flags);  	exynos_drm_subdrv_close(dev, file); @@ -241,6 +239,9 @@ static const struct file_operations exynos_drm_driver_fops = {  	.poll		= drm_poll,  	.read		= drm_read,  	.unlocked_ioctl	= drm_ioctl, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.release	= drm_release,  }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index a68d2b313f0..b19cd93e704 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -831,11 +831,6 @@ static int __devinit fimd_probe(struct platform_device *pdev)  	}  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_err(dev, "failed to find registers\n"); -		ret = -ENOENT; -		goto err_clk; -	}  	ctx->regs = devm_request_and_ioremap(&pdev->dev, res);  	if (!ctx->regs) { diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index d2d88f22a03..1065e90d091 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -129,7 +129,6 @@ struct g2d_runqueue_node {  struct g2d_data {  	struct device			*dev;  	struct clk			*gate_clk; -	struct resource			*regs_res;  	void __iomem			*regs;  	int				irq;  	struct workqueue_struct		*g2d_workq; @@ -751,7 +750,7 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	struct exynos_drm_subdrv *subdrv;  	int ret; -	g2d = kzalloc(sizeof(*g2d), GFP_KERNEL); +	g2d = devm_kzalloc(&pdev->dev, sizeof(*g2d), GFP_KERNEL);  	if (!g2d) {  		dev_err(dev, "failed to allocate driver data\n");  		return -ENOMEM; @@ -759,10 +758,8 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab",  			sizeof(struct g2d_runqueue_node), 0, 0, NULL); -	if (!g2d->runqueue_slab) { -		ret = -ENOMEM; -		goto err_free_mem; -	} +	if (!g2d->runqueue_slab) +		return -ENOMEM;  	g2d->dev = dev; @@ -794,38 +791,26 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	pm_runtime_enable(dev);  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_err(dev, "failed to get I/O memory\n"); -		ret = -ENOENT; -		goto err_put_clk; -	} -	g2d->regs_res = request_mem_region(res->start, resource_size(res), -					   dev_name(dev)); -	if (!g2d->regs_res) { -		dev_err(dev, "failed to request I/O memory\n"); -		ret = -ENOENT; -		goto err_put_clk; -	} - -	g2d->regs = ioremap(res->start, resource_size(res)); +	g2d->regs = devm_request_and_ioremap(&pdev->dev, res);  	if (!g2d->regs) {  		dev_err(dev, "failed to remap I/O memory\n");  		ret = -ENXIO; -		goto err_release_res; +		goto err_put_clk;  	}  	g2d->irq = platform_get_irq(pdev, 0);  	if (g2d->irq < 0) {  		dev_err(dev, "failed to get irq\n");  		ret = g2d->irq; -		goto err_unmap_base; +		goto err_put_clk;  	} -	ret = request_irq(g2d->irq, g2d_irq_handler, 0, "drm_g2d", g2d); +	ret = devm_request_irq(&pdev->dev, g2d->irq, g2d_irq_handler, 0, +								"drm_g2d", g2d);  	if (ret < 0) {  		dev_err(dev, "irq request failed\n"); -		goto err_unmap_base; +		goto err_put_clk;  	}  	platform_set_drvdata(pdev, g2d); @@ -838,7 +823,7 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	ret = exynos_drm_subdrv_register(subdrv);  	if (ret < 0) {  		dev_err(dev, "failed to register drm g2d device\n"); -		goto err_free_irq; +		goto err_put_clk;  	}  	dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n", @@ -846,13 +831,6 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	return 0; -err_free_irq: -	free_irq(g2d->irq, g2d); -err_unmap_base: -	iounmap(g2d->regs); -err_release_res: -	release_resource(g2d->regs_res); -	kfree(g2d->regs_res);  err_put_clk:  	pm_runtime_disable(dev);  	clk_put(g2d->gate_clk); @@ -862,8 +840,6 @@ err_destroy_workqueue:  	destroy_workqueue(g2d->g2d_workq);  err_destroy_slab:  	kmem_cache_destroy(g2d->runqueue_slab); -err_free_mem: -	kfree(g2d);  	return ret;  } @@ -873,24 +849,18 @@ static int __devexit g2d_remove(struct platform_device *pdev)  	cancel_work_sync(&g2d->runqueue_work);  	exynos_drm_subdrv_unregister(&g2d->subdrv); -	free_irq(g2d->irq, g2d);  	while (g2d->runqueue_node) {  		g2d_free_runqueue_node(g2d, g2d->runqueue_node);  		g2d->runqueue_node = g2d_get_runqueue_node(g2d);  	} -	iounmap(g2d->regs); -	release_resource(g2d->regs_res); -	kfree(g2d->regs_res); -  	pm_runtime_disable(&pdev->dev);  	clk_put(g2d->gate_clk);  	g2d_fini_cmdlist(g2d);  	destroy_workqueue(g2d->g2d_workq);  	kmem_cache_destroy(g2d->runqueue_slab); -	kfree(g2d);  	return 0;  } @@ -924,7 +894,7 @@ static int g2d_resume(struct device *dev)  }  #endif -SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume); +static SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume);  struct platform_driver g2d_driver = {  	.probe		= g2d_probe, diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index f9efde40c09..a38051c95ec 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -122,7 +122,7 @@ fail:  		__free_page(pages[i]);  	drm_free_large(pages); -	return ERR_PTR(PTR_ERR(p)); +	return ERR_CAST(p);  }  static void exynos_gem_put_pages(struct drm_gem_object *obj, @@ -662,7 +662,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,  	 */  	args->pitch = args->width * ((args->bpp + 7) / 8); -	args->size = PAGE_ALIGN(args->pitch * args->height); +	args->size = args->pitch * args->height;  	exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size);  	if (IS_ERR(exynos_gem_obj)) diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 8ffcdf8b9e2..3fdf0b65f47 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c @@ -345,7 +345,7 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)  	DRM_DEBUG_KMS("%s\n", __FILE__); -	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); +	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);  	if (!ctx) {  		DRM_LOG_KMS("failed to alloc common hdmi context.\n");  		return -ENOMEM; @@ -371,7 +371,6 @@ static int __devexit exynos_drm_hdmi_remove(struct platform_device *pdev)  	DRM_DEBUG_KMS("%s\n", __FILE__);  	exynos_drm_subdrv_unregister(&ctx->subdrv); -	kfree(ctx);  	return 0;  } diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index b89829e5043..e1f94b746bd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -29,7 +29,6 @@ static const uint32_t formats[] = {  	DRM_FORMAT_XRGB8888,  	DRM_FORMAT_ARGB8888,  	DRM_FORMAT_NV12, -	DRM_FORMAT_NV12M,  	DRM_FORMAT_NV12MT,  }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index bb1550c4dd5..537027a74fd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -633,7 +633,7 @@ static int __devinit vidi_probe(struct platform_device *pdev)  	DRM_DEBUG_KMS("%s\n", __FILE__); -	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); +	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);  	if (!ctx)  		return -ENOMEM; @@ -673,8 +673,6 @@ static int __devexit vidi_remove(struct platform_device *pdev)  		ctx->raw_edid = NULL;  	} -	kfree(ctx); -  	return 0;  } diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 409e2ec1207..a6aea6f3ea1 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -2172,7 +2172,7 @@ static int __devinit hdmi_resources_init(struct hdmi_context *hdata)  	DRM_DEBUG_KMS("HDMI resource init\n"); -	memset(res, 0, sizeof *res); +	memset(res, 0, sizeof(*res));  	/* get clocks, power */  	res->hdmi = clk_get(dev, "hdmi"); @@ -2204,7 +2204,7 @@ static int __devinit hdmi_resources_init(struct hdmi_context *hdata)  	clk_set_parent(res->sclk_hdmi, res->sclk_pixel);  	res->regul_bulk = kzalloc(ARRAY_SIZE(supply) * -		sizeof res->regul_bulk[0], GFP_KERNEL); +		sizeof(res->regul_bulk[0]), GFP_KERNEL);  	if (!res->regul_bulk) {  		DRM_ERROR("failed to get memory for regulators\n");  		goto fail; @@ -2243,7 +2243,7 @@ static int hdmi_resources_cleanup(struct hdmi_context *hdata)  		clk_put(res->sclk_hdmi);  	if (!IS_ERR_OR_NULL(res->hdmi))  		clk_put(res->hdmi); -	memset(res, 0, sizeof *res); +	memset(res, 0, sizeof(*res));  	return 0;  } @@ -2312,11 +2312,6 @@ static int __devinit hdmi_probe(struct platform_device *pdev)  	}  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		DRM_ERROR("failed to find registers\n"); -		ret = -ENOENT; -		goto err_resource; -	}  	hdata->regs = devm_request_and_ioremap(&pdev->dev, res);  	if (!hdata->regs) { diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 30fcc12f81d..25b97d5e5fc 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -236,11 +236,11 @@ static inline void vp_filter_set(struct mixer_resources *res,  static void vp_default_filter(struct mixer_resources *res)  {  	vp_filter_set(res, VP_POLY8_Y0_LL, -		filter_y_horiz_tap8, sizeof filter_y_horiz_tap8); +		filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8));  	vp_filter_set(res, VP_POLY4_Y0_LL, -		filter_y_vert_tap4, sizeof filter_y_vert_tap4); +		filter_y_vert_tap4, sizeof(filter_y_vert_tap4));  	vp_filter_set(res, VP_POLY4_C0_LL, -		filter_cr_horiz_tap4, sizeof filter_cr_horiz_tap4); +		filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4));  }  static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c index 0f9b7db80f6..cf49ba5a54b 100644 --- a/drivers/gpu/drm/gma500/oaktrail_device.c +++ b/drivers/gpu/drm/gma500/oaktrail_device.c @@ -476,6 +476,7 @@ static const struct psb_offset oaktrail_regmap[2] = {  		.pos = DSPAPOS,  		.surf = DSPASURF,  		.addr = MRST_DSPABASE, +		.base = MRST_DSPABASE,  		.status = PIPEASTAT,  		.linoff = DSPALINOFF,  		.tileoff = DSPATILEOFF, @@ -499,6 +500,7 @@ static const struct psb_offset oaktrail_regmap[2] = {  		.pos = DSPBPOS,  		.surf = DSPBSURF,  		.addr = DSPBBASE, +		.base = DSPBBASE,  		.status = PIPEBSTAT,  		.linoff = DSPBLINOFF,  		.tileoff = DSPBTILEOFF, diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 57d892eaaa6..463ec6871fe 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -115,6 +115,9 @@ static const struct file_operations i810_buffer_fops = {  	.unlocked_ioctl = drm_ioctl,  	.mmap = i810_mmap_buffers,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index f9924ad04d0..48cfcca2b35 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c @@ -51,6 +51,9 @@ static const struct file_operations i810_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9cf7dfe022b..914c0dfabe6 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1587,6 +1587,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)  	spin_lock_init(&dev_priv->irq_lock);  	spin_lock_init(&dev_priv->error_lock);  	spin_lock_init(&dev_priv->rps_lock); +	spin_lock_init(&dev_priv->dpio_lock);  	if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))  		dev_priv->num_pipe = 3; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8a3828528b9..5249640cce1 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2700,9 +2700,6 @@ void intel_irq_init(struct drm_device *dev)  			dev->driver->irq_handler = i8xx_irq_handler;  			dev->driver->irq_uninstall = i8xx_irq_uninstall;  		} else if (INTEL_INFO(dev)->gen == 3) { -			/* IIR "flip pending" means done if this bit is set */ -			I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); -  			dev->driver->irq_preinstall = i915_irq_preinstall;  			dev->driver->irq_postinstall = i915_irq_postinstall;  			dev->driver->irq_uninstall = i915_irq_uninstall; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2dfa6cf4886..bc2ad348e5d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1376,7 +1376,8 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,  	     "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",  	     reg, pipe_name(pipe)); -	WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), +	WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0 +	     && (val & DP_PIPEB_SELECT),  	     "IBX PCH dp port still using transcoder B\n");  } @@ -1388,7 +1389,8 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,  	     "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",  	     reg, pipe_name(pipe)); -	WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), +	WARN(HAS_PCH_IBX(dev_priv->dev) && (val & PORT_ENABLE) == 0 +	     && (val & SDVO_PIPE_B_SELECT),  	     "IBX PCH hdmi port still using transcoder B\n");  } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a6c426afaa7..ace757af913 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2533,14 +2533,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)  			break;  	} -	intel_dp_i2c_init(intel_dp, intel_connector, name); -  	/* Cache some DPCD data in the eDP case */  	if (is_edp(intel_dp)) { -		bool ret;  		struct edp_power_seq	cur, vbt;  		u32 pp_on, pp_off, pp_div; -		struct edid *edid;  		pp_on = I915_READ(PCH_PP_ON_DELAYS);  		pp_off = I915_READ(PCH_PP_OFF_DELAYS); @@ -2591,6 +2587,13 @@ intel_dp_init(struct drm_device *dev, int output_reg)  		DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",  			      intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); +	} + +	intel_dp_i2c_init(intel_dp, intel_connector, name); + +	if (is_edp(intel_dp)) { +		bool ret; +		struct edid *edid;  		ironlake_edp_panel_vdd_on(intel_dp);  		ret = intel_dp_get_dpcd(intel_dp); diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 3df4f5fa892..e019b236986 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -162,19 +162,12 @@ static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv)  	return val;  } -u32 intel_panel_get_max_backlight(struct drm_device *dev) +static u32 _intel_panel_get_max_backlight(struct drm_device *dev)  {  	struct drm_i915_private *dev_priv = dev->dev_private;  	u32 max;  	max = i915_read_blc_pwm_ctl(dev_priv); -	if (max == 0) { -		/* XXX add code here to query mode clock or hardware clock -		 * and program max PWM appropriately. -		 */ -		pr_warn_once("fixme: max PWM is zero\n"); -		return 1; -	}  	if (HAS_PCH_SPLIT(dev)) {  		max >>= 16; @@ -188,6 +181,22 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev)  			max *= 0xff;  	} +	return max; +} + +u32 intel_panel_get_max_backlight(struct drm_device *dev) +{ +	u32 max; + +	max = _intel_panel_get_max_backlight(dev); +	if (max == 0) { +		/* XXX add code here to query mode clock or hardware clock +		 * and program max PWM appropriately. +		 */ +		pr_warn_once("fixme: max PWM is zero\n"); +		return 1; +	} +  	DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max);  	return max;  } @@ -424,7 +433,11 @@ int intel_panel_setup_backlight(struct drm_device *dev)  	memset(&props, 0, sizeof(props));  	props.type = BACKLIGHT_RAW; -	props.max_brightness = intel_panel_get_max_backlight(dev); +	props.max_brightness = _intel_panel_get_max_backlight(dev); +	if (props.max_brightness == 0) { +		DRM_ERROR("Failed to get maximum backlight value\n"); +		return -ENODEV; +	}  	dev_priv->backlight =  		backlight_device_register("intel_backlight",  					  &connector->kdev, dev, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 1881c8c83f0..ba8a27b1757 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3672,6 +3672,9 @@ static void gen3_init_clock_gating(struct drm_device *dev)  	if (IS_PINEVIEW(dev))  		I915_WRITE(ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); + +	/* IIR "flip pending" means done if this bit is set */ +	I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE));  }  static void i85x_init_clock_gating(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d81bb0bf288..123afd35761 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2573,7 +2573,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)  		hotplug_mask = intel_sdvo->is_sdvob ?  			SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915;  	} -	dev_priv->hotplug_supported_mask |= hotplug_mask;  	drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); @@ -2581,14 +2580,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)  	if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))  		goto err; -	/* Set up hotplug command - note paranoia about contents of reply. -	 * We assume that the hardware is in a sane state, and only touch -	 * the bits we think we understand. -	 */ -	intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, -			     &intel_sdvo->hotplug_active, 2); -	intel_sdvo->hotplug_active[0] &= ~0x3; -  	if (intel_sdvo_output_setup(intel_sdvo,  				    intel_sdvo->caps.output_flags) != true) {  		DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", @@ -2596,6 +2587,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)  		goto err;  	} +	/* Only enable the hotplug irq if we need it, to work around noisy +	 * hotplug lines. +	 */ +	if (intel_sdvo->hotplug_active[0]) +		dev_priv->hotplug_supported_mask |= hotplug_mask; +  	intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg);  	/* Set the input timing to the screen. Assume always input 0. */ diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index ea1024d7997..e5f145d2cb3 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -84,6 +84,9 @@ static const struct file_operations mgag200_driver_fops = {  	.mmap = mgag200_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.read = drm_read,  }; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 69688ef5cf4..7e16dc5e646 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -598,7 +598,7 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,  	args->size = args->pitch * args->height;  	args->size = roundup(args->size, PAGE_SIZE); -	ret = nouveau_gem_new(dev, args->size, 0, TTM_PL_FLAG_VRAM, 0, 0, &bo); +	ret = nouveau_gem_new(dev, args->size, 0, NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, &bo);  	if (ret)  		return ret; diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c index f429e6a8ca7..f0349053489 100644 --- a/drivers/gpu/drm/nouveau/nv50_gpio.c +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c @@ -115,6 +115,9 @@ nv50_gpio_init(struct drm_device *dev)  {  	struct drm_nouveau_private *dev_priv = dev->dev_private; +	/* initialise gpios and routing to vbios defaults */ +	nouveau_gpio_reset(dev); +  	/* disable, and ack any pending gpio interrupts */  	nv_wr32(dev, 0xe050, 0x00000000);  	nv_wr32(dev, 0xe054, 0xffffffff); diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index dac525b2994..8a2fc89b776 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c @@ -1510,10 +1510,10 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,  	case OUTPUT_DP:  		if (nv_connector->base.display_info.bpc == 6) {  			nv_encoder->dp.datarate = mode->clock * 18 / 8; -			syncs |= 0x00000140; +			syncs |= 0x00000002 << 6;  		} else {  			nv_encoder->dp.datarate = mode->clock * 24 / 8; -			syncs |= 0x00000180; +			syncs |= 0x00000005 << 6;  		}  		if (nv_encoder->dcb->sorconf.link & 1) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 2817101fb16..e721e3087b9 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1479,14 +1479,98 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)  	}  } +/** + * radeon_get_pll_use_mask - look up a mask of which pplls are in use + * + * @crtc: drm crtc + * + * Returns the mask of which PPLLs (Pixel PLLs) are in use. + */ +static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc) +{ +	struct drm_device *dev = crtc->dev; +	struct drm_crtc *test_crtc; +	struct radeon_crtc *radeon_test_crtc; +	u32 pll_in_use = 0; + +	list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { +		if (crtc == test_crtc) +			continue; + +		radeon_test_crtc = to_radeon_crtc(test_crtc); +		if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID) +			pll_in_use |= (1 << radeon_test_crtc->pll_id); +	} +	return pll_in_use; +} + +/** + * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP + * + * @crtc: drm crtc + * + * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is + * also in DP mode.  For DP, a single PPLL can be used for all DP + * crtcs/encoders. + */ +static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc) +{ +	struct drm_device *dev = crtc->dev; +	struct drm_encoder *test_encoder; +	struct radeon_crtc *radeon_test_crtc; + +	list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { +		if (test_encoder->crtc && (test_encoder->crtc != crtc)) { +			if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { +				/* for DP use the same PLL for all */ +				radeon_test_crtc = to_radeon_crtc(test_encoder->crtc); +				if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID) +					return radeon_test_crtc->pll_id; +			} +		} +	} +	return ATOM_PPLL_INVALID; +} + +/** + * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc. + * + * @crtc: drm crtc + * + * Returns the PPLL (Pixel PLL) to be used by the crtc.  For DP monitors + * a single PPLL can be used for all DP crtcs/encoders.  For non-DP + * monitors a dedicated PPLL must be used.  If a particular board has + * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming + * as there is no need to program the PLL itself.  If we are not able to + * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to + * avoid messing up an existing monitor. + * + * Asic specific PLL information + * + * DCE 6.1 + * - PPLL2 is only available to UNIPHYA (both DP and non-DP) + * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP) + * + * DCE 6.0 + * - PPLL0 is available to all UNIPHY (DP only) + * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC + * + * DCE 5.0 + * - DCPLL is available to all UNIPHY (DP only) + * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC + * + * DCE 3.0/4.0/4.1 + * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC + * + */  static int radeon_atom_pick_pll(struct drm_crtc *crtc)  {  	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);  	struct drm_device *dev = crtc->dev;  	struct radeon_device *rdev = dev->dev_private;  	struct drm_encoder *test_encoder; -	struct drm_crtc *test_crtc; -	uint32_t pll_in_use = 0; +	u32 pll_in_use; +	int pll;  	if (ASIC_IS_DCE61(rdev)) {  		list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { @@ -1498,32 +1582,40 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)  				if ((test_radeon_encoder->encoder_id ==  				     ENCODER_OBJECT_ID_INTERNAL_UNIPHY) && -				    (dig->linkb == false)) /* UNIPHY A uses PPLL2 */ +				    (dig->linkb == false)) +					/* UNIPHY A uses PPLL2 */  					return ATOM_PPLL2; +				else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { +					/* UNIPHY B/C/D/E/F */ +					if (rdev->clock.dp_extclk) +						/* skip PPLL programming if using ext clock */ +						return ATOM_PPLL_INVALID; +					else { +						/* use the same PPLL for all DP monitors */ +						pll = radeon_get_shared_dp_ppll(crtc); +						if (pll != ATOM_PPLL_INVALID) +							return pll; +					} +				} +				break;  			}  		}  		/* UNIPHY B/C/D/E/F */ -		list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { -			struct radeon_crtc *radeon_test_crtc; - -			if (crtc == test_crtc) -				continue; - -			radeon_test_crtc = to_radeon_crtc(test_crtc); -			if ((radeon_test_crtc->pll_id == ATOM_PPLL0) || -			    (radeon_test_crtc->pll_id == ATOM_PPLL1)) -				pll_in_use |= (1 << radeon_test_crtc->pll_id); -		} -		if (!(pll_in_use & 4)) +		pll_in_use = radeon_get_pll_use_mask(crtc); +		if (!(pll_in_use & (1 << ATOM_PPLL0)))  			return ATOM_PPLL0; -		return ATOM_PPLL1; +		if (!(pll_in_use & (1 << ATOM_PPLL1))) +			return ATOM_PPLL1; +		DRM_ERROR("unable to allocate a PPLL\n"); +		return ATOM_PPLL_INVALID;  	} else if (ASIC_IS_DCE4(rdev)) {  		list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {  			if (test_encoder->crtc && (test_encoder->crtc == crtc)) {  				/* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,  				 * depending on the asic:  				 * DCE4: PPLL or ext clock -				 * DCE5: DCPLL or ext clock +				 * DCE5: PPLL, DCPLL, or ext clock +				 * DCE6: PPLL, PPLL0, or ext clock  				 *  				 * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip  				 * PPLL/DCPLL programming and only program the DP DTO for the @@ -1531,31 +1623,34 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)  				 */  				if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {  					if (rdev->clock.dp_extclk) +						/* skip PPLL programming if using ext clock */  						return ATOM_PPLL_INVALID;  					else if (ASIC_IS_DCE6(rdev)) +						/* use PPLL0 for all DP */  						return ATOM_PPLL0;  					else if (ASIC_IS_DCE5(rdev)) +						/* use DCPLL for all DP */  						return ATOM_DCPLL; +					else { +						/* use the same PPLL for all DP monitors */ +						pll = radeon_get_shared_dp_ppll(crtc); +						if (pll != ATOM_PPLL_INVALID) +							return pll; +					}  				} +				break;  			}  		} - -		/* otherwise, pick one of the plls */ -		list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { -			struct radeon_crtc *radeon_test_crtc; - -			if (crtc == test_crtc) -				continue; - -			radeon_test_crtc = to_radeon_crtc(test_crtc); -			if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) && -			    (radeon_test_crtc->pll_id <= ATOM_PPLL2)) -				pll_in_use |= (1 << radeon_test_crtc->pll_id); -		} -		if (!(pll_in_use & 1)) +		/* all other cases */ +		pll_in_use = radeon_get_pll_use_mask(crtc); +		if (!(pll_in_use & (1 << ATOM_PPLL2))) +			return ATOM_PPLL2; +		if (!(pll_in_use & (1 << ATOM_PPLL1)))  			return ATOM_PPLL1; -		return ATOM_PPLL2; +		DRM_ERROR("unable to allocate a PPLL\n"); +		return ATOM_PPLL_INVALID;  	} else +		/* use PPLL1 or PPLL2 */  		return radeon_crtc->crtc_id;  } @@ -1697,7 +1792,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)  		break;  	}  done: -	radeon_crtc->pll_id = -1; +	radeon_crtc->pll_id = ATOM_PPLL_INVALID;  }  static const struct drm_crtc_helper_funcs atombios_helper_funcs = { @@ -1746,6 +1841,6 @@ void radeon_atombios_init_crtc(struct drm_device *dev,  		else  			radeon_crtc->crtc_offset = 0;  	} -	radeon_crtc->pll_id = -1; +	radeon_crtc->pll_id = ATOM_PPLL_INVALID;  	drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);  } diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 7b737b9339a..2a59375dbe5 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -131,7 +131,7 @@ int radeon_fence_emit(struct radeon_device *rdev,   */  void radeon_fence_process(struct radeon_device *rdev, int ring)  { -	uint64_t seq, last_seq; +	uint64_t seq, last_seq, last_emitted;  	unsigned count_loop = 0;  	bool wake = false; @@ -158,13 +158,15 @@ void radeon_fence_process(struct radeon_device *rdev, int ring)  	 */  	last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq);  	do { +		last_emitted = rdev->fence_drv[ring].sync_seq[ring];  		seq = radeon_fence_read(rdev, ring);  		seq |= last_seq & 0xffffffff00000000LL;  		if (seq < last_seq) { -			seq += 0x100000000LL; +			seq &= 0xffffffff; +			seq |= last_emitted & 0xffffffff00000000LL;  		} -		if (seq == last_seq) { +		if (seq <= last_seq || seq > last_emitted) {  			break;  		}  		/* If we loop over we don't want to return without diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c index d31d4cca9a4..c5a164337bd 100644 --- a/drivers/gpu/drm/savage/savage_drv.c +++ b/drivers/gpu/drm/savage/savage_drv.c @@ -43,6 +43,9 @@ static const struct file_operations savage_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 7f119870147..867dc03000e 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c @@ -74,6 +74,9 @@ static const struct file_operations sis_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c index 90f6b13acfa..a7f4d6bd133 100644 --- a/drivers/gpu/drm/tdfx/tdfx_drv.c +++ b/drivers/gpu/drm/tdfx/tdfx_drv.c @@ -49,6 +49,9 @@ static const struct file_operations tdfx_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 6e52069894b..9f84128505b 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -66,6 +66,9 @@ static const struct file_operations udl_driver_fops = {  	.unlocked_ioctl	= drm_ioctl,  	.release = drm_release,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c index e927b4c052f..af1b914b17e 100644 --- a/drivers/gpu/drm/via/via_drv.c +++ b/drivers/gpu/drm/via/via_drv.c @@ -65,6 +65,9 @@ static const struct file_operations via_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/vmwgfx/Kconfig b/drivers/gpu/drm/vmwgfx/Kconfig index 794ff67c570..b71bcd0bfbb 100644 --- a/drivers/gpu/drm/vmwgfx/Kconfig +++ b/drivers/gpu/drm/vmwgfx/Kconfig @@ -12,3 +12,11 @@ config DRM_VMWGFX  	  This is a KMS enabled DRM driver for the VMware SVGA2  	  virtual hardware.  	  The compiled module will be called "vmwgfx.ko". + +config DRM_VMWGFX_FBCON +	depends on DRM_VMWGFX +	bool "Enable framebuffer console under vmwgfx by default" +	help +	   Choose this option if you are shipping a new vmwgfx +	   userspace driver that supports using the kernel driver. + diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 4d9edead01a..ba2c35dbf10 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -182,8 +182,9 @@ static struct pci_device_id vmw_pci_id_list[] = {  	{0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII},  	{0, 0, 0}  }; +MODULE_DEVICE_TABLE(pci, vmw_pci_id_list); -static int enable_fbdev; +static int enable_fbdev = IS_ENABLED(CONFIG_DRM_VMWGFX_FBCON);  static int vmw_probe(struct pci_dev *, const struct pci_device_id *);  static void vmw_master_init(struct vmw_master *); @@ -1154,6 +1155,11 @@ static struct drm_driver driver = {  	.open = vmw_driver_open,  	.preclose = vmw_preclose,  	.postclose = vmw_postclose, + +	.dumb_create = vmw_dumb_create, +	.dumb_map_offset = vmw_dumb_map_offset, +	.dumb_destroy = vmw_dumb_destroy, +  	.fops = &vmwgfx_driver_fops,  	.name = VMWGFX_DRIVER_NAME,  	.desc = VMWGFX_DRIVER_DESC, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index d0f2c079ee2..29c984ff7f2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -645,6 +645,16 @@ int vmw_kms_readback(struct vmw_private *dev_priv,  int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,  				struct drm_file *file_priv); +int vmw_dumb_create(struct drm_file *file_priv, +		    struct drm_device *dev, +		    struct drm_mode_create_dumb *args); + +int vmw_dumb_map_offset(struct drm_file *file_priv, +			struct drm_device *dev, uint32_t handle, +			uint64_t *offset); +int vmw_dumb_destroy(struct drm_file *file_priv, +		     struct drm_device *dev, +		     uint32_t handle);  /**   * Overlay control - vmwgfx_overlay.c   */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 22bf9a21ec7..2c6ffe0e2c0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -1917,3 +1917,76 @@ err_ref:  	vmw_resource_unreference(&res);  	return ret;  } + + +int vmw_dumb_create(struct drm_file *file_priv, +		    struct drm_device *dev, +		    struct drm_mode_create_dumb *args) +{ +	struct vmw_private *dev_priv = vmw_priv(dev); +	struct vmw_master *vmaster = vmw_master(file_priv->master); +	struct vmw_user_dma_buffer *vmw_user_bo; +	struct ttm_buffer_object *tmp; +	int ret; + +	args->pitch = args->width * ((args->bpp + 7) / 8); +	args->size = args->pitch * args->height; + +	vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL); +	if (vmw_user_bo == NULL) +		return -ENOMEM; + +	ret = ttm_read_lock(&vmaster->lock, true); +	if (ret != 0) { +		kfree(vmw_user_bo); +		return ret; +	} + +	ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, args->size, +			      &vmw_vram_sys_placement, true, +			      &vmw_user_dmabuf_destroy); +	if (ret != 0) +		goto out_no_dmabuf; + +	tmp = ttm_bo_reference(&vmw_user_bo->dma.base); +	ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile, +				   &vmw_user_bo->base, +				   false, +				   ttm_buffer_type, +				   &vmw_user_dmabuf_release, NULL); +	if (unlikely(ret != 0)) +		goto out_no_base_object; + +	args->handle = vmw_user_bo->base.hash.key; + +out_no_base_object: +	ttm_bo_unref(&tmp); +out_no_dmabuf: +	ttm_read_unlock(&vmaster->lock); +	return ret; +} + +int vmw_dumb_map_offset(struct drm_file *file_priv, +			struct drm_device *dev, uint32_t handle, +			uint64_t *offset) +{ +	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; +	struct vmw_dma_buffer *out_buf; +	int ret; + +	ret = vmw_user_dmabuf_lookup(tfile, handle, &out_buf); +	if (ret != 0) +		return -EINVAL; + +	*offset = out_buf->base.addr_space_offset; +	vmw_dmabuf_unreference(&out_buf); +	return 0; +} + +int vmw_dumb_destroy(struct drm_file *file_priv, +		     struct drm_device *dev, +		     uint32_t handle) +{ +	return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, +					 handle, TTM_REF_USAGE); +}  |