return to_rcar_du_plane_state(plane->plane.state)->zpos;
}
-static void rcar_du_crtc_update_planes(struct drm_crtc *crtc)
+static const struct rcar_du_format_info *
+plane_format(struct rcar_du_plane *plane)
+{
+ return to_rcar_du_plane_state(plane->plane.state)->format;
+}
+
+static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
{
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES];
unsigned int num_planes = 0;
unsigned int prio = 0;
}
planes[j] = plane;
- prio += plane->format->planes * 4;
+ prio += plane_format(plane)->planes * 4;
}
for (i = 0; i < num_planes; ++i) {
struct rcar_du_plane *plane = planes[i];
- unsigned int index = plane->hwindex;
+ struct drm_plane_state *state = plane->plane.state;
+ unsigned int index = to_rcar_du_plane_state(state)->hwindex;
prio -= 4;
dspr |= (index + 1) << prio;
dptsr |= DPTSR_PnDK(index) | DPTSR_PnTS(index);
- if (plane->format->planes == 2) {
+ if (plane_format(plane)->planes == 2) {
index = (index + 1) % 8;
prio -= 4;
* with superposition controller 2.
*/
if (rcrtc->index % 2) {
- u32 value = rcar_du_group_read(rcrtc->group, DPTSR);
-
/* 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
* split, or through a module parameter). Flicker would then
* occur only if we need to break the pre-association.
*/
- if (value != dptsr) {
+ 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);
}
rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR,
{
struct drm_crtc *crtc = &rcrtc->crtc;
bool interlaced;
- unsigned int i;
if (rcrtc->started)
return;
rcar_du_crtc_set_display_timing(rcrtc);
rcar_du_group_set_routing(rcrtc->group);
- /* FIXME: Commit the planes state. This is required here as the CRTC can
- * be started from the system resume handler, which don't go
- * through .atomic_plane_update() and .atomic_flush() to commit plane
- * state. Additionally, given that the plane state atomic commit occurs
- * between CRTC disable and enable, the hardware state could also be
- * lost due to runtime PM, requiring a full commit here. This will be
- * fixed later after switching to atomic updates completely.
- */
- mutex_lock(&rcrtc->group->planes.lock);
- rcar_du_crtc_update_planes(crtc);
- mutex_unlock(&rcrtc->group->planes.lock);
-
- for (i = 0; i < ARRAY_SIZE(rcrtc->group->planes.planes); ++i) {
- struct rcar_du_plane *plane = &rcrtc->group->planes.planes[i];
-
- if (plane->plane.state->crtc != crtc)
- continue;
-
- rcar_du_plane_setup(plane);
- }
+ /* Start with all planes disabled. */
+ rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
/* Select master sync mode. This enables display operation in master
* sync mode (with the HSYNC and VSYNC signals configured as outputs and
void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc)
{
+ unsigned int i;
+
if (!rcrtc->enabled)
return;
rcar_du_crtc_get(rcrtc);
rcar_du_crtc_start(rcrtc);
+
+ /* 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];
+
+ if (plane->plane.state->crtc != &rcrtc->crtc)
+ continue;
+
+ rcar_du_plane_setup(plane);
+ }
+
+ rcar_du_crtc_update_planes(rcrtc);
}
/* -----------------------------------------------------------------------------
struct drm_device *dev = rcrtc->crtc.dev;
unsigned long flags;
- /* We need to access the hardware during atomic update, acquire a
- * reference to the CRTC.
- */
- rcar_du_crtc_get(rcrtc);
-
if (event) {
- event->pipe = rcrtc->index;
-
WARN_ON(drm_crtc_vblank_get(crtc) != 0);
spin_lock_irqsave(&dev->event_lock, flags);
{
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
- /* We're done, apply the configuration and drop the reference acquired
- * in .atomic_begin().
- */
- mutex_lock(&rcrtc->group->planes.lock);
- rcar_du_crtc_update_planes(crtc);
- mutex_unlock(&rcrtc->group->planes.lock);
-
- rcar_du_crtc_put(rcrtc);
+ rcar_du_crtc_update_planes(rcrtc);
}
static const struct drm_crtc_helper_funcs crtc_helper_funcs = {