1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter.git synced 2025-02-15 04:42:02 +00:00
openmptcprouter/6.1/target/linux/bcm27xx/patches-6.1/0014-drm-vc4-hvs-Force-modeset-on-gamma-lut-change.patch

114 lines
3.7 KiB
Diff

From c6186375d4b403bc6b078e317ef65e196dc38ce8 Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime@cerno.tech>
Date: Mon, 14 Jun 2021 15:28:30 +0200
Subject: [PATCH 014/726] 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 halted 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 <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 17 +++++++++++++++++
drivers/gpu/drm/vc4/vc4_drv.h | 3 +++
drivers/gpu/drm/vc4/vc4_hvs.c | 32 +++++++++++++++++++++++++++++++-
3 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 1e22d13768a0..187508545053 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -293,6 +293,23 @@ struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc,
return NULL;
}
+#define drm_for_each_connector_mask(connector, dev, connector_mask) \
+ list_for_each_entry((connector), &(dev)->mode_config.connector_list, head) \
+ for_each_if ((connector_mask) & drm_connector_mask(connector))
+
+struct drm_connector *vc4_get_crtc_connector(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+{
+ struct drm_connector *connector;
+
+ WARN_ON(hweight32(state->connector_mask) > 1);
+
+ drm_for_each_connector_mask(connector, crtc->dev, state->connector_mask)
+ return connector;
+
+ return NULL;
+}
+
static void vc4_crtc_pixelvalve_reset(struct drm_crtc *crtc)
{
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 71a07c838c35..d54182f995ef 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -568,6 +568,9 @@ vc4_crtc_to_vc4_pv_data(const struct vc4_crtc *crtc)
return container_of(data, struct vc4_pv_data, base);
}
+struct drm_connector *vc4_get_crtc_connector(struct drm_crtc *crtc,
+ struct drm_crtc_state *state);
+
struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc,
struct drm_crtc_state *state);
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index 5374502bce37..950d719a126b 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -594,6 +594,36 @@ void vc4_hvs_stop_channel(struct vc4_hvs *hvs, unsigned int chan)
drm_dev_exit(idx);
}
+static int vc4_hvs_gamma_check(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+ struct drm_connector_state *conn_state;
+ struct drm_connector *connector;
+ struct drm_device *dev = crtc->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+ if (!vc4->is_vc5)
+ return 0;
+
+ if (!crtc_state->color_mgmt_changed)
+ return 0;
+
+ connector = vc4_get_crtc_connector(crtc, crtc_state);
+ if (!connector)
+ return -EINVAL;
+
+ if (!(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))
+ return 0;
+
+ conn_state = drm_atomic_get_connector_state(state, connector);
+ if (!conn_state)
+ return -EINVAL;
+
+ crtc_state->mode_changed = true;
+ return 0;
+}
+
int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
{
struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
@@ -624,7 +654,7 @@ int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
if (ret)
return ret;
- return 0;
+ return vc4_hvs_gamma_check(crtc, state);
}
static void vc4_hvs_install_dlist(struct drm_crtc *crtc)
--
2.33.1