linux/drivers/gpu/drm/sun4i
Samuel Holland 215be713d0
drm/sun4i: dsi: Remove incorrect use of runtime PM
The driver currently uses runtime PM to perform some of the module
initialization and cleanup. This has three problems:

1) There is no Kconfig dependency on CONFIG_PM, so if runtime PM is
   disabled, the driver will not work at all, since the module will
   never be initialized.

2) The driver does not ensure that the device is suspended when
   sun6i_dsi_probe() fails or when sun6i_dsi_remove() is called. It
   simply disables runtime PM. From the docs of pm_runtime_disable():

      The device can be either active or suspended after its runtime PM
      has been disabled.

   And indeed, the device will likely still be active if sun6i_dsi_probe
   fails. For example, if the panel driver is not yet loaded, we have
   the following sequence:

   sun6i_dsi_probe()
      pm_runtime_enable()
      mipi_dsi_host_register()
         of_mipi_dsi_device_add(child)
            ...device_add()...
               __device_attach()
                 pm_runtime_get_sync(dev->parent) -> Causes resume
                 bus_for_each_drv()
                    __device_attach_driver() -> No match for panel
                 pm_runtime_put(dev->parent) -> Async idle request
      component_add()
         __component_add()
            try_to_bring_up_masters()
               try_to_bring_up_master()
                  sun4i_drv_bind()
                     component_bind_all()
                        component_bind()
                           sun6i_dsi_bind() -> Fails with -EPROBE_DEFER
      mipi_dsi_host_unregister()
      pm_runtime_disable()
         __pm_runtime_disable()
            __pm_runtime_barrier() -> Idle request is still pending
               cancel_work_sync()  -> DSI host is *not* suspended!

   Since the device is not suspended, the clock and regulator are never
   disabled. The imbalance causes a WARN at devres free time.

3) The driver relies on being suspended when sun6i_dsi_encoder_enable()
   is called. The resume callback has a comment that says:

      Some part of it can only be done once we get a number of
      lanes, see sun6i_dsi_inst_init

   And then part of the resume callback only runs if dsi->device is not
   NULL (that is, if sun6i_dsi_attach() has been called). However, as
   the above call graph shows, the resume callback is guaranteed to be
   called before sun6i_dsi_attach(); it is called before child devices
   get their drivers attached.

   Therefore, part of the controller initialization will only run if the
   device is suspended between the calls to mipi_dsi_host_register() and
   component_add() (which ends up calling sun6i_dsi_encoder_enable()).
   Again, as shown by the above call graph, this is not the case. It
   appears that the controller happens to work because it is still
   initialized by the bootloader.

   Because the connector is hardcoded to always be connected, the
   device's runtime PM reference is not dropped until system suspend,
   when sun4i_drv_drm_sys_suspend() ends up calling
   sun6i_dsi_encoder_disable(). However, that is done as a system sleep
   PM hook, and at that point the system PM core has already taken
   another runtime PM reference, so sun6i_dsi_runtime_suspend() is
   not called. Likewise, by the time the PM core releases its reference,
   sun4i_drv_drm_sys_resume() has already re-enabled the encoder.

   So after system suspend and resume, we have *still never called*
   sun6i_dsi_inst_init(), and now that the rest of the display pipeline
   has been reset, the DSI host is unable to communicate with the panel,
   causing VBLANK timeouts.

Fix all of these issues by inlining the runtime PM hooks into the
encoder enable/disable functions, which are guaranteed to run after a
panel is attached. This allows sun6i_dsi_inst_init() to be called
unconditionally. Furthermore, this causes the hardware to be turned off
during system suspend and reinitialized on resume, which was not
happening before.

Fixes: 133add5b5a ("drm/sun4i: Add Allwinner A31 MIPI-DSI controller support")
Signed-off-by: Samuel Holland <samuel@sholland.org>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20200211072858.30784-4-samuel@sholland.org
2020-02-14 16:25:59 +01:00
..
Kconfig drm/sun4i: Fix Kconfig indentation 2019-11-25 10:04:41 +01:00
Makefile phy: Move Allwinner A31 D-PHY driver to drivers/phy/ 2019-02-07 09:34:49 +01:00
sun4i_backend.c drm/sun4i: backend: Make sure we enforce the clock rate 2020-01-08 09:13:47 +01:00
sun4i_backend.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun4i_crtc.c drm/sun4i: drop use of drmP.h 2019-07-17 12:52:45 +02:00
sun4i_crtc.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun4i_dotclock.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun4i_dotclock.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun4i_drv.c drm: sun4i: Add support for suspending the display driver 2019-12-26 10:20:54 +01:00
sun4i_drv.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun4i_framebuffer.c drm/sun4i: drop use of drmP.h 2019-07-17 12:52:45 +02:00
sun4i_framebuffer.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun4i_frontend.c drm/sun4i: drop use of drmP.h 2019-07-17 12:52:45 +02:00
sun4i_frontend.h drm/sun4i: frontend: Move the FIR filter phases to our quirks 2019-01-18 21:12:26 +01:00
sun4i_hdmi_ddc_clk.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun4i_hdmi_enc.c drm/sun4i/sun4i_hdmi_enc: call cec_s_conn_info() 2019-09-09 11:57:01 +02:00
sun4i_hdmi_i2c.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun4i_hdmi_tmds_clk.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun4i_hdmi.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun4i_layer.c drm/sun4i: Remove unneeded semicolon in sun4i_layer.c 2019-12-14 18:48:15 +01:00
sun4i_layer.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun4i_lvds.c drm/panel: decouple connector from drm_panel 2019-12-09 22:57:26 +01:00
sun4i_lvds.h
sun4i_rgb.c drm/panel: decouple connector from drm_panel 2019-12-09 22:57:26 +01:00
sun4i_rgb.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun4i_tcon.c drm main pull for 5.5-rc1 2019-11-27 17:45:48 -08:00
sun4i_tcon.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun4i_tv.c drm/sun4i: drop use of drmP.h 2019-07-17 12:52:45 +02:00
sun6i_drc.c drm/sun4i: drc: Make sure we enforce the clock rate 2020-01-08 09:14:08 +01:00
sun6i_mipi_dsi.c drm/sun4i: dsi: Remove incorrect use of runtime PM 2020-02-14 16:25:59 +01:00
sun6i_mipi_dsi.h drm/sun4i: dsi: Allow binding the host without a panel 2020-02-14 16:20:27 +01:00
sun8i_csc.c drm/sun4i: sun8i-csc: Add support for color encoding and range 2019-07-20 07:38:09 +02:00
sun8i_csc.h drm/sun4i: sun8i-csc: Add support for color encoding and range 2019-07-20 07:38:09 +02:00
sun8i_dw_hdmi.c drm/sun4i: Enable DRM InfoFrame support on H6 2019-10-10 12:50:03 +02:00
sun8i_dw_hdmi.h drm/sun4i: Enable DRM InfoFrame support on H6 2019-10-10 12:50:03 +02:00
sun8i_hdmi_phy_clk.c
sun8i_hdmi_phy.c drm/sun4i: Fix sun8i HDMI PHY configuration for > 148.5 MHz 2019-05-16 10:44:52 +02:00
sun8i_mixer.c drm/sun4i: Remove unneeded semicolon in sun8i_mixer.c 2019-12-14 18:48:07 +01:00
sun8i_mixer.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun8i_tcon_top.c drm/sun4i: drop use of drmP.h 2019-07-17 12:52:45 +02:00
sun8i_tcon_top.h drm/sun4i: tcon-top: Add helpers for mux switching 2018-07-11 09:54:54 +02:00
sun8i_ui_layer.c drm/sun4i: drop use of drmP.h 2019-07-17 12:52:45 +02:00
sun8i_ui_layer.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun8i_ui_scaler.c drm/sun4i: Add basic support for DE3 2018-11-05 11:48:23 +01:00
sun8i_ui_scaler.h drm/sun4i: Add basic support for DE3 2018-11-05 11:48:23 +01:00
sun8i_vi_layer.c drm/sun4i: sun8i-csc: Add support for color encoding and range 2019-07-20 07:38:09 +02:00
sun8i_vi_layer.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sun8i_vi_scaler.c drm/sun4i: Add basic support for DE3 2018-11-05 11:48:23 +01:00
sun8i_vi_scaler.h drm/sun4i: Add basic support for DE3 2018-11-05 11:48:23 +01:00
sunxi_engine.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00