Lines Matching +full:hdmi +full:- +full:switch
1 // SPDX-License-Identifier: GPL-2.0-only
14 #include "hdmi.h"
18 struct drm_device *dev = bridge->dev; in msm_hdmi_power_on()
20 struct hdmi *hdmi = hdmi_bridge->hdmi; in msm_hdmi_power_on() local
23 pm_runtime_resume_and_get(&hdmi->pdev->dev); in msm_hdmi_power_on()
25 if (hdmi->extp_clk) { in msm_hdmi_power_on()
26 DBG("pixclock: %lu", hdmi->pixclock); in msm_hdmi_power_on()
27 ret = clk_set_rate(hdmi->extp_clk, hdmi->pixclock); in msm_hdmi_power_on()
29 DRM_DEV_ERROR(dev->dev, "failed to set extp clk rate: %d\n", ret); in msm_hdmi_power_on()
31 ret = clk_prepare_enable(hdmi->extp_clk); in msm_hdmi_power_on()
33 DRM_DEV_ERROR(dev->dev, "failed to enable extp clk: %d\n", ret); in msm_hdmi_power_on()
40 struct hdmi *hdmi = hdmi_bridge->hdmi; in power_off() local
47 if (hdmi->extp_clk) in power_off()
48 clk_disable_unprepare(hdmi->extp_clk); in power_off()
50 pm_runtime_put(&hdmi->pdev->dev); in power_off()
57 static int msm_hdmi_config_avi_infoframe(struct hdmi *hdmi, in msm_hdmi_config_avi_infoframe() argument
64 if (len != HDMI_INFOFRAME_SIZE(AVI) || len - 3 > sizeof(buf)) { in msm_hdmi_config_avi_infoframe()
65 DRM_DEV_ERROR(&hdmi->pdev->dev, in msm_hdmi_config_avi_infoframe()
67 return -EINVAL; in msm_hdmi_config_avi_infoframe()
76 memcpy(buf, &buffer[3], len - 3); in msm_hdmi_config_avi_infoframe()
81 hdmi_write(hdmi, REG_HDMI_AVI_INFO(i), buf[i]); in msm_hdmi_config_avi_infoframe()
83 val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); in msm_hdmi_config_avi_infoframe()
86 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); in msm_hdmi_config_avi_infoframe()
88 val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); in msm_hdmi_config_avi_infoframe()
91 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); in msm_hdmi_config_avi_infoframe()
96 static int msm_hdmi_config_audio_infoframe(struct hdmi *hdmi, in msm_hdmi_config_audio_infoframe() argument
102 DRM_DEV_ERROR(&hdmi->pdev->dev, in msm_hdmi_config_audio_infoframe()
104 return -EINVAL; in msm_hdmi_config_audio_infoframe()
107 hdmi_write(hdmi, REG_HDMI_AUDIO_INFO0, in msm_hdmi_config_audio_infoframe()
113 hdmi_write(hdmi, REG_HDMI_AUDIO_INFO1, in msm_hdmi_config_audio_infoframe()
119 val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); in msm_hdmi_config_audio_infoframe()
124 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); in msm_hdmi_config_audio_infoframe()
129 static int msm_hdmi_config_spd_infoframe(struct hdmi *hdmi, in msm_hdmi_config_spd_infoframe() argument
136 if (len != HDMI_INFOFRAME_SIZE(SPD) || len - 3 > sizeof(buf)) { in msm_hdmi_config_spd_infoframe()
137 DRM_DEV_ERROR(&hdmi->pdev->dev, in msm_hdmi_config_spd_infoframe()
139 return -EINVAL; in msm_hdmi_config_spd_infoframe()
143 hdmi_write(hdmi, REG_HDMI_GENERIC1_HDR, in msm_hdmi_config_spd_infoframe()
148 memcpy(buf, &buffer[3], len - 3); in msm_hdmi_config_spd_infoframe()
151 hdmi_write(hdmi, REG_HDMI_GENERIC1(i), buf[i]); in msm_hdmi_config_spd_infoframe()
153 val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); in msm_hdmi_config_spd_infoframe()
157 hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); in msm_hdmi_config_spd_infoframe()
162 static int msm_hdmi_config_hdmi_infoframe(struct hdmi *hdmi, in msm_hdmi_config_hdmi_infoframe() argument
170 len - 3 > sizeof(buf)) { in msm_hdmi_config_hdmi_infoframe()
171 DRM_DEV_ERROR(&hdmi->pdev->dev, in msm_hdmi_config_hdmi_infoframe()
172 "failed to configure HDMI infoframe\n"); in msm_hdmi_config_hdmi_infoframe()
173 return -EINVAL; in msm_hdmi_config_hdmi_infoframe()
177 hdmi_write(hdmi, REG_HDMI_GENERIC0_HDR, in msm_hdmi_config_hdmi_infoframe()
182 memcpy(buf, &buffer[3], len - 3); in msm_hdmi_config_hdmi_infoframe()
185 hdmi_write(hdmi, REG_HDMI_GENERIC0(i), buf[i]); in msm_hdmi_config_hdmi_infoframe()
187 val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); in msm_hdmi_config_hdmi_infoframe()
192 hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); in msm_hdmi_config_hdmi_infoframe()
201 struct hdmi *hdmi = hdmi_bridge->hdmi; in msm_hdmi_bridge_clear_infoframe() local
204 switch (type) { in msm_hdmi_bridge_clear_infoframe()
206 val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0); in msm_hdmi_bridge_clear_infoframe()
209 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); in msm_hdmi_bridge_clear_infoframe()
211 val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); in msm_hdmi_bridge_clear_infoframe()
213 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); in msm_hdmi_bridge_clear_infoframe()
218 val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0); in msm_hdmi_bridge_clear_infoframe()
223 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); in msm_hdmi_bridge_clear_infoframe()
225 val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); in msm_hdmi_bridge_clear_infoframe()
227 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); in msm_hdmi_bridge_clear_infoframe()
232 val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); in msm_hdmi_bridge_clear_infoframe()
236 hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); in msm_hdmi_bridge_clear_infoframe()
241 val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); in msm_hdmi_bridge_clear_infoframe()
246 hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); in msm_hdmi_bridge_clear_infoframe()
251 drm_dbg_driver(hdmi_bridge->base.dev, "Unsupported infoframe type %x\n", type); in msm_hdmi_bridge_clear_infoframe()
262 struct hdmi *hdmi = hdmi_bridge->hdmi; in msm_hdmi_bridge_write_infoframe() local
266 switch (type) { in msm_hdmi_bridge_write_infoframe()
268 return msm_hdmi_config_avi_infoframe(hdmi, buffer, len); in msm_hdmi_bridge_write_infoframe()
270 return msm_hdmi_config_audio_infoframe(hdmi, buffer, len); in msm_hdmi_bridge_write_infoframe()
272 return msm_hdmi_config_spd_infoframe(hdmi, buffer, len); in msm_hdmi_bridge_write_infoframe()
274 return msm_hdmi_config_hdmi_infoframe(hdmi, buffer, len); in msm_hdmi_bridge_write_infoframe()
276 drm_dbg_driver(hdmi_bridge->base.dev, "Unsupported infoframe type %x\n", type); in msm_hdmi_bridge_write_infoframe()
281 static void msm_hdmi_set_timings(struct hdmi *hdmi,
288 struct hdmi *hdmi = hdmi_bridge->hdmi; in msm_hdmi_bridge_atomic_pre_enable() local
289 struct hdmi_phy *phy = hdmi->phy; in msm_hdmi_bridge_atomic_pre_enable()
290 struct drm_encoder *encoder = bridge->encoder; in msm_hdmi_bridge_atomic_pre_enable()
299 crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); in msm_hdmi_bridge_atomic_pre_enable()
301 hdmi->pixclock = conn_state->hdmi.tmds_char_rate; in msm_hdmi_bridge_atomic_pre_enable()
303 msm_hdmi_set_timings(hdmi, &crtc_state->adjusted_mode); in msm_hdmi_bridge_atomic_pre_enable()
305 mutex_lock(&hdmi->state_mutex); in msm_hdmi_bridge_atomic_pre_enable()
306 if (!hdmi->power_on) { in msm_hdmi_bridge_atomic_pre_enable()
309 hdmi->power_on = true; in msm_hdmi_bridge_atomic_pre_enable()
311 mutex_unlock(&hdmi->state_mutex); in msm_hdmi_bridge_atomic_pre_enable()
313 if (connector->display_info.is_hdmi) in msm_hdmi_bridge_atomic_pre_enable()
314 msm_hdmi_audio_update(hdmi); in msm_hdmi_bridge_atomic_pre_enable()
318 msm_hdmi_phy_powerup(phy, hdmi->pixclock); in msm_hdmi_bridge_atomic_pre_enable()
320 msm_hdmi_set_mode(hdmi, true); in msm_hdmi_bridge_atomic_pre_enable()
322 if (hdmi->hdcp_ctrl) in msm_hdmi_bridge_atomic_pre_enable()
323 msm_hdmi_hdcp_on(hdmi->hdcp_ctrl); in msm_hdmi_bridge_atomic_pre_enable()
330 struct hdmi *hdmi = hdmi_bridge->hdmi; in msm_hdmi_bridge_atomic_post_disable() local
331 struct hdmi_phy *phy = hdmi->phy; in msm_hdmi_bridge_atomic_post_disable()
333 if (hdmi->hdcp_ctrl) in msm_hdmi_bridge_atomic_post_disable()
334 msm_hdmi_hdcp_off(hdmi->hdcp_ctrl); in msm_hdmi_bridge_atomic_post_disable()
338 /* Keep the HDMI enabled if the HPD is enabled */ in msm_hdmi_bridge_atomic_post_disable()
339 mutex_lock(&hdmi->state_mutex); in msm_hdmi_bridge_atomic_post_disable()
340 msm_hdmi_set_mode(hdmi, hdmi->hpd_enabled); in msm_hdmi_bridge_atomic_post_disable()
344 if (hdmi->power_on) { in msm_hdmi_bridge_atomic_post_disable()
346 hdmi->power_on = false; in msm_hdmi_bridge_atomic_post_disable()
347 if (hdmi->connector->display_info.is_hdmi) in msm_hdmi_bridge_atomic_post_disable()
348 msm_hdmi_audio_update(hdmi); in msm_hdmi_bridge_atomic_post_disable()
351 mutex_unlock(&hdmi->state_mutex); in msm_hdmi_bridge_atomic_post_disable()
354 static void msm_hdmi_set_timings(struct hdmi *hdmi, in msm_hdmi_set_timings() argument
360 hstart = mode->htotal - mode->hsync_start; in msm_hdmi_set_timings()
361 hend = mode->htotal - mode->hsync_start + mode->hdisplay; in msm_hdmi_set_timings()
363 vstart = mode->vtotal - mode->vsync_start - 1; in msm_hdmi_set_timings()
364 vend = mode->vtotal - mode->vsync_start + mode->vdisplay - 1; in msm_hdmi_set_timings()
367 mode->htotal, mode->vtotal, hstart, hend, vstart, vend); in msm_hdmi_set_timings()
369 hdmi_write(hdmi, REG_HDMI_TOTAL, in msm_hdmi_set_timings()
370 HDMI_TOTAL_H_TOTAL(mode->htotal - 1) | in msm_hdmi_set_timings()
371 HDMI_TOTAL_V_TOTAL(mode->vtotal - 1)); in msm_hdmi_set_timings()
373 hdmi_write(hdmi, REG_HDMI_ACTIVE_HSYNC, in msm_hdmi_set_timings()
376 hdmi_write(hdmi, REG_HDMI_ACTIVE_VSYNC, in msm_hdmi_set_timings()
380 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { in msm_hdmi_set_timings()
381 hdmi_write(hdmi, REG_HDMI_VSYNC_TOTAL_F2, in msm_hdmi_set_timings()
382 HDMI_VSYNC_TOTAL_F2_V_TOTAL(mode->vtotal)); in msm_hdmi_set_timings()
383 hdmi_write(hdmi, REG_HDMI_VSYNC_ACTIVE_F2, in msm_hdmi_set_timings()
387 hdmi_write(hdmi, REG_HDMI_VSYNC_TOTAL_F2, in msm_hdmi_set_timings()
389 hdmi_write(hdmi, REG_HDMI_VSYNC_ACTIVE_F2, in msm_hdmi_set_timings()
395 if (mode->flags & DRM_MODE_FLAG_NHSYNC) in msm_hdmi_set_timings()
397 if (mode->flags & DRM_MODE_FLAG_NVSYNC) in msm_hdmi_set_timings()
399 if (mode->flags & DRM_MODE_FLAG_INTERLACE) in msm_hdmi_set_timings()
402 hdmi_write(hdmi, REG_HDMI_FRAME_CTRL, frame_ctrl); in msm_hdmi_set_timings()
409 struct hdmi *hdmi = hdmi_bridge->hdmi; in msm_hdmi_bridge_edid_read() local
413 hdmi_ctrl = hdmi_read(hdmi, REG_HDMI_CTRL); in msm_hdmi_bridge_edid_read()
414 hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl | HDMI_CTRL_ENABLE); in msm_hdmi_bridge_edid_read()
416 drm_edid = drm_edid_read_ddc(connector, hdmi->i2c); in msm_hdmi_bridge_edid_read()
418 hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl); in msm_hdmi_bridge_edid_read()
428 struct hdmi *hdmi = hdmi_bridge->hdmi; in msm_hdmi_bridge_tmds_char_rate_valid() local
429 struct msm_drm_private *priv = bridge->dev->dev_private; in msm_hdmi_bridge_tmds_char_rate_valid()
430 struct msm_kms *kms = priv->kms; in msm_hdmi_bridge_tmds_char_rate_valid()
437 if (kms->funcs->round_pixclk) in msm_hdmi_bridge_tmds_char_rate_valid()
438 actual = kms->funcs->round_pixclk(kms, in msm_hdmi_bridge_tmds_char_rate_valid()
440 hdmi_bridge->hdmi->encoder); in msm_hdmi_bridge_tmds_char_rate_valid()
441 else if (hdmi->extp_clk) in msm_hdmi_bridge_tmds_char_rate_valid()
442 actual = clk_round_rate(hdmi->extp_clk, tmds_rate); in msm_hdmi_bridge_tmds_char_rate_valid()
476 struct drm_bridge *bridge = &hdmi_bridge->base; in msm_hdmi_hotplug_work()
478 drm_bridge_hpd_notify(bridge, drm_bridge_detect(bridge, hdmi_bridge->hdmi->connector)); in msm_hdmi_hotplug_work()
482 int msm_hdmi_bridge_init(struct hdmi *hdmi) in msm_hdmi_bridge_init() argument
488 hdmi_bridge = devm_drm_bridge_alloc(hdmi->dev->dev, struct hdmi_bridge, base, in msm_hdmi_bridge_init()
493 hdmi_bridge->hdmi = hdmi; in msm_hdmi_bridge_init()
494 INIT_WORK(&hdmi_bridge->hpd_work, msm_hdmi_hotplug_work); in msm_hdmi_bridge_init()
496 bridge = &hdmi_bridge->base; in msm_hdmi_bridge_init()
497 bridge->ddc = hdmi->i2c; in msm_hdmi_bridge_init()
498 bridge->type = DRM_MODE_CONNECTOR_HDMIA; in msm_hdmi_bridge_init()
499 bridge->vendor = "Qualcomm"; in msm_hdmi_bridge_init()
500 bridge->product = "Snapdragon"; in msm_hdmi_bridge_init()
501 bridge->ops = DRM_BRIDGE_OP_HPD | in msm_hdmi_bridge_init()
506 bridge->hdmi_audio_max_i2s_playback_channels = 8; in msm_hdmi_bridge_init()
507 bridge->hdmi_audio_dev = &hdmi->pdev->dev; in msm_hdmi_bridge_init()
508 bridge->hdmi_audio_dai_port = -1; in msm_hdmi_bridge_init()
510 ret = devm_drm_bridge_add(hdmi->dev->dev, bridge); in msm_hdmi_bridge_init()
514 ret = drm_bridge_attach(hdmi->encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); in msm_hdmi_bridge_init()
518 hdmi->bridge = bridge; in msm_hdmi_bridge_init()