Skip to content

Commit 411efa1

Browse files
committed
drm/vc4: hdmi: Move the HSM clock enable to runtime_pm
In order to access the HDMI controller, we need to make sure the HSM clock is enabled. If we were to access it with the clock disabled, the CPU would completely hang, resulting in an hard crash. Since we have different code path that would require it, let's move that clock enable / disable to runtime_pm that will take care of the reference counting for us. Fixes: 4f6e3d6 ("drm/vc4: Add runtime PM support to the HDMI encoder driver") Signed-off-by: Maxime Ripard <[email protected]> Reviewed-by: Dave Stevenson <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent c336a5e commit 411efa1

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

drivers/gpu/drm/vc4/vc4_hdmi.c

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,6 @@ static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder,
473473
HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
474474

475475
clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock);
476-
clk_disable_unprepare(vc4_hdmi->hsm_clock);
477476
clk_disable_unprepare(vc4_hdmi->pixel_clock);
478477

479478
ret = pm_runtime_put(&vc4_hdmi->pdev->dev);
@@ -784,13 +783,6 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
784783
return;
785784
}
786785

787-
ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
788-
if (ret) {
789-
DRM_ERROR("Failed to turn on HSM clock: %d\n", ret);
790-
clk_disable_unprepare(vc4_hdmi->pixel_clock);
791-
return;
792-
}
793-
794786
vc4_hdmi_cec_update_clk_div(vc4_hdmi);
795787

796788
/*
@@ -801,15 +793,13 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
801793
(hsm_rate > VC4_HSM_MID_CLOCK ? 150000000 : 75000000));
802794
if (ret) {
803795
DRM_ERROR("Failed to set pixel bvb clock rate: %d\n", ret);
804-
clk_disable_unprepare(vc4_hdmi->hsm_clock);
805796
clk_disable_unprepare(vc4_hdmi->pixel_clock);
806797
return;
807798
}
808799

809800
ret = clk_prepare_enable(vc4_hdmi->pixel_bvb_clock);
810801
if (ret) {
811802
DRM_ERROR("Failed to turn on pixel bvb clock: %d\n", ret);
812-
clk_disable_unprepare(vc4_hdmi->hsm_clock);
813803
clk_disable_unprepare(vc4_hdmi->pixel_clock);
814804
return;
815805
}
@@ -1929,6 +1919,29 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
19291919
return 0;
19301920
}
19311921

1922+
#ifdef CONFIG_PM
1923+
static int vc4_hdmi_runtime_suspend(struct device *dev)
1924+
{
1925+
struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
1926+
1927+
clk_disable_unprepare(vc4_hdmi->hsm_clock);
1928+
1929+
return 0;
1930+
}
1931+
1932+
static int vc4_hdmi_runtime_resume(struct device *dev)
1933+
{
1934+
struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
1935+
int ret;
1936+
1937+
ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
1938+
if (ret)
1939+
return ret;
1940+
1941+
return 0;
1942+
}
1943+
#endif
1944+
19321945
static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
19331946
{
19341947
const struct vc4_hdmi_variant *variant = of_device_get_match_data(dev);
@@ -2165,11 +2178,18 @@ static const struct of_device_id vc4_hdmi_dt_match[] = {
21652178
{}
21662179
};
21672180

2181+
static const struct dev_pm_ops vc4_hdmi_pm_ops = {
2182+
SET_RUNTIME_PM_OPS(vc4_hdmi_runtime_suspend,
2183+
vc4_hdmi_runtime_resume,
2184+
NULL)
2185+
};
2186+
21682187
struct platform_driver vc4_hdmi_driver = {
21692188
.probe = vc4_hdmi_dev_probe,
21702189
.remove = vc4_hdmi_dev_remove,
21712190
.driver = {
21722191
.name = "vc4_hdmi",
21732192
.of_match_table = vc4_hdmi_dt_match,
2193+
.pm = &vc4_hdmi_pm_ops,
21742194
},
21752195
};

0 commit comments

Comments
 (0)