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

Merge tag 'drm-misc-next-2018-12-06' of git://anongit.freedesktop.org/drm/drm-misc into drm-next



Final changes to drm-misc-next for v4.21:

UAPI Changes:

Core Changes:
- Add dma_fence_get_stub to dma-buf, and use it in drm/syncobj.
- Add and use DRM_MODESET_LOCK_BEGIN/END helpers.
- Small fixes to drm_atomic_helper_resume(), drm_mode_setcrtc() and
  drm_atomic_helper_commit_duplicated_state()
- Fix drm_atomic_state_helper.[c] extraction.

Driver Changes:
- Small fixes to tinydrm, vkms, meson, rcar-du, virtio, vkms,
  v3d, and pl111.
- vc4: Allow scaling and YUV formats on cursor planes.
- v3d: Enable use of the Texture Formatting Unit, and fix
  prime imports of buffers from other drivers.
- Add support for the AUO G101EVN010 panel.
- sun4i: Enable support for the H6 display engine.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
[airlied: added drm/v3d: fix broken build to the merge commit]
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/321be9d3-ab75-5f92-8193-e5113662edef@linux.intel.com
parents 1f9a5dce 0b258ed1
Loading
Loading
Loading
Loading
+12 −0
Original line number Original line Diff line number Diff line
AU Optronics Corporation 10.1" (1280x800) color TFT LCD panel

Required properties:
- compatible: should be "auo,g101evn010"
- power-supply: as specified in the base binding

Optional properties:
- backlight: as specified in the base binding
- enable-gpios: as specified in the base binding

This binding is compatible with the simple-panel binding, which is specified
in simple-panel.txt in this directory.
+15 −0
Original line number Original line Diff line number Diff line
@@ -241,6 +241,21 @@ struct drm_gem_object_funcs
GEM objects can now have a function table instead of having the callbacks on the
GEM objects can now have a function table instead of having the callbacks on the
DRM driver struct. This is now the preferred way and drivers can be moved over.
DRM driver struct. This is now the preferred way and drivers can be moved over.


Use DRM_MODESET_LOCK_ALL_* helpers instead of boilerplate
---------------------------------------------------------

For cases where drivers are attempting to grab the modeset locks with a local
acquire context. Replace the boilerplate code surrounding
drm_modeset_lock_all_ctx() with DRM_MODESET_LOCK_ALL_BEGIN() and
DRM_MODESET_LOCK_ALL_END() instead.

This should also be done for all places where drm_modest_lock_all() is still
used.

As a reference, take a look at the conversions already completed in drm core.

Contact: Sean Paul, respective driver maintainers

Core refactorings
Core refactorings
=================
=================


+35 −1
Original line number Original line Diff line number Diff line
@@ -30,13 +30,16 @@
EXPORT_TRACEPOINT_SYMBOL(dma_fence_emit);
EXPORT_TRACEPOINT_SYMBOL(dma_fence_emit);
EXPORT_TRACEPOINT_SYMBOL(dma_fence_enable_signal);
EXPORT_TRACEPOINT_SYMBOL(dma_fence_enable_signal);


static DEFINE_SPINLOCK(dma_fence_stub_lock);
static struct dma_fence dma_fence_stub;

/*
/*
 * fence context counter: each execution context should have its own
 * fence context counter: each execution context should have its own
 * fence context, this allows checking if fences belong to the same
 * fence context, this allows checking if fences belong to the same
 * context or not. One device can have multiple separate contexts,
 * context or not. One device can have multiple separate contexts,
 * and they're used if some engine can run independently of another.
 * and they're used if some engine can run independently of another.
 */
 */
static atomic64_t dma_fence_context_counter = ATOMIC64_INIT(0);
static atomic64_t dma_fence_context_counter = ATOMIC64_INIT(1);


/**
/**
 * DOC: DMA fences overview
 * DOC: DMA fences overview
@@ -68,6 +71,37 @@ static atomic64_t dma_fence_context_counter = ATOMIC64_INIT(0);
 *   &dma_buf.resv pointer.
 *   &dma_buf.resv pointer.
 */
 */


static const char *dma_fence_stub_get_name(struct dma_fence *fence)
{
        return "stub";
}

static const struct dma_fence_ops dma_fence_stub_ops = {
	.get_driver_name = dma_fence_stub_get_name,
	.get_timeline_name = dma_fence_stub_get_name,
};

/**
 * dma_fence_get_stub - return a signaled fence
 *
 * Return a stub fence which is already signaled.
 */
struct dma_fence *dma_fence_get_stub(void)
{
	spin_lock(&dma_fence_stub_lock);
	if (!dma_fence_stub.ops) {
		dma_fence_init(&dma_fence_stub,
			       &dma_fence_stub_ops,
			       &dma_fence_stub_lock,
			       0, 0);
		dma_fence_signal_locked(&dma_fence_stub);
	}
	spin_unlock(&dma_fence_stub_lock);

	return dma_fence_get(&dma_fence_stub);
}
EXPORT_SYMBOL(dma_fence_get_stub);

/**
/**
 * dma_fence_context_alloc - allocate an array of fence contexts
 * dma_fence_context_alloc - allocate an array of fence contexts
 * @num: amount of contexts to allocate
 * @num: amount of contexts to allocate
+1 −1
Original line number Original line Diff line number Diff line
@@ -1193,7 +1193,7 @@ static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p)
	int i;
	int i;


	for (i = 0; i < p->num_post_dep_syncobjs; ++i)
	for (i = 0; i < p->num_post_dep_syncobjs; ++i)
		drm_syncobj_replace_fence(p->post_dep_syncobjs[i], 0, p->fence);
		drm_syncobj_replace_fence(p->post_dep_syncobjs[i], p->fence);
}
}


static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
+175 −42
Original line number Original line Diff line number Diff line
@@ -3131,25 +3131,102 @@ void drm_atomic_helper_shutdown(struct drm_device *dev)
	struct drm_modeset_acquire_ctx ctx;
	struct drm_modeset_acquire_ctx ctx;
	int ret;
	int ret;


	drm_modeset_acquire_init(&ctx, 0);
	DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
	while (1) {

		ret = drm_modeset_lock_all_ctx(dev, &ctx);
		if (!ret)
	ret = __drm_atomic_helper_disable_all(dev, &ctx, true);
	ret = __drm_atomic_helper_disable_all(dev, &ctx, true);
	if (ret)
		DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret);


		if (ret != -EDEADLK)
	DRM_MODESET_LOCK_ALL_END(ctx, ret);
			break;
}
EXPORT_SYMBOL(drm_atomic_helper_shutdown);

/**
 * drm_atomic_helper_duplicate_state - duplicate an atomic state object
 * @dev: DRM device
 * @ctx: lock acquisition context
 *
 * Makes a copy of the current atomic state by looping over all objects and
 * duplicating their respective states. This is used for example by suspend/
 * resume support code to save the state prior to suspend such that it can
 * be restored upon resume.
 *
 * Note that this treats atomic state as persistent between save and restore.
 * Drivers must make sure that this is possible and won't result in confusion
 * or erroneous behaviour.
 *
 * Note that if callers haven't already acquired all modeset locks this might
 * return -EDEADLK, which must be handled by calling drm_modeset_backoff().
 *
 * Returns:
 * A pointer to the copy of the atomic state object on success or an
 * ERR_PTR()-encoded error code on failure.
 *
 * See also:
 * drm_atomic_helper_suspend(), drm_atomic_helper_resume()
 */
struct drm_atomic_state *
drm_atomic_helper_duplicate_state(struct drm_device *dev,
				  struct drm_modeset_acquire_ctx *ctx)
{
	struct drm_atomic_state *state;
	struct drm_connector *conn;
	struct drm_connector_list_iter conn_iter;
	struct drm_plane *plane;
	struct drm_crtc *crtc;
	int err = 0;

	state = drm_atomic_state_alloc(dev);
	if (!state)
		return ERR_PTR(-ENOMEM);


		drm_modeset_backoff(&ctx);
	state->acquire_ctx = ctx;

	drm_for_each_crtc(crtc, dev) {
		struct drm_crtc_state *crtc_state;

		crtc_state = drm_atomic_get_crtc_state(state, crtc);
		if (IS_ERR(crtc_state)) {
			err = PTR_ERR(crtc_state);
			goto free;
		}
	}
	}


	if (ret)
	drm_for_each_plane(plane, dev) {
		DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret);
		struct drm_plane_state *plane_state;


	drm_modeset_drop_locks(&ctx);
		plane_state = drm_atomic_get_plane_state(state, plane);
	drm_modeset_acquire_fini(&ctx);
		if (IS_ERR(plane_state)) {
			err = PTR_ERR(plane_state);
			goto free;
		}
		}
EXPORT_SYMBOL(drm_atomic_helper_shutdown);
	}

	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(conn, &conn_iter) {
		struct drm_connector_state *conn_state;

		conn_state = drm_atomic_get_connector_state(state, conn);
		if (IS_ERR(conn_state)) {
			err = PTR_ERR(conn_state);
			drm_connector_list_iter_end(&conn_iter);
			goto free;
		}
	}
	drm_connector_list_iter_end(&conn_iter);

	/* clear the acquire context so that it isn't accidentally reused */
	state->acquire_ctx = NULL;

free:
	if (err < 0) {
		drm_atomic_state_put(state);
		state = ERR_PTR(err);
	}

	return state;
}
EXPORT_SYMBOL(drm_atomic_helper_duplicate_state);


/**
/**
 * drm_atomic_helper_suspend - subsystem-level suspend helper
 * drm_atomic_helper_suspend - subsystem-level suspend helper
@@ -3182,14 +3259,10 @@ struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev)
	struct drm_atomic_state *state;
	struct drm_atomic_state *state;
	int err;
	int err;


	drm_modeset_acquire_init(&ctx, 0);
	/* This can never be returned, but it makes the compiler happy */
	state = ERR_PTR(-EINVAL);


retry:
	DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, err);
	err = drm_modeset_lock_all_ctx(dev, &ctx);
	if (err < 0) {
		state = ERR_PTR(err);
		goto unlock;
	}


	state = drm_atomic_helper_duplicate_state(dev, &ctx);
	state = drm_atomic_helper_duplicate_state(dev, &ctx);
	if (IS_ERR(state))
	if (IS_ERR(state))
@@ -3203,13 +3276,10 @@ retry:
	}
	}


unlock:
unlock:
	if (PTR_ERR(state) == -EDEADLK) {
	DRM_MODESET_LOCK_ALL_END(ctx, err);
		drm_modeset_backoff(&ctx);
	if (err)
		goto retry;
		return ERR_PTR(err);
	}


	drm_modeset_drop_locks(&ctx);
	drm_modeset_acquire_fini(&ctx);
	return state;
	return state;
}
}
EXPORT_SYMBOL(drm_atomic_helper_suspend);
EXPORT_SYMBOL(drm_atomic_helper_suspend);
@@ -3232,7 +3302,7 @@ EXPORT_SYMBOL(drm_atomic_helper_suspend);
int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
					      struct drm_modeset_acquire_ctx *ctx)
					      struct drm_modeset_acquire_ctx *ctx)
{
{
	int i;
	int i, ret;
	struct drm_plane *plane;
	struct drm_plane *plane;
	struct drm_plane_state *new_plane_state;
	struct drm_plane_state *new_plane_state;
	struct drm_connector *connector;
	struct drm_connector *connector;
@@ -3251,7 +3321,11 @@ int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
	for_each_new_connector_in_state(state, connector, new_conn_state, i)
	for_each_new_connector_in_state(state, connector, new_conn_state, i)
		state->connectors[i].old_state = connector->state;
		state->connectors[i].old_state = connector->state;


	return drm_atomic_commit(state);
	ret = drm_atomic_commit(state);

	state->acquire_ctx = NULL;

	return ret;
}
}
EXPORT_SYMBOL(drm_atomic_helper_commit_duplicated_state);
EXPORT_SYMBOL(drm_atomic_helper_commit_duplicated_state);


@@ -3279,23 +3353,12 @@ int drm_atomic_helper_resume(struct drm_device *dev,


	drm_mode_config_reset(dev);
	drm_mode_config_reset(dev);


	drm_modeset_acquire_init(&ctx, 0);
	DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, err);
	while (1) {
		err = drm_modeset_lock_all_ctx(dev, &ctx);
		if (err)
			goto out;


	err = drm_atomic_helper_commit_duplicated_state(state, &ctx);
	err = drm_atomic_helper_commit_duplicated_state(state, &ctx);
out:
		if (err != -EDEADLK)
			break;

		drm_modeset_backoff(&ctx);
	}


	DRM_MODESET_LOCK_ALL_END(ctx, err);
	drm_atomic_state_put(state);
	drm_atomic_state_put(state);
	drm_modeset_drop_locks(&ctx);
	drm_modeset_acquire_fini(&ctx);


	return err;
	return err;
}
}
@@ -3434,3 +3497,73 @@ fail:
	return ret;
	return ret;
}
}
EXPORT_SYMBOL(drm_atomic_helper_page_flip_target);
EXPORT_SYMBOL(drm_atomic_helper_page_flip_target);

/**
 * drm_atomic_helper_legacy_gamma_set - set the legacy gamma correction table
 * @crtc: CRTC object
 * @red: red correction table
 * @green: green correction table
 * @blue: green correction table
 * @size: size of the tables
 * @ctx: lock acquire context
 *
 * Implements support for legacy gamma correction table for drivers
 * that support color management through the DEGAMMA_LUT/GAMMA_LUT
 * properties. See drm_crtc_enable_color_mgmt() and the containing chapter for
 * how the atomic color management and gamma tables work.
 */
int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
				       u16 *red, u16 *green, u16 *blue,
				       uint32_t size,
				       struct drm_modeset_acquire_ctx *ctx)
{
	struct drm_device *dev = crtc->dev;
	struct drm_atomic_state *state;
	struct drm_crtc_state *crtc_state;
	struct drm_property_blob *blob = NULL;
	struct drm_color_lut *blob_data;
	int i, ret = 0;
	bool replaced;

	state = drm_atomic_state_alloc(crtc->dev);
	if (!state)
		return -ENOMEM;

	blob = drm_property_create_blob(dev,
					sizeof(struct drm_color_lut) * size,
					NULL);
	if (IS_ERR(blob)) {
		ret = PTR_ERR(blob);
		blob = NULL;
		goto fail;
	}

	/* Prepare GAMMA_LUT with the legacy values. */
	blob_data = blob->data;
	for (i = 0; i < size; i++) {
		blob_data[i].red = red[i];
		blob_data[i].green = green[i];
		blob_data[i].blue = blue[i];
	}

	state->acquire_ctx = ctx;
	crtc_state = drm_atomic_get_crtc_state(state, crtc);
	if (IS_ERR(crtc_state)) {
		ret = PTR_ERR(crtc_state);
		goto fail;
	}

	/* Reset DEGAMMA_LUT and CTM properties. */
	replaced  = drm_property_replace_blob(&crtc_state->degamma_lut, NULL);
	replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL);
	replaced |= drm_property_replace_blob(&crtc_state->gamma_lut, blob);
	crtc_state->color_mgmt_changed |= replaced;

	ret = drm_atomic_commit(state);

fail:
	drm_atomic_state_put(state);
	drm_property_blob_put(blob);
	return ret;
}
EXPORT_SYMBOL(drm_atomic_helper_legacy_gamma_set);
Loading