Merge tag 'drm-misc-next-2022-09-09' of git://anongit.freedesktop.org/drm/drm-misc...
[linux-block.git] / drivers / gpu / drm / sun4i / sun4i_tv.c
index 94883abe0dfdb2b3f7e2f00987973cb0548e4b10..c65f0a89b6b0603035492bf6ce9c7764beb6351d 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/regmap.h>
 #include <linux/reset.h>
 
+#include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_of.h>
 #include <drm/drm_panel.h>
@@ -275,13 +276,6 @@ drm_encoder_to_sun4i_tv(struct drm_encoder *encoder)
                            encoder);
 }
 
-static inline struct sun4i_tv *
-drm_connector_to_sun4i_tv(struct drm_connector *connector)
-{
-       return container_of(connector, struct sun4i_tv,
-                           connector);
-}
-
 /*
  * FIXME: If only the drm_display_mode private field was usable, this
  * could go away...
@@ -339,7 +333,8 @@ static void sun4i_tv_mode_to_drm_mode(const struct tv_mode *tv_mode,
        mode->vtotal = mode->vsync_end  + tv_mode->vback_porch;
 }
 
-static void sun4i_tv_disable(struct drm_encoder *encoder)
+static void sun4i_tv_disable(struct drm_encoder *encoder,
+                           struct drm_atomic_state *state)
 {
        struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
        struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
@@ -353,27 +348,18 @@ static void sun4i_tv_disable(struct drm_encoder *encoder)
        sunxi_engine_disable_color_correction(crtc->engine);
 }
 
-static void sun4i_tv_enable(struct drm_encoder *encoder)
+static void sun4i_tv_enable(struct drm_encoder *encoder,
+                           struct drm_atomic_state *state)
 {
        struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
        struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
+       struct drm_crtc_state *crtc_state =
+               drm_atomic_get_new_crtc_state(state, encoder->crtc);
+       struct drm_display_mode *mode = &crtc_state->mode;
+       const struct tv_mode *tv_mode = sun4i_tv_find_tv_by_mode(mode);
 
        DRM_DEBUG_DRIVER("Enabling the TV Output\n");
 
-       sunxi_engine_apply_color_correction(crtc->engine);
-
-       regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
-                          SUN4I_TVE_EN_ENABLE,
-                          SUN4I_TVE_EN_ENABLE);
-}
-
-static void sun4i_tv_mode_set(struct drm_encoder *encoder,
-                             struct drm_display_mode *mode,
-                             struct drm_display_mode *adjusted_mode)
-{
-       struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
-       const struct tv_mode *tv_mode = sun4i_tv_find_tv_by_mode(mode);
-
        /* Enable and map the DAC to the output */
        regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
                           SUN4I_TVE_EN_DAC_MAP_MASK,
@@ -466,12 +452,17 @@ static void sun4i_tv_mode_set(struct drm_encoder *encoder,
                      SUN4I_TVE_RESYNC_FIELD : 0));
 
        regmap_write(tv->regs, SUN4I_TVE_SLAVE_REG, 0);
+
+       sunxi_engine_apply_color_correction(crtc->engine);
+
+       regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
+                          SUN4I_TVE_EN_ENABLE,
+                          SUN4I_TVE_EN_ENABLE);
 }
 
 static const struct drm_encoder_helper_funcs sun4i_tv_helper_funcs = {
-       .disable        = sun4i_tv_disable,
-       .enable         = sun4i_tv_enable,
-       .mode_set       = sun4i_tv_mode_set,
+       .atomic_disable = sun4i_tv_disable,
+       .atomic_enable  = sun4i_tv_enable,
 };
 
 static int sun4i_tv_comp_get_modes(struct drm_connector *connector)
@@ -497,27 +488,13 @@ static int sun4i_tv_comp_get_modes(struct drm_connector *connector)
        return i;
 }
 
-static int sun4i_tv_comp_mode_valid(struct drm_connector *connector,
-                                   struct drm_display_mode *mode)
-{
-       /* TODO */
-       return MODE_OK;
-}
-
 static const struct drm_connector_helper_funcs sun4i_tv_comp_connector_helper_funcs = {
        .get_modes      = sun4i_tv_comp_get_modes,
-       .mode_valid     = sun4i_tv_comp_mode_valid,
 };
 
-static void
-sun4i_tv_comp_connector_destroy(struct drm_connector *connector)
-{
-       drm_connector_cleanup(connector);
-}
-
 static const struct drm_connector_funcs sun4i_tv_comp_connector_funcs = {
        .fill_modes             = drm_helper_probe_single_connector_modes,
-       .destroy                = sun4i_tv_comp_connector_destroy,
+       .destroy                = drm_connector_cleanup,
        .reset                  = drm_atomic_helper_connector_reset,
        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
        .atomic_destroy_state   = drm_atomic_helper_connector_destroy_state,
@@ -604,7 +581,7 @@ static int sun4i_tv_bind(struct device *dev, struct device *master,
        if (ret) {
                dev_err(dev,
                        "Couldn't initialise the Composite connector\n");
-               goto err_cleanup_connector;
+               goto err_cleanup_encoder;
        }
        tv->connector.interlace_allowed = true;
 
@@ -612,7 +589,7 @@ static int sun4i_tv_bind(struct device *dev, struct device *master,
 
        return 0;
 
-err_cleanup_connector:
+err_cleanup_encoder:
        drm_encoder_cleanup(&tv->encoder);
 err_disable_clk:
        clk_disable_unprepare(tv->clk);
@@ -629,6 +606,7 @@ static void sun4i_tv_unbind(struct device *dev, struct device *master,
        drm_connector_cleanup(&tv->connector);
        drm_encoder_cleanup(&tv->encoder);
        clk_disable_unprepare(tv->clk);
+       reset_control_assert(tv->reset);
 }
 
 static const struct component_ops sun4i_tv_ops = {