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

Reply via email to