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: Maxime Ripard <maxime@cerno.tech>
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Tested-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1dd78efe8f29add73c97d0148cfd4ec8e34aaf22.1599120059.git-series.maxime@cerno.tech
This commit is contained in:
Maxime Ripard 2020-09-03 10:01:00 +02:00
parent 4b72b10a64
commit 792c3132bc
No known key found for this signature in database
GPG key ID: E3EF0D6F671851C5
2 changed files with 26 additions and 0 deletions

View file

@ -389,6 +389,8 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
{
struct drm_device *dev = crtc->dev;
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;
require_hvs_enabled(dev);
@ -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);
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);
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
* someone was waiting it.
@ -424,6 +432,8 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
{
struct drm_device *dev = crtc->dev;
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);
@ -434,15 +444,24 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
vc4_hvs_atomic_enable(crtc, old_state);
if (vc4_encoder->pre_crtc_configure)
vc4_encoder->pre_crtc_configure(encoder);
vc4_crtc_config_pv(crtc);
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
* should not be enabled.
*/
CRTC_WRITE(PV_V_CONTROL,
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,

View file

@ -439,6 +439,13 @@ struct vc4_encoder {
struct drm_encoder base;
enum vc4_encoder_type type;
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 *