diff options
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun4i_tv.c')
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_tv.c | 64 |
1 files changed, 21 insertions, 43 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c index 94883abe0dfd..c65f0a89b6b0 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tv.c +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c @@ -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 = { |