mirror of https://gitee.com/openkylin/linux.git
drm/vc4: hdmi: Store pixel frequency in the connector state
The pixel rate is for now quite simple to compute, but with more features (30 and 36 bits output, YUV output, etc.) will depend on a bunch of connectors properties. Let's store the rate we have to run the pixel clock at in our custom connector state, and compute it in atomic_check. Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Link: https://patchwork.freedesktop.org/patch/msgid/20201215154243.540115-7-maxime@cerno.tech
This commit is contained in:
parent
fbe7271e47
commit
f623746f74
|
@ -198,6 +198,7 @@ vc4_hdmi_connector_duplicate_state(struct drm_connector *connector)
|
|||
if (!new_state)
|
||||
return NULL;
|
||||
|
||||
new_state->pixel_rate = vc4_state->pixel_rate;
|
||||
__drm_atomic_helper_connector_duplicate_state(connector, &new_state->base);
|
||||
|
||||
return &new_state->base;
|
||||
|
@ -618,9 +619,29 @@ static void vc4_hdmi_recenter_fifo(struct vc4_hdmi *vc4_hdmi)
|
|||
"VC4_HDMI_FIFO_CTL_RECENTER_DONE");
|
||||
}
|
||||
|
||||
static struct drm_connector_state *
|
||||
vc4_hdmi_encoder_get_connector_state(struct drm_encoder *encoder,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_connector_state *conn_state;
|
||||
struct drm_connector *connector;
|
||||
unsigned int i;
|
||||
|
||||
for_each_new_connector_in_state(state, connector, conn_state, i) {
|
||||
if (conn_state->best_encoder == encoder)
|
||||
return conn_state;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_connector_state *conn_state =
|
||||
vc4_hdmi_encoder_get_connector_state(encoder, state);
|
||||
struct vc4_hdmi_connector_state *vc4_conn_state =
|
||||
conn_state_to_vc4_hdmi_conn_state(conn_state);
|
||||
struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
|
||||
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
|
||||
unsigned long pixel_rate, hsm_rate;
|
||||
|
@ -632,7 +653,7 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
|
|||
return;
|
||||
}
|
||||
|
||||
pixel_rate = mode->clock * 1000 * ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1);
|
||||
pixel_rate = vc4_conn_state->pixel_rate;
|
||||
ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to set pixel clock rate: %d\n", ret);
|
||||
|
@ -804,6 +825,7 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
|
|||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct vc4_hdmi_connector_state *vc4_state = conn_state_to_vc4_hdmi_conn_state(conn_state);
|
||||
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
|
||||
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
|
||||
unsigned long long pixel_rate = mode->clock * 1000;
|
||||
|
@ -834,6 +856,8 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
|
|||
if (pixel_rate > vc4_hdmi->variant->max_pixel_clock)
|
||||
return -EINVAL;
|
||||
|
||||
vc4_state->pixel_rate = pixel_rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -182,6 +182,7 @@ encoder_to_vc4_hdmi(struct drm_encoder *encoder)
|
|||
|
||||
struct vc4_hdmi_connector_state {
|
||||
struct drm_connector_state base;
|
||||
unsigned long long pixel_rate;
|
||||
};
|
||||
|
||||
static inline struct vc4_hdmi_connector_state *
|
||||
|
|
Loading…
Reference in New Issue