The new HDMI connector infrastructure allows to remove some boilerplate,
especially to generate infoframes. Let's switch to it.

Signed-off-by: Maxime Ripard <mrip...@kernel.org>
---
 drivers/gpu/drm/rockchip/inno_hdmi.c | 86 ++++++++++++++++++------------------
 1 file changed, 42 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 0f3ec6eaf270..97fb4268bd7f 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -155,26 +155,29 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
        inno_hdmi_set_pwr_mode(hdmi, NORMAL);
 }
 
-static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi,
-                                   enum hdmi_infoframe_type type)
+static int inno_hdmi_disable_frame(struct drm_connector *connector,
+                                  enum hdmi_infoframe_type type)
 {
-       struct drm_connector *connector = &hdmi->connector;
+       struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
 
        if (type != HDMI_INFOFRAME_TYPE_AVI) {
                drm_err(connector->dev,
                        "Unsupported infoframe type: %u\n", type);
-               return;
+               return 0;
        }
 
        hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI);
+
+       return 0;
 }
 
-static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
-                                 union hdmi_infoframe *frame, enum 
hdmi_infoframe_type type)
+static int inno_hdmi_upload_frame(struct drm_connector *connector,
+                                 enum hdmi_infoframe_type type,
+                                 const u8 *buffer, size_t len)
 {
-       struct drm_connector *connector = &hdmi->connector;
+       struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
        u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
-       ssize_t rc, i;
+       ssize_t i;
 
        if (type != HDMI_INFOFRAME_TYPE_AVI) {
                drm_err(connector->dev,
@@ -182,38 +185,19 @@ static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
                return 0;
        }
 
-       inno_hdmi_disable_frame(hdmi, type);
+       inno_hdmi_disable_frame(connector, type);
 
-       rc = hdmi_infoframe_pack(frame, packed_frame,
-                                sizeof(packed_frame));
-       if (rc < 0)
-               return rc;
-
-       for (i = 0; i < rc; i++)
+       for (i = 0; i < len; i++)
                hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
                            packed_frame[i]);
 
        return 0;
 }
 
-static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
-                                     struct drm_display_mode *mode)
-{
-       union hdmi_infoframe frame;
-       int rc;
-
-       rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
-                                                     &hdmi->connector,
-                                                     mode);
-       if (rc) {
-               inno_hdmi_disable_frame(hdmi, HDMI_INFOFRAME_TYPE_AVI);
-               return rc;
-       }
-
-       frame.avi.colorspace = HDMI_COLORSPACE_RGB;
-
-       return inno_hdmi_upload_frame(hdmi, &frame, HDMI_INFOFRAME_TYPE_AVI);
-}
+static const struct drm_connector_hdmi_funcs inno_hdmi_hdmi_connector_funcs = {
+       .clear_infoframe        = inno_hdmi_disable_frame,
+       .write_infoframe        = inno_hdmi_upload_frame,
+};
 
 static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
 {
@@ -292,9 +276,12 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi 
*hdmi,
 }
 
 static int inno_hdmi_setup(struct inno_hdmi *hdmi,
-                          struct drm_display_mode *mode)
+                          struct drm_crtc_state *new_crtc_state,
+                          struct drm_connector_state *new_conn_state)
 {
-       struct drm_display_info *display = &hdmi->connector.display_info;
+       struct drm_connector *connector = &hdmi->connector;
+       struct drm_display_info *display = &connector->display_info;
+       struct drm_display_mode *mode = &new_crtc_state->adjusted_mode;
 
        /* Mute video and audio output */
        hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
@@ -308,8 +295,8 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
 
        inno_hdmi_config_video_csc(hdmi);
 
-       if (display->is_hdmi)
-               inno_hdmi_config_video_avi(hdmi, mode);
+       drm_atomic_helper_connector_hdmi_update_infoframes(connector,
+                                                          
new_conn_state->state);
 
        /*
         * When IP controller have configured to an accurate video
@@ -317,7 +304,7 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
         * DCLK_LCDC, so we need to init the TMDS rate to mode pixel
         * clock rate, and reconfigure the DDC clock.
         */
-       inno_hdmi_i2c_init(hdmi, mode->clock * 1000);
+       inno_hdmi_i2c_init(hdmi, new_conn_state->hdmi.tmds_char_rate);
 
        /* Unmute video and audio output */
        hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
@@ -341,7 +328,7 @@ static void inno_hdmi_encoder_enable(struct drm_encoder 
*encoder,
        if (WARN_ON(!crtc_state))
                return;
 
-       inno_hdmi_setup(hdmi, &crtc_state->adjusted_mode);
+       inno_hdmi_setup(hdmi, crtc_state, conn_state);
        inno_hdmi_set_pwr_mode(hdmi, NORMAL);
 }
 
@@ -407,6 +394,12 @@ inno_hdmi_probe_single_connector_modes(struct 
drm_connector *connector,
        return drm_helper_probe_single_connector_modes(connector, 1920, 1080);
 }
 
+static void inno_hdmi_connector_reset(struct drm_connector *connector)
+{
+       drm_atomic_helper_connector_reset(connector);
+       __drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
+}
+
 static void inno_hdmi_connector_destroy(struct drm_connector *connector)
 {
        drm_connector_unregister(connector);
@@ -417,12 +410,13 @@ static const struct drm_connector_funcs 
inno_hdmi_connector_funcs = {
        .fill_modes = inno_hdmi_probe_single_connector_modes,
        .detect = inno_hdmi_connector_detect,
        .destroy = inno_hdmi_connector_destroy,
-       .reset = drm_atomic_helper_connector_reset,
+       .reset = inno_hdmi_connector_reset,
        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = {
+       .atomic_check = drm_atomic_helper_connector_hdmi_check,
        .get_modes = inno_hdmi_connector_get_modes,
 };
 
@@ -449,10 +443,14 @@ static int inno_hdmi_register(struct drm_device *drm, 
struct inno_hdmi *hdmi)
 
        drm_connector_helper_add(&hdmi->connector,
                                 &inno_hdmi_connector_helper_funcs);
-       drm_connector_init_with_ddc(drm, &hdmi->connector,
-                                   &inno_hdmi_connector_funcs,
-                                   DRM_MODE_CONNECTOR_HDMIA,
-                                   hdmi->ddc);
+       drmm_connector_hdmi_init(drm, &hdmi->connector,
+                                "Rockchip", "Inno HDMI",
+                                &inno_hdmi_connector_funcs,
+                                &inno_hdmi_hdmi_connector_funcs,
+                                DRM_MODE_CONNECTOR_HDMIA,
+                                hdmi->ddc,
+                                BIT(HDMI_COLORSPACE_RGB),
+                                8);
 
        drm_connector_attach_encoder(&hdmi->connector, encoder);
 

-- 
2.43.0

Reply via email to