drm/vc4: hdmi: Make sure the controller is powered up during bind
authorMaxime Ripard <maxime@cerno.tech>
Fri, 2 Jul 2021 10:03:28 +0000 (12:03 +0200)
committerPhil Elwell <8911409+pelwell@users.noreply.github.com>
Fri, 2 Jul 2021 15:45:04 +0000 (16:45 +0100)
In the bind hook, we actually need the device to have the HSM clock
running during the final part of the display initialisation where we
reset the controller and initialise the CEC component.

Failing to do so will result in a complete, silent, hang of the CPU.

Fixes: 411efa18e4b0 ("drm/vc4: hdmi: Move the HSM clock enable to runtime_pm")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
drivers/gpu/drm/vc4/vc4_hdmi.c

index eefb81af0faba6319f3f4bcb8b7ca16cb631ff3f..0833cbfb2100eb607b5f6120347566b5c7e6738f 100644 (file)
@@ -2253,6 +2253,18 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
                        vc4_hdmi->disable_4kp60 = true;
        }
 
+       /*
+        * We need to have the device powered up at this point to call
+        * our reset hook and for the CEC init.
+        */
+       ret = vc4_hdmi_runtime_resume(dev);
+       if (ret)
+               goto err_put_ddc;
+
+       pm_runtime_get_noresume(dev);
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
+
        if (vc4_hdmi->variant->reset)
                vc4_hdmi->variant->reset(vc4_hdmi);
 
@@ -2264,8 +2276,6 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
                clk_prepare_enable(vc4_hdmi->pixel_bvb_clock);
        }
 
-       pm_runtime_enable(dev);
-
        drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
        drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs);
 
@@ -2289,6 +2299,8 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
                             vc4_hdmi_debugfs_regs,
                             vc4_hdmi);
 
+       pm_runtime_put_sync(dev);
+
        return 0;
 
 err_free_cec:
@@ -2297,6 +2309,7 @@ err_destroy_conn:
        vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
 err_destroy_encoder:
        drm_encoder_cleanup(encoder);
+       pm_runtime_put_sync(dev);
        pm_runtime_disable(dev);
 err_put_ddc:
        put_device(&vc4_hdmi->ddc->dev);