Skip to content

Commit 7ee54bf

Browse files
committed
drm/vc4: hvs: Force modeset on gamma lut change
The HVS Gamma block can only be updated when idle, so we need to disable the HVS channel when the gamma property is set in an atomic commit. Since the pixelvalve cannot have its assigned channel without stalling unless it's disabled as well, in our case that means forcing a full disable / enable cycle on the pipeline. Signed-off-by: Maxime Ripard <[email protected]>
1 parent 14b5e9c commit 7ee54bf

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

drivers/gpu/drm/vc4/vc4_crtc.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,23 @@ struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc,
292292
return NULL;
293293
}
294294

295+
#define drm_for_each_connector_mask(connector, dev, connector_mask) \
296+
list_for_each_entry((connector), &(dev)->mode_config.connector_list, head) \
297+
for_each_if ((connector_mask) & drm_connector_mask(connector))
298+
299+
struct drm_connector *vc4_get_crtc_connector(struct drm_crtc *crtc,
300+
struct drm_crtc_state *state)
301+
{
302+
struct drm_connector *connector;
303+
304+
WARN_ON(hweight32(state->connector_mask) > 1);
305+
306+
drm_for_each_connector_mask(connector, crtc->dev, state->connector_mask)
307+
return connector;
308+
309+
return NULL;
310+
}
311+
295312
static void vc4_crtc_pixelvalve_reset(struct drm_crtc *crtc)
296313
{
297314
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);

drivers/gpu/drm/vc4/vc4_drv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,9 @@ vc4_crtc_to_vc4_pv_data(const struct vc4_crtc *crtc)
540540
return container_of(data, struct vc4_pv_data, base);
541541
}
542542

543+
struct drm_connector *vc4_get_crtc_connector(struct drm_crtc *crtc,
544+
struct drm_crtc_state *state);
545+
543546
struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc,
544547
struct drm_crtc_state *state);
545548

drivers/gpu/drm/vc4/vc4_hvs.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,36 @@ void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int chan)
519519
SCALER_DISPSTATX_EMPTY);
520520
}
521521

522+
static int vc4_hvs_gamma_check(struct drm_crtc *crtc,
523+
struct drm_atomic_state *state)
524+
{
525+
struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
526+
struct drm_connector_state *conn_state;
527+
struct drm_connector *connector;
528+
struct drm_device *dev = crtc->dev;
529+
struct vc4_dev *vc4 = to_vc4_dev(dev);
530+
531+
if (!vc4->hvs->hvs5)
532+
return 0;
533+
534+
if (!crtc_state->color_mgmt_changed)
535+
return 0;
536+
537+
connector = vc4_get_crtc_connector(crtc, crtc_state);
538+
if (!connector)
539+
return -EINVAL;
540+
541+
if (!(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))
542+
return 0;
543+
544+
conn_state = drm_atomic_get_connector_state(state, connector);
545+
if (!conn_state)
546+
return -EINVAL;
547+
548+
crtc_state->mode_changed = true;
549+
return 0;
550+
}
551+
522552
int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
523553
{
524554
struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
@@ -549,7 +579,7 @@ int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
549579
if (ret)
550580
return ret;
551581

552-
return 0;
582+
return vc4_hvs_gamma_check(crtc, state);
553583
}
554584

555585
static void vc4_hvs_update_dlist(struct drm_crtc *crtc)

0 commit comments

Comments
 (0)