The dispc hardware needs to be put in a known-good state when the driver starts. This was previously done unconditionally during dispc_init(), but it should only be performed on the reset path when implementing state readout.
Rename dispc_init_hw() to dispc_reset_hw(), export it, and remove the call from dispc_init(). Implement &drm_mode_config_funcs.hw_reset through tidss_hw_reset() which performs the dispc soft reset and then calls drm_mode_config_helper_hw_reset() to reset the rest of the objects. Signed-off-by: Maxime Ripard <[email protected]> --- drivers/gpu/drm/tidss/tidss_dispc.c | 6 +----- drivers/gpu/drm/tidss/tidss_dispc.h | 1 + drivers/gpu/drm/tidss/tidss_kms.c | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c index a19b74b0ca30..fdd3b166c118 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -2907,11 +2907,11 @@ static int dispc_softreset(struct dispc_device *dispc) } return 0; } -static int dispc_init_hw(struct dispc_device *dispc) +int dispc_reset_hw(struct dispc_device *dispc) { struct device *dev = dispc->dev; int ret; ret = pm_runtime_set_active(dev); @@ -3057,13 +3057,9 @@ int dispc_init(struct tidss_device *tidss) dev_dbg(dev, "DSS fclk %lu Hz\n", clk_get_rate(dispc->fclk)); of_property_read_u32(dispc->dev->of_node, "max-memory-bandwidth", &dispc->memory_bandwidth_limit); - r = dispc_init_hw(dispc); - if (r) - return r; - tidss->dispc = dispc; return 0; } diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/tidss_dispc.h index 2183254f1ab7..e51a2088b40c 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.h +++ b/drivers/gpu/drm/tidss/tidss_dispc.h @@ -143,9 +143,10 @@ void dispc_plane_setup(struct dispc_device *dispc, u32 hw_plane, struct drm_plane_state *state, u32 hw_videoport); void dispc_plane_enable(struct dispc_device *dispc, u32 hw_plane, bool enable); const u32 *dispc_plane_formats(struct dispc_device *dispc, unsigned int *len); +int dispc_reset_hw(struct dispc_device *dispc); int dispc_init(struct tidss_device *tidss); void dispc_remove(struct tidss_device *tidss); #endif diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c index 70c14c3be10d..3b97c08c4f71 100644 --- a/drivers/gpu/drm/tidss/tidss_kms.c +++ b/drivers/gpu/drm/tidss/tidss_kms.c @@ -8,10 +8,11 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_of.h> #include <drm/drm_panel.h> +#include <drm/drm_print.h> #include <drm/drm_vblank.h> #include "tidss_crtc.h" #include "tidss_dispc.h" #include "tidss_drv.h" @@ -114,14 +115,27 @@ static int tidss_atomic_check(struct drm_device *ddev, } return 0; } +static void tidss_hw_reset(struct drm_device *dev) +{ + struct tidss_device *tidss = to_tidss(dev); + int ret; + + ret = dispc_reset_hw(tidss->dispc); + if (ret) + drm_warn(dev, "Couldn't reset dispc"); + + drm_mode_config_helper_hw_reset(dev); +} + static const struct drm_mode_config_funcs mode_config_funcs = { .fb_create = drm_gem_fb_create, .atomic_check = tidss_atomic_check, .atomic_commit = drm_atomic_helper_commit, + .hw_reset = tidss_hw_reset, }; static int tidss_dispc_modeset_init(struct tidss_device *tidss) { struct device *dev = tidss->dev; -- 2.55.0
