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

Commit e0611671 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

Pull drm gixes from Dave Airlie:
 - exynos: infinite loop regressions fixed
 - i915: one regression
 - radeon: one race condition on monitor probing
 - noveau: two regressions
 - tegra: one vblank regression fix

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/tegra: dc: Add missing call to drm_vblank_on()
  drm/nouveau/nv50/disp: Fix modeset on G94
  drm/gk20a/fb: fix setting of large page size bit
  drm/radeon: add locking around atombios scratch space usage
  drm/i915: Fix obj->map_and_fenceable across tiling changes
  drm/exynos: fix possible infinite loop issue
  drm/exynos: g2d: fix null pointer dereference
  drm/exynos: resolve infinite loop issue on non multi-platform
  drm/exynos: resolve infinite loop issue on multi-platform
parents 51b97e35 bcfef973
Loading
Loading
Loading
Loading
+33 −16
Original line number Diff line number Diff line
@@ -495,6 +495,12 @@ static struct component_match *exynos_drm_match_add(struct device *dev)

	mutex_lock(&drm_component_lock);

	/* Do not retry to probe if there is no any kms driver regitered. */
	if (list_empty(&drm_component_list)) {
		mutex_unlock(&drm_component_lock);
		return ERR_PTR(-ENODEV);
	}

	list_for_each_entry(cdev, &drm_component_list, list) {
		/*
		 * Add components to master only in case that crtc and
@@ -585,10 +591,21 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
		goto err_unregister_mixer_drv;
#endif

	match = exynos_drm_match_add(&pdev->dev);
	if (IS_ERR(match)) {
		ret = PTR_ERR(match);
		goto err_unregister_hdmi_drv;
	}

	ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
						match);
	if (ret < 0)
		goto err_unregister_hdmi_drv;

#ifdef CONFIG_DRM_EXYNOS_G2D
	ret = platform_driver_register(&g2d_driver);
	if (ret < 0)
		goto err_unregister_hdmi_drv;
		goto err_del_component_master;
#endif

#ifdef CONFIG_DRM_EXYNOS_FIMC
@@ -619,23 +636,9 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
		goto err_unregister_ipp_drv;
#endif

	match = exynos_drm_match_add(&pdev->dev);
	if (IS_ERR(match)) {
		ret = PTR_ERR(match);
		goto err_unregister_resources;
	}

	ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
						match);
	if (ret < 0)
		goto err_unregister_resources;

	return ret;

err_unregister_resources:

#ifdef CONFIG_DRM_EXYNOS_IPP
	exynos_platform_device_ipp_unregister();
err_unregister_ipp_drv:
	platform_driver_unregister(&ipp_driver);
err_unregister_gsc_drv:
@@ -658,9 +661,11 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)

#ifdef CONFIG_DRM_EXYNOS_G2D
	platform_driver_unregister(&g2d_driver);
err_unregister_hdmi_drv:
err_del_component_master:
#endif
	component_master_del(&pdev->dev, &exynos_drm_ops);

err_unregister_hdmi_drv:
#ifdef CONFIG_DRM_EXYNOS_HDMI
	platform_driver_unregister(&hdmi_driver);
err_unregister_mixer_drv:
@@ -741,6 +746,18 @@ static int exynos_drm_init(void)
{
	int ret;

	/*
	 * Register device object only in case of Exynos SoC.
	 *
	 * Below codes resolves temporarily infinite loop issue incurred
	 * by Exynos drm driver when using multi-platform kernel.
	 * So these codes will be replaced with more generic way later.
	 */
	if (!of_machine_is_compatible("samsung,exynos3") &&
			!of_machine_is_compatible("samsung,exynos4") &&
			!of_machine_is_compatible("samsung,exynos5"))
		return -ENODEV;

	exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1,
								NULL, 0);
	if (IS_ERR(exynos_drm_pdev))
+6 −3
Original line number Diff line number Diff line
@@ -302,10 +302,13 @@ static void g2d_fini_cmdlist(struct g2d_data *g2d)
	struct exynos_drm_subdrv *subdrv = &g2d->subdrv;

	kfree(g2d->cmdlist_node);

	if (g2d->cmdlist_pool_virt && g2d->cmdlist_pool) {
		dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE,
				g2d->cmdlist_pool_virt,
				g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs);
	}
}

static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d)
{
+3 −16
Original line number Diff line number Diff line
@@ -364,22 +364,9 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
		 * has to also include the unfenced register the GPU uses
		 * whilst executing a fenced command for an untiled object.
		 */

		obj->map_and_fenceable =
			!i915_gem_obj_ggtt_bound(obj) ||
			(i915_gem_obj_ggtt_offset(obj) +
			 obj->base.size <= dev_priv->gtt.mappable_end &&
			 i915_gem_object_fence_ok(obj, args->tiling_mode));

		/* Rebind if we need a change of alignment */
		if (!obj->map_and_fenceable) {
			u32 unfenced_align =
				i915_gem_get_gtt_alignment(dev, obj->base.size,
							    args->tiling_mode,
							    false);
			if (i915_gem_obj_ggtt_offset(obj) & (unfenced_align - 1))
		if (obj->map_and_fenceable &&
		    !i915_gem_object_fence_ok(obj, args->tiling_mode))
			ret = i915_gem_object_ggtt_unbind(obj);
		}

		if (ret == 0) {
			obj->fence_dirty =
+15 −1
Original line number Diff line number Diff line
@@ -26,6 +26,20 @@ struct gk20a_fb_priv {
	struct nouveau_fb base;
};

static int
gk20a_fb_init(struct nouveau_object *object)
{
	struct gk20a_fb_priv *priv = (void *)object;
	int ret;

	ret = nouveau_fb_init(&priv->base);
	if (ret)
		return ret;

	nv_mask(priv, 0x100c80, 0x00000001, 0x00000000); /* 128KiB lpg */
	return 0;
}

static int
gk20a_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
	     struct nouveau_oclass *oclass, void *data, u32 size,
@@ -48,7 +62,7 @@ gk20a_fb_oclass = &(struct nouveau_fb_impl) {
	.base.ofuncs = &(struct nouveau_ofuncs) {
		.ctor = gk20a_fb_ctor,
		.dtor = _nouveau_fb_dtor,
		.init = _nouveau_fb_init,
		.init = gk20a_fb_init,
		.fini = _nouveau_fb_fini,
	},
	.memtype = nvc0_fb_memtype_valid,
+23 −2
Original line number Diff line number Diff line
@@ -790,6 +790,22 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update)
	return 0;
}

static int
nv50_crtc_set_raster_vblank_dmi(struct nouveau_crtc *nv_crtc, u32 usec)
{
	struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
	u32 *push;

	push = evo_wait(mast, 8);
	if (!push)
		return -ENOMEM;

	evo_mthd(push, 0x0828 + (nv_crtc->index * 0x400), 1);
	evo_data(push, usec);
	evo_kick(push, mast);
	return 0;
}

static int
nv50_crtc_set_color_vibrance(struct nouveau_crtc *nv_crtc, bool update)
{
@@ -1104,14 +1120,14 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode,
			evo_mthd(push, 0x0804 + (nv_crtc->index * 0x400), 2);
			evo_data(push, 0x00800000 | mode->clock);
			evo_data(push, (ilace == 2) ? 2 : 0);
			evo_mthd(push, 0x0810 + (nv_crtc->index * 0x400), 8);
			evo_mthd(push, 0x0810 + (nv_crtc->index * 0x400), 6);
			evo_data(push, 0x00000000);
			evo_data(push, (vactive << 16) | hactive);
			evo_data(push, ( vsynce << 16) | hsynce);
			evo_data(push, (vblanke << 16) | hblanke);
			evo_data(push, (vblanks << 16) | hblanks);
			evo_data(push, (vblan2e << 16) | vblan2s);
			evo_data(push, vblankus);
			evo_mthd(push, 0x082c + (nv_crtc->index * 0x400), 1);
			evo_data(push, 0x00000000);
			evo_mthd(push, 0x0900 + (nv_crtc->index * 0x400), 2);
			evo_data(push, 0x00000311);
@@ -1141,6 +1157,11 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode,
	nv_connector = nouveau_crtc_connector_get(nv_crtc);
	nv50_crtc_set_dither(nv_crtc, false);
	nv50_crtc_set_scale(nv_crtc, false);

	/* G94 only accepts this after setting scale */
	if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA)
		nv50_crtc_set_raster_vblank_dmi(nv_crtc, vblankus);

	nv50_crtc_set_color_vibrance(nv_crtc, false);
	nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, false);
	return 0;
Loading