diff options
Diffstat (limited to 'drivers/gpu/drm/meson/meson_dw_hdmi.c')
-rw-r--r-- | drivers/gpu/drm/meson/meson_dw_hdmi.c | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 29a8ff41595d..aad75a22dc33 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c | |||
@@ -145,8 +145,6 @@ struct meson_dw_hdmi { | |||
145 | struct reset_control *hdmitx_apb; | 145 | struct reset_control *hdmitx_apb; |
146 | struct reset_control *hdmitx_ctrl; | 146 | struct reset_control *hdmitx_ctrl; |
147 | struct reset_control *hdmitx_phy; | 147 | struct reset_control *hdmitx_phy; |
148 | struct clk *hdmi_pclk; | ||
149 | struct clk *venci_clk; | ||
150 | struct regulator *hdmi_supply; | 148 | struct regulator *hdmi_supply; |
151 | u32 irq_stat; | 149 | u32 irq_stat; |
152 | struct dw_hdmi *hdmi; | 150 | struct dw_hdmi *hdmi; |
@@ -941,6 +939,34 @@ static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi) | |||
941 | 939 | ||
942 | } | 940 | } |
943 | 941 | ||
942 | static void meson_disable_regulator(void *data) | ||
943 | { | ||
944 | regulator_disable(data); | ||
945 | } | ||
946 | |||
947 | static void meson_disable_clk(void *data) | ||
948 | { | ||
949 | clk_disable_unprepare(data); | ||
950 | } | ||
951 | |||
952 | static int meson_enable_clk(struct device *dev, char *name) | ||
953 | { | ||
954 | struct clk *clk; | ||
955 | int ret; | ||
956 | |||
957 | clk = devm_clk_get(dev, name); | ||
958 | if (IS_ERR(clk)) { | ||
959 | dev_err(dev, "Unable to get %s pclk\n", name); | ||
960 | return PTR_ERR(clk); | ||
961 | } | ||
962 | |||
963 | ret = clk_prepare_enable(clk); | ||
964 | if (!ret) | ||
965 | ret = devm_add_action_or_reset(dev, meson_disable_clk, clk); | ||
966 | |||
967 | return ret; | ||
968 | } | ||
969 | |||
944 | static int meson_dw_hdmi_bind(struct device *dev, struct device *master, | 970 | static int meson_dw_hdmi_bind(struct device *dev, struct device *master, |
945 | void *data) | 971 | void *data) |
946 | { | 972 | { |
@@ -989,6 +1015,10 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, | |||
989 | ret = regulator_enable(meson_dw_hdmi->hdmi_supply); | 1015 | ret = regulator_enable(meson_dw_hdmi->hdmi_supply); |
990 | if (ret) | 1016 | if (ret) |
991 | return ret; | 1017 | return ret; |
1018 | ret = devm_add_action_or_reset(dev, meson_disable_regulator, | ||
1019 | meson_dw_hdmi->hdmi_supply); | ||
1020 | if (ret) | ||
1021 | return ret; | ||
992 | } | 1022 | } |
993 | 1023 | ||
994 | meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev, | 1024 | meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev, |
@@ -1017,19 +1047,17 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, | |||
1017 | if (IS_ERR(meson_dw_hdmi->hdmitx)) | 1047 | if (IS_ERR(meson_dw_hdmi->hdmitx)) |
1018 | return PTR_ERR(meson_dw_hdmi->hdmitx); | 1048 | return PTR_ERR(meson_dw_hdmi->hdmitx); |
1019 | 1049 | ||
1020 | meson_dw_hdmi->hdmi_pclk = devm_clk_get(dev, "isfr"); | 1050 | ret = meson_enable_clk(dev, "isfr"); |
1021 | if (IS_ERR(meson_dw_hdmi->hdmi_pclk)) { | 1051 | if (ret) |
1022 | dev_err(dev, "Unable to get HDMI pclk\n"); | 1052 | return ret; |
1023 | return PTR_ERR(meson_dw_hdmi->hdmi_pclk); | ||
1024 | } | ||
1025 | clk_prepare_enable(meson_dw_hdmi->hdmi_pclk); | ||
1026 | 1053 | ||
1027 | meson_dw_hdmi->venci_clk = devm_clk_get(dev, "venci"); | 1054 | ret = meson_enable_clk(dev, "iahb"); |
1028 | if (IS_ERR(meson_dw_hdmi->venci_clk)) { | 1055 | if (ret) |
1029 | dev_err(dev, "Unable to get venci clk\n"); | 1056 | return ret; |
1030 | return PTR_ERR(meson_dw_hdmi->venci_clk); | 1057 | |
1031 | } | 1058 | ret = meson_enable_clk(dev, "venci"); |
1032 | clk_prepare_enable(meson_dw_hdmi->venci_clk); | 1059 | if (ret) |
1060 | return ret; | ||
1033 | 1061 | ||
1034 | dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi, | 1062 | dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi, |
1035 | &meson_dw_hdmi_regmap_config); | 1063 | &meson_dw_hdmi_regmap_config); |
@@ -1062,10 +1090,10 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, | |||
1062 | 1090 | ||
1063 | encoder->possible_crtcs = BIT(0); | 1091 | encoder->possible_crtcs = BIT(0); |
1064 | 1092 | ||
1065 | DRM_DEBUG_DRIVER("encoder initialized\n"); | ||
1066 | |||
1067 | meson_dw_hdmi_init(meson_dw_hdmi); | 1093 | meson_dw_hdmi_init(meson_dw_hdmi); |
1068 | 1094 | ||
1095 | DRM_DEBUG_DRIVER("encoder initialized\n"); | ||
1096 | |||
1069 | /* Bridge / Connector */ | 1097 | /* Bridge / Connector */ |
1070 | 1098 | ||
1071 | dw_plat_data->priv_data = meson_dw_hdmi; | 1099 | dw_plat_data->priv_data = meson_dw_hdmi; |