diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt b/Documentation/devicetree/bindings/video/exynos_hdmi.txt index 75ada041389e..1fd8cf9cbfac 100644 --- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt +++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt @@ -28,6 +28,7 @@ Required properties: "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi". - ddc: phandle to the hdmi ddc node - phy: phandle to the hdmi phy node +- samsung,syscon-phandle: phandle for system controller node for PMU. Example: @@ -38,4 +39,5 @@ Example: hpd-gpio = <&gpx3 7 1>; ddc = <&hdmi_ddc_node>; phy = <&hdmi_phy_node>; + samsung,syscon-phandle = <&pmu_system_controller>; }; diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index ed6176ebfbcd..941b235ca1db 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include @@ -81,7 +83,6 @@ struct hdmi_resources { struct clk *sclk_hdmi; struct clk *sclk_pixel; struct clk *sclk_hdmiphy; - struct clk *hdmiphy; struct clk *mout_hdmi; struct regulator_bulk_data *regul_bulk; int regul_count; @@ -208,6 +209,7 @@ struct hdmi_context { const struct hdmiphy_config *phy_confs; unsigned int phy_conf_count; + struct regmap *pmureg; enum hdmi_type type; }; @@ -2013,7 +2015,10 @@ static void hdmi_poweron(struct exynos_drm_display *display) if (regulator_bulk_enable(res->regul_count, res->regul_bulk)) DRM_DEBUG_KMS("failed to enable regulator bulk\n"); - clk_prepare_enable(res->hdmiphy); + /* set pmu hdmiphy control bit to enable hdmiphy */ + regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL, + PMU_HDMI_PHY_ENABLE_BIT, 1); + clk_prepare_enable(res->hdmi); clk_prepare_enable(res->sclk_hdmi); @@ -2040,7 +2045,11 @@ static void hdmi_poweroff(struct exynos_drm_display *display) clk_disable_unprepare(res->sclk_hdmi); clk_disable_unprepare(res->hdmi); - clk_disable_unprepare(res->hdmiphy); + + /* reset pmu hdmiphy control bit to disable hdmiphy */ + regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL, + PMU_HDMI_PHY_ENABLE_BIT, 0); + regulator_bulk_disable(res->regul_count, res->regul_bulk); pm_runtime_put_sync(hdata->dev); @@ -2143,11 +2152,6 @@ static int hdmi_resources_init(struct hdmi_context *hdata) DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n"); goto fail; } - res->hdmiphy = devm_clk_get(dev, "hdmiphy"); - if (IS_ERR(res->hdmiphy)) { - DRM_ERROR("failed to get clock 'hdmiphy'\n"); - goto fail; - } res->mout_hdmi = devm_clk_get(dev, "mout_hdmi"); if (IS_ERR(res->mout_hdmi)) { DRM_ERROR("failed to get clock 'mout_hdmi'\n"); @@ -2383,6 +2387,13 @@ out_get_phy_port: goto err_hdmiphy; } + hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, + "samsung,syscon-phandle"); + if (IS_ERR(hdata->pmureg)) { + DRM_ERROR("syscon regmap lookup failed.\n"); + goto err_hdmiphy; + } + pm_runtime_enable(dev); hdmi_display.ctx = hdata; diff --git a/drivers/gpu/drm/exynos/regs-hdmi.h b/drivers/gpu/drm/exynos/regs-hdmi.h index 84a69cdd8e8d..6d846b979045 100644 --- a/drivers/gpu/drm/exynos/regs-hdmi.h +++ b/drivers/gpu/drm/exynos/regs-hdmi.h @@ -585,4 +585,8 @@ #define HDMI_PHY_DISABLE_MODE_SET 0x80 #define HDMI_PHY_ENABLE_MODE_SET 0x00 +/* PMU Registers for PHY */ +#define PMU_HDMI_PHY_CONTROL 0x700 +#define PMU_HDMI_PHY_ENABLE_BIT BIT(0) + #endif /* SAMSUNG_REGS_HDMI_H */