2 * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
3 * Copyright (C) 2013 Red Hat
4 * Author: Rob Clark <robdclark@gmail.com>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "sde_connector.h"
25 struct sde_hdmi_bridge {
26 struct drm_bridge base;
29 #define to_hdmi_bridge(x) container_of(x, struct sde_hdmi_bridge, base)
31 /* TX major version that supports scrambling */
32 #define HDMI_TX_SCRAMBLER_MIN_TX_VERSION 0x04
33 #define HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ 340000
34 #define HDMI_TX_SCRAMBLER_TIMEOUT_MSEC 200
35 /* default hsyncs for 4k@60 for 200ms */
36 #define HDMI_DEFAULT_TIMEOUT_HSYNC 28571
39 #define HDMI_AVI_INFOFRAME_BUFFER_SIZE \
40 (HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE)
41 #define HDMI_VS_INFOFRAME_BUFFER_SIZE (HDMI_INFOFRAME_HEADER_SIZE + 6)
42 #define HDMI_SPD_INFOFRAME_BUFFER_SIZE \
43 (HDMI_INFOFRAME_HEADER_SIZE + HDMI_SPD_INFOFRAME_SIZE)
44 #define HDMI_DEFAULT_VENDOR_NAME "unknown"
45 #define HDMI_DEFAULT_PRODUCT_NAME "msm"
46 #define LEFT_SHIFT_BYTE(x) ((x) << 8)
47 #define LEFT_SHIFT_WORD(x) ((x) << 16)
48 #define LEFT_SHIFT_24BITS(x) ((x) << 24)
49 #define HDMI_AVI_IFRAME_LINE_NUMBER 1
50 #define HDMI_VENDOR_IFRAME_LINE_NUMBER 3
52 void _sde_hdmi_bridge_destroy(struct drm_bridge *bridge)
56 static void _sde_hdmi_bridge_power_on(struct drm_bridge *bridge)
58 struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
59 struct hdmi *hdmi = sde_hdmi_bridge->hdmi;
60 const struct hdmi_platform_config *config = hdmi->config;
63 for (i = 0; i < config->pwr_reg_cnt; i++) {
64 ret = regulator_enable(hdmi->pwr_regs[i]);
66 SDE_ERROR("failed to enable pwr regulator: %s (%d)\n",
67 config->pwr_reg_names[i], ret);
71 if (config->pwr_clk_cnt > 0) {
72 DRM_DEBUG("pixclock: %lu", hdmi->pixclock);
73 ret = clk_set_rate(hdmi->pwr_clks[0], hdmi->pixclock);
75 SDE_ERROR("failed to set pixel clk: %s (%d)\n",
76 config->pwr_clk_names[0], ret);
80 for (i = 0; i < config->pwr_clk_cnt; i++) {
81 ret = clk_prepare_enable(hdmi->pwr_clks[i]);
83 SDE_ERROR("failed to enable pwr clk: %s (%d)\n",
84 config->pwr_clk_names[i], ret);
89 static void _sde_hdmi_bridge_power_off(struct drm_bridge *bridge)
91 struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
92 struct hdmi *hdmi = sde_hdmi_bridge->hdmi;
93 const struct hdmi_platform_config *config = hdmi->config;
99 for (i = 0; i < config->pwr_clk_cnt; i++)
100 clk_disable_unprepare(hdmi->pwr_clks[i]);
102 for (i = 0; i < config->pwr_reg_cnt; i++) {
103 ret = regulator_disable(hdmi->pwr_regs[i]);
105 SDE_ERROR("failed to disable pwr regulator: %s (%d)\n",
106 config->pwr_reg_names[i], ret);
111 static int _sde_hdmi_bridge_ddc_clear_irq(struct hdmi *hdmi,
114 u32 ddc_int_ctrl, ddc_status, in_use, timeout;
115 u32 sw_done_mask = BIT(2);
116 u32 sw_done_ack = BIT(1);
117 u32 in_use_by_sw = BIT(0);
118 u32 in_use_by_hw = BIT(1);
120 /* clear and enable interrutps */
121 ddc_int_ctrl = sw_done_mask | sw_done_ack;
123 hdmi_write(hdmi, REG_HDMI_DDC_INT_CTRL, ddc_int_ctrl);
125 /* wait until DDC HW is free */
128 ddc_status = hdmi_read(hdmi, REG_HDMI_DDC_HW_STATUS);
129 in_use = ddc_status & (in_use_by_sw | in_use_by_hw);
131 SDE_DEBUG("ddc is in use by %s, timeout(%d)\n",
132 ddc_status & in_use_by_sw ? "sw" : "hw",
136 } while (in_use && --timeout);
139 SDE_ERROR("%s: timedout\n", what);
146 static int _sde_hdmi_bridge_scrambler_ddc_check_status(struct hdmi *hdmi)
151 /* check for errors and clear status */
152 reg_val = hdmi_read(hdmi, REG_HDMI_SCRAMBLER_STATUS_DDC_STATUS);
153 if (reg_val & BIT(4)) {
154 SDE_ERROR("ddc aborted\n");
159 if (reg_val & BIT(8)) {
160 SDE_ERROR("timed out\n");
165 if (reg_val & BIT(12)) {
166 SDE_ERROR("NACK0\n");
170 if (reg_val & BIT(14)) {
171 SDE_ERROR("NACK1\n");
175 hdmi_write(hdmi, REG_HDMI_SCRAMBLER_STATUS_DDC_STATUS, reg_val);
180 static void _sde_hdmi_bridge_scrambler_ddc_reset(struct hdmi *hdmi)
184 /* clear ack and disable interrupts */
185 reg_val = BIT(14) | BIT(9) | BIT(5) | BIT(1);
186 hdmi_write(hdmi, REG_HDMI_DDC_INT_CTRL2, reg_val);
188 /* Reset DDC timers */
189 reg_val = BIT(0) | hdmi_read(hdmi, REG_HDMI_SCRAMBLER_STATUS_DDC_CTRL);
190 hdmi_write(hdmi, REG_HDMI_SCRAMBLER_STATUS_DDC_CTRL, reg_val);
192 reg_val = hdmi_read(hdmi, REG_HDMI_SCRAMBLER_STATUS_DDC_CTRL);
194 hdmi_write(hdmi, REG_HDMI_SCRAMBLER_STATUS_DDC_CTRL, reg_val);
197 static void _sde_hdmi_bridge_scrambler_ddc_disable(struct hdmi *hdmi)
201 _sde_hdmi_bridge_scrambler_ddc_reset(hdmi);
202 /* Disable HW DDC access to RxStatus register */
203 reg_val = hdmi_read(hdmi, REG_HDMI_HW_DDC_CTRL);
204 reg_val &= ~(BIT(8) | BIT(9));
205 hdmi_write(hdmi, REG_HDMI_HW_DDC_CTRL, reg_val);
208 static int _sde_hdmi_bridge_scrambler_status_timer_setup(struct hdmi *hdmi,
214 _sde_hdmi_bridge_ddc_clear_irq(hdmi, "scrambler");
216 hdmi_write(hdmi, REG_HDMI_SCRAMBLER_STATUS_DDC_TIMER_CTRL,
218 hdmi_write(hdmi, REG_HDMI_SCRAMBLER_STATUS_DDC_TIMER_CTRL2,
220 reg_val = hdmi_read(hdmi, REG_HDMI_DDC_INT_CTRL5);
222 hdmi_write(hdmi, REG_HDMI_DDC_INT_CTRL5, reg_val);
224 reg_val = hdmi_read(hdmi, REG_HDMI_DDC_INT_CTRL2);
225 /* Trigger interrupt if scrambler status is 0 or DDC failure */
227 reg_val &= ~(BIT(15) | BIT(16));
229 hdmi_write(hdmi, REG_HDMI_DDC_INT_CTRL2, reg_val);
231 /* Enable DDC access */
232 reg_val = hdmi_read(hdmi, REG_HDMI_HW_DDC_CTRL);
234 reg_val &= ~(BIT(8) | BIT(9));
236 hdmi_write(hdmi, REG_HDMI_HW_DDC_CTRL, reg_val);
238 /* WAIT for 200ms as per HDMI 2.0 standard for sink to respond */
241 /* clear the scrambler status */
242 rc = _sde_hdmi_bridge_scrambler_ddc_check_status(hdmi);
244 SDE_ERROR("scrambling ddc error %d\n", rc);
246 _sde_hdmi_bridge_scrambler_ddc_disable(hdmi);
251 static int _sde_hdmi_bridge_setup_ddc_timers(struct hdmi *hdmi,
252 u32 type, u32 to_in_num_lines)
254 if (type >= HDMI_TX_DDC_TIMER_MAX) {
255 SDE_ERROR("Invalid timer type %d\n", type);
260 case HDMI_TX_DDC_TIMER_SCRAMBLER_STATUS:
261 _sde_hdmi_bridge_scrambler_status_timer_setup(hdmi,
265 SDE_ERROR("%d type not supported\n", type);
272 static inline int _sde_hdmi_bridge_get_timeout_in_hysnc(
273 struct drm_display_mode *mode, u32 timeout_ms)
276 * pixel clock = h_total * v_total * fps
277 * 1 sec = pixel clock number of pixels are transmitted.
278 * time taken by one line (h_total) = 1s / (v_total * fps).
279 * lines for give time = (time_ms * 1000) / (1000000 / (v_total * fps))
280 * = (time_ms * clock) / h_total
283 return (timeout_ms * mode->clock / mode->htotal);
286 static int _sde_hdmi_bridge_setup_scrambler(struct hdmi *hdmi,
287 struct drm_display_mode *mode)
292 u32 tmds_clock_ratio = 0;
293 bool scrambler_on = false;
295 struct drm_connector *connector = NULL;
297 if (!hdmi || !mode) {
298 SDE_ERROR("invalid input\n");
301 connector = hdmi->connector;
303 /* Read HDMI version */
304 reg_val = hdmi_read(hdmi, REG_HDMI_VERSION);
305 reg_val = (reg_val & 0xF0000000) >> 28;
306 /* Scrambling is supported from HDMI TX 4.0 */
307 if (reg_val < HDMI_TX_SCRAMBLER_MIN_TX_VERSION) {
308 DRM_INFO("scrambling not supported by tx\n");
312 if (mode->clock > HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ) {
314 tmds_clock_ratio = 1;
316 scrambler_on = connector->supports_scramble;
319 DRM_INFO("scrambler %s\n", scrambler_on ? "on" : "off");
322 rc = sde_hdmi_scdc_write(hdmi,
323 HDMI_TX_SCDC_TMDS_BIT_CLOCK_RATIO_UPDATE,
326 SDE_ERROR("TMDS CLK RATIO ERR\n");
330 reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
331 reg_val |= BIT(31); /* Enable Update DATAPATH_MODE */
332 reg_val |= BIT(28); /* Set SCRAMBLER_EN bit */
334 hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
336 rc = sde_hdmi_scdc_write(hdmi,
337 HDMI_TX_SCDC_SCRAMBLING_ENABLE, 0x1);
339 SDE_ERROR("failed to enable scrambling\n");
344 * Setup hardware to periodically check for scrambler
345 * status bit on the sink. Sink should set this bit
346 * with in 200ms after scrambler is enabled.
348 timeout_hsync = _sde_hdmi_bridge_get_timeout_in_hysnc(
350 HDMI_TX_SCRAMBLER_TIMEOUT_MSEC);
351 if (timeout_hsync <= 0) {
352 SDE_ERROR("err in timeout hsync calc\n");
353 timeout_hsync = HDMI_DEFAULT_TIMEOUT_HSYNC;
355 SDE_DEBUG("timeout for scrambling en: %d hsyncs\n",
358 rc = _sde_hdmi_bridge_setup_ddc_timers(hdmi,
359 HDMI_TX_DDC_TIMER_SCRAMBLER_STATUS, timeout_hsync);
361 sde_hdmi_scdc_write(hdmi, HDMI_TX_SCDC_SCRAMBLING_ENABLE, 0x0);
362 reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
363 reg_val &= ~BIT(31); /* Disable Update DATAPATH_MODE */
364 reg_val &= ~BIT(28); /* Unset SCRAMBLER_EN bit */
365 hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
370 static void _sde_hdmi_bridge_pre_enable(struct drm_bridge *bridge)
372 struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
373 struct hdmi *hdmi = sde_hdmi_bridge->hdmi;
374 struct hdmi_phy *phy = hdmi->phy;
376 DRM_DEBUG("power up");
378 if (!hdmi->power_on) {
379 _sde_hdmi_bridge_power_on(bridge);
380 hdmi->power_on = true;
384 phy->funcs->powerup(phy, hdmi->pixclock);
386 sde_hdmi_set_mode(hdmi, true);
388 if (hdmi->hdcp_ctrl && hdmi->is_hdcp_supported)
389 hdmi_hdcp_ctrl_on(hdmi->hdcp_ctrl);
391 sde_hdmi_ack_state(hdmi->connector, EXT_DISPLAY_CABLE_CONNECT);
394 static void sde_hdmi_force_update_audio(struct drm_connector *connector,
395 enum drm_connector_status status)
397 struct sde_connector *c_conn = to_sde_connector(connector);
398 struct sde_hdmi *display = (struct sde_hdmi *)c_conn->display;
400 if (display && display->non_pluggable) {
401 display->ext_audio_data.intf_ops.hpd(display->ext_pdev,
402 display->ext_audio_data.type,
404 MSM_EXT_DISP_HPD_AUDIO);
408 static void _sde_hdmi_bridge_enable(struct drm_bridge *bridge)
410 struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
411 struct hdmi *hdmi = sde_hdmi_bridge->hdmi;
413 /* force update audio ops when there's no HPD event */
414 sde_hdmi_force_update_audio(hdmi->connector,
415 EXT_DISPLAY_CABLE_CONNECT);
418 static void _sde_hdmi_bridge_disable(struct drm_bridge *bridge)
420 struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
421 struct hdmi *hdmi = sde_hdmi_bridge->hdmi;
423 /* force update audio ops when there's no HPD event */
424 sde_hdmi_force_update_audio(hdmi->connector,
425 EXT_DISPLAY_CABLE_DISCONNECT);
428 static void _sde_hdmi_bridge_post_disable(struct drm_bridge *bridge)
430 struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
431 struct hdmi *hdmi = sde_hdmi_bridge->hdmi;
432 struct hdmi_phy *phy = hdmi->phy;
434 if (hdmi->hdcp_ctrl && hdmi->is_hdcp_supported)
435 hdmi_hdcp_ctrl_off(hdmi->hdcp_ctrl);
437 sde_hdmi_audio_off(hdmi);
439 DRM_DEBUG("power down");
440 sde_hdmi_set_mode(hdmi, false);
443 phy->funcs->powerdown(phy);
445 if (hdmi->power_on) {
446 _sde_hdmi_bridge_power_off(bridge);
447 hdmi->power_on = false;
450 sde_hdmi_ack_state(hdmi->connector, EXT_DISPLAY_CABLE_DISCONNECT);
453 static void _sde_hdmi_bridge_set_avi_infoframe(struct hdmi *hdmi,
454 const struct drm_display_mode *mode)
456 u8 avi_iframe[HDMI_AVI_INFOFRAME_BUFFER_SIZE] = {0};
457 u8 *avi_frame = &avi_iframe[HDMI_INFOFRAME_HEADER_SIZE];
460 struct hdmi_avi_infoframe info;
462 drm_hdmi_avi_infoframe_from_display_mode(&info, mode);
463 hdmi_avi_infoframe_pack(&info, avi_iframe, sizeof(avi_iframe));
464 checksum = avi_iframe[HDMI_INFOFRAME_HEADER_SIZE - 1];
467 LEFT_SHIFT_BYTE(avi_frame[0]) |
468 LEFT_SHIFT_WORD(avi_frame[1]) |
469 LEFT_SHIFT_24BITS(avi_frame[2]);
470 hdmi_write(hdmi, REG_HDMI_AVI_INFO(0), reg_val);
472 reg_val = avi_frame[3] |
473 LEFT_SHIFT_BYTE(avi_frame[4]) |
474 LEFT_SHIFT_WORD(avi_frame[5]) |
475 LEFT_SHIFT_24BITS(avi_frame[6]);
476 hdmi_write(hdmi, REG_HDMI_AVI_INFO(1), reg_val);
478 reg_val = avi_frame[7] |
479 LEFT_SHIFT_BYTE(avi_frame[8]) |
480 LEFT_SHIFT_WORD(avi_frame[9]) |
481 LEFT_SHIFT_24BITS(avi_frame[10]);
482 hdmi_write(hdmi, REG_HDMI_AVI_INFO(2), reg_val);
484 reg_val = avi_frame[11] |
485 LEFT_SHIFT_BYTE(avi_frame[12]) |
486 LEFT_SHIFT_24BITS(avi_iframe[1]);
487 hdmi_write(hdmi, REG_HDMI_AVI_INFO(3), reg_val);
489 /* AVI InfFrame enable (every frame) */
490 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0,
491 hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0) | BIT(1) | BIT(0));
493 reg_val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
495 reg_val |= HDMI_AVI_IFRAME_LINE_NUMBER;
496 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, reg_val);
499 static void _sde_hdmi_bridge_set_vs_infoframe(struct hdmi *hdmi,
500 const struct drm_display_mode *mode)
502 u8 vs_iframe[HDMI_VS_INFOFRAME_BUFFER_SIZE] = {0};
504 struct hdmi_vendor_infoframe info;
507 rc = drm_hdmi_vendor_infoframe_from_display_mode(&info, mode);
509 SDE_DEBUG("don't send vendor infoframe\n");
512 hdmi_vendor_infoframe_pack(&info, vs_iframe, sizeof(vs_iframe));
514 reg_val = (info.s3d_struct << 24) | (info.vic << 16) |
515 (vs_iframe[3] << 8) | (vs_iframe[7] << 5) |
517 hdmi_write(hdmi, REG_HDMI_VENSPEC_INFO0, reg_val);
519 /* vendor specific info-frame enable (every frame) */
520 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0,
521 hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0) | BIT(13) | BIT(12));
523 reg_val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
524 reg_val &= ~0x3F000000;
525 reg_val |= (HDMI_VENDOR_IFRAME_LINE_NUMBER << 24);
526 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, reg_val);
529 static void _sde_hdmi_bridge_set_spd_infoframe(struct hdmi *hdmi,
530 const struct drm_display_mode *mode)
532 u8 spd_iframe[HDMI_SPD_INFOFRAME_BUFFER_SIZE] = {0};
533 u32 packet_payload, packet_control, packet_header;
534 struct hdmi_spd_infoframe info;
537 /* Need to query vendor and product name from platform setup */
538 hdmi_spd_infoframe_init(&info, HDMI_DEFAULT_VENDOR_NAME,
539 HDMI_DEFAULT_PRODUCT_NAME);
540 hdmi_spd_infoframe_pack(&info, spd_iframe, sizeof(spd_iframe));
542 packet_header = spd_iframe[0]
543 | LEFT_SHIFT_BYTE(spd_iframe[1] & 0x7f)
544 | LEFT_SHIFT_WORD(spd_iframe[2] & 0x7f);
545 hdmi_write(hdmi, REG_HDMI_GENERIC1_HDR, packet_header);
547 for (i = 0; i < MAX_REG_HDMI_GENERIC1_INDEX; i++) {
548 packet_payload = spd_iframe[3 + i * 4]
549 | LEFT_SHIFT_BYTE(spd_iframe[4 + i * 4] & 0x7f)
550 | LEFT_SHIFT_WORD(spd_iframe[5 + i * 4] & 0x7f)
551 | LEFT_SHIFT_24BITS(spd_iframe[6 + i * 4] & 0x7f);
552 hdmi_write(hdmi, REG_HDMI_GENERIC1(i), packet_payload);
555 packet_payload = (spd_iframe[27] & 0x7f)
556 | LEFT_SHIFT_BYTE(spd_iframe[28] & 0x7f);
557 hdmi_write(hdmi, REG_HDMI_GENERIC1(MAX_REG_HDMI_GENERIC1_INDEX),
561 * GENERIC1_LINE | GENERIC1_CONT | GENERIC1_SEND
562 * Setup HDMI TX generic packet control
563 * Enable this packet to transmit every frame
564 * Enable HDMI TX engine to transmit Generic packet 1
566 packet_control = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);
567 packet_control |= ((0x1 << 24) | (1 << 5) | (1 << 4));
568 hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, packet_control);
571 static inline void _sde_hdmi_save_mode(struct hdmi *hdmi,
572 struct drm_display_mode *mode)
574 struct sde_connector *c_conn = to_sde_connector(hdmi->connector);
575 struct sde_hdmi *display = (struct sde_hdmi *)c_conn->display;
577 drm_mode_copy(&display->mode, mode);
580 static void _sde_hdmi_bridge_mode_set(struct drm_bridge *bridge,
581 struct drm_display_mode *mode,
582 struct drm_display_mode *adjusted_mode)
584 struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
585 struct hdmi *hdmi = sde_hdmi_bridge->hdmi;
586 int hstart, hend, vstart, vend;
589 mode = adjusted_mode;
591 hdmi->pixclock = mode->clock * 1000;
593 hstart = mode->htotal - mode->hsync_start;
594 hend = mode->htotal - mode->hsync_start + mode->hdisplay;
596 vstart = mode->vtotal - mode->vsync_start - 1;
597 vend = mode->vtotal - mode->vsync_start + mode->vdisplay - 1;
600 "htotal=%d, vtotal=%d, hstart=%d, hend=%d, vstart=%d, vend=%d",
601 mode->htotal, mode->vtotal, hstart, hend, vstart, vend);
603 hdmi_write(hdmi, REG_HDMI_TOTAL,
604 HDMI_TOTAL_H_TOTAL(mode->htotal - 1) |
605 HDMI_TOTAL_V_TOTAL(mode->vtotal - 1));
607 hdmi_write(hdmi, REG_HDMI_ACTIVE_HSYNC,
608 HDMI_ACTIVE_HSYNC_START(hstart) |
609 HDMI_ACTIVE_HSYNC_END(hend));
610 hdmi_write(hdmi, REG_HDMI_ACTIVE_VSYNC,
611 HDMI_ACTIVE_VSYNC_START(vstart) |
612 HDMI_ACTIVE_VSYNC_END(vend));
614 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
615 hdmi_write(hdmi, REG_HDMI_VSYNC_TOTAL_F2,
616 HDMI_VSYNC_TOTAL_F2_V_TOTAL(mode->vtotal));
617 hdmi_write(hdmi, REG_HDMI_VSYNC_ACTIVE_F2,
618 HDMI_VSYNC_ACTIVE_F2_START(vstart + 1) |
619 HDMI_VSYNC_ACTIVE_F2_END(vend + 1));
621 hdmi_write(hdmi, REG_HDMI_VSYNC_TOTAL_F2,
622 HDMI_VSYNC_TOTAL_F2_V_TOTAL(0));
623 hdmi_write(hdmi, REG_HDMI_VSYNC_ACTIVE_F2,
624 HDMI_VSYNC_ACTIVE_F2_START(0) |
625 HDMI_VSYNC_ACTIVE_F2_END(0));
629 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
630 frame_ctrl |= HDMI_FRAME_CTRL_HSYNC_LOW;
631 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
632 frame_ctrl |= HDMI_FRAME_CTRL_VSYNC_LOW;
633 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
634 frame_ctrl |= HDMI_FRAME_CTRL_INTERLACED_EN;
635 DRM_DEBUG("frame_ctrl=%08x\n", frame_ctrl);
636 hdmi_write(hdmi, REG_HDMI_FRAME_CTRL, frame_ctrl);
640 * Current drm_edid driver doesn't have all CEA formats defined in
641 * latest CEA-861(CTA-861) spec. So, don't check if mode is CEA mode
642 * in here. Once core framework is updated, the check needs to be
645 if (hdmi->hdmi_mode) {
646 _sde_hdmi_bridge_set_avi_infoframe(hdmi, mode);
647 _sde_hdmi_bridge_set_vs_infoframe(hdmi, mode);
648 _sde_hdmi_bridge_set_spd_infoframe(hdmi, mode);
649 DRM_DEBUG("hdmi setup info frame\n");
651 _sde_hdmi_bridge_setup_scrambler(hdmi, mode);
653 _sde_hdmi_save_mode(hdmi, mode);
656 static const struct drm_bridge_funcs _sde_hdmi_bridge_funcs = {
657 .pre_enable = _sde_hdmi_bridge_pre_enable,
658 .enable = _sde_hdmi_bridge_enable,
659 .disable = _sde_hdmi_bridge_disable,
660 .post_disable = _sde_hdmi_bridge_post_disable,
661 .mode_set = _sde_hdmi_bridge_mode_set,
665 /* initialize bridge */
666 struct drm_bridge *sde_hdmi_bridge_init(struct hdmi *hdmi)
668 struct drm_bridge *bridge = NULL;
669 struct sde_hdmi_bridge *sde_hdmi_bridge;
672 sde_hdmi_bridge = devm_kzalloc(hdmi->dev->dev,
673 sizeof(*sde_hdmi_bridge), GFP_KERNEL);
674 if (!sde_hdmi_bridge) {
679 sde_hdmi_bridge->hdmi = hdmi;
681 bridge = &sde_hdmi_bridge->base;
682 bridge->funcs = &_sde_hdmi_bridge_funcs;
684 ret = drm_bridge_attach(hdmi->dev, bridge);
692 _sde_hdmi_bridge_destroy(bridge);