blob: 00bf5f10443ee5d711df69d3239d68518f3c5df6 [file] [log] [blame]
Ajay Singh Parmar2a2e3d62015-02-12 16:57:28 -08001/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29#include <err.h>
30#include <debug.h>
31#include <reg.h>
Casey Piper77f69c52015-03-20 15:55:12 -070032#include <malloc.h>
33#include <string.h>
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -070034#include <msm_panel.h>
35#include <platform/timer.h>
36#include <platform/clock.h>
Casey Piper77f69c52015-03-20 15:55:12 -070037#include "mdp5.h"
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -070038#include <platform/iomap.h>
Casey Piper77f69c52015-03-20 15:55:12 -070039#include "mdss_hdmi.h"
Casey Piper6c2f1132015-03-24 11:37:19 -070040#include <target/display.h>
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -070041
42static struct msm_fb_panel_data panel;
Casey Piper77f69c52015-03-20 15:55:12 -070043extern int msm_display_init(struct msm_fb_panel_data *pdata);
Casey Piper7ab92992015-03-18 14:19:23 -070044static bool hdmi_power_enabled;
45static bool hdmi_panel_clock_enabled;
46static bool hdmi_pll_clock_enabled;
Casey Piper77f69c52015-03-20 15:55:12 -070047
Casey Piper1d3611d2015-03-17 15:45:44 -070048/* Supported HDMI Audio channels */
49#define MSM_HDMI_AUDIO_CHANNEL_2 1
50#define MSM_HDMI_AUDIO_CHANNEL_MAX 8
51
52enum msm_hdmi_supported_audio_sample_rates {
53 AUDIO_SAMPLE_RATE_32KHZ,
54 AUDIO_SAMPLE_RATE_44_1KHZ,
55 AUDIO_SAMPLE_RATE_48KHZ,
56 AUDIO_SAMPLE_RATE_88_2KHZ,
57 AUDIO_SAMPLE_RATE_96KHZ,
58 AUDIO_SAMPLE_RATE_176_4KHZ,
59 AUDIO_SAMPLE_RATE_192KHZ,
60 AUDIO_SAMPLE_RATE_MAX
61};
62
63struct hdmi_msm_audio_acr {
64 uint32_t n; /* N parameter for clock regeneration */
65 uint32_t cts; /* CTS parameter for clock regeneration */
66};
67
68struct hdmi_msm_audio_arcs {
69 uint32_t pclk;
70 struct hdmi_msm_audio_acr lut[AUDIO_SAMPLE_RATE_MAX];
71};
72
73#define HDMI_MSM_AUDIO_ARCS(pclk, ...) { pclk, __VA_ARGS__ }
74
75/* Audio constants lookup table for hdmi_msm_audio_acr_setup */
76/* Valid Pixel-Clock rates: 25.2MHz, 27MHz, 27.03MHz, 74.25MHz, 148.5MHz */
77static struct hdmi_msm_audio_arcs hdmi_audio_acr_lut[] = {
78 /* 25.200MHz */
79 HDMI_MSM_AUDIO_ARCS(25200, {
80 {4096, 25200}, {6272, 28000}, {6144, 25200}, {12544, 28000},
81 {12288, 25200}, {25088, 28000}, {24576, 25200} }),
82 /* 27.000MHz */
83 HDMI_MSM_AUDIO_ARCS(27000, {
84 {4096, 27000}, {6272, 30000}, {6144, 27000}, {12544, 30000},
85 {12288, 27000}, {25088, 30000}, {24576, 27000} }),
86 /* 27.027MHz */
87 HDMI_MSM_AUDIO_ARCS(27030, {
88 {4096, 27027}, {6272, 30030}, {6144, 27027}, {12544, 30030},
89 {12288, 27027}, {25088, 30030}, {24576, 27027} }),
90 /* 74.250MHz */
91 HDMI_MSM_AUDIO_ARCS(74250, {
92 {4096, 74250}, {6272, 82500}, {6144, 74250}, {12544, 82500},
93 {12288, 74250}, {25088, 82500}, {24576, 74250} }),
94 /* 148.500MHz */
95 HDMI_MSM_AUDIO_ARCS(148500, {
96 {4096, 148500}, {6272, 165000}, {6144, 148500}, {12544, 165000},
97 {12288, 148500}, {25088, 165000}, {24576, 148500} }),
98 /* 297.000MHz */
99 HDMI_MSM_AUDIO_ARCS(297000, {
100 {3072, 222750}, {4704, 247500}, {5120, 247500}, {9408, 247500},
101 {10240, 247500}, {18816, 247500}, {20480, 247500} }),
Tatenda Chipeperekwa8edad1d2016-03-15 10:47:02 -0700102 /* 594.000MHz */
103 HDMI_MSM_AUDIO_ARCS(594000, {{3072, 445500}, {9408, 990000}, {6144, 594000},
104 {18816, 990000}, {12288, 594000}, {37632, 990000},
105 {24576, 594000} } ),
Casey Piper1d3611d2015-03-17 15:45:44 -0700106};
107
Ajay Singh Parmar2a2e3d62015-02-12 16:57:28 -0800108extern int msm_display_init(struct msm_fb_panel_data *pdata);
109
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700110/* AVI INFOFRAME DATA */
111#define NUM_MODES_AVI 20
112#define AVI_MAX_DATA_BYTES 13
113
114enum {
115 DATA_BYTE_1,
116 DATA_BYTE_2,
117 DATA_BYTE_3,
118 DATA_BYTE_4,
119 DATA_BYTE_5,
120 DATA_BYTE_6,
121 DATA_BYTE_7,
122 DATA_BYTE_8,
123 DATA_BYTE_9,
124 DATA_BYTE_10,
125 DATA_BYTE_11,
126 DATA_BYTE_12,
127 DATA_BYTE_13,
128};
129
130#define IFRAME_PACKET_OFFSET 0x80
131/*
132 * InfoFrame Type Code:
133 * 0x0 - Reserved
134 * 0x1 - Vendor Specific
135 * 0x2 - Auxiliary Video Information
136 * 0x3 - Source Product Description
137 * 0x4 - AUDIO
138 * 0x5 - MPEG Source
139 * 0x6 - NTSC VBI
140 * 0x7 - 0xFF - Reserved
141 */
142#define AVI_IFRAME_TYPE 0x2
143#define AVI_IFRAME_VERSION 0x2
Tatenda Chipeperekwac50c8dd2016-02-23 18:59:08 -0800144#define AVI_IFRAME_LINE_NUMBER 1
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700145#define LEFT_SHIFT_BYTE(x) ((x) << 8)
146#define LEFT_SHIFT_WORD(x) ((x) << 16)
147#define LEFT_SHIFT_24BITS(x) ((x) << 24)
148
Casey Piper1d3611d2015-03-17 15:45:44 -0700149#define MAX_AUDIO_DATA_BLOCK_SIZE 0x80
Casey Piper97d25272015-03-17 15:10:34 -0700150#define DBC_START_OFFSET 4
151#define VIC_INDEX 3
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -0800152#define HDMI_VIC_STR_MAX 4
153#define MAX_EDID_BLOCK_SIZE 0x80
Casey Piper97d25272015-03-17 15:10:34 -0700154
155enum edid_data_block_type {
156 RESERVED_DATA_BLOCK1 = 0,
157 AUDIO_DATA_BLOCK,
158 VIDEO_DATA_BLOCK,
159 VENDOR_SPECIFIC_DATA_BLOCK,
160 SPEAKER_ALLOCATION_DATA_BLOCK,
161 VESA_DTC_DATA_BLOCK,
162 RESERVED_DATA_BLOCK2,
163 USE_EXTENDED_TAG
164};
165
166/* video formats defined by CEA 861D */
167#define HDMI_VFRMT_UNKNOWN 0
168#define HDMI_VFRMT_640x480p60_4_3 1
169#define HDMI_VFRMT_1280x720p60_16_9 4
170#define HDMI_VFRMT_1920x1080p60_16_9 16
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -0800171#define HDMI_VFRMT_4096x2160p24_256_135 98
172#define HDMI_VFRMT_4096x2160p25_256_135 99
173#define HDMI_VFRMT_4096x2160p30_256_135 100
174#define HDMI_VFRMT_3840x2160p24_64_27 103
175#define HDMI_VFRMT_3840x2160p25_64_27 104
176#define HDMI_VFRMT_3840x2160p30_64_27 105
177#define HDMI_EVFRMT_4096x2160p24_16_9 131
Tatenda Chipeperekwa8edad1d2016-03-15 10:47:02 -0700178#define HDMI_VFRMT_4096x2160p60_256_135 102
179#define HDMI_VFRMT_COUNT 11
Tatenda Chipeperekwac50c8dd2016-02-23 18:59:08 -0800180#define HDMI_VFRMT_END 127
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -0800181#define HDMI_VSDB_3D_EVF_DATA_OFFSET(vsd) \
182 (!((vsd)[8] & BIT(7)) ? 9 : (!((vsd)[8] & BIT(6)) ? 11 : 13))
Tatenda Chipeperekwaf4917642016-03-23 11:34:48 -0700183#define MSM_MDP_MAX_PIPE_WIDTH 2560
Tatenda Chipeperekwa6d683e62016-05-02 11:42:53 -0700184/* TX major version that supports scrambling */
185#define HDMI_TX_SCRAMBLER_MIN_TX_VERSION 0x04
186#define HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ 340000
187#define HDMI_TX_SCRAMBLER_TIMEOUT_MSEC 200
188/* default hsyncs for 4k@60 for 200ms */
189#define HDMI_DEFAULT_TIMEOUT_HSYNC 28571
190#define HDMI_SCDC_TMDS_CONFIG 0x20
191#define HDMI_SCDC_CONFIG_0 0x30
192#define HDMI_SCDC_UNKNOWN_REGISTER "Unknown register"
193#define HDMI_SEC_TO_MS 1000
194#define HDMI_MS_TO_US 1000
195#define HDMI_SEC_TO_US (HDMI_SEC_TO_MS * HDMI_MS_TO_US)
196#define HDMI_KHZ_TO_HZ 1000
197#define HDMI_DDC_TRANSACTION_DELAY_US 468
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -0800198static uint8_t mdss_hdmi_video_formats[HDMI_VFRMT_COUNT];
199static uint8_t mdss_hdmi_mode_count;
Casey Piper97d25272015-03-17 15:10:34 -0700200
201#define DEFAULT_RESOLUTION HDMI_VFRMT_1920x1080p60_16_9
202static uint8_t mdss_hdmi_video_fmt = HDMI_VFRMT_UNKNOWN;
203static uint8_t mdss_hdmi_pref_fmt = HDMI_VFRMT_UNKNOWN;
204static uint8_t pt_scan_info;
205static uint8_t it_scan_info;
206static uint8_t ce_scan_info;
207
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -0800208static uint8_t mdss_hdmi_edid_buf[MAX_EDID_BLOCK_SIZE];
Casey Piper97d25272015-03-17 15:10:34 -0700209
Tatenda Chipeperekwa6d683e62016-05-02 11:42:53 -0700210enum scdc_access_type {
211 SCDC_SCRAMBLING_STATUS,
212 SCDC_SCRAMBLING_ENABLE,
213 SCDC_TMDS_BIT_CLOCK_RATIO_UPDATE,
214 SCDC_CLOCK_DET_STATUS,
215 SCDC_CH0_LOCK_STATUS,
216 SCDC_CH1_LOCK_STATUS,
217 SCDC_CH2_LOCK_STATUS,
218 SCDC_CH0_ERROR_COUNT,
219 SCDC_CH1_ERROR_COUNT,
220 SCDC_CH2_ERROR_COUNT,
221 SCDC_READ_ENABLE,
222 SCDC_MAX,
223};
224
225enum ddc_timer_type {
226 DDC_TIMER_HDCP2P2_RD_MSG,
227 DDC_TIMER_SCRAMBLER_STATUS,
228 DDC_TIMER_UPDATE_FLAGS,
229 DDC_TIMER_STATUS_FLAGS,
230 DDC_TIMER_CED,
231 DDC_TIMER_MAX,
232};
233
234struct hdmi_tx_ddc_data {
235 char *what;
236 uint8_t *data_buf;
237 uint32_t data_len;
238 uint32_t dev_addr;
239 uint32_t offset;
240 uint32_t request_len;
241 uint32_t retry_align;
242 uint32_t hard_timeout;
243 uint32_t timeout_left;
244 int retry;
245};
246
247enum trigger_mode {
248 TRIGGER_WRITE,
249 TRIGGER_READ
250};
251
Casey Piper97d25272015-03-17 15:10:34 -0700252enum aspect_ratio {
253 HDMI_RES_AR_INVALID,
254 HDMI_RES_AR_4_3,
255 HDMI_RES_AR_5_4,
256 HDMI_RES_AR_16_9,
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -0800257 HDMI_RES_AR_64_27,
Casey Piper97d25272015-03-17 15:10:34 -0700258 HDMI_RES_AR_16_10,
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -0800259 HDMI_RES_AR_256_135,
Casey Piper97d25272015-03-17 15:10:34 -0700260 HDMI_RES_AR_MAX,
261};
262
Tatenda Chipeperekwac50c8dd2016-02-23 18:59:08 -0800263enum hdmi_quantization_range {
264 HDMI_QUANTIZATION_DEFAULT,
265 HDMI_QUANTIZATION_LIMITED_RANGE,
266 HDMI_QUANTIZATION_FULL_RANGE
267};
268
269enum hdmi_scaling_info {
270 HDMI_SCALING_NONE,
271 HDMI_SCALING_HORZ,
272 HDMI_SCALING_VERT,
273 HDMI_SCALING_HORZ_VERT,
274};
275
276struct hdmi_avi_iframe_bar_info {
277 bool vert_binfo_present;
278 bool horz_binfo_present;
279 uint32_t end_of_top_bar;
280 uint32_t start_of_bottom_bar;
281 uint32_t end_of_left_bar;
282 uint32_t start_of_right_bar;
283};
284
285struct hdmi_avi_infoframe_config {
286 uint32_t pixel_format;
287 uint32_t scan_info;
288 bool act_fmt_info_present;
289 uint32_t colorimetry_info;
290 uint32_t ext_colorimetry_info;
291 uint32_t rgb_quantization_range;
292 uint32_t yuv_quantization_range;
293 uint32_t scaling_info;
294 bool is_it_content;
295 uint8_t content_type;
296 uint8_t pixel_rpt_factor;
297 struct hdmi_avi_iframe_bar_info bar_info;
298};
299
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700300struct mdss_hdmi_timing_info {
301 uint32_t video_format;
302 uint32_t active_h;
303 uint32_t front_porch_h;
304 uint32_t pulse_width_h;
305 uint32_t back_porch_h;
306 uint32_t active_low_h;
307 uint32_t active_v;
308 uint32_t front_porch_v;
309 uint32_t pulse_width_v;
310 uint32_t back_porch_v;
311 uint32_t active_low_v;
312 /* Must divide by 1000 to get the actual frequency in MHZ */
313 uint32_t pixel_freq;
314 /* Must divide by 1000 to get the actual frequency in HZ */
315 uint32_t refresh_rate;
316 uint32_t interlaced;
317 uint32_t supported;
Casey Piper97d25272015-03-17 15:10:34 -0700318 enum aspect_ratio ar;
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700319};
320
Casey Piper97d25272015-03-17 15:10:34 -0700321#define HDMI_VFRMT_640x480p60_4_3_TIMING \
322 {HDMI_VFRMT_640x480p60_4_3, 640, 16, 96, 48, true, \
323 480, 10, 2, 33, true, 25200, 60000, false, true, HDMI_RES_AR_4_3}
Ajay Singh Parmar392f07a2014-11-19 15:06:19 -0800324
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700325#define HDMI_VFRMT_1280x720p60_16_9_TIMING \
326 {HDMI_VFRMT_1280x720p60_16_9, 1280, 110, 40, 220, false, \
Casey Piper97d25272015-03-17 15:10:34 -0700327 720, 5, 5, 20, false, 74250, 60000, false, true, HDMI_RES_AR_16_9}
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700328
Casey Piper97d25272015-03-17 15:10:34 -0700329#define HDMI_VFRMT_1920x1080p60_16_9_TIMING \
330 {HDMI_VFRMT_1920x1080p60_16_9, 1920, 88, 44, 148, false, \
331 1080, 4, 5, 36, false, 148500, 60000, false, true, HDMI_RES_AR_16_9}
332
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -0800333#define HDMI_VFRMT_4096x2160p24_256_135_TIMING \
334 {HDMI_VFRMT_4096x2160p24_256_135, 4096, 1020, 88, 296, false, \
335 2160, 8, 10, 72, false, 297000, 24000, false, true, \
336 HDMI_RES_AR_256_135}
337
338#define HDMI_VFRMT_4096x2160p25_256_135_TIMING \
339 {HDMI_VFRMT_4096x2160p25_256_135, 4096, 968, 88, 128, false, \
340 2160, 8, 10, 72, false, 297000, 25000, false, true, \
341 HDMI_RES_AR_256_135}
342
343#define HDMI_VFRMT_4096x2160p30_256_135_TIMING \
344 {HDMI_VFRMT_4096x2160p30_256_135, 4096, 88, 88, 128, false, \
345 2160, 8, 10, 72, false, 297000, 30000, false, true, \
346 HDMI_RES_AR_256_135}
347
348#define HDMI_EVFRMT_4096x2160p24_16_9_TIMING \
349 {HDMI_EVFRMT_4096x2160p24_16_9, 4096, 1020, 88, 296, false, \
350 2160, 8, 10, 72, false, 297000, 24000, false, true, \
351 HDMI_RES_AR_16_9}
352
353#define HDMI_VFRMT_3840x2160p24_64_27_TIMING \
354 {HDMI_VFRMT_3840x2160p24_64_27, 3840, 1276, 88, 296, false, \
355 2160, 8, 10, 72, false, 297000, 24000, false, true, \
356 HDMI_RES_AR_64_27}
357
358#define HDMI_VFRMT_3840x2160p25_64_27_TIMING \
359 {HDMI_VFRMT_3840x2160p25_64_27, 3840, 1056, 88, 296, false, \
360 2160, 8, 10, 72, false, 297000, 25000, false, true, \
361 HDMI_RES_AR_64_27}
362
363#define HDMI_VFRMT_3840x2160p30_64_27_TIMING \
364 {HDMI_VFRMT_3840x2160p30_64_27, 3840, 176, 88, 296, false, \
365 2160, 8, 10, 72, false, 297000, 30000, false, true, \
366 HDMI_RES_AR_64_27}
367
Tatenda Chipeperekwa8edad1d2016-03-15 10:47:02 -0700368#define HDMI_VFRMT_4096x2160p60_256_135_TIMING \
369 {HDMI_VFRMT_4096x2160p60_256_135, 4096, 88, 88, 128, false, \
370 2160, 8, 10, 72, false, 594000, 60000, false, true, \
371 HDMI_RES_AR_256_135}
372
Casey Piper97d25272015-03-17 15:10:34 -0700373#define MSM_HDMI_MODES_GET_DETAILS(mode, MODE) do { \
374 struct mdss_hdmi_timing_info info = MODE##_TIMING; \
375 *mode = info; \
376 } while (0)
377
378static inline int mdss_hdmi_get_timing_info(
379 struct mdss_hdmi_timing_info *mode, int id)
380{
381 int ret = 0;
382
383 switch (id) {
384 case HDMI_VFRMT_640x480p60_4_3:
385 MSM_HDMI_MODES_GET_DETAILS(mode, HDMI_VFRMT_640x480p60_4_3);
386 break;
387
388 case HDMI_VFRMT_1280x720p60_16_9:
389 MSM_HDMI_MODES_GET_DETAILS(mode, HDMI_VFRMT_1280x720p60_16_9);
390 break;
391
392 case HDMI_VFRMT_1920x1080p60_16_9:
393 MSM_HDMI_MODES_GET_DETAILS(mode, HDMI_VFRMT_1920x1080p60_16_9);
394 break;
395
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -0800396 case HDMI_VFRMT_4096x2160p24_256_135:
397 MSM_HDMI_MODES_GET_DETAILS(mode, HDMI_VFRMT_4096x2160p24_256_135);
398 break;
399
400 case HDMI_VFRMT_4096x2160p25_256_135:
401 MSM_HDMI_MODES_GET_DETAILS(mode, HDMI_VFRMT_4096x2160p25_256_135);
402 break;
403
404 case HDMI_VFRMT_4096x2160p30_256_135:
405 MSM_HDMI_MODES_GET_DETAILS(mode, HDMI_VFRMT_4096x2160p30_256_135);
406 break;
407
408 case HDMI_EVFRMT_4096x2160p24_16_9:
409 MSM_HDMI_MODES_GET_DETAILS(mode, HDMI_EVFRMT_4096x2160p24_16_9);
410 break;
411
412 case HDMI_VFRMT_3840x2160p24_64_27:
413 MSM_HDMI_MODES_GET_DETAILS(mode, HDMI_VFRMT_3840x2160p24_64_27);
414 break;
415
416 case HDMI_VFRMT_3840x2160p25_64_27:
417 MSM_HDMI_MODES_GET_DETAILS(mode, HDMI_VFRMT_3840x2160p25_64_27);
418 break;
419
420 case HDMI_VFRMT_3840x2160p30_64_27:
421 MSM_HDMI_MODES_GET_DETAILS(mode, HDMI_VFRMT_3840x2160p30_64_27);
422 break;
423
Tatenda Chipeperekwa8edad1d2016-03-15 10:47:02 -0700424 case HDMI_VFRMT_4096x2160p60_256_135:
425 MSM_HDMI_MODES_GET_DETAILS(mode, HDMI_VFRMT_4096x2160p60_256_135);
426 break;
427
Casey Piper97d25272015-03-17 15:10:34 -0700428 default:
429 ret = ERROR;
430 }
431
432 return ret;
433}
434
Casey Piper1d3611d2015-03-17 15:45:44 -0700435static void mdss_hdmi_audio_acr_setup(uint32_t sample_rate)
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700436{
Casey Piper1d3611d2015-03-17 15:45:44 -0700437 /* Read first before writing */
438 uint32_t acr_pck_ctrl_reg = readl(HDMI_ACR_PKT_CTRL);
439 struct mdss_hdmi_timing_info tinfo = {0};
440 uint32_t ret = mdss_hdmi_get_timing_info(&tinfo, mdss_hdmi_video_fmt);
441 struct hdmi_msm_audio_arcs *audio_acr = &hdmi_audio_acr_lut[0];
442 uint32_t lut_size = sizeof(hdmi_audio_acr_lut)
443 / sizeof(*hdmi_audio_acr_lut);
444 uint32_t i, n, cts, layout, multiplier, aud_pck_ctrl_2_reg;
445 uint32_t channel_num = MSM_HDMI_AUDIO_CHANNEL_2;
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700446
Casey Piper1d3611d2015-03-17 15:45:44 -0700447 if (ret || !tinfo.supported) {
448 dprintf(CRITICAL, "%s: video format %d not supported\n",
449 __func__, mdss_hdmi_video_fmt);
450 return;
451 }
452
453 for (i = 0; i < lut_size; audio_acr = &hdmi_audio_acr_lut[++i]) {
454 if (audio_acr->pclk == tinfo.pixel_freq)
455 break;
456 }
457
458 if (i >= lut_size) {
459 dprintf(CRITICAL, "%s: pixel clk %d not supported\n", __func__,
460 tinfo.pixel_freq);
461 return;
462 }
463
464 n = audio_acr->lut[sample_rate].n;
465 cts = audio_acr->lut[sample_rate].cts;
466 layout = (MSM_HDMI_AUDIO_CHANNEL_2 == channel_num) ? 0 : 1;
467
468 if ((AUDIO_SAMPLE_RATE_192KHZ == sample_rate) ||
469 (AUDIO_SAMPLE_RATE_176_4KHZ == sample_rate)) {
470 multiplier = 4;
471 n >>= 2; /* divide N by 4 and use multiplier */
472 } else if ((AUDIO_SAMPLE_RATE_96KHZ == sample_rate) ||
473 (AUDIO_SAMPLE_RATE_88_2KHZ == sample_rate)) {
474 multiplier = 2;
475 n >>= 1; /* divide N by 2 and use multiplier */
476 } else {
477 multiplier = 1;
478 }
479
480 dprintf(SPEW, "%s: n=%u, cts=%u, layout=%u\n", __func__, n, cts,
481 layout);
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700482
483 /* AUDIO_PRIORITY | SOURCE */
484 acr_pck_ctrl_reg |= 0x80000100;
485
Casey Piper1d3611d2015-03-17 15:45:44 -0700486 /* Reset multiplier bits */
487 acr_pck_ctrl_reg &= ~(7 << 16);
488
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700489 /* N_MULTIPLE(multiplier) */
490 acr_pck_ctrl_reg |= (multiplier & 7) << 16;
491
Casey Piper1d3611d2015-03-17 15:45:44 -0700492 if ((AUDIO_SAMPLE_RATE_48KHZ == sample_rate) ||
493 (AUDIO_SAMPLE_RATE_96KHZ == sample_rate) ||
494 (AUDIO_SAMPLE_RATE_192KHZ == sample_rate)) {
495 /* SELECT(3) */
496 acr_pck_ctrl_reg |= 3 << 4;
497 /* CTS_48 */
498 cts <<= 12;
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700499
Casey Piper1d3611d2015-03-17 15:45:44 -0700500 /* CTS: need to determine how many fractional bits */
501 writel(cts, HDMI_ACR_48_0);
502 /* N */
503 writel(n, HDMI_ACR_48_1);
504 } else if ((AUDIO_SAMPLE_RATE_44_1KHZ == sample_rate) ||
505 (AUDIO_SAMPLE_RATE_88_2KHZ == sample_rate) ||
506 (AUDIO_SAMPLE_RATE_176_4KHZ == sample_rate)) {
507 /* SELECT(2) */
508 acr_pck_ctrl_reg |= 2 << 4;
509 /* CTS_44 */
510 cts <<= 12;
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700511
Casey Piper1d3611d2015-03-17 15:45:44 -0700512 /* CTS: need to determine how many fractional bits */
513 writel(cts, HDMI_ACR_44_0);
514 /* N */
515 writel(n, HDMI_ACR_44_1);
516 } else { /* default to 32k */
517 /* SELECT(1) */
518 acr_pck_ctrl_reg |= 1 << 4;
519 /* CTS_32 */
520 cts <<= 12;
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700521
Casey Piper1d3611d2015-03-17 15:45:44 -0700522 /* CTS: need to determine how many fractional bits */
523 writel(cts, HDMI_ACR_32_0);
524 /* N */
525 writel(n, HDMI_ACR_32_1);
526 }
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700527
528 /* Payload layout depends on number of audio channels */
Casey Piper1d3611d2015-03-17 15:45:44 -0700529 /* LAYOUT_SEL(layout) */
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700530 aud_pck_ctrl_2_reg = 1 | (layout << 1);
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700531 /* override | layout */
532 writel(aud_pck_ctrl_2_reg, HDMI_AUDIO_PKT_CTRL2);
533
534 /* SEND | CONT */
Casey Piper1d3611d2015-03-17 15:45:44 -0700535 acr_pck_ctrl_reg |= 0x00000003;
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700536
537 writel(acr_pck_ctrl_reg, HDMI_ACR_PKT_CTRL);
538}
539
Casey Piper1d3611d2015-03-17 15:45:44 -0700540static void mdss_hdmi_audio_info_setup(void)
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700541{
Casey Piper1d3611d2015-03-17 15:45:44 -0700542 uint32_t channel_count = MSM_HDMI_AUDIO_CHANNEL_2;
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700543 uint32_t channel_allocation = 0;
544 uint32_t level_shift = 0;
545 uint32_t down_mix = 0;
546 uint32_t check_sum, audio_info_0_reg, audio_info_1_reg;
547 uint32_t audio_info_ctrl_reg;
548 uint32_t aud_pck_ctrl_2_reg;
549 uint32_t layout;
550
Casey Piper1d3611d2015-03-17 15:45:44 -0700551 layout = (MSM_HDMI_AUDIO_CHANNEL_2 == channel_count) ? 0 : 1;;
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700552 aud_pck_ctrl_2_reg = 1 | (layout << 1);
553 writel(aud_pck_ctrl_2_reg, HDMI_AUDIO_PKT_CTRL2);
554
555 /* Read first then write because it is bundled with other controls */
556 audio_info_ctrl_reg = readl(HDMI_INFOFRAME_CTRL0);
557
558 channel_allocation = 0; /* Default to FR,FL */
559
560 /* Program the Channel-Speaker allocation */
561 audio_info_1_reg = 0;
562
563 /* CA(channel_allocation) */
564 audio_info_1_reg |= channel_allocation & 0xff;
565
566 /* Program the Level shifter */
567 /* LSV(level_shift) */
568 audio_info_1_reg |= (level_shift << 11) & 0x00007800;
569
570 /* Program the Down-mix Inhibit Flag */
571 /* DM_INH(down_mix) */
572 audio_info_1_reg |= (down_mix << 15) & 0x00008000;
573
574 writel(audio_info_1_reg, HDMI_AUDIO_INFO1);
575
576 check_sum = 0;
577 /* HDMI_AUDIO_INFO_FRAME_PACKET_HEADER_TYPE[0x84] */
578 check_sum += 0x84;
579 /* HDMI_AUDIO_INFO_FRAME_PACKET_HEADER_VERSION[0x01] */
580 check_sum += 1;
581 /* HDMI_AUDIO_INFO_FRAME_PACKET_LENGTH[0x0A] */
582 check_sum += 0x0A;
583 check_sum += channel_count;
584 check_sum += channel_allocation;
585 /* See Table 8.5 in HDMI spec */
586 check_sum += (level_shift & 0xF) << 3 | (down_mix & 0x1) << 7;
587 check_sum &= 0xFF;
588 check_sum = (256 - check_sum);
589
590 audio_info_0_reg = 0;
591 /* CHECKSUM(check_sum) */
592 audio_info_0_reg |= check_sum & 0xff;
593 /* CC(channel_count) */
594 audio_info_0_reg |= (channel_count << 8) & 0x00000700;
595
596 writel(audio_info_0_reg, HDMI_AUDIO_INFO0);
597
598 /* Set these flags */
599 /* AUDIO_INFO_UPDATE | AUDIO_INFO_SOURCE | AUDIO_INFO_CONT
600 | AUDIO_INFO_SEND */
601 audio_info_ctrl_reg |= 0xF0;
602
603 /* HDMI_INFOFRAME_CTRL0[0x002C] */
604 writel(audio_info_ctrl_reg, HDMI_INFOFRAME_CTRL0);
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700605}
606
Casey Piper97d25272015-03-17 15:10:34 -0700607static uint8_t* hdmi_edid_find_block(uint32_t start_offset,
608 uint8_t type, uint8_t *len)
609{
610 /* the start of data block collection, start of Video Data Block */
611 uint8_t *in_buf = mdss_hdmi_edid_buf;
612 uint32_t offset = start_offset;
613 uint32_t end_dbc_offset = in_buf[2];
614
615 *len = 0;
616
617 /*
618 * edid buffer 1, byte 2 being 4 means no non-DTD/Data block collection
619 * present.
620 * edid buffer 1, byte 2 being 0 means no non-DTD/DATA block collection
621 * present and no DTD data present.
622 */
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -0800623 if ((end_dbc_offset == 0) || (end_dbc_offset == 4) ||
624 (end_dbc_offset >= MAX_EDID_BLOCK_SIZE))
Casey Piper97d25272015-03-17 15:10:34 -0700625 return NULL;
626
627 while (offset < end_dbc_offset) {
628 uint8_t block_len = in_buf[offset] & 0x1F;
629 if ((in_buf[offset] >> 5) == type) {
630 *len = block_len;
631 dprintf(SPEW,
632 "EDID: block=%d found @ %d with length=%d\n",
633 type, offset, block_len);
634 return in_buf + offset;
635 }
636 offset += 1 + block_len;
637 }
638
639 return NULL;
640}
641
Casey Piper1d3611d2015-03-17 15:45:44 -0700642static bool mdss_hdmi_is_audio_freq_supported(uint32_t freq)
643{
644 uint8_t *in_buf = mdss_hdmi_edid_buf;
645 const uint8_t *adb = NULL;
646 uint32_t adb_size = 0;
647 uint8_t len = 0, count = 0;
648 uint32_t next_offset = DBC_START_OFFSET;
649 uint8_t audio_data_block[MAX_AUDIO_DATA_BLOCK_SIZE];
650
651 do {
652 adb = hdmi_edid_find_block(next_offset,
653 AUDIO_DATA_BLOCK, &len);
654
655 if ((adb_size + len) > MAX_AUDIO_DATA_BLOCK_SIZE) {
656 dprintf(INFO, "%s: invalid adb length\n", __func__);
657 break;
658 }
659
660 if (!adb)
661 break;
662
663 memcpy((audio_data_block + adb_size), adb + 1, len);
664 next_offset = (adb - in_buf) + 1 + len;
665
666 adb_size += len;
667
668 } while (adb);
669
670 count = adb_size/3;
671 adb = audio_data_block;
672
673 while (count--) {
674 uint8_t freq_lst = *(adb + 1) & 0xFF;
675
676 if (freq_lst & BIT(freq))
677 return true;
678
679 adb += 3;
680 }
681
682 return false;
683}
684
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700685static void mdss_hdmi_audio_playback(void)
686{
Casey Piper77f69c52015-03-20 15:55:12 -0700687 char *base_addr;
Casey Piper1d3611d2015-03-17 15:45:44 -0700688 uint32_t sample_rate;
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700689
Casey Piper77f69c52015-03-20 15:55:12 -0700690 base_addr = (char *) memalign(4096, 0x1000);
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700691 if (base_addr == NULL) {
692 dprintf(CRITICAL, "%s: Error audio buffer alloc\n", __func__);
693 return;
694 }
695
696 memset(base_addr, 0, 0x1000);
697
698 writel(0x00000010, HDMI_AUDIO_PKT_CTRL);
699 writel(0x00000080, HDMI_AUDIO_CFG);
700
701 writel(0x0000096E, LPASS_LPAIF_RDDMA_CTL0);
702 writel(0x00000A6E, LPASS_LPAIF_RDDMA_CTL0);
703 writel(0x00002000, HDMI_VBI_PKT_CTRL);
704 writel(0x00000000, HDMI_GEN_PKT_CTRL);
705 writel(0x0000096E, LPASS_LPAIF_RDDMA_CTL0);
Casey Piper77f69c52015-03-20 15:55:12 -0700706 writel((uint32_t) base_addr, LPASS_LPAIF_RDDMA_BASE0);
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700707 writel(0x000005FF, LPASS_LPAIF_RDDMA_BUFF_LEN0);
708 writel(0x000005FF, LPASS_LPAIF_RDDMA_PER_LEN0);
709 writel(0x0000096F, LPASS_LPAIF_RDDMA_CTL0);
710 writel(0x00000010, LPASS_LPAIF_DEBUG_CTL);
711 writel(0x00000000, HDMI_GC);
712 writel(0x00002030, HDMI_VBI_PKT_CTRL);
713 writel(0x00002030, HDMI_VBI_PKT_CTRL);
714 writel(0x00002030, HDMI_VBI_PKT_CTRL);
715
Casey Piper1d3611d2015-03-17 15:45:44 -0700716 if (mdss_hdmi_is_audio_freq_supported(AUDIO_SAMPLE_RATE_48KHZ))
717 sample_rate = AUDIO_SAMPLE_RATE_48KHZ;
718 else
719 sample_rate = AUDIO_SAMPLE_RATE_32KHZ;
720
721 mdss_hdmi_audio_acr_setup(sample_rate);
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700722 mdss_hdmi_audio_info_setup();
723
724 writel(0x00000010, HDMI_AUDIO_PKT_CTRL);
725 writel(0x00000080, HDMI_AUDIO_CFG);
726 writel(0x00000011, HDMI_AUDIO_PKT_CTRL);
727 writel(0x00000081, HDMI_AUDIO_CFG);
Casey Piper1d3611d2015-03-17 15:45:44 -0700728
729 dprintf(SPEW, "audio sample rate %s\n",
730 sample_rate == AUDIO_SAMPLE_RATE_48KHZ ? "48KHz" : "32KHz");
Ajay Singh Parmara1771a12014-08-13 15:56:11 -0700731}
732
Casey Piper77f69c52015-03-20 15:55:12 -0700733static uint32_t mdss_hdmi_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700734{
Casey Piper7ab92992015-03-18 14:19:23 -0700735 int ret = NO_ERROR;
736 if (hdmi_panel_clock_enabled)
737 return ret;
738
739 ret = target_hdmi_panel_clock(enable, pinfo);
740
741 hdmi_panel_clock_enabled = enable;
742
743 return ret;
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700744}
745
Casey Piper6c2f1132015-03-24 11:37:19 -0700746static uint32_t mdss_hdmi_pll_clock(uint8_t enable, struct msm_panel_info *pinfo)
747{
Casey Piper7ab92992015-03-18 14:19:23 -0700748 int ret = NO_ERROR;
749
750 if (hdmi_pll_clock_enabled)
751 return ret;
752
753 ret = target_hdmi_pll_clock(enable, pinfo);
754
755 hdmi_pll_clock_enabled = enable;
756
757 return ret;
Casey Piper6c2f1132015-03-24 11:37:19 -0700758}
759
Ajay Singh Parmar9d2ba152014-08-14 00:42:24 -0700760static int mdss_hdmi_enable_power(uint8_t enable, struct msm_panel_info *pinfo)
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700761{
Casey Piper7ab92992015-03-18 14:19:23 -0700762 int ret = NO_ERROR;
763
764 if (hdmi_power_enabled)
765 return ret;
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700766
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700767 ret = target_hdmi_regulator_ctrl(enable);
768 if (ret) {
Ajay Singh Parmar9d2ba152014-08-14 00:42:24 -0700769 dprintf(CRITICAL, "hdmi regulator control enable failed\n");
770 goto bail_regulator_fail;
Casey Piper7ab92992015-03-18 14:19:23 -0700771 }
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700772
Ajay Singh Parmar9d2ba152014-08-14 00:42:24 -0700773 ret = target_hdmi_gpio_ctrl(enable);
774 if (ret) {
775 dprintf(CRITICAL, "hdmi gpio control enable failed\n");
776 goto bail_gpio_fail;
Casey Piper7ab92992015-03-18 14:19:23 -0700777 }
778
779 hdmi_power_enabled = enable;
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700780
Ajay Singh Parmar9d2ba152014-08-14 00:42:24 -0700781 dprintf(SPEW, "HDMI Panel power %s done\n", enable ? "on" : "off");
782
783 return ret;
784
785bail_gpio_fail:
786 target_hdmi_regulator_ctrl(0);
787
788bail_regulator_fail:
Ajay Singh Parmar9d2ba152014-08-14 00:42:24 -0700789 return ret;
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700790}
791
Ajay Singh Parmar9ddfa572015-02-17 12:49:53 -0800792static bool mdss_hdmi_is_dvi_mode(void)
793{
794 uint8_t len;
795 uint32_t ieee_tag;
796 const uint8_t *vsd = NULL;
797
798 vsd = hdmi_edid_find_block(DBC_START_OFFSET,
799 VENDOR_SPECIFIC_DATA_BLOCK, &len);
800
801 if (vsd == NULL || len == 0) {
802 dprintf(SPEW, "%s: Invalid VSDB\n", __func__);
803 return false;
804 }
805
806 ieee_tag = ((uint32_t) vsd[3] << 16) + ((uint32_t) vsd[2] << 8) +
807 (uint32_t) vsd[1];
808
809 if (ieee_tag == 0x0c03)
810 return false;
811 else
812 return true;
813}
814
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700815static void mdss_hdmi_set_mode(bool on)
816{
817 uint32_t val = 0;
Ajay Singh Parmar9ddfa572015-02-17 12:49:53 -0800818 if (on) {
819 /* tx on */
Tatenda Chipeperekwab12d7db2015-12-04 15:39:10 -0800820 val |= BIT(0);
821 /* hdcp legacy mode*/
822 val |= BIT(31);
Ajay Singh Parmar9ddfa572015-02-17 12:49:53 -0800823
824 if (!mdss_hdmi_is_dvi_mode())
Tatenda Chipeperekwab12d7db2015-12-04 15:39:10 -0800825 val |= BIT(1);
Ajay Singh Parmar9ddfa572015-02-17 12:49:53 -0800826 }
Casey Piper6c2f1132015-03-24 11:37:19 -0700827
828 writel(val, HDMI_CTRL);
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -0700829}
830
Casey Piper97d25272015-03-17 15:10:34 -0700831
832static int mdss_hdmi_read_edid(void)
833{
834 uint8_t ndx;
835 uint32_t reg_val;
836 uint32_t dev_addr = 0xA0;
837 uint32_t len = 0x80;
838 uint32_t offset = 0x80;
839 uint32_t time_out;
840 uint32_t retry = 5;
841
842 dev_addr &= 0xFE;
843
844again:
845 time_out = 10;
846 writel(readl(HDMI_DDC_ARBITRATION) & ~BIT(4), HDMI_DDC_ARBITRATION);
847
848 /* Enable DDC Interrupts */
849 writel(BIT(1) | BIT(2), HDMI_DDC_INT_CTRL);
850
851 /* config DDC to read CEA block */
852 writel((10 << 16) | (2 << 0), HDMI_DDC_SPEED);
853 writel(0xFF000000, HDMI_DDC_SETUP);
854 writel((1 << 16) | (19 << 0), HDMI_DDC_REF);
855 writel(BIT(31) | (dev_addr << 8), HDMI_DDC_DATA);
856 writel(offset << 8, HDMI_DDC_DATA);
857 writel((dev_addr | BIT(0)) << 8, HDMI_DDC_DATA);
858 writel(BIT(12) | BIT(16), HDMI_DDC_TRANS0);
859 writel(BIT(0) | BIT(12) | BIT(13) | (len << 16), HDMI_DDC_TRANS1);
860 writel(BIT(0) | BIT(20), HDMI_DDC_CTRL);
861
862 /* poll for 100ms for read to complete */
863 reg_val = readl(HDMI_DDC_INT_CTRL);
864 while (!(reg_val & BIT(0)) && time_out) {
865 reg_val = readl(HDMI_DDC_INT_CTRL);
866 time_out--;
867 mdelay(10);
868 }
869
870 if (!time_out) {
871 dprintf(CRITICAL, "%s: Timeout reading EDID\n", __func__);
872 if (retry--)
873 goto again;
874 else
875 return ERROR;
876 }
877
878 /* clear interrupts */
879 writel(BIT(1), HDMI_DDC_INT_CTRL);
880
881 reg_val = readl(HDMI_DDC_SW_STATUS);
882 reg_val &= BIT(12) | BIT(13) | BIT(14) | BIT(15);
883
884 /* Check if any NACK occurred */
885 if (reg_val) {
886 /* SW_STATUS_RESET */
887 writel(BIT(3), HDMI_DDC_CTRL);
888
889 /* SOFT_RESET */
890 writel(BIT(1), HDMI_DDC_CTRL);
891
892 dprintf(CRITICAL, "%s: NACK reading EDID\n", __func__);
893
894 if (retry--)
895 goto again;
896 else
897 return ERROR;
898 }
899
900 /* Write this data to DDC buffer */
901 writel(BIT(0) | (3 << 16) | BIT(31), HDMI_DDC_DATA);
902
903 /* Discard first byte */
904 readl(HDMI_DDC_DATA);
905
906 for (ndx = 0; ndx < 0x80; ndx++) {
907 reg_val = readl(HDMI_DDC_DATA);
908 mdss_hdmi_edid_buf[ndx] = (uint8_t)((reg_val & 0x0000FF00) >> 8);
909 }
910
911 dprintf(INFO, "%s: EDID read successful\n", __func__);
912
913 return NO_ERROR;
914}
915
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -0800916static void mdss_hdmi_add_video_format(uint32_t video_format)
917{
918 if (mdss_hdmi_mode_count >= HDMI_VFRMT_COUNT) {
919 dprintf(SPEW, "%s: unsupported format (%d)", __func__,
920 video_format);
921 return;
922 }
923
924 dprintf(SPEW, "%s: vic=%d\n", __func__, video_format);
925 mdss_hdmi_video_formats[mdss_hdmi_mode_count] = video_format;
926 mdss_hdmi_mode_count++;
927}
928
929static void mdss_hdmi_get_extended_video_formats()
930{
931 uint8_t db_len, offset, i;
932 uint8_t hdmi_vic_len;
933 uint32_t video_format;
934 const uint8_t *vsd = NULL;
935
936 vsd = hdmi_edid_find_block(DBC_START_OFFSET,
937 VENDOR_SPECIFIC_DATA_BLOCK, &db_len);
938
939 if (!vsd || db_len == 0) {
940 dprintf(SPEW, "%s: No/Invalid Vendor Specific Data Block\n",
941 __func__);
942 return;
943 }
944
945 /* check if HDMI_Video_present flag is set or not */
946 if (!(vsd[8] & BIT(5))) {
947 dprintf(SPEW, "%s: extended vfmts not supported by the sink.\n",
948 __func__);
949 return;
950 }
951
952 offset = HDMI_VSDB_3D_EVF_DATA_OFFSET(vsd);
953
954 hdmi_vic_len = vsd[offset + 1] >> 5;
955 if (hdmi_vic_len) {
956 for (i = 0; i < hdmi_vic_len; i++) {
957 struct mdss_hdmi_timing_info tinfo = {0};
958 uint32_t ret = 0;
959
960 video_format = HDMI_VFRMT_END + vsd[offset + 2 + i];
961 ret = mdss_hdmi_get_timing_info(&tinfo, video_format);
962
963 if (ret || !tinfo.supported)
964 continue;
965
966 mdss_hdmi_add_video_format(video_format);
967 }
968 }
969}
970
971static void mdss_hdmi_get_cea_video_formats()
Casey Piper97d25272015-03-17 15:10:34 -0700972{
973 uint8_t len, i;
974 uint32_t video_format;
Casey Piper97d25272015-03-17 15:10:34 -0700975
976 uint8_t *svd = hdmi_edid_find_block(DBC_START_OFFSET,
977 VIDEO_DATA_BLOCK, &len);
978
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -0800979 if (!svd || len == 0) {
980 dprintf(SPEW, "%s: No/Invalid Video Data Block\n",
981 __func__);
Ajay Singh Parmar392f07a2014-11-19 15:06:19 -0800982 return;
Casey Piper97d25272015-03-17 15:10:34 -0700983 }
Ajay Singh Parmar392f07a2014-11-19 15:06:19 -0800984
Casey Piper97d25272015-03-17 15:10:34 -0700985 ++svd;
986
987 for (i = 0; i < len; ++i, ++svd) {
988 struct mdss_hdmi_timing_info tinfo = {0};
989 uint32_t ret = 0;
990
991 video_format = (*svd & 0x7F);
992
993 if (i == 0)
994 mdss_hdmi_pref_fmt = video_format;
995
996 ret = mdss_hdmi_get_timing_info(&tinfo, video_format);
997
998 if (ret || !tinfo.supported)
999 continue;
1000
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -08001001 mdss_hdmi_add_video_format(video_format);
1002 }
1003}
Casey Piper97d25272015-03-17 15:10:34 -07001004
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -08001005static void mdss_hdmi_parse_res(void)
1006{
1007 int index, ret;
1008 uint8_t current_video_format;
1009 struct mdss_hdmi_timing_info current_timing_info = {0};
1010
1011 mdss_hdmi_mode_count = 0;
1012 mdss_hdmi_video_fmt = DEFAULT_RESOLUTION;
1013 current_video_format = mdss_hdmi_video_fmt;
1014 mdss_hdmi_get_timing_info(&current_timing_info, mdss_hdmi_video_fmt);
1015
1016 mdss_hdmi_get_extended_video_formats();
1017 mdss_hdmi_get_cea_video_formats();
1018
1019 for (index = 0; index < mdss_hdmi_mode_count; index++) {
1020 struct mdss_hdmi_timing_info new_timing_info = {0};
1021
1022 if (!mdss_hdmi_video_formats[index])
1023 break;
1024
1025 ret = mdss_hdmi_get_timing_info(&new_timing_info, mdss_hdmi_video_formats[index]);
1026 if (ret || !new_timing_info.supported)
1027 continue;
1028
1029 if (new_timing_info.active_h > current_timing_info.active_h) {
1030 current_video_format = mdss_hdmi_video_formats[index];
1031 } else if (new_timing_info.active_h ==
1032 current_timing_info.active_h) {
1033 if (new_timing_info.active_v >
1034 current_timing_info.active_v) {
1035 current_video_format = mdss_hdmi_video_formats[index];
1036 } else if (new_timing_info.active_v ==
1037 current_timing_info.active_v) {
Tatenda Chipeperekwad83a3002016-03-15 10:37:06 -07001038 if (new_timing_info.refresh_rate >
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -08001039 current_timing_info.refresh_rate) {
1040 current_video_format = mdss_hdmi_video_formats[index];
1041 }
1042 }
Casey Piper97d25272015-03-17 15:10:34 -07001043 }
Tatenda Chipeperekwad83a3002016-03-15 10:37:06 -07001044
1045 mdss_hdmi_get_timing_info(&current_timing_info, current_video_format);
Casey Piper97d25272015-03-17 15:10:34 -07001046 }
1047
Tatenda Chipeperekwa3fe8bd82016-02-23 18:49:10 -08001048 if (mdss_hdmi_video_fmt != current_video_format)
1049 mdss_hdmi_video_fmt = current_video_format;
Ajay Singh Parmar392f07a2014-11-19 15:06:19 -08001050}
1051
Casey Piper6c2f1132015-03-24 11:37:19 -07001052void mdss_hdmi_get_vic(char *buf)
1053{
1054 struct mdss_hdmi_timing_info tinfo = {0};
1055 uint32_t ret = mdss_hdmi_get_timing_info(&tinfo, mdss_hdmi_video_fmt);
1056
1057 if (ret)
1058 snprintf(buf, HDMI_VIC_STR_MAX, "%d", HDMI_VFRMT_UNKNOWN);
1059 else
1060 snprintf(buf, HDMI_VIC_STR_MAX, "%d", tinfo.video_format);
1061
1062}
1063
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001064static void mdss_hdmi_panel_init(struct msm_panel_info *pinfo)
1065{
Casey Piper97d25272015-03-17 15:10:34 -07001066 struct mdss_hdmi_timing_info tinfo = {0};
1067 uint32_t ret = mdss_hdmi_get_timing_info(&tinfo, mdss_hdmi_video_fmt);
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001068
Casey Piper97d25272015-03-17 15:10:34 -07001069 if (!pinfo || ret)
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001070 return;
1071
1072 pinfo->xres = tinfo.active_h;
1073 pinfo->yres = tinfo.active_v;
1074 pinfo->bpp = 24;
1075 pinfo->type = HDMI_PANEL;
Casey Piper97d25272015-03-17 15:10:34 -07001076 pinfo->clk_rate = tinfo.pixel_freq * 1000;
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001077
Casey Piper97d25272015-03-17 15:10:34 -07001078 pinfo->lcdc.h_back_porch = tinfo.back_porch_h;
1079 pinfo->lcdc.h_front_porch = tinfo.front_porch_h;
1080 pinfo->lcdc.h_pulse_width = tinfo.pulse_width_h;
1081 pinfo->lcdc.v_back_porch = tinfo.back_porch_v;
1082 pinfo->lcdc.v_front_porch = tinfo.front_porch_v;
1083 pinfo->lcdc.v_pulse_width = tinfo.pulse_width_v;
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001084
Casey Piper97d25272015-03-17 15:10:34 -07001085 pinfo->lcdc.hsync_skew = 0;
1086 pinfo->lcdc.xres_pad = 0;
1087 pinfo->lcdc.yres_pad = 0;
Tatenda Chipeperekwaf4917642016-03-23 11:34:48 -07001088
1089 /* Add dual pipe configuration for resultions greater than
1090 * MSM_MDP_MAX_PIPE_WIDTH.
1091 */
1092 if (pinfo->xres > MSM_MDP_MAX_PIPE_WIDTH) {
1093 pinfo->lcdc.dual_pipe = 1;
1094 pinfo->lm_split[0] = pinfo->xres / 2;
1095 pinfo->lm_split[1] = pinfo->xres - pinfo->lm_split[0];
1096 }
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001097}
1098
Casey Piper7ab92992015-03-18 14:19:23 -07001099static uint8_t mdss_hdmi_cable_status(void)
1100{
1101 uint32_t reg_val;
1102 uint8_t cable_status;
1103
1104 mdss_hdmi_set_mode(true);
1105
1106 /* Enable USEC REF timer */
1107 writel(0x0001001B, HDMI_USEC_REFTIMER);
1108
1109 /* set timeout to 4.1ms (max) for hardware debounce */
1110 reg_val = readl(HDMI_HPD_CTRL) | 0x1FFF;
1111
1112 /* enable HPD circuit */
1113 writel(reg_val | BIT(28), HDMI_HPD_CTRL);
1114
1115 writel(BIT(2) | BIT(1), HDMI_HPD_INT_CTRL);
1116
1117 /* Toggle HPD circuit to trigger HPD sense */
1118 reg_val = readl(HDMI_HPD_CTRL) | 0x1FFF;
1119 writel(reg_val & ~BIT(28), HDMI_HPD_CTRL);
1120 writel(reg_val & BIT(28), HDMI_HPD_CTRL);
1121
1122 mdelay(20);
1123
1124 cable_status = (readl(HDMI_HPD_INT_STATUS) & BIT(1)) >> 1;
1125
1126 dprintf(INFO, "hdmi cable %s\n",
1127 cable_status ? "connected" : "not connected");
1128
1129 writel(BIT(0), HDMI_HPD_INT_CTRL);
1130 writel(reg_val & ~BIT(28), HDMI_HPD_CTRL);
1131
1132 mdss_hdmi_set_mode(false);
1133
1134 return cable_status;
1135}
1136
Casey Piper6c2f1132015-03-24 11:37:19 -07001137static int mdss_hdmi_update_panel_info(void)
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001138{
Casey Piper6c2f1132015-03-24 11:37:19 -07001139 mdss_hdmi_set_mode(true);
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001140
Casey Piper6c2f1132015-03-24 11:37:19 -07001141 if (!mdss_hdmi_read_edid())
1142 mdss_hdmi_parse_res();
1143 else
1144 mdss_hdmi_video_fmt = DEFAULT_RESOLUTION;
1145
1146 mdss_hdmi_set_mode(false);
1147
1148 mdss_hdmi_panel_init(&(panel.panel_info));
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001149
1150 panel.fb.width = panel.panel_info.xres;
1151 panel.fb.height = panel.panel_info.yres;
1152 panel.fb.stride = panel.panel_info.xres;
1153 panel.fb.bpp = panel.panel_info.bpp;
1154 panel.fb.format = FB_FORMAT_RGB888;
1155
Casey Piper6c2f1132015-03-24 11:37:19 -07001156 return NO_ERROR;
1157}
1158
1159void mdss_hdmi_display_init(uint32_t rev, void *base)
1160{
1161 panel.power_func = mdss_hdmi_enable_power;
1162 panel.clk_func = mdss_hdmi_panel_clock;
1163 panel.update_panel_info = mdss_hdmi_update_panel_info;
1164 panel.pll_clk_func = mdss_hdmi_pll_clock;
1165
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001166 panel.fb.base = base;
1167 panel.mdp_rev = rev;
1168
1169 msm_display_init(&panel);
1170}
1171
1172static int mdss_hdmi_video_setup(void)
1173{
1174 uint32_t total_v = 0;
1175 uint32_t total_h = 0;
1176 uint32_t start_h = 0;
1177 uint32_t end_h = 0;
1178 uint32_t start_v = 0;
1179 uint32_t end_v = 0;
1180
Casey Piper97d25272015-03-17 15:10:34 -07001181 struct mdss_hdmi_timing_info tinfo = {0};
1182 uint32_t ret = mdss_hdmi_get_timing_info(&tinfo, mdss_hdmi_video_fmt);
1183
1184 if (ret)
1185 return ERROR;
1186
1187 dprintf(INFO, "hdmi resolution %dx%d@p%dHz (%d)\n",
1188 tinfo.active_h, tinfo.active_v, tinfo.refresh_rate/1000,
1189 mdss_hdmi_video_fmt);
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001190
1191 total_h = tinfo.active_h + tinfo.front_porch_h +
1192 tinfo.back_porch_h + tinfo.pulse_width_h - 1;
1193 total_v = tinfo.active_v + tinfo.front_porch_v +
1194 tinfo.back_porch_v + tinfo.pulse_width_v - 1;
1195 if (((total_v << 16) & 0xE0000000) || (total_h & 0xFFFFE000)) {
1196 dprintf(CRITICAL,
1197 "%s: total v=%d or h=%d is larger than supported\n",
1198 __func__, total_v, total_h);
1199 return ERROR;
1200 }
1201 writel((total_v << 16) | (total_h << 0), HDMI_TOTAL);
1202
1203 start_h = tinfo.back_porch_h + tinfo.pulse_width_h;
1204 end_h = (total_h + 1) - tinfo.front_porch_h;
1205 if (((end_h << 16) & 0xE0000000) || (start_h & 0xFFFFE000)) {
1206 dprintf(CRITICAL,
1207 "%s: end_h=%d or start_h=%d is larger than supported\n",
1208 __func__, end_h, start_h);
1209 return ERROR;
1210 }
1211 writel((end_h << 16) | (start_h << 0), HDMI_ACTIVE_H);
1212
1213 start_v = tinfo.back_porch_v + tinfo.pulse_width_v - 1;
1214 end_v = total_v - tinfo.front_porch_v;
1215 if (((end_v << 16) & 0xE0000000) || (start_v & 0xFFFFE000)) {
1216 dprintf(CRITICAL,
1217 "%s: end_v=%d or start_v=%d is larger than supported\n",
1218 __func__, end_v, start_v);
1219 return ERROR;
1220 }
1221 writel((end_v << 16) | (start_v << 0), HDMI_ACTIVE_V);
1222
1223 if (tinfo.interlaced) {
1224 writel((total_v + 1) << 0, HDMI_V_TOTAL_F2);
1225 writel(((end_v + 1) << 16) | ((start_v + 1) << 0),
1226 HDMI_ACTIVE_V_F2);
1227 } else {
1228 writel(0, HDMI_V_TOTAL_F2);
1229 writel(0, HDMI_ACTIVE_V_F2);
1230 }
1231
1232 writel(((tinfo.interlaced << 31) & 0x80000000) |
1233 ((tinfo.active_low_h << 29) & 0x20000000) |
1234 ((tinfo.active_low_v << 28) & 0x10000000), HDMI_FRAME_CTRL);
1235
1236 return 0;
1237}
1238
Casey Piper97d25272015-03-17 15:10:34 -07001239static void mdss_hdmi_extract_extended_data_blocks(void)
1240{
1241 uint8_t len = 0;
1242 uint32_t start_offset = DBC_START_OFFSET;
1243 uint8_t const *etag = NULL;
1244 uint8_t *in_buf = mdss_hdmi_edid_buf;
1245
1246 do {
1247 /* A Tage code of 7 identifies extended data blocks */
1248 etag = hdmi_edid_find_block(start_offset,
1249 USE_EXTENDED_TAG, &len);
1250
1251 start_offset = etag - in_buf + len + 1;
1252
1253 /* The extended data block should at least be 2 bytes long */
1254 if (len < 2) {
1255 dprintf(SPEW, "%s: data block of len < 2 bytes\n",
1256 __func__);
1257 continue;
1258 }
1259
1260 /*
1261 * The second byte of the extended data block has the
1262 * extended tag code
1263 */
1264 switch (etag[1]) {
1265 case 0:
1266 /*
1267 * Check if the sink specifies underscan
1268 * support for:
1269 * BIT 5: preferred video format
1270 * BIT 3: IT video format
1271 * BIT 1: CE video format
1272 */
1273 pt_scan_info = (etag[2] & (BIT(4) | BIT(5))) >> 4;
1274 it_scan_info = (etag[2] & (BIT(3) | BIT(2))) >> 2;
1275 ce_scan_info = etag[2] & (BIT(1) | BIT(0));
1276
1277 dprintf(INFO, "scan Info (pt|it|ce): (%d|%d|%d)\n",
1278 pt_scan_info, it_scan_info, ce_scan_info);
1279 break;
1280 default:
1281 dprintf(SPEW, "%s: Tag Code %d not supported\n",
1282 __func__, etag[1]);
1283 break;
1284 }
1285 } while (etag != NULL);
1286}
1287
1288/*
1289 * If the sink specified support for both underscan/overscan then, by default,
1290 * set the underscan bit. Only checking underscan support for preferred
1291 * format and cea formats.
1292 */
1293uint8_t mdss_hdmi_get_scan_info(void)
1294{
1295 uint8_t scaninfo = 0;
1296 bool use_ce_scan_info = true;
1297
1298 mdss_hdmi_extract_extended_data_blocks();
1299
1300 if (mdss_hdmi_video_fmt == mdss_hdmi_pref_fmt) {
1301 use_ce_scan_info = false;
1302
1303 switch (pt_scan_info) {
1304 case 0:
1305 use_ce_scan_info = true;
1306 break;
1307 case 3:
1308 scaninfo = BIT(1);
1309 break;
1310 default:
1311 break;
1312 }
1313 }
1314
1315 if (use_ce_scan_info) {
1316 if (3 == ce_scan_info)
1317 scaninfo |= BIT(1);
1318 }
1319
1320 return scaninfo;
1321}
1322
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001323void mdss_hdmi_avi_info_frame(void)
1324{
1325 uint32_t sum;
1326 uint32_t reg_val;
1327 uint8_t checksum;
Tatenda Chipeperekwac50c8dd2016-02-23 18:59:08 -08001328 uint32_t i;
1329 struct hdmi_avi_infoframe_config avi_info = {0};
1330 struct mdss_hdmi_timing_info tinfo = {0};
1331 uint8_t avi_iframe[AVI_MAX_DATA_BYTES] = {0};
Casey Piper97d25272015-03-17 15:10:34 -07001332
Tatenda Chipeperekwac50c8dd2016-02-23 18:59:08 -08001333 mdss_hdmi_get_timing_info(&tinfo, mdss_hdmi_video_fmt);
1334
1335 /* Setup AVI Infoframe content */
1336 avi_info.scan_info = mdss_hdmi_get_scan_info();
1337 avi_info.bar_info.end_of_top_bar = 0x0;
1338 avi_info.bar_info.start_of_bottom_bar = tinfo.active_v + 1;
1339 avi_info.bar_info.end_of_left_bar = 0;
1340 avi_info.bar_info.start_of_right_bar = tinfo.active_h + 1;
1341 avi_info.act_fmt_info_present = true;
1342 avi_info.rgb_quantization_range = HDMI_QUANTIZATION_DEFAULT;
1343 avi_info.yuv_quantization_range = HDMI_QUANTIZATION_DEFAULT;
1344 avi_info.scaling_info = HDMI_SCALING_NONE;
1345 avi_info.colorimetry_info = 0;
1346 avi_info.ext_colorimetry_info = 0;
1347 avi_info.pixel_rpt_factor = 0;
1348
1349 /*
1350 * BYTE - 1:
1351 * 0:1 - Scan Information
1352 * 2:3 - Bar Info
1353 * 4 - Active Format Info present
1354 * 5:6 - Pixel format type;
1355 * 7 - Reserved;
1356 */
1357 avi_iframe[0] = (avi_info.scan_info & 0x3) |
1358 (avi_info.bar_info.vert_binfo_present ? BIT(2) : 0) |
1359 (avi_info.bar_info.horz_binfo_present ? BIT(3) : 0) |
1360 (avi_info.act_fmt_info_present ? BIT(4) : 0);
1361
1362 /*
1363 * BYTE - 2:
1364 * 0:3 - Active format info
1365 * 4:5 - Picture aspect ratio
1366 * 6:7 - Colorimetry info
1367 */
1368 avi_iframe[1] |= 0x08;
1369 if (tinfo.ar == HDMI_RES_AR_4_3)
1370 avi_iframe[1] |= (0x1 << 4);
1371 else if (tinfo.ar == HDMI_RES_AR_16_9)
1372 avi_iframe[1] |= (0x2 << 4);
1373
1374 avi_iframe[1] |= (avi_info.colorimetry_info & 0x3) << 6;
1375
1376 /*
1377 * BYTE - 3:
1378 * 0:1 - Scaling info
1379 * 2:3 - Quantization range
1380 * 4:6 - Extended Colorimetry
1381 * 7 - IT content
1382 */
1383 avi_iframe[2] |= (avi_info.scaling_info & 0x3) |
1384 ((avi_info.rgb_quantization_range & 0x3) << 2) |
1385 ((avi_info.ext_colorimetry_info & 0x7) << 4) |
1386 ((avi_info.is_it_content ? 0x1 : 0x0) << 7);
1387 /*
1388 * BYTE - 4:
1389 * 0:7 - VIC
1390 */
1391 if (tinfo.video_format < HDMI_VFRMT_END)
1392 avi_iframe[3] = tinfo.video_format;
1393
1394 /*
1395 * BYTE - 5:
1396 * 0:3 - Pixel Repeat factor
1397 * 4:5 - Content type
1398 * 6:7 - YCC Quantization range
1399 */
1400 avi_iframe[4] = (avi_info.pixel_rpt_factor & 0xF) |
1401 ((avi_info.content_type & 0x3) << 4) |
1402 ((avi_info.yuv_quantization_range & 0x3) << 6);
1403
1404 /* BYTE - 6,7: End of top bar */
1405 avi_iframe[5] = avi_info.bar_info.end_of_top_bar & 0xFF;
1406 avi_iframe[6] = ((avi_info.bar_info.end_of_top_bar & 0xFF00) >> 8);
1407
1408 /* BYTE - 8,9: Start of bottom bar */
1409 avi_iframe[7] = avi_info.bar_info.start_of_bottom_bar & 0xFF;
1410 avi_iframe[8] = ((avi_info.bar_info.start_of_bottom_bar & 0xFF00) >> 8);
1411
1412 /* BYTE - 10,11: Endof of left bar */
1413 avi_iframe[9] = avi_info.bar_info.end_of_left_bar & 0xFF;
1414 avi_iframe[10] = ((avi_info.bar_info.end_of_left_bar & 0xFF00) >> 8);
1415
1416 /* BYTE - 12,13: Start of right bar */
1417 avi_iframe[11] = avi_info.bar_info.start_of_right_bar & 0xFF;
1418 avi_iframe[12] = ((avi_info.bar_info.start_of_right_bar & 0xFF00) >> 8);
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001419
1420 sum = IFRAME_PACKET_OFFSET + AVI_IFRAME_TYPE +
1421 AVI_IFRAME_VERSION + AVI_MAX_DATA_BYTES;
1422
1423 for (i = 0; i < AVI_MAX_DATA_BYTES; i++)
Tatenda Chipeperekwac50c8dd2016-02-23 18:59:08 -08001424 sum += avi_iframe[i];
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001425 sum &= 0xFF;
1426 sum = 256 - sum;
1427 checksum = (uint8_t) sum;
1428
1429 reg_val = checksum |
Tatenda Chipeperekwac50c8dd2016-02-23 18:59:08 -08001430 LEFT_SHIFT_BYTE(avi_iframe[DATA_BYTE_1]) |
1431 LEFT_SHIFT_WORD(avi_iframe[DATA_BYTE_2]) |
1432 LEFT_SHIFT_24BITS(avi_iframe[DATA_BYTE_3]);
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001433 writel(reg_val, HDMI_AVI_INFO0);
1434
Tatenda Chipeperekwac50c8dd2016-02-23 18:59:08 -08001435 reg_val = avi_iframe[DATA_BYTE_4] |
1436 LEFT_SHIFT_BYTE(avi_iframe[DATA_BYTE_5]) |
1437 LEFT_SHIFT_WORD(avi_iframe[DATA_BYTE_6]) |
1438 LEFT_SHIFT_24BITS(avi_iframe[DATA_BYTE_7]);
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001439 writel(reg_val, HDMI_AVI_INFO1);
1440
Tatenda Chipeperekwac50c8dd2016-02-23 18:59:08 -08001441 reg_val = avi_iframe[DATA_BYTE_8] |
1442 LEFT_SHIFT_BYTE(avi_iframe[DATA_BYTE_9]) |
1443 LEFT_SHIFT_WORD(avi_iframe[DATA_BYTE_10]) |
1444 LEFT_SHIFT_24BITS(avi_iframe[DATA_BYTE_11]);
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001445 writel(reg_val, HDMI_AVI_INFO2);
1446
Tatenda Chipeperekwac50c8dd2016-02-23 18:59:08 -08001447 reg_val = avi_iframe[DATA_BYTE_12] |
1448 LEFT_SHIFT_BYTE(avi_iframe[DATA_BYTE_13]) |
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001449 LEFT_SHIFT_24BITS(AVI_IFRAME_VERSION);
1450 writel(reg_val, HDMI_AVI_INFO3);
1451
1452 /* AVI InfFrame enable (every frame) */
1453 writel(readl(HDMI_INFOFRAME_CTRL0) | BIT(1) | BIT(0),
Tatenda Chipeperekwac50c8dd2016-02-23 18:59:08 -08001454 HDMI_INFOFRAME_CTRL0);
1455
1456 reg_val = readl(HDMI_INFOFRAME_CTRL1);
1457 reg_val &= ~0x3F;
1458 reg_val |= AVI_IFRAME_LINE_NUMBER;
1459 writel(reg_val, HDMI_INFOFRAME_CTRL1);
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07001460}
1461
Tatenda Chipeperekwa6d683e62016-05-02 11:42:53 -07001462static int mdss_hdmi_ddc_check_status(char *what)
1463{
1464 uint32_t reg_val;
1465 int rc = 0;
1466
1467 /* Read DDC status */
1468 reg_val = readl(HDMI_DDC_SW_STATUS);
1469 reg_val &= BIT(12) | BIT(13) | BIT(14) | BIT(15);
1470
1471 /* Check if any NACK occurred */
1472 if (reg_val) {
1473 dprintf(SPEW, "%s: %s: NACK: HDMI_DDC_SW_STATUS 0x%x\n",
1474 __func__, what, reg_val);
1475
1476 /* SW_STATUS_RESET, SOFT_RESET */
1477 reg_val = BIT(3) | BIT(1);
1478
1479 writel(reg_val, HDMI_DDC_CTRL);
1480
1481 rc = ERROR;
1482 }
1483
1484 return rc;
1485}
1486
1487static void mdss_hdmi_ddc_trigger(struct hdmi_tx_ddc_data *ddc_data,
1488 enum trigger_mode mode, bool seg)
1489{
1490 uint32_t const seg_addr = 0x60, seg_num = 0x01;
1491 uint32_t ddc_ctrl_reg_val;
1492
1493 ddc_data->dev_addr &= 0xFE;
1494
1495 if (mode == TRIGGER_READ && seg) {
1496 writel(BIT(31) | (seg_addr << 8), HDMI_DDC_DATA);
1497 writel(seg_num << 8, HDMI_DDC_DATA);
1498 }
1499
1500 /* handle portion #1 */
1501 writel(BIT(31) | (ddc_data->dev_addr << 8), HDMI_DDC_DATA);
1502
1503 /* handle portion #2 */
1504 writel(ddc_data->offset << 8, HDMI_DDC_DATA);
1505
1506 if (mode == TRIGGER_READ) {
1507 /* handle portion #3 */
1508 writel((ddc_data->dev_addr | BIT(0)) << 8, HDMI_DDC_DATA);
1509
1510 /* HDMI_I2C_TRANSACTION0 */
1511 writel(BIT(12) | BIT(16), HDMI_DDC_TRANS0);
1512
1513 /* Write to HDMI_I2C_TRANSACTION1 */
1514 if (seg) {
1515 writel(BIT(12) | BIT(16), HDMI_DDC_TRANS1);
1516 writel(BIT(0) | BIT(12) | BIT(13) |
1517 (ddc_data->request_len << 16), HDMI_DDC_TRANS2);
1518
1519 ddc_ctrl_reg_val = BIT(0) | BIT(21);
1520 } else {
1521 writel(BIT(0) | BIT(12) | BIT(13) |
1522 (ddc_data->request_len << 16), HDMI_DDC_TRANS1);
1523
1524 ddc_ctrl_reg_val = BIT(0) | BIT(20);
1525 }
1526 } else {
1527 uint32_t ndx;
1528
1529 /* write buffer */
1530 for (ndx = 0; ndx < ddc_data->data_len; ++ndx)
1531 writel(((uint32_t)ddc_data->data_buf[ndx]) << 8,
1532 HDMI_DDC_DATA);
1533
1534 writel((ddc_data->data_len + 1) << 16 | BIT(12) | BIT(13),
1535 HDMI_DDC_TRANS0);
1536
1537 ddc_ctrl_reg_val = BIT(0);
1538 }
1539
1540 /* Trigger the I2C transfer */
1541 writel(ddc_ctrl_reg_val, HDMI_DDC_CTRL);
1542}
1543
1544static int mdss_hdmi_ddc_clear_irq(char *what)
1545{
1546 uint32_t ddc_int_ctrl, ddc_status, in_use, timeout;
1547 uint32_t sw_done_mask = BIT(2);
1548 uint32_t sw_done_ack = BIT(1);
1549 uint32_t in_use_by_sw = BIT(0);
1550 uint32_t in_use_by_hw = BIT(1);
1551
1552 /* clear and enable interrutps */
1553 ddc_int_ctrl = sw_done_mask | sw_done_ack;
1554
1555 writel(ddc_int_ctrl, HDMI_DDC_INT_CTRL);
1556
1557 /* wait until DDC HW is free */
1558 timeout = 100;
1559 do {
1560 ddc_status = readl(HDMI_DDC_HW_STATUS);
1561 in_use = ddc_status & (in_use_by_sw | in_use_by_hw);
1562 if (in_use) {
1563 dprintf(INFO, "%s: ddc is in use by %s, timeout(%d)\n",
1564 __func__,
1565 ddc_status & in_use_by_sw ? "sw" : "hw",
1566 timeout);
1567 udelay(100);
1568 }
1569 } while (in_use && --timeout);
1570
1571 if (!timeout) {
1572 dprintf(CRITICAL, "%s: %s: timed out\n", __func__, what);
1573 return ERROR;
1574 }
1575
1576 return 0;
1577}
1578
1579static int mdss_hdmi_ddc_read_retry(struct hdmi_tx_ddc_data *ddc_data)
1580{
1581 uint32_t reg_val, ndx;
1582 int status, rc;
1583
1584 if (!ddc_data) {
1585 dprintf(CRITICAL, "%s: invalid input\n", __func__);
1586 return ERROR;
1587 }
1588
1589 if (!ddc_data->data_buf) {
1590 status = ERROR;
1591 dprintf(CRITICAL, "%s: %s: invalid buf\n",
1592 __func__, ddc_data->what);
1593 goto error;
1594 }
1595
1596 if (ddc_data->retry < 0) {
1597 dprintf(CRITICAL, "%s: invalid no. of retries %d\n",
1598 __func__, ddc_data->retry);
1599 status = ERROR;
1600 goto error;
1601 }
1602
1603 do {
1604 status = mdss_hdmi_ddc_clear_irq(ddc_data->what);
1605 if (status)
1606 continue;
1607
1608 mdss_hdmi_ddc_trigger(ddc_data, TRIGGER_READ, false);
1609
1610 dprintf(SPEW, "%s: ddc read done\n", __func__);
1611
1612 rc = mdss_hdmi_ddc_check_status(ddc_data->what);
1613
1614 if (!status)
1615 status = rc;
1616
1617 udelay(HDMI_DDC_TRANSACTION_DELAY_US);
1618 } while (status && ddc_data->retry--);
1619
1620 if (status)
1621 goto error;
1622
1623 /* Write data to DDC buffer */
1624 writel(BIT(0) | (3 << 16) | BIT(31), HDMI_DDC_DATA);
1625
1626 /* Discard first byte */
1627 readl(HDMI_DDC_DATA);
1628 for (ndx = 0; ndx < ddc_data->data_len; ++ndx) {
1629 reg_val = readl(HDMI_DDC_DATA);
1630 ddc_data->data_buf[ndx] = (uint8_t)((reg_val & 0x0000FF00) >> 8);
1631 }
1632
1633 dprintf(SPEW, "%s: %s: success\n", __func__, ddc_data->what);
1634error:
1635 return status;
1636}
1637
1638static int mdss_hdmi_ddc_read(struct hdmi_tx_ddc_data *ddc_data)
1639{
1640 int rc = 0;
1641 int retry;
1642
1643 if (!ddc_data) {
1644 dprintf(CRITICAL, "%s: invalid ddc data\n", __func__);
1645 return ERROR;
1646 }
1647
1648 retry = ddc_data->retry;
1649
1650 rc = mdss_hdmi_ddc_read_retry(ddc_data);
1651 if (!rc)
1652 return rc;
1653
1654 if (ddc_data->retry_align) {
1655 ddc_data->retry = retry;
1656
1657 ddc_data->request_len = 32 * ((ddc_data->data_len + 31) / 32);
1658 rc = mdss_hdmi_ddc_read_retry(ddc_data);
1659 }
1660
1661 return rc;
1662}
1663
1664static int mdss_hdmi_ddc_write(struct hdmi_tx_ddc_data *ddc_data)
1665{
1666 int status, rc;
1667
1668 if (!ddc_data->data_buf) {
1669 status = ERROR;
1670 dprintf(CRITICAL, "%s: %s: invalid buf\n",
1671 __func__, ddc_data->what);
1672 goto error;
1673 }
1674
1675 if (ddc_data->retry < 0) {
1676 dprintf(CRITICAL, "%s: invalid no. of retries %d\n",
1677 __func__, ddc_data->retry);
1678 status = ERROR;
1679 goto error;
1680 }
1681
1682 do {
1683 status = mdss_hdmi_ddc_clear_irq(ddc_data->what);
1684 if (status)
1685 continue;
1686
1687 mdss_hdmi_ddc_trigger(ddc_data, TRIGGER_WRITE, false);
1688
1689 dprintf(SPEW, "%s: DDC write done\n", __func__);
1690
1691 rc = mdss_hdmi_ddc_check_status(ddc_data->what);
1692
1693 if (!status)
1694 status = rc;
1695
1696 udelay(HDMI_DDC_TRANSACTION_DELAY_US);
1697 } while (status && ddc_data->retry--);
1698
1699 if (status)
1700 goto error;
1701
1702 dprintf(SPEW, "%s: %s: success\n", __func__, ddc_data->what);
1703error:
1704 return status;
1705}
1706
1707static inline char *mdss_hdmi_scdc_reg2string(uint32_t type)
1708{
1709 switch (type) {
1710 case SCDC_SCRAMBLING_STATUS:
1711 return "SCDC_SCRAMBLING_STATUS";
1712 case SCDC_SCRAMBLING_ENABLE:
1713 return "SCDC_SCRAMBLING_ENABLE";
1714 case SCDC_TMDS_BIT_CLOCK_RATIO_UPDATE:
1715 return "SCDC_TMDS_BIT_CLOCK_RATIO_UPDATE";
1716 case SCDC_CLOCK_DET_STATUS:
1717 return "SCDC_CLOCK_DET_STATUS";
1718 case SCDC_CH0_LOCK_STATUS:
1719 return "SCDC_CH0_LOCK_STATUS";
1720 case SCDC_CH1_LOCK_STATUS:
1721 return "SCDC_CH1_LOCK_STATUS";
1722 case SCDC_CH2_LOCK_STATUS:
1723 return "SCDC_CH2_LOCK_STATUS";
1724 case SCDC_CH0_ERROR_COUNT:
1725 return "SCDC_CH0_ERROR_COUNT";
1726 case SCDC_CH1_ERROR_COUNT:
1727 return "SCDC_CH1_ERROR_COUNT";
1728 case SCDC_CH2_ERROR_COUNT:
1729 return "SCDC_CH2_ERROR_COUNT";
1730 case SCDC_READ_ENABLE:
1731 return"SCDC_READ_ENABLE";
1732 default:
1733 return HDMI_SCDC_UNKNOWN_REGISTER;
1734 }
1735}
1736
1737static int mdss_hdmi_scdc_write(uint32_t data_type, uint32_t val)
1738{
1739 struct hdmi_tx_ddc_data data = {0};
1740 struct hdmi_tx_ddc_data rdata = {0};
1741 int rc = 0;
1742 uint8_t data_buf[2] = {0};
1743 uint8_t read_val = 0;
1744
1745 if (data_type >= SCDC_MAX) {
1746 dprintf(CRITICAL, "Unsupported data type\n");
1747 return ERROR;
1748 }
1749
1750 data.what = mdss_hdmi_scdc_reg2string(data_type);
1751 data.dev_addr = 0xA8;
1752 data.retry = 1;
1753 data.data_buf = data_buf;
1754
1755 switch (data_type) {
1756 case SCDC_SCRAMBLING_ENABLE:
1757 case SCDC_TMDS_BIT_CLOCK_RATIO_UPDATE:
1758 rdata.what = "TMDS CONFIG";
1759 rdata.dev_addr = 0xA8;
1760 rdata.retry = 2;
1761 rdata.data_buf = &read_val;
1762 rdata.data_len = 1;
1763 rdata.offset = HDMI_SCDC_TMDS_CONFIG;
1764 rdata.request_len = 1;
1765 rc = mdss_hdmi_ddc_read(&rdata);
1766 if (rc) {
1767 dprintf(CRITICAL, "scdc read failed\n");
1768 return rc;
1769 }
1770 if (data_type == SCDC_SCRAMBLING_ENABLE) {
1771 data_buf[0] = ((((uint8_t)(read_val & 0xFF)) & (~BIT(0))) |
1772 ((uint8_t)(val & BIT(0))));
1773 } else {
1774 data_buf[0] = ((((uint8_t)(read_val & 0xFF)) & (~BIT(1))) |
1775 (((uint8_t)(val & BIT(0))) << 1));
1776 }
1777 data.data_len = 1;
1778 data.request_len = 1;
1779 data.offset = HDMI_SCDC_TMDS_CONFIG;
1780 break;
1781 case SCDC_READ_ENABLE:
1782 data.data_len = 1;
1783 data.request_len = 1;
1784 data.offset = HDMI_SCDC_CONFIG_0;
1785 data_buf[0] = (uint8_t)(val & 0x1);
1786 break;
1787 default:
1788 dprintf(CRITICAL, "Cannot write to read only reg (%d)\n",
1789 data_type);
1790 return ERROR;
1791 }
1792
1793 rc = mdss_hdmi_ddc_write(&data);
1794 if (rc) {
1795 dprintf(CRITICAL, "DDC Read failed for %s\n", data.what);
1796 return rc;
1797 }
1798
1799 return 0;
1800}
1801
1802static inline int mdss_hdmi_get_v_total(const struct mdss_hdmi_timing_info *t)
1803{
1804 if (t) {
1805 return t->active_v + t->front_porch_v + t->pulse_width_v +
1806 t->back_porch_v;
1807 }
1808
1809 return 0;
1810}
1811
1812static int mdss_hdmi_get_timeout_in_hysnc(struct mdss_hdmi_timing_info *timing,
1813 uint32_t timeout_ms)
1814{
1815 uint32_t fps, v_total;
1816 uint32_t time_taken_by_one_line_us, lines_needed_for_given_time;
1817
1818 if (!timing || !timeout_ms) {
1819 dprintf(CRITICAL, "invalid input\n");
1820 return ERROR;
1821 }
1822
1823 fps = timing->refresh_rate / HDMI_KHZ_TO_HZ;
1824 v_total = mdss_hdmi_get_v_total(timing);
1825
1826 /*
1827 * pixel clock = h_total * v_total * fps
1828 * 1 sec = pixel clock number of pixels are transmitted.
1829 * time taken by one line (h_total) = 1 / (v_total * fps).
1830 */
1831 time_taken_by_one_line_us = HDMI_SEC_TO_US / (v_total * fps);
1832 lines_needed_for_given_time = (timeout_ms * HDMI_MS_TO_US) /
1833 time_taken_by_one_line_us;
1834
1835 return lines_needed_for_given_time;
1836}
1837
1838static void mdss_hdmi_scrambler_ddc_reset()
1839{
1840 uint32_t reg_val;
1841
1842 /* clear ack and disable interrupts */
1843 reg_val = BIT(14) | BIT(9) | BIT(5) | BIT(1);
1844 writel(reg_val, HDMI_DDC_INT_CTRL2);
1845
1846 /* Reset DDC timers */
1847 reg_val = BIT(0) | readl(HDMI_SCRAMBLER_STATUS_DDC_CTRL);
1848 writel(reg_val, HDMI_SCRAMBLER_STATUS_DDC_CTRL);
1849
1850 reg_val = readl(HDMI_SCRAMBLER_STATUS_DDC_CTRL);
1851 reg_val &= ~BIT(0);
1852 writel(reg_val, HDMI_SCRAMBLER_STATUS_DDC_CTRL);
1853}
1854
1855static void mdss_hdmi_scrambler_ddc_disable()
1856{
1857 uint32_t reg_val;
1858
1859 mdss_hdmi_scrambler_ddc_reset();
1860
1861 /* Disable HW DDC access to RxStatus register */
1862 reg_val = readl(HDMI_HW_DDC_CTRL);
1863 reg_val &= ~(BIT(8) | BIT(9));
1864
1865 writel(reg_val, HDMI_HW_DDC_CTRL);
1866}
1867
1868static int mdss_hdmi_scrambler_ddc_check_status()
1869{
1870 int rc = 0;
1871 uint32_t reg_val;
1872
1873 /* check for errors and clear status */
1874 reg_val = readl(HDMI_SCRAMBLER_STATUS_DDC_STATUS);
1875
1876 if (reg_val & BIT(4)) {
1877 dprintf(CRITICAL, "ddc aborted\n");
1878 reg_val |= BIT(5);
1879 rc = ERROR;
1880 }
1881
1882 if (reg_val & BIT(8)) {
1883 dprintf(CRITICAL, "timed out\n");
1884 reg_val |= BIT(9);
1885 rc = ERROR;
1886 }
1887
1888 if (reg_val & BIT(12)) {
1889 dprintf(CRITICAL, "NACK0\n");
1890 reg_val |= BIT(13);
1891 rc = ERROR;
1892 }
1893
1894 if (reg_val & BIT(14)) {
1895 dprintf(CRITICAL, "NACK1\n");
1896 reg_val |= BIT(15);
1897 rc = ERROR;
1898 }
1899
1900 writel(reg_val, HDMI_SCRAMBLER_STATUS_DDC_STATUS);
1901
1902 return rc;
1903}
1904
1905static int mdss_hdmi_scrambler_status_timer_setup(uint32_t timeout_hsync)
1906{
1907 uint32_t reg_val;
1908 int rc;
1909
1910 mdss_hdmi_ddc_clear_irq("scrambler");
1911
1912 writel(timeout_hsync, HDMI_SCRAMBLER_STATUS_DDC_TIMER_CTRL);
1913 writel(timeout_hsync, HDMI_SCRAMBLER_STATUS_DDC_TIMER_CTRL2);
1914
1915 reg_val = readl(HDMI_DDC_INT_CTRL5);
1916 reg_val |= BIT(10);
1917 writel(reg_val, HDMI_DDC_INT_CTRL5);
1918
1919 reg_val = readl(HDMI_DDC_INT_CTRL2);
1920 /* Trigger interrupt if scrambler status is 0 or DDC failure */
1921 reg_val |= BIT(10);
1922 reg_val &= ~(BIT(15) | BIT(16));
1923 reg_val |= BIT(16);
1924 writel(reg_val, HDMI_DDC_INT_CTRL2);
1925
1926 /* Enable DDC access */
1927 reg_val = readl(HDMI_HW_DDC_CTRL);
1928
1929 reg_val &= ~(BIT(8) | BIT(9));
1930 reg_val |= BIT(8);
1931 writel(reg_val, HDMI_HW_DDC_CTRL);
1932
1933 /* WAIT for 200ms as per HDMI 2.0 standard for sink to respond */
1934 udelay(2000);
1935
1936 /* clear the scrambler status */
1937 rc = mdss_hdmi_scrambler_ddc_check_status();
1938 if (rc)
1939 dprintf(CRITICAL, "scrambling ddc error %d\n", rc);
1940
1941 mdss_hdmi_scrambler_ddc_disable();
1942
1943 return rc;
1944}
1945
1946static int mdss_hdmi_setup_ddc_timers(uint32_t type, uint32_t to_in_num_lines)
1947{
1948 if (type >= DDC_TIMER_MAX) {
1949 dprintf(CRITICAL, "Invalid timer type %d\n", type);
1950 return ERROR;
1951 }
1952
1953 switch (type) {
1954 case DDC_TIMER_SCRAMBLER_STATUS:
1955 mdss_hdmi_scrambler_status_timer_setup(to_in_num_lines);
1956 break;
1957 default:
1958 dprintf(CRITICAL, "%d type not supported\n", type);
1959 return ERROR;
1960 }
1961
1962 return 0;
1963}
1964
1965static int mdss_hdmi_setup_scrambler()
1966{
1967 int rc = 0;
1968 uint32_t reg_val = 0;
1969 uint32_t tmds_clock_ratio = 0;
1970 bool scrambler_on = false;
1971 struct mdss_hdmi_timing_info timing = {0};
1972 mdss_hdmi_get_timing_info(&timing, mdss_hdmi_video_fmt);
1973 int timeout_hsync;
1974
1975 /* Scrambling is supported from HDMI TX 4.0 */
1976 reg_val = readl(HDMI_VERSION);
1977 reg_val = (reg_val & 0xF0000000) >> 28;
1978 if (reg_val < HDMI_TX_SCRAMBLER_MIN_TX_VERSION) {
1979 dprintf(INFO, "%s: HDMI TX does not support scrambling\n",
1980 __func__);
1981 return 0;
1982 }
1983
1984 if (timing.pixel_freq > HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ) {
1985 scrambler_on = true;
1986 tmds_clock_ratio = 1;
1987 }
1988
1989 dprintf(SPEW, "%s: freq=%d, scrambler=%d, clock_ratio=%d\n",
1990 __func__, timing.pixel_freq, scrambler_on,
1991 tmds_clock_ratio);
1992
1993 if (scrambler_on) {
1994 rc = mdss_hdmi_scdc_write(SCDC_TMDS_BIT_CLOCK_RATIO_UPDATE,
1995 tmds_clock_ratio);
1996 if (rc) {
1997 dprintf(CRITICAL, "%s: TMDS CLK RATIO ERR\n", __func__);
1998 return rc;
1999 }
2000
2001 reg_val = readl(HDMI_CTRL);
2002 reg_val |= BIT(31); /* Enable Update DATAPATH_MODE */
2003 reg_val |= BIT(28); /* Set SCRAMBLER_EN bit */
2004
2005 writel(reg_val, HDMI_CTRL);
2006
2007 rc = mdss_hdmi_scdc_write(SCDC_SCRAMBLING_ENABLE, 0x1);
2008 if (rc) {
2009 dprintf(CRITICAL, "%s: failed to enable scrambling\n",
2010 __func__);
2011 return rc;
2012 }
2013
2014 /*
2015 * Setup hardware to periodically check for scrambler
2016 * status bit on the sink. Sink should set this bit
2017 * with in 200ms after scrambler is enabled.
2018 */
2019 timeout_hsync = mdss_hdmi_get_timeout_in_hysnc(&timing,
2020 HDMI_TX_SCRAMBLER_TIMEOUT_MSEC);
2021
2022 if (timeout_hsync <= 0) {
2023 dprintf(CRITICAL, "%s: err in timeout hsync calc\n",
2024 __func__);
2025 timeout_hsync = HDMI_DEFAULT_TIMEOUT_HSYNC;
2026 }
2027
2028 dprintf(SPEW, "%s: timeout for scrambling en: %d hsyncs\n",
2029 __func__, timeout_hsync);
2030
2031 rc = mdss_hdmi_setup_ddc_timers(DDC_TIMER_SCRAMBLER_STATUS,
2032 timeout_hsync);
2033 } else {
2034 mdss_hdmi_scdc_write(SCDC_SCRAMBLING_ENABLE, 0x0);
2035 }
2036
2037 return rc;
2038}
2039
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07002040int mdss_hdmi_init(void)
2041{
Ajay Singh Parmar9ddfa572015-02-17 12:49:53 -08002042 bool is_dvi_mode = mdss_hdmi_is_dvi_mode();
2043
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07002044 mdss_hdmi_set_mode(false);
2045
Tatenda Chipeperekwa6d683e62016-05-02 11:42:53 -07002046 /* Enable USEC REF timer */
2047 writel(0x0001001B, HDMI_USEC_REFTIMER);
2048
Ajay Singh Parmara1771a12014-08-13 15:56:11 -07002049 /* Audio settings */
Ajay Singh Parmar9ddfa572015-02-17 12:49:53 -08002050 if (!is_dvi_mode)
2051 mdss_hdmi_audio_playback();
Ajay Singh Parmara1771a12014-08-13 15:56:11 -07002052
2053 /* Video settings */
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07002054 mdss_hdmi_video_setup();
2055
Ajay Singh Parmara1771a12014-08-13 15:56:11 -07002056 /* AVI info settings */
Ajay Singh Parmar9ddfa572015-02-17 12:49:53 -08002057 if (!is_dvi_mode)
2058 mdss_hdmi_avi_info_frame();
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07002059
Ajay Singh Parmara1771a12014-08-13 15:56:11 -07002060 /* Enable HDMI */
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07002061 mdss_hdmi_set_mode(true);
2062
Tatenda Chipeperekwa6d683e62016-05-02 11:42:53 -07002063 mdss_hdmi_setup_scrambler();
2064
Ajay Singh Parmar243d82b2014-07-23 23:01:44 -07002065 return 0;
2066}