Przeglądaj źródła

Merge branch 'drm/next/rcar-du' of git://linuxtv.org/pinchartl/fbdev into drm-next

rcar-du fixes
* 'drm/next/rcar-du' of git://linuxtv.org/pinchartl/fbdev:
  drm: rcar-du: Split planes pre-association 4/4 between CRTCs
  drm: rcar-du: Store the number of CRTCs per group in the group structure
  drm: rcar-du: Consider plane to CRTC associations in the plane allocator
  drm: rcar-du: Keep plane to CRTC associations when disabling a plane
  drm: rcar-du: Add plane allocation debugging
  drm: rcar-du: Rename to_rcar_du_plane_state to to_rcar_plane_state
  drm: rcar-du: Embed rcar_du_planes structure into rcar_du_group
  drm: rcar-du: Move properties from rcar_du_planes to rcar_du_device
  drm: rcar-du: Document the rcar_du_plane_state structure
  drm: rcar-du: Document the rcar_du_crtc structure
Dave Airlie 10 lat temu
rodzic
commit
f025705e73

+ 33 - 28
drivers/gpu/drm/rcar-du/rcar_du_crtc.c

@@ -195,26 +195,27 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc,
 
 
 static unsigned int plane_zpos(struct rcar_du_plane *plane)
 static unsigned int plane_zpos(struct rcar_du_plane *plane)
 {
 {
-	return to_rcar_du_plane_state(plane->plane.state)->zpos;
+	return to_rcar_plane_state(plane->plane.state)->zpos;
 }
 }
 
 
 static const struct rcar_du_format_info *
 static const struct rcar_du_format_info *
 plane_format(struct rcar_du_plane *plane)
 plane_format(struct rcar_du_plane *plane)
 {
 {
-	return to_rcar_du_plane_state(plane->plane.state)->format;
+	return to_rcar_plane_state(plane->plane.state)->format;
 }
 }
 
 
 static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
 static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
 {
 {
 	struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES];
 	struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES];
 	unsigned int num_planes = 0;
 	unsigned int num_planes = 0;
+	unsigned int dptsr_planes;
+	unsigned int hwplanes = 0;
 	unsigned int prio = 0;
 	unsigned int prio = 0;
 	unsigned int i;
 	unsigned int i;
-	u32 dptsr = 0;
 	u32 dspr = 0;
 	u32 dspr = 0;
 
 
-	for (i = 0; i < ARRAY_SIZE(rcrtc->group->planes.planes); ++i) {
-		struct rcar_du_plane *plane = &rcrtc->group->planes.planes[i];
+	for (i = 0; i < ARRAY_SIZE(rcrtc->group->planes); ++i) {
+		struct rcar_du_plane *plane = &rcrtc->group->planes[i];
 		unsigned int j;
 		unsigned int j;
 
 
 		if (plane->plane.state->crtc != &rcrtc->crtc)
 		if (plane->plane.state->crtc != &rcrtc->crtc)
@@ -234,41 +235,45 @@ static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
 	for (i = 0; i < num_planes; ++i) {
 	for (i = 0; i < num_planes; ++i) {
 		struct rcar_du_plane *plane = planes[i];
 		struct rcar_du_plane *plane = planes[i];
 		struct drm_plane_state *state = plane->plane.state;
 		struct drm_plane_state *state = plane->plane.state;
-		unsigned int index = to_rcar_du_plane_state(state)->hwindex;
+		unsigned int index = to_rcar_plane_state(state)->hwindex;
 
 
 		prio -= 4;
 		prio -= 4;
 		dspr |= (index + 1) << prio;
 		dspr |= (index + 1) << prio;
-		dptsr |= DPTSR_PnDK(index) |  DPTSR_PnTS(index);
+		hwplanes |= 1 << index;
 
 
 		if (plane_format(plane)->planes == 2) {
 		if (plane_format(plane)->planes == 2) {
 			index = (index + 1) % 8;
 			index = (index + 1) % 8;
 
 
 			prio -= 4;
 			prio -= 4;
 			dspr |= (index + 1) << prio;
 			dspr |= (index + 1) << prio;
-			dptsr |= DPTSR_PnDK(index) |  DPTSR_PnTS(index);
+			hwplanes |= 1 << index;
 		}
 		}
 	}
 	}
 
 
-	/* Select display timing and dot clock generator 2 for planes associated
-	 * with superposition controller 2.
+	/* Update the planes to display timing and dot clock generator
+	 * associations.
+	 *
+	 * Updating the DPTSR register requires restarting the CRTC group,
+	 * resulting in visible flicker. To mitigate the issue only update the
+	 * association if needed by enabled planes. Planes being disabled will
+	 * keep their current association.
 	 */
 	 */
-	if (rcrtc->index % 2) {
-		/* The DPTSR register is updated when the display controller is
-		 * stopped. We thus need to restart the DU. Once again, sorry
-		 * for the flicker. One way to mitigate the issue would be to
-		 * pre-associate planes with CRTCs (either with a fixed 4/4
-		 * split, or through a module parameter). Flicker would then
-		 * occur only if we need to break the pre-association.
-		 */
-		mutex_lock(&rcrtc->group->lock);
-		if (rcar_du_group_read(rcrtc->group, DPTSR) != dptsr) {
-			rcar_du_group_write(rcrtc->group, DPTSR, dptsr);
-			if (rcrtc->group->used_crtcs)
-				rcar_du_group_restart(rcrtc->group);
-		}
-		mutex_unlock(&rcrtc->group->lock);
+	mutex_lock(&rcrtc->group->lock);
+
+	dptsr_planes = rcrtc->index % 2 ? rcrtc->group->dptsr_planes | hwplanes
+		     : rcrtc->group->dptsr_planes & ~hwplanes;
+
+	if (dptsr_planes != rcrtc->group->dptsr_planes) {
+		rcar_du_group_write(rcrtc->group, DPTSR,
+				    (dptsr_planes << 16) | dptsr_planes);
+		rcrtc->group->dptsr_planes = dptsr_planes;
+
+		if (rcrtc->group->used_crtcs)
+			rcar_du_group_restart(rcrtc->group);
 	}
 	}
 
 
+	mutex_unlock(&rcrtc->group->lock);
+
 	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR,
 	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR,
 			    dspr);
 			    dspr);
 }
 }
@@ -427,8 +432,8 @@ void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc)
 	rcar_du_crtc_start(rcrtc);
 	rcar_du_crtc_start(rcrtc);
 
 
 	/* Commit the planes state. */
 	/* Commit the planes state. */
-	for (i = 0; i < ARRAY_SIZE(rcrtc->group->planes.planes); ++i) {
-		struct rcar_du_plane *plane = &rcrtc->group->planes.planes[i];
+	for (i = 0; i < ARRAY_SIZE(rcrtc->group->planes); ++i) {
+		struct rcar_du_plane *plane = &rcrtc->group->planes[i];
 
 
 		if (plane->plane.state->crtc != &rcrtc->crtc)
 		if (plane->plane.state->crtc != &rcrtc->crtc)
 			continue;
 			continue;
@@ -592,7 +597,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
 	rcrtc->enabled = false;
 	rcrtc->enabled = false;
 
 
 	ret = drm_crtc_init_with_planes(rcdu->ddev, crtc,
 	ret = drm_crtc_init_with_planes(rcdu->ddev, crtc,
-					&rgrp->planes.planes[index % 2].plane,
+					&rgrp->planes[index % 2].plane,
 					NULL, &crtc_funcs);
 					NULL, &crtc_funcs);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;

+ 14 - 0
drivers/gpu/drm/rcar-du/rcar_du_crtc.h

@@ -22,6 +22,20 @@
 
 
 struct rcar_du_group;
 struct rcar_du_group;
 
 
+/**
+ * struct rcar_du_crtc - the CRTC, representing a DU superposition processor
+ * @crtc: base DRM CRTC
+ * @clock: the CRTC functional clock
+ * @extclock: external pixel dot clock (optional)
+ * @mmio_offset: offset of the CRTC registers in the DU MMIO block
+ * @index: CRTC software and hardware index
+ * @started: whether the CRTC has been started and is running
+ * @event: event to post when the pending page flip completes
+ * @flip_wait: wait queue used to signal page flip completion
+ * @outputs: bitmask of the outputs (enum rcar_du_output) driven by this CRTC
+ * @enabled: whether the CRTC is enabled, used to control system resume
+ * @group: CRTC group this CRTC belongs to
+ */
 struct rcar_du_crtc {
 struct rcar_du_crtc {
 	struct drm_crtc crtc;
 	struct drm_crtc crtc;
 
 

+ 6 - 0
drivers/gpu/drm/rcar-du/rcar_du_drv.h

@@ -83,6 +83,12 @@ struct rcar_du_device {
 
 
 	struct rcar_du_group groups[RCAR_DU_MAX_GROUPS];
 	struct rcar_du_group groups[RCAR_DU_MAX_GROUPS];
 
 
+	struct {
+		struct drm_property *alpha;
+		struct drm_property *colorkey;
+		struct drm_property *zpos;
+	} props;
+
 	unsigned int dpad0_source;
 	unsigned int dpad0_source;
 	struct rcar_du_lvdsenc *lvds[RCAR_DU_MAX_LVDS];
 	struct rcar_du_lvdsenc *lvds[RCAR_DU_MAX_LVDS];
 
 

+ 6 - 0
drivers/gpu/drm/rcar-du/rcar_du_group.c

@@ -85,6 +85,12 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
 	 * superposition 0 to DU0 pins. DU1 pins will be configured dynamically.
 	 * superposition 0 to DU0 pins. DU1 pins will be configured dynamically.
 	 */
 	 */
 	rcar_du_group_write(rgrp, DORCR, DORCR_PG1D_DS1 | DORCR_DPRS);
 	rcar_du_group_write(rgrp, DORCR, DORCR_PG1D_DS1 | DORCR_DPRS);
+
+	/* Apply planes to CRTCs association. */
+	mutex_lock(&rgrp->lock);
+	rcar_du_group_write(rgrp, DPTSR, (rgrp->dptsr_planes << 16) |
+			    rgrp->dptsr_planes);
+	mutex_unlock(&rgrp->lock);
 }
 }
 
 
 /*
 /*

+ 6 - 2
drivers/gpu/drm/rcar-du/rcar_du_group.h

@@ -25,9 +25,11 @@ struct rcar_du_device;
  * @dev: the DU device
  * @dev: the DU device
  * @mmio_offset: registers offset in the device memory map
  * @mmio_offset: registers offset in the device memory map
  * @index: group index
  * @index: group index
+ * @num_crtcs: number of CRTCs in this group (1 or 2)
  * @use_count: number of users of the group (rcar_du_group_(get|put))
  * @use_count: number of users of the group (rcar_du_group_(get|put))
  * @used_crtcs: number of CRTCs currently in use
  * @used_crtcs: number of CRTCs currently in use
- * @lock: protects the DPTSR register
+ * @lock: protects the dptsr_planes field and the DPTSR register
+ * @dptsr_planes: bitmask of planes driven by dot-clock and timing generator 1
  * @planes: planes handled by the group
  * @planes: planes handled by the group
  */
  */
 struct rcar_du_group {
 struct rcar_du_group {
@@ -35,12 +37,14 @@ struct rcar_du_group {
 	unsigned int mmio_offset;
 	unsigned int mmio_offset;
 	unsigned int index;
 	unsigned int index;
 
 
+	unsigned int num_crtcs;
 	unsigned int use_count;
 	unsigned int use_count;
 	unsigned int used_crtcs;
 	unsigned int used_crtcs;
 
 
 	struct mutex lock;
 	struct mutex lock;
+	unsigned int dptsr_planes;
 
 
-	struct rcar_du_planes planes;
+	struct rcar_du_plane planes[RCAR_DU_NUM_KMS_PLANES];
 };
 };
 
 
 u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg);
 u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg);

+ 96 - 9
drivers/gpu/drm/rcar-du/rcar_du_kms.c

@@ -221,7 +221,7 @@ static bool rcar_du_plane_needs_realloc(struct rcar_du_plane *plane,
 {
 {
 	const struct rcar_du_format_info *cur_format;
 	const struct rcar_du_format_info *cur_format;
 
 
-	cur_format = to_rcar_du_plane_state(plane->plane.state)->format;
+	cur_format = to_rcar_plane_state(plane->plane.state)->format;
 
 
 	/* Lowering the number of planes doesn't strictly require reallocation
 	/* Lowering the number of planes doesn't strictly require reallocation
 	 * as the extra hardware plane will be freed when committing, but doing
 	 * as the extra hardware plane will be freed when committing, but doing
@@ -284,14 +284,19 @@ static int rcar_du_atomic_check(struct drm_device *dev,
 			continue;
 			continue;
 
 
 		plane = to_rcar_plane(state->planes[i]);
 		plane = to_rcar_plane(state->planes[i]);
-		plane_state = to_rcar_du_plane_state(state->plane_states[i]);
+		plane_state = to_rcar_plane_state(state->plane_states[i]);
+
+		dev_dbg(rcdu->dev, "%s: checking plane (%u,%u)\n", __func__,
+			plane->group->index, plane - plane->group->planes);
 
 
 		/* If the plane is being disabled we don't need to go through
 		/* If the plane is being disabled we don't need to go through
 		 * the full reallocation procedure. Just mark the hardware
 		 * the full reallocation procedure. Just mark the hardware
 		 * plane(s) as freed.
 		 * plane(s) as freed.
 		 */
 		 */
 		if (!plane_state->format) {
 		if (!plane_state->format) {
-			index = plane - plane->group->planes.planes;
+			dev_dbg(rcdu->dev, "%s: plane is being disabled\n",
+				__func__);
+			index = plane - plane->group->planes;
 			group_freed_planes[plane->group->index] |= 1 << index;
 			group_freed_planes[plane->group->index] |= 1 << index;
 			plane_state->hwindex = -1;
 			plane_state->hwindex = -1;
 			continue;
 			continue;
@@ -301,10 +306,12 @@ static int rcar_du_atomic_check(struct drm_device *dev,
 		 * mark the hardware plane(s) as free.
 		 * mark the hardware plane(s) as free.
 		 */
 		 */
 		if (rcar_du_plane_needs_realloc(plane, plane_state)) {
 		if (rcar_du_plane_needs_realloc(plane, plane_state)) {
+			dev_dbg(rcdu->dev, "%s: plane needs reallocation\n",
+				__func__);
 			groups |= 1 << plane->group->index;
 			groups |= 1 << plane->group->index;
 			needs_realloc = true;
 			needs_realloc = true;
 
 
-			index = plane - plane->group->planes.planes;
+			index = plane - plane->group->planes;
 			group_freed_planes[plane->group->index] |= 1 << index;
 			group_freed_planes[plane->group->index] |= 1 << index;
 			plane_state->hwindex = -1;
 			plane_state->hwindex = -1;
 		}
 		}
@@ -326,8 +333,11 @@ static int rcar_du_atomic_check(struct drm_device *dev,
 		struct rcar_du_group *group = &rcdu->groups[index];
 		struct rcar_du_group *group = &rcdu->groups[index];
 		unsigned int used_planes = 0;
 		unsigned int used_planes = 0;
 
 
+		dev_dbg(rcdu->dev, "%s: finding free planes for group %u\n",
+			__func__, index);
+
 		for (i = 0; i < RCAR_DU_NUM_KMS_PLANES; ++i) {
 		for (i = 0; i < RCAR_DU_NUM_KMS_PLANES; ++i) {
-			struct rcar_du_plane *plane = &group->planes.planes[i];
+			struct rcar_du_plane *plane = &group->planes[i];
 			struct rcar_du_plane_state *plane_state;
 			struct rcar_du_plane_state *plane_state;
 			struct drm_plane_state *s;
 			struct drm_plane_state *s;
 
 
@@ -342,28 +352,49 @@ static int rcar_du_atomic_check(struct drm_device *dev,
 			 * above. Use the local freed planes list to check for
 			 * above. Use the local freed planes list to check for
 			 * that condition instead.
 			 * that condition instead.
 			 */
 			 */
-			if (group_freed_planes[index] & (1 << i))
+			if (group_freed_planes[index] & (1 << i)) {
+				dev_dbg(rcdu->dev,
+					"%s: plane (%u,%u) has been freed, skipping\n",
+					__func__, plane->group->index,
+					plane - plane->group->planes);
 				continue;
 				continue;
+			}
 
 
-			plane_state = to_rcar_du_plane_state(plane->plane.state);
+			plane_state = to_rcar_plane_state(plane->plane.state);
 			used_planes |= rcar_du_plane_hwmask(plane_state);
 			used_planes |= rcar_du_plane_hwmask(plane_state);
+
+			dev_dbg(rcdu->dev,
+				"%s: plane (%u,%u) uses %u hwplanes (index %d)\n",
+				__func__, plane->group->index,
+				plane - plane->group->planes,
+				plane_state->format ?
+				plane_state->format->planes : 0,
+				plane_state->hwindex);
 		}
 		}
 
 
 		group_free_planes[index] = 0xff & ~used_planes;
 		group_free_planes[index] = 0xff & ~used_planes;
 		groups &= ~(1 << index);
 		groups &= ~(1 << index);
+
+		dev_dbg(rcdu->dev, "%s: group %u free planes mask 0x%02x\n",
+			__func__, index, group_free_planes[index]);
 	}
 	}
 
 
 	/* Reallocate hardware planes for each plane that needs it. */
 	/* Reallocate hardware planes for each plane that needs it. */
 	for (i = 0; i < dev->mode_config.num_total_plane; ++i) {
 	for (i = 0; i < dev->mode_config.num_total_plane; ++i) {
 		struct rcar_du_plane_state *plane_state;
 		struct rcar_du_plane_state *plane_state;
 		struct rcar_du_plane *plane;
 		struct rcar_du_plane *plane;
+		unsigned int crtc_planes;
+		unsigned int free;
 		int idx;
 		int idx;
 
 
 		if (!state->planes[i])
 		if (!state->planes[i])
 			continue;
 			continue;
 
 
 		plane = to_rcar_plane(state->planes[i]);
 		plane = to_rcar_plane(state->planes[i]);
-		plane_state = to_rcar_du_plane_state(state->plane_states[i]);
+		plane_state = to_rcar_plane_state(state->plane_states[i]);
+
+		dev_dbg(rcdu->dev, "%s: allocating plane (%u,%u)\n", __func__,
+			plane->group->index, plane - plane->group->planes);
 
 
 		/* Skip planes that are being disabled or don't need to be
 		/* Skip planes that are being disabled or don't need to be
 		 * reallocated.
 		 * reallocated.
@@ -372,18 +403,38 @@ static int rcar_du_atomic_check(struct drm_device *dev,
 		    !rcar_du_plane_needs_realloc(plane, plane_state))
 		    !rcar_du_plane_needs_realloc(plane, plane_state))
 			continue;
 			continue;
 
 
+		/* Try to allocate the plane from the free planes currently
+		 * associated with the target CRTC to avoid restarting the CRTC
+		 * group and thus minimize flicker. If it fails fall back to
+		 * allocating from all free planes.
+		 */
+		crtc_planes = to_rcar_crtc(plane_state->state.crtc)->index % 2
+			    ? plane->group->dptsr_planes
+			    : ~plane->group->dptsr_planes;
+		free = group_free_planes[plane->group->index];
+
 		idx = rcar_du_plane_hwalloc(plane_state->format->planes,
 		idx = rcar_du_plane_hwalloc(plane_state->format->planes,
-					group_free_planes[plane->group->index]);
+					    free & crtc_planes);
+		if (idx < 0)
+			idx = rcar_du_plane_hwalloc(plane_state->format->planes,
+						    free);
 		if (idx < 0) {
 		if (idx < 0) {
 			dev_dbg(rcdu->dev, "%s: no available hardware plane\n",
 			dev_dbg(rcdu->dev, "%s: no available hardware plane\n",
 				__func__);
 				__func__);
 			return idx;
 			return idx;
 		}
 		}
 
 
+		dev_dbg(rcdu->dev, "%s: allocated %u hwplanes (index %u)\n",
+			__func__, plane_state->format->planes, idx);
+
 		plane_state->hwindex = idx;
 		plane_state->hwindex = idx;
 
 
 		group_free_planes[plane->group->index] &=
 		group_free_planes[plane->group->index] &=
 			~rcar_du_plane_hwmask(plane_state);
 			~rcar_du_plane_hwmask(plane_state);
+
+		dev_dbg(rcdu->dev, "%s: group %u free planes mask 0x%02x\n",
+			__func__, plane->group->index,
+			group_free_planes[plane->group->index]);
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -648,6 +699,31 @@ static int rcar_du_encoders_init(struct rcar_du_device *rcdu)
 	return num_encoders;
 	return num_encoders;
 }
 }
 
 
+static int rcar_du_properties_init(struct rcar_du_device *rcdu)
+{
+	rcdu->props.alpha =
+		drm_property_create_range(rcdu->ddev, 0, "alpha", 0, 255);
+	if (rcdu->props.alpha == NULL)
+		return -ENOMEM;
+
+	/* The color key is expressed as an RGB888 triplet stored in a 32-bit
+	 * integer in XRGB8888 format. Bit 24 is used as a flag to disable (0)
+	 * or enable source color keying (1).
+	 */
+	rcdu->props.colorkey =
+		drm_property_create_range(rcdu->ddev, 0, "colorkey",
+					  0, 0x01ffffff);
+	if (rcdu->props.colorkey == NULL)
+		return -ENOMEM;
+
+	rcdu->props.zpos =
+		drm_property_create_range(rcdu->ddev, 0, "zpos", 1, 7);
+	if (rcdu->props.zpos == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+
 int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 {
 {
 	static const unsigned int mmio_offsets[] = {
 	static const unsigned int mmio_offsets[] = {
@@ -672,6 +748,10 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 
 
 	rcdu->num_crtcs = rcdu->info->num_crtcs;
 	rcdu->num_crtcs = rcdu->info->num_crtcs;
 
 
+	ret = rcar_du_properties_init(rcdu);
+	if (ret < 0)
+		return ret;
+
 	/* Initialize the groups. */
 	/* Initialize the groups. */
 	num_groups = DIV_ROUND_UP(rcdu->num_crtcs, 2);
 	num_groups = DIV_ROUND_UP(rcdu->num_crtcs, 2);
 
 
@@ -683,6 +763,13 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 		rgrp->dev = rcdu;
 		rgrp->dev = rcdu;
 		rgrp->mmio_offset = mmio_offsets[i];
 		rgrp->mmio_offset = mmio_offsets[i];
 		rgrp->index = i;
 		rgrp->index = i;
+		rgrp->num_crtcs = min(rcdu->num_crtcs - 2 * i, 2U);
+
+		/* If we have more than one CRTCs in this group pre-associate
+		 * planes 0-3 with CRTC 0 and planes 4-7 with CRTC 1 to minimize
+		 * flicker occurring when the association is changed.
+		 */
+		rgrp->dptsr_planes = rgrp->num_crtcs > 1 ? 0xf0 : 0;
 
 
 		ret = rcar_du_planes_init(rgrp);
 		ret = rcar_du_planes_init(rgrp);
 		if (ret < 0)
 		if (ret < 0)

+ 23 - 48
drivers/gpu/drm/rcar-du/rcar_du_plane.c

@@ -45,7 +45,7 @@ static void rcar_du_plane_write(struct rcar_du_group *rgrp,
 static void rcar_du_plane_setup_fb(struct rcar_du_plane *plane)
 static void rcar_du_plane_setup_fb(struct rcar_du_plane *plane)
 {
 {
 	struct rcar_du_plane_state *state =
 	struct rcar_du_plane_state *state =
-		to_rcar_du_plane_state(plane->plane.state);
+		to_rcar_plane_state(plane->plane.state);
 	struct drm_framebuffer *fb = plane->plane.state->fb;
 	struct drm_framebuffer *fb = plane->plane.state->fb;
 	struct rcar_du_group *rgrp = plane->group;
 	struct rcar_du_group *rgrp = plane->group;
 	unsigned int src_x = state->state.src_x >> 16;
 	unsigned int src_x = state->state.src_x >> 16;
@@ -109,7 +109,7 @@ static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane,
 				     unsigned int index)
 				     unsigned int index)
 {
 {
 	struct rcar_du_plane_state *state =
 	struct rcar_du_plane_state *state =
-		to_rcar_du_plane_state(plane->plane.state);
+		to_rcar_plane_state(plane->plane.state);
 	struct rcar_du_group *rgrp = plane->group;
 	struct rcar_du_group *rgrp = plane->group;
 	u32 colorkey;
 	u32 colorkey;
 	u32 pnmr;
 	u32 pnmr;
@@ -172,7 +172,7 @@ static void __rcar_du_plane_setup(struct rcar_du_plane *plane,
 				  unsigned int index)
 				  unsigned int index)
 {
 {
 	struct rcar_du_plane_state *state =
 	struct rcar_du_plane_state *state =
-		to_rcar_du_plane_state(plane->plane.state);
+		to_rcar_plane_state(plane->plane.state);
 	struct rcar_du_group *rgrp = plane->group;
 	struct rcar_du_group *rgrp = plane->group;
 	u32 ddcr2 = PnDDCR2_CODE;
 	u32 ddcr2 = PnDDCR2_CODE;
 	u32 ddcr4;
 	u32 ddcr4;
@@ -222,7 +222,7 @@ static void __rcar_du_plane_setup(struct rcar_du_plane *plane,
 void rcar_du_plane_setup(struct rcar_du_plane *plane)
 void rcar_du_plane_setup(struct rcar_du_plane *plane)
 {
 {
 	struct rcar_du_plane_state *state =
 	struct rcar_du_plane_state *state =
-		to_rcar_du_plane_state(plane->plane.state);
+		to_rcar_plane_state(plane->plane.state);
 
 
 	__rcar_du_plane_setup(plane, state->hwindex);
 	__rcar_du_plane_setup(plane, state->hwindex);
 	if (state->format->planes == 2)
 	if (state->format->planes == 2)
@@ -234,7 +234,7 @@ void rcar_du_plane_setup(struct rcar_du_plane *plane)
 static int rcar_du_plane_atomic_check(struct drm_plane *plane,
 static int rcar_du_plane_atomic_check(struct drm_plane *plane,
 				      struct drm_plane_state *state)
 				      struct drm_plane_state *state)
 {
 {
-	struct rcar_du_plane_state *rstate = to_rcar_du_plane_state(state);
+	struct rcar_du_plane_state *rstate = to_rcar_plane_state(state);
 	struct rcar_du_plane *rplane = to_rcar_plane(plane);
 	struct rcar_du_plane *rplane = to_rcar_plane(plane);
 	struct rcar_du_device *rcdu = rplane->group->dev;
 	struct rcar_du_device *rcdu = rplane->group->dev;
 
 
@@ -302,7 +302,7 @@ rcar_du_plane_atomic_duplicate_state(struct drm_plane *plane)
 	struct rcar_du_plane_state *state;
 	struct rcar_du_plane_state *state;
 	struct rcar_du_plane_state *copy;
 	struct rcar_du_plane_state *copy;
 
 
-	state = to_rcar_du_plane_state(plane->state);
+	state = to_rcar_plane_state(plane->state);
 	copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
 	copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
 	if (copy == NULL)
 	if (copy == NULL)
 		return NULL;
 		return NULL;
@@ -319,7 +319,7 @@ static void rcar_du_plane_atomic_destroy_state(struct drm_plane *plane,
 	if (state->fb)
 	if (state->fb)
 		drm_framebuffer_unreference(state->fb);
 		drm_framebuffer_unreference(state->fb);
 
 
-	kfree(to_rcar_du_plane_state(state));
+	kfree(to_rcar_plane_state(state));
 }
 }
 
 
 static int rcar_du_plane_atomic_set_property(struct drm_plane *plane,
 static int rcar_du_plane_atomic_set_property(struct drm_plane *plane,
@@ -327,15 +327,14 @@ static int rcar_du_plane_atomic_set_property(struct drm_plane *plane,
 					     struct drm_property *property,
 					     struct drm_property *property,
 					     uint64_t val)
 					     uint64_t val)
 {
 {
-	struct rcar_du_plane_state *rstate = to_rcar_du_plane_state(state);
-	struct rcar_du_plane *rplane = to_rcar_plane(plane);
-	struct rcar_du_group *rgrp = rplane->group;
+	struct rcar_du_plane_state *rstate = to_rcar_plane_state(state);
+	struct rcar_du_device *rcdu = to_rcar_plane(plane)->group->dev;
 
 
-	if (property == rgrp->planes.alpha)
+	if (property == rcdu->props.alpha)
 		rstate->alpha = val;
 		rstate->alpha = val;
-	else if (property == rgrp->planes.colorkey)
+	else if (property == rcdu->props.colorkey)
 		rstate->colorkey = val;
 		rstate->colorkey = val;
-	else if (property == rgrp->planes.zpos)
+	else if (property == rcdu->props.zpos)
 		rstate->zpos = val;
 		rstate->zpos = val;
 	else
 	else
 		return -EINVAL;
 		return -EINVAL;
@@ -349,14 +348,13 @@ static int rcar_du_plane_atomic_get_property(struct drm_plane *plane,
 {
 {
 	const struct rcar_du_plane_state *rstate =
 	const struct rcar_du_plane_state *rstate =
 		container_of(state, const struct rcar_du_plane_state, state);
 		container_of(state, const struct rcar_du_plane_state, state);
-	struct rcar_du_plane *rplane = to_rcar_plane(plane);
-	struct rcar_du_group *rgrp = rplane->group;
+	struct rcar_du_device *rcdu = to_rcar_plane(plane)->group->dev;
 
 
-	if (property == rgrp->planes.alpha)
+	if (property == rcdu->props.alpha)
 		*val = rstate->alpha;
 		*val = rstate->alpha;
-	else if (property == rgrp->planes.colorkey)
+	else if (property == rcdu->props.colorkey)
 		*val = rstate->colorkey;
 		*val = rstate->colorkey;
-	else if (property == rgrp->planes.zpos)
+	else if (property == rcdu->props.zpos)
 		*val = rstate->zpos;
 		*val = rstate->zpos;
 	else
 	else
 		return -EINVAL;
 		return -EINVAL;
@@ -391,47 +389,24 @@ static const uint32_t formats[] = {
 
 
 int rcar_du_planes_init(struct rcar_du_group *rgrp)
 int rcar_du_planes_init(struct rcar_du_group *rgrp)
 {
 {
-	struct rcar_du_planes *planes = &rgrp->planes;
 	struct rcar_du_device *rcdu = rgrp->dev;
 	struct rcar_du_device *rcdu = rgrp->dev;
 	unsigned int num_planes;
 	unsigned int num_planes;
-	unsigned int num_crtcs;
 	unsigned int crtcs;
 	unsigned int crtcs;
 	unsigned int i;
 	unsigned int i;
 	int ret;
 	int ret;
 
 
-	planes->alpha =
-		drm_property_create_range(rcdu->ddev, 0, "alpha", 0, 255);
-	if (planes->alpha == NULL)
-		return -ENOMEM;
-
-	/* The color key is expressed as an RGB888 triplet stored in a 32-bit
-	 * integer in XRGB8888 format. Bit 24 is used as a flag to disable (0)
-	 * or enable source color keying (1).
-	 */
-	planes->colorkey =
-		drm_property_create_range(rcdu->ddev, 0, "colorkey",
-					  0, 0x01ffffff);
-	if (planes->colorkey == NULL)
-		return -ENOMEM;
-
-	planes->zpos =
-		drm_property_create_range(rcdu->ddev, 0, "zpos", 1, 7);
-	if (planes->zpos == NULL)
-		return -ENOMEM;
-
-	 /* Create one primary plane per in this group CRTC and seven overlay
+	 /* Create one primary plane per CRTC in this group and seven overlay
 	  * planes.
 	  * planes.
 	  */
 	  */
-	num_crtcs = min(rcdu->num_crtcs - 2 * rgrp->index, 2U);
-	num_planes = num_crtcs + 7;
+	num_planes = rgrp->num_crtcs + 7;
 
 
 	crtcs = ((1 << rcdu->num_crtcs) - 1) & (3 << (2 * rgrp->index));
 	crtcs = ((1 << rcdu->num_crtcs) - 1) & (3 << (2 * rgrp->index));
 
 
 	for (i = 0; i < num_planes; ++i) {
 	for (i = 0; i < num_planes; ++i) {
-		enum drm_plane_type type = i < num_crtcs
+		enum drm_plane_type type = i < rgrp->num_crtcs
 					 ? DRM_PLANE_TYPE_PRIMARY
 					 ? DRM_PLANE_TYPE_PRIMARY
 					 : DRM_PLANE_TYPE_OVERLAY;
 					 : DRM_PLANE_TYPE_OVERLAY;
-		struct rcar_du_plane *plane = &planes->planes[i];
+		struct rcar_du_plane *plane = &rgrp->planes[i];
 
 
 		plane->group = rgrp;
 		plane->group = rgrp;
 
 
@@ -448,12 +423,12 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp)
 			continue;
 			continue;
 
 
 		drm_object_attach_property(&plane->plane.base,
 		drm_object_attach_property(&plane->plane.base,
-					   planes->alpha, 255);
+					   rcdu->props.alpha, 255);
 		drm_object_attach_property(&plane->plane.base,
 		drm_object_attach_property(&plane->plane.base,
-					   planes->colorkey,
+					   rcdu->props.colorkey,
 					   RCAR_DU_COLORKEY_NONE);
 					   RCAR_DU_COLORKEY_NONE);
 		drm_object_attach_property(&plane->plane.base,
 		drm_object_attach_property(&plane->plane.base,
-					   planes->zpos, 1);
+					   rcdu->props.zpos, 1);
 	}
 	}
 
 
 	return 0;
 	return 0;

+ 11 - 10
drivers/gpu/drm/rcar-du/rcar_du_plane.h

@@ -38,19 +38,20 @@ static inline struct rcar_du_plane *to_rcar_plane(struct drm_plane *plane)
 	return container_of(plane, struct rcar_du_plane, plane);
 	return container_of(plane, struct rcar_du_plane, plane);
 }
 }
 
 
-struct rcar_du_planes {
-	struct rcar_du_plane planes[RCAR_DU_NUM_KMS_PLANES];
-
-	struct drm_property *alpha;
-	struct drm_property *colorkey;
-	struct drm_property *zpos;
-};
-
+/**
+ * struct rcar_du_plane_state - Driver-specific plane state
+ * @state: base DRM plane state
+ * @format: information about the pixel format used by the plane
+ * @hwindex: 0-based hardware plane index, -1 means unused
+ * @alpha: value of the plane alpha property
+ * @colorkey: value of the plane colorkey property
+ * @zpos: value of the plane zpos property
+ */
 struct rcar_du_plane_state {
 struct rcar_du_plane_state {
 	struct drm_plane_state state;
 	struct drm_plane_state state;
 
 
 	const struct rcar_du_format_info *format;
 	const struct rcar_du_format_info *format;
-	int hwindex;		/* 0-based, -1 means unused */
+	int hwindex;
 
 
 	unsigned int alpha;
 	unsigned int alpha;
 	unsigned int colorkey;
 	unsigned int colorkey;
@@ -58,7 +59,7 @@ struct rcar_du_plane_state {
 };
 };
 
 
 static inline struct rcar_du_plane_state *
 static inline struct rcar_du_plane_state *
-to_rcar_du_plane_state(struct drm_plane_state *state)
+to_rcar_plane_state(struct drm_plane_state *state)
 {
 {
 	return container_of(state, struct rcar_du_plane_state, state);
 	return container_of(state, struct rcar_du_plane_state, state);
 }
 }