diff options
Diffstat (limited to 'drivers/gpu/drm/rockchip/analogix_dp-rockchip.c')
-rw-r--r-- | drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 116 |
1 files changed, 60 insertions, 56 deletions
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 9aae3d8e99ef..f38f5e113c6b 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -16,19 +16,18 @@ #include <linux/reset.h> #include <linux/clk.h> -#include <drm/drmP.h> -#include <drm/drm_dp_helper.h> -#include <drm/drm_of.h> -#include <drm/drm_panel.h> -#include <drm/drm_probe_helper.h> - #include <video/of_videomode.h> #include <video/videomode.h> +#include <drm/drm_atomic.h> +#include <drm/drm_atomic_helper.h> #include <drm/bridge/analogix_dp.h> +#include <drm/drm_dp_helper.h> +#include <drm/drm_of.h> +#include <drm/drm_panel.h> +#include <drm/drm_probe_helper.h> #include "rockchip_drm_drv.h" -#include "rockchip_drm_psr.h" #include "rockchip_drm_vop.h" #define RK3288_GRF_SOC_CON6 0x25c @@ -73,29 +72,6 @@ struct rockchip_dp_device { struct analogix_dp_plat_data plat_data; }; -static int analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled) -{ - struct rockchip_dp_device *dp = to_dp(encoder); - int ret; - - if (!analogix_dp_psr_enabled(dp->adp)) - return 0; - - DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit"); - - ret = rockchip_drm_wait_vact_end(dp->encoder.crtc, - PSR_WAIT_LINE_FLAG_TIMEOUT_MS); - if (ret) { - DRM_DEV_ERROR(dp->dev, "line flag interrupt did not arrive\n"); - return -ETIMEDOUT; - } - - if (enabled) - return analogix_dp_enable_psr(dp->adp); - else - return analogix_dp_disable_psr(dp->adp); -} - static int rockchip_dp_pre_init(struct rockchip_dp_device *dp) { reset_control_assert(dp->rst); @@ -126,21 +102,9 @@ static int rockchip_dp_poweron_start(struct analogix_dp_plat_data *plat_data) return ret; } -static int rockchip_dp_poweron_end(struct analogix_dp_plat_data *plat_data) -{ - struct rockchip_dp_device *dp = to_dp(plat_data); - - return rockchip_drm_psr_inhibit_put(&dp->encoder); -} - static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data) { struct rockchip_dp_device *dp = to_dp(plat_data); - int ret; - - ret = rockchip_drm_psr_inhibit_get(&dp->encoder); - if (ret != 0) - return ret; clk_disable_unprepare(dp->pclk); @@ -180,12 +144,42 @@ static void rockchip_dp_drm_encoder_mode_set(struct drm_encoder *encoder, /* do nothing */ } -static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder) +static +struct drm_crtc *rockchip_dp_drm_get_new_crtc(struct drm_encoder *encoder, + struct drm_atomic_state *state) +{ + struct drm_connector *connector; + struct drm_connector_state *conn_state; + + connector = drm_atomic_get_new_connector_for_encoder(state, encoder); + if (!connector) + return NULL; + + conn_state = drm_atomic_get_new_connector_state(state, connector); + if (!conn_state) + return NULL; + + return conn_state->crtc; +} + +static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder, + struct drm_atomic_state *state) { struct rockchip_dp_device *dp = to_dp(encoder); + struct drm_crtc *crtc; + struct drm_crtc_state *old_crtc_state; int ret; u32 val; + crtc = rockchip_dp_drm_get_new_crtc(encoder, state); + if (!crtc) + return; + + old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); + /* Coming back from self refresh, nothing to do */ + if (old_crtc_state && old_crtc_state->self_refresh_active) + return; + ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder); if (ret < 0) return; @@ -210,9 +204,27 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder) clk_disable_unprepare(dp->grfclk); } -static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder) +static void rockchip_dp_drm_encoder_disable(struct drm_encoder *encoder, + struct drm_atomic_state *state) { - /* do nothing */ + struct rockchip_dp_device *dp = to_dp(encoder); + struct drm_crtc *crtc; + struct drm_crtc_state *new_crtc_state = NULL; + int ret; + + crtc = rockchip_dp_drm_get_new_crtc(encoder, state); + /* No crtc means we're doing a full shutdown */ + if (!crtc) + return; + + new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + /* If we're not entering self-refresh, no need to wait for vact */ + if (!new_crtc_state || !new_crtc_state->self_refresh_active) + return; + + ret = rockchip_drm_wait_vact_end(crtc, PSR_WAIT_LINE_FLAG_TIMEOUT_MS); + if (ret) + DRM_DEV_ERROR(dp->dev, "line flag irq timed out\n"); } static int @@ -241,8 +253,8 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder, static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = { .mode_fixup = rockchip_dp_drm_encoder_mode_fixup, .mode_set = rockchip_dp_drm_encoder_mode_set, - .enable = rockchip_dp_drm_encoder_enable, - .disable = rockchip_dp_drm_encoder_nop, + .atomic_enable = rockchip_dp_drm_encoder_enable, + .atomic_disable = rockchip_dp_drm_encoder_disable, .atomic_check = rockchip_dp_drm_encoder_atomic_check, }; @@ -334,23 +346,16 @@ static int rockchip_dp_bind(struct device *dev, struct device *master, dp->plat_data.dev_type = dp->data->chip_type; dp->plat_data.power_on_start = rockchip_dp_poweron_start; - dp->plat_data.power_on_end = rockchip_dp_poweron_end; dp->plat_data.power_off = rockchip_dp_powerdown; dp->plat_data.get_modes = rockchip_dp_get_modes; - ret = rockchip_drm_psr_register(&dp->encoder, analogix_dp_psr_set); - if (ret < 0) - goto err_cleanup_encoder; - dp->adp = analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data); if (IS_ERR(dp->adp)) { ret = PTR_ERR(dp->adp); - goto err_unreg_psr; + goto err_cleanup_encoder; } return 0; -err_unreg_psr: - rockchip_drm_psr_unregister(&dp->encoder); err_cleanup_encoder: dp->encoder.funcs->destroy(&dp->encoder); return ret; @@ -362,7 +367,6 @@ static void rockchip_dp_unbind(struct device *dev, struct device *master, struct rockchip_dp_device *dp = dev_get_drvdata(dev); analogix_dp_unbind(dp->adp); - rockchip_drm_psr_unregister(&dp->encoder); dp->encoder.funcs->destroy(&dp->encoder); dp->adp = ERR_PTR(-ENODEV); |