Commit 792c3132 authored by Maxime Ripard's avatar Maxime Ripard

drm/vc4: encoder: Add finer-grained encoder callbacks

In the BCM2711, the setup of the HVS, pixelvalve and HDMI controller
requires very precise ordering and timing that the regular atomic callbacks
don't provide. Let's add new callbacks on top of the regular ones to be
able to split the configuration as needed.
Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
Tested-by: default avatarChanwoo Choi <cw00.choi@samsung.com>
Tested-by: default avatarHoegeun Kwon <hoegeun.kwon@samsung.com>
Tested-by: default avatarStefan Wahren <stefan.wahren@i2se.com>
Reviewed-by: default avatarDave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1dd78efe8f29add73c97d0148cfd4ec8e34aaf22.1599120059.git-series.maxime@cerno.tech
parent 4b72b10a
...@@ -389,6 +389,8 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc, ...@@ -389,6 +389,8 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
int ret; int ret;
require_hvs_enabled(dev); require_hvs_enabled(dev);
...@@ -401,10 +403,16 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc, ...@@ -401,10 +403,16 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1); ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n"); WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
if (vc4_encoder->post_crtc_disable)
vc4_encoder->post_crtc_disable(encoder);
CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN); CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN);
vc4_hvs_atomic_disable(crtc, old_state); vc4_hvs_atomic_disable(crtc, old_state);
if (vc4_encoder->post_crtc_powerdown)
vc4_encoder->post_crtc_powerdown(encoder);
/* /*
* Make sure we issue a vblank event after disabling the CRTC if * Make sure we issue a vblank event after disabling the CRTC if
* someone was waiting it. * someone was waiting it.
...@@ -424,6 +432,8 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc, ...@@ -424,6 +432,8 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
require_hvs_enabled(dev); require_hvs_enabled(dev);
...@@ -434,15 +444,24 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc, ...@@ -434,15 +444,24 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
vc4_hvs_atomic_enable(crtc, old_state); vc4_hvs_atomic_enable(crtc, old_state);
if (vc4_encoder->pre_crtc_configure)
vc4_encoder->pre_crtc_configure(encoder);
vc4_crtc_config_pv(crtc); vc4_crtc_config_pv(crtc);
CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN); CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
if (vc4_encoder->pre_crtc_enable)
vc4_encoder->pre_crtc_enable(encoder);
/* When feeding the transposer block the pixelvalve is unneeded and /* When feeding the transposer block the pixelvalve is unneeded and
* should not be enabled. * should not be enabled.
*/ */
CRTC_WRITE(PV_V_CONTROL, CRTC_WRITE(PV_V_CONTROL,
CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN); CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
if (vc4_encoder->post_crtc_enable)
vc4_encoder->post_crtc_enable(encoder);
} }
static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc, static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc,
......
...@@ -439,6 +439,13 @@ struct vc4_encoder { ...@@ -439,6 +439,13 @@ struct vc4_encoder {
struct drm_encoder base; struct drm_encoder base;
enum vc4_encoder_type type; enum vc4_encoder_type type;
u32 clock_select; u32 clock_select;
void (*pre_crtc_configure)(struct drm_encoder *encoder);
void (*pre_crtc_enable)(struct drm_encoder *encoder);
void (*post_crtc_enable)(struct drm_encoder *encoder);
void (*post_crtc_disable)(struct drm_encoder *encoder);
void (*post_crtc_powerdown)(struct drm_encoder *encoder);
}; };
static inline struct vc4_encoder * static inline struct vc4_encoder *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment