aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJernej Skrabec <jernej.skrabec@siol.net>2018-02-14 15:08:58 -0500
committerMaxime Ripard <maxime.ripard@bootlin.com>2018-02-16 03:32:29 -0500
commit5765916afa4e859b92457a4a14f82ef2a9876758 (patch)
treecf16030bad6216d840d118e0266030f125d8e45d
parent46d1b42bfac6ea085169a23b266178719b19a778 (diff)
drm/bridge/synopsys: dw-hdmi: Export some PHY related functions
Parts of PHY code could be useful also for custom PHYs. For example, Allwinner A83T has custom PHY which is probably Synopsys gen2 PHY with few additional memory mapped registers, so most of the Synopsys PHY related code could be reused. Functions exported here are actually not specific to Synopsys PHYs but to DWC HDMI controller PHY interface. This means that even if the PHY is completely custom, i.e. not designed by Synopsys, exported functions can be useful. Reviewed-by: Archit Taneja <architt@codeaurora.org> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180214200906.31509-5-jernej.skrabec@siol.net
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c44
-rw-r--r--drivers/gpu/drm/meson/meson_dw_hdmi.c8
-rw-r--r--include/drm/bridge/dw_hdmi.h11
3 files changed, 45 insertions, 18 deletions
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 7ca14d7325b5..7d80f4b56683 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1037,19 +1037,21 @@ static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable)
1037 HDMI_PHY_CONF0_SVSRET_MASK); 1037 HDMI_PHY_CONF0_SVSRET_MASK);
1038} 1038}
1039 1039
1040static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) 1040void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
1041{ 1041{
1042 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, 1042 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
1043 HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET, 1043 HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
1044 HDMI_PHY_CONF0_GEN2_PDDQ_MASK); 1044 HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
1045} 1045}
1046EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_pddq);
1046 1047
1047static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable) 1048void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable)
1048{ 1049{
1049 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, 1050 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
1050 HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET, 1051 HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
1051 HDMI_PHY_CONF0_GEN2_TXPWRON_MASK); 1052 HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
1052} 1053}
1054EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_txpwron);
1053 1055
1054static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable) 1056static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable)
1055{ 1057{
@@ -1065,6 +1067,22 @@ static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable)
1065 HDMI_PHY_CONF0_SELDIPIF_MASK); 1067 HDMI_PHY_CONF0_SELDIPIF_MASK);
1066} 1068}
1067 1069
1070void dw_hdmi_phy_reset(struct dw_hdmi *hdmi)
1071{
1072 /* PHY reset. The reset signal is active high on Gen2 PHYs. */
1073 hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ);
1074 hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ);
1075}
1076EXPORT_SYMBOL_GPL(dw_hdmi_phy_reset);
1077
1078void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address)
1079{
1080 hdmi_phy_test_clear(hdmi, 1);
1081 hdmi_writeb(hdmi, address, HDMI_PHY_I2CM_SLAVE_ADDR);
1082 hdmi_phy_test_clear(hdmi, 0);
1083}
1084EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_set_addr);
1085
1068static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi) 1086static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
1069{ 1087{
1070 const struct dw_hdmi_phy_data *phy = hdmi->phy.data; 1088 const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
@@ -1203,16 +1221,11 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
1203 if (phy->has_svsret) 1221 if (phy->has_svsret)
1204 dw_hdmi_phy_enable_svsret(hdmi, 1); 1222 dw_hdmi_phy_enable_svsret(hdmi, 1);
1205 1223
1206 /* PHY reset. The reset signal is active high on Gen2 PHYs. */ 1224 dw_hdmi_phy_reset(hdmi);
1207 hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ);
1208 hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ);
1209 1225
1210 hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); 1226 hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
1211 1227
1212 hdmi_phy_test_clear(hdmi, 1); 1228 dw_hdmi_phy_i2c_set_addr(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2);
1213 hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
1214 HDMI_PHY_I2CM_SLAVE_ADDR);
1215 hdmi_phy_test_clear(hdmi, 0);
1216 1229
1217 /* Write to the PHY as configured by the platform */ 1230 /* Write to the PHY as configured by the platform */
1218 if (pdata->configure_phy) 1231 if (pdata->configure_phy)
@@ -1251,15 +1264,16 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data)
1251 dw_hdmi_phy_power_off(hdmi); 1264 dw_hdmi_phy_power_off(hdmi);
1252} 1265}
1253 1266
1254static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, 1267enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,
1255 void *data) 1268 void *data)
1256{ 1269{
1257 return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ? 1270 return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
1258 connector_status_connected : connector_status_disconnected; 1271 connector_status_connected : connector_status_disconnected;
1259} 1272}
1273EXPORT_SYMBOL_GPL(dw_hdmi_phy_read_hpd);
1260 1274
1261static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, 1275void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data,
1262 bool force, bool disabled, bool rxsense) 1276 bool force, bool disabled, bool rxsense)
1263{ 1277{
1264 u8 old_mask = hdmi->phy_mask; 1278 u8 old_mask = hdmi->phy_mask;
1265 1279
@@ -1271,8 +1285,9 @@ static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data,
1271 if (old_mask != hdmi->phy_mask) 1285 if (old_mask != hdmi->phy_mask)
1272 hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); 1286 hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
1273} 1287}
1288EXPORT_SYMBOL_GPL(dw_hdmi_phy_update_hpd);
1274 1289
1275static void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data) 1290void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data)
1276{ 1291{
1277 /* 1292 /*
1278 * Configure the PHY RX SENSE and HPD interrupts polarities and clear 1293 * Configure the PHY RX SENSE and HPD interrupts polarities and clear
@@ -1291,6 +1306,7 @@ static void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data)
1291 hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), 1306 hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
1292 HDMI_IH_MUTE_PHY_STAT0); 1307 HDMI_IH_MUTE_PHY_STAT0);
1293} 1308}
1309EXPORT_SYMBOL_GPL(dw_hdmi_phy_setup_hpd);
1294 1310
1295static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = { 1311static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = {
1296 .init = dw_hdmi_phy_init, 1312 .init = dw_hdmi_phy_init,
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index 17de3afd98f6..e8c3ef8a94ce 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -302,7 +302,7 @@ static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi,
302 } 302 }
303} 303}
304 304
305static inline void dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi) 305static inline void meson_dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi)
306{ 306{
307 struct meson_drm *priv = dw_hdmi->priv; 307 struct meson_drm *priv = dw_hdmi->priv;
308 308
@@ -409,9 +409,9 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
409 msleep(100); 409 msleep(100);
410 410
411 /* Reset PHY 3 times in a row */ 411 /* Reset PHY 3 times in a row */
412 dw_hdmi_phy_reset(dw_hdmi); 412 meson_dw_hdmi_phy_reset(dw_hdmi);
413 dw_hdmi_phy_reset(dw_hdmi); 413 meson_dw_hdmi_phy_reset(dw_hdmi);
414 dw_hdmi_phy_reset(dw_hdmi); 414 meson_dw_hdmi_phy_reset(dw_hdmi);
415 415
416 /* Temporary Disable VENC video stream */ 416 /* Temporary Disable VENC video stream */
417 if (priv->venc.hdmi_use_enci) 417 if (priv->venc.hdmi_use_enci)
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 182f83283e24..f3f3f0e1b2d3 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -157,7 +157,18 @@ void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
157void dw_hdmi_audio_disable(struct dw_hdmi *hdmi); 157void dw_hdmi_audio_disable(struct dw_hdmi *hdmi);
158 158
159/* PHY configuration */ 159/* PHY configuration */
160void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address);
160void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, 161void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
161 unsigned char addr); 162 unsigned char addr);
162 163
164void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable);
165void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable);
166void dw_hdmi_phy_reset(struct dw_hdmi *hdmi);
167
168enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,
169 void *data);
170void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data,
171 bool force, bool disabled, bool rxsense);
172void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data);
173
163#endif /* __IMX_HDMI_H__ */ 174#endif /* __IMX_HDMI_H__ */