blob: 3823d3be27f25f12535d7836d506c6a06b368769 [file] [log] [blame]
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301/* Copyright (c) 2010-2016, 2018, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#define pr_fmt(fmt) "%s: " fmt, __func__
15
16#include <linux/bitops.h>
17#include <linux/delay.h>
18#include <linux/module.h>
19#include <linux/types.h>
20#include <linux/types.h>
21
22#include "video/msm_hdmi_modes.h"
23#include "mdss_debug.h"
24#include "mdss_fb.h"
25#include "mdss.h"
26#include "mdss_hdmi_util.h"
27#include "mdss_panel.h"
28#include "mdss_hdmi_panel.h"
29
30#define HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ 340000
31#define HDMI_TX_SCRAMBLER_TIMEOUT_MSEC 200
32
33#define HDMI_TX_KHZ_TO_HZ 1000U
34
35/* AVI INFOFRAME DATA */
36#define NUM_MODES_AVI 20
37#define AVI_MAX_DATA_BYTES 13
38
39/* Line numbers at which AVI Infoframe and Vendor Infoframe will be sent */
40#define AVI_IFRAME_LINE_NUMBER 1
41#define VENDOR_IFRAME_LINE_NUMBER 3
42
43#define IFRAME_CHECKSUM_32(d) \
44 ((d & 0xff) + ((d >> 8) & 0xff) + \
45 ((d >> 16) & 0xff) + ((d >> 24) & 0xff))
46
47#define IFRAME_PACKET_OFFSET 0x80
48/*
49 * InfoFrame Type Code:
50 * 0x0 - Reserved
51 * 0x1 - Vendor Specific
52 * 0x2 - Auxiliary Video Information
53 * 0x3 - Source Product Description
54 * 0x4 - AUDIO
55 * 0x5 - MPEG Source
56 * 0x6 - NTSC VBI
57 * 0x7 - 0xFF - Reserved
58 */
59#define AVI_IFRAME_TYPE 0x2
60#define AVI_IFRAME_VERSION 0x2
61#define LEFT_SHIFT_BYTE(x) ((x) << 8)
62#define LEFT_SHIFT_WORD(x) ((x) << 16)
63#define LEFT_SHIFT_24BITS(x) ((x) << 24)
64
65/* AVI Infoframe data byte 3, bit 7 (msb) represents ITC bit */
66#define SET_ITC_BIT(byte) (byte = (byte | BIT(7)))
67#define CLR_ITC_BIT(byte) (byte = (byte & ~BIT(7)))
68
69/*
70 * CN represents IT content type, if ITC bit in infoframe data byte 3
71 * is set, CN bits will represent content type as below:
72 * 0b00 Graphics
73 * 0b01 Photo
74 * 0b10 Cinema
75 * 0b11 Game
76 */
77#define CONFIG_CN_BITS(bits, byte) \
78 (byte = (byte & ~(BIT(4) | BIT(5))) |\
79 ((bits & (BIT(0) | BIT(1))) << 4))
80
81struct hdmi_avi_iframe_bar_info {
82 bool vert_binfo_present;
83 bool horz_binfo_present;
84 u32 end_of_top_bar;
85 u32 start_of_bottom_bar;
86 u32 end_of_left_bar;
87 u32 start_of_right_bar;
88};
89
90struct hdmi_avi_infoframe_config {
91 u32 pixel_format;
92 u32 scan_info;
93 bool act_fmt_info_present;
94 u32 colorimetry_info;
95 u32 ext_colorimetry_info;
96 u32 rgb_quantization_range;
97 u32 yuv_quantization_range;
98 u32 scaling_info;
99 bool is_it_content;
100 u8 content_type;
101 u8 pixel_rpt_factor;
102 struct hdmi_avi_iframe_bar_info bar_info;
103};
104
105struct hdmi_video_config {
106 struct msm_hdmi_mode_timing_info *timing;
107 struct hdmi_avi_infoframe_config avi_iframe;
108};
109
110struct hdmi_panel {
Sachin Bhayare5076e252018-01-18 14:56:45 +0530111 struct mdss_io_data *io;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530112 struct hdmi_util_ds_data *ds_data;
113 struct hdmi_panel_data *data;
114 struct hdmi_video_config vid_cfg;
115 struct hdmi_tx_ddc_ctrl *ddc;
116 u32 version;
117 u32 vic;
118 u8 *spd_vendor_name;
119 u8 *spd_product_description;
120 bool on;
121 bool scrambler_enabled;
122};
123
124enum {
125 DATA_BYTE_1,
126 DATA_BYTE_2,
127 DATA_BYTE_3,
128 DATA_BYTE_4,
129 DATA_BYTE_5,
130 DATA_BYTE_6,
131 DATA_BYTE_7,
132 DATA_BYTE_8,
133 DATA_BYTE_9,
134 DATA_BYTE_10,
135 DATA_BYTE_11,
136 DATA_BYTE_12,
137 DATA_BYTE_13,
138};
139
140enum hdmi_quantization_range {
141 HDMI_QUANTIZATION_DEFAULT,
142 HDMI_QUANTIZATION_LIMITED_RANGE,
143 HDMI_QUANTIZATION_FULL_RANGE
144};
145
146enum hdmi_scaling_info {
147 HDMI_SCALING_NONE,
148 HDMI_SCALING_HORZ,
149 HDMI_SCALING_VERT,
150 HDMI_SCALING_HORZ_VERT,
151};
152
153static int hdmi_panel_get_vic(struct mdss_panel_info *pinfo,
154 struct hdmi_util_ds_data *ds_data)
155{
156 int new_vic = -1;
157 u32 h_total, v_total;
158 struct msm_hdmi_mode_timing_info timing;
159
160 if (!pinfo) {
161 pr_err("invalid panel data\n");
162 return -EINVAL;
163 }
164
165 if (pinfo->vic) {
166 struct msm_hdmi_mode_timing_info info = {0};
167 u32 ret = hdmi_get_supported_mode(&info, ds_data, pinfo->vic);
168 u32 supported = info.supported;
169
170 if (!ret && supported) {
171 new_vic = pinfo->vic;
172 } else {
173 pr_err("invalid or not supported vic %d\n",
174 pinfo->vic);
175 return -EPERM;
176 }
177 } else {
178 timing.active_h = pinfo->xres;
179 timing.back_porch_h = pinfo->lcdc.h_back_porch;
180 timing.front_porch_h = pinfo->lcdc.h_front_porch;
181 timing.pulse_width_h = pinfo->lcdc.h_pulse_width;
182
183 h_total = timing.active_h + timing.back_porch_h +
184 timing.front_porch_h + timing.pulse_width_h;
185
186 pr_debug("ah=%d bph=%d fph=%d pwh=%d ht=%d\n",
187 timing.active_h, timing.back_porch_h,
188 timing.front_porch_h, timing.pulse_width_h,
189 h_total);
190
191 timing.active_v = pinfo->yres;
192 timing.back_porch_v = pinfo->lcdc.v_back_porch;
193 timing.front_porch_v = pinfo->lcdc.v_front_porch;
194 timing.pulse_width_v = pinfo->lcdc.v_pulse_width;
195
196 v_total = timing.active_v + timing.back_porch_v +
197 timing.front_porch_v + timing.pulse_width_v;
198
199 pr_debug("av=%d bpv=%d fpv=%d pwv=%d vt=%d\n",
200 timing.active_v, timing.back_porch_v,
201 timing.front_porch_v, timing.pulse_width_v, v_total);
202
203 timing.pixel_freq = ((unsigned long int)pinfo->clk_rate / 1000);
204 if (h_total && v_total) {
205 timing.refresh_rate = ((timing.pixel_freq * 1000) /
206 (h_total * v_total)) * 1000;
207 } else {
208 pr_err("cannot cal refresh rate\n");
209 return -EPERM;
210 }
211
212 pr_debug("pixel_freq=%d refresh_rate=%d\n",
213 timing.pixel_freq, timing.refresh_rate);
214
215 new_vic = hdmi_get_video_id_code(&timing, ds_data);
216 }
217
218 return new_vic;
219}
220
221static void hdmi_panel_update_dfps_data(struct hdmi_panel *panel)
222{
223 struct mdss_panel_info *pinfo = panel->data->pinfo;
224
225 pinfo->saved_total = mdss_panel_get_htotal(pinfo, true);
226 pinfo->saved_fporch = panel->vid_cfg.timing->front_porch_h;
227
228 pinfo->current_fps = panel->vid_cfg.timing->refresh_rate;
229 pinfo->default_fps = panel->vid_cfg.timing->refresh_rate;
230 pinfo->lcdc.frame_rate = panel->vid_cfg.timing->refresh_rate;
231}
232
233static int hdmi_panel_config_avi(struct hdmi_panel *panel)
234{
235 struct mdss_panel_info *pinfo = panel->data->pinfo;
236 struct hdmi_video_config *vid_cfg = &panel->vid_cfg;
237 struct hdmi_avi_infoframe_config *avi = &vid_cfg->avi_iframe;
238 struct msm_hdmi_mode_timing_info *timing;
239 u32 ret = 0;
240
241 timing = panel->vid_cfg.timing;
242 if (!timing) {
243 pr_err("fmt not supported: %d\n", panel->vic);
244 ret = -EPERM;
245 goto end;
246 }
247
248 /* Setup AVI Infoframe content */
249 avi->pixel_format = pinfo->out_format;
250 avi->is_it_content = panel->data->is_it_content;
251 avi->content_type = panel->data->content_type;
252 avi->scan_info = panel->data->scan_info;
253
254 avi->bar_info.end_of_top_bar = 0x0;
255 avi->bar_info.start_of_bottom_bar = timing->active_v + 1;
256 avi->bar_info.end_of_left_bar = 0;
257 avi->bar_info.start_of_right_bar = timing->active_h + 1;
258
259 avi->act_fmt_info_present = true;
260 avi->rgb_quantization_range = HDMI_QUANTIZATION_DEFAULT;
261 avi->yuv_quantization_range = HDMI_QUANTIZATION_DEFAULT;
262
263 avi->scaling_info = HDMI_SCALING_NONE;
264
265 avi->colorimetry_info = 0;
266 avi->ext_colorimetry_info = 0;
267
268 avi->pixel_rpt_factor = 0;
269end:
270 return ret;
271}
272
273static int hdmi_panel_setup_video(struct hdmi_panel *panel)
274{
275 u32 total_h, start_h, end_h;
276 u32 total_v, start_v, end_v;
277 u32 div = 0;
Sachin Bhayare5076e252018-01-18 14:56:45 +0530278 struct mdss_io_data *io = panel->io;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530279 struct msm_hdmi_mode_timing_info *timing;
280
281 timing = panel->vid_cfg.timing;
282 if (!timing) {
283 pr_err("fmt not supported: %d\n", panel->vic);
284 return -EPERM;
285 }
286
287 /* reduce horizontal params by half for YUV420 output */
288 if (panel->vid_cfg.avi_iframe.pixel_format == MDP_Y_CBCR_H2V2)
289 div = 1;
290
291 total_h = (hdmi_tx_get_h_total(timing) >> div) - 1;
292 total_v = hdmi_tx_get_v_total(timing) - 1;
293
294 if (((total_v << 16) & 0xE0000000) || (total_h & 0xFFFFE000)) {
295 pr_err("total v=%d or h=%d is larger than supported\n",
296 total_v, total_h);
297 return -EPERM;
298 }
299 DSS_REG_W(io, HDMI_TOTAL, (total_v << 16) | (total_h << 0));
300
301 start_h = (timing->back_porch_h >> div) +
302 (timing->pulse_width_h >> div);
303 end_h = (total_h + 1) - (timing->front_porch_h >> div);
304 if (((end_h << 16) & 0xE0000000) || (start_h & 0xFFFFE000)) {
305 pr_err("end_h=%d or start_h=%d is larger than supported\n",
306 end_h, start_h);
307 return -EPERM;
308 }
309 DSS_REG_W(io, HDMI_ACTIVE_H, (end_h << 16) | (start_h << 0));
310
311 start_v = timing->back_porch_v + timing->pulse_width_v - 1;
312 end_v = total_v - timing->front_porch_v;
313 if (((end_v << 16) & 0xE0000000) || (start_v & 0xFFFFE000)) {
314 pr_err("end_v=%d or start_v=%d is larger than supported\n",
315 end_v, start_v);
316 return -EPERM;
317 }
318 DSS_REG_W(io, HDMI_ACTIVE_V, (end_v << 16) | (start_v << 0));
319
320 if (timing->interlaced) {
321 DSS_REG_W(io, HDMI_V_TOTAL_F2, (total_v + 1) << 0);
322 DSS_REG_W(io, HDMI_ACTIVE_V_F2,
323 ((end_v + 1) << 16) | ((start_v + 1) << 0));
324 } else {
325 DSS_REG_W(io, HDMI_V_TOTAL_F2, 0);
326 DSS_REG_W(io, HDMI_ACTIVE_V_F2, 0);
327 }
328
329 DSS_REG_W(io, HDMI_FRAME_CTRL,
330 ((timing->interlaced << 31) & 0x80000000) |
331 ((timing->active_low_h << 29) & 0x20000000) |
332 ((timing->active_low_v << 28) & 0x10000000));
333
334 hdmi_panel_update_dfps_data(panel);
335
336 return 0;
337}
338
339static void hdmi_panel_set_avi_infoframe(struct hdmi_panel *panel)
340{
341 int i;
342 u8 avi_iframe[AVI_MAX_DATA_BYTES] = {0};
343 u8 checksum;
344 u32 sum, reg_val;
Sachin Bhayare5076e252018-01-18 14:56:45 +0530345 struct mdss_io_data *io = panel->io;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530346 struct hdmi_avi_infoframe_config *avi;
347 struct msm_hdmi_mode_timing_info *timing;
348
349 avi = &panel->vid_cfg.avi_iframe;
350 timing = panel->vid_cfg.timing;
351
352 /*
353 * BYTE - 1:
354 * 0:1 - Scan Information
355 * 2:3 - Bar Info
356 * 4 - Active Format Info present
357 * 5:6 - Pixel format type;
358 * 7 - Reserved;
359 */
360 avi_iframe[0] = (avi->scan_info & 0x3) |
361 (avi->bar_info.vert_binfo_present ? BIT(2) : 0) |
362 (avi->bar_info.horz_binfo_present ? BIT(3) : 0) |
363 (avi->act_fmt_info_present ? BIT(4) : 0);
364 if (avi->pixel_format == MDP_Y_CBCR_H2V2)
365 avi_iframe[0] |= (0x3 << 5);
366 else if (avi->pixel_format == MDP_Y_CBCR_H2V1)
367 avi_iframe[0] |= (0x1 << 5);
368 else if (avi->pixel_format == MDP_Y_CBCR_H1V1)
369 avi_iframe[0] |= (0x2 << 5);
370
371 /*
372 * BYTE - 2:
373 * 0:3 - Active format info
374 * 4:5 - Picture aspect ratio
375 * 6:7 - Colorimetry info
376 */
377 avi_iframe[1] |= 0x08;
378 if (timing->ar == HDMI_RES_AR_4_3)
379 avi_iframe[1] |= (0x1 << 4);
380 else if (timing->ar == HDMI_RES_AR_16_9)
381 avi_iframe[1] |= (0x2 << 4);
382
383 avi_iframe[1] |= (avi->colorimetry_info & 0x3) << 6;
384
385 /*
386 * BYTE - 3:
387 * 0:1 - Scaling info
388 * 2:3 - Quantization range
389 * 4:6 - Extended Colorimetry
390 * 7 - IT content
391 */
392 avi_iframe[2] |= (avi->scaling_info & 0x3) |
393 ((avi->rgb_quantization_range & 0x3) << 2) |
394 ((avi->ext_colorimetry_info & 0x7) << 4) |
395 ((avi->is_it_content ? 0x1 : 0x0) << 7);
396 /*
397 * BYTE - 4:
398 * 0:7 - VIC
399 */
400 if (timing->video_format < HDMI_VFRMT_END)
401 avi_iframe[3] = timing->video_format;
402
403 /*
404 * BYTE - 5:
405 * 0:3 - Pixel Repeat factor
406 * 4:5 - Content type
407 * 6:7 - YCC Quantization range
408 */
409 avi_iframe[4] = (avi->pixel_rpt_factor & 0xF) |
410 ((avi->content_type & 0x3) << 4) |
411 ((avi->yuv_quantization_range & 0x3) << 6);
412
413 /* BYTE - 6,7: End of top bar */
414 avi_iframe[5] = avi->bar_info.end_of_top_bar & 0xFF;
415 avi_iframe[6] = ((avi->bar_info.end_of_top_bar & 0xFF00) >> 8);
416
417 /* BYTE - 8,9: Start of bottom bar */
418 avi_iframe[7] = avi->bar_info.start_of_bottom_bar & 0xFF;
419 avi_iframe[8] = ((avi->bar_info.start_of_bottom_bar & 0xFF00) >>
420 8);
421
422 /* BYTE - 10,11: Endof of left bar */
423 avi_iframe[9] = avi->bar_info.end_of_left_bar & 0xFF;
424 avi_iframe[10] = ((avi->bar_info.end_of_left_bar & 0xFF00) >> 8);
425
426 /* BYTE - 12,13: Start of right bar */
427 avi_iframe[11] = avi->bar_info.start_of_right_bar & 0xFF;
428 avi_iframe[12] = ((avi->bar_info.start_of_right_bar & 0xFF00) >>
429 8);
430
431 sum = IFRAME_PACKET_OFFSET + AVI_IFRAME_TYPE +
432 AVI_IFRAME_VERSION + AVI_MAX_DATA_BYTES;
433
434 for (i = 0; i < AVI_MAX_DATA_BYTES; i++)
435 sum += avi_iframe[i];
436 sum &= 0xFF;
437 sum = 256 - sum;
438 checksum = (u8) sum;
439
440 reg_val = checksum |
441 LEFT_SHIFT_BYTE(avi_iframe[DATA_BYTE_1]) |
442 LEFT_SHIFT_WORD(avi_iframe[DATA_BYTE_2]) |
443 LEFT_SHIFT_24BITS(avi_iframe[DATA_BYTE_3]);
444 DSS_REG_W(io, HDMI_AVI_INFO0, reg_val);
445
446 reg_val = avi_iframe[DATA_BYTE_4] |
447 LEFT_SHIFT_BYTE(avi_iframe[DATA_BYTE_5]) |
448 LEFT_SHIFT_WORD(avi_iframe[DATA_BYTE_6]) |
449 LEFT_SHIFT_24BITS(avi_iframe[DATA_BYTE_7]);
450 DSS_REG_W(io, HDMI_AVI_INFO1, reg_val);
451
452 reg_val = avi_iframe[DATA_BYTE_8] |
453 LEFT_SHIFT_BYTE(avi_iframe[DATA_BYTE_9]) |
454 LEFT_SHIFT_WORD(avi_iframe[DATA_BYTE_10]) |
455 LEFT_SHIFT_24BITS(avi_iframe[DATA_BYTE_11]);
456 DSS_REG_W(io, HDMI_AVI_INFO2, reg_val);
457
458 reg_val = avi_iframe[DATA_BYTE_12] |
459 LEFT_SHIFT_BYTE(avi_iframe[DATA_BYTE_13]) |
460 LEFT_SHIFT_24BITS(AVI_IFRAME_VERSION);
461 DSS_REG_W(io, HDMI_AVI_INFO3, reg_val);
462
463 /* AVI InfFrame enable (every frame) */
464 DSS_REG_W(io, HDMI_INFOFRAME_CTRL0,
465 DSS_REG_R(io, HDMI_INFOFRAME_CTRL0) | BIT(1) | BIT(0));
466
467 reg_val = DSS_REG_R(io, HDMI_INFOFRAME_CTRL1);
468 reg_val &= ~0x3F;
469 reg_val |= AVI_IFRAME_LINE_NUMBER;
470 DSS_REG_W(io, HDMI_INFOFRAME_CTRL1, reg_val);
471}
472
473static void hdmi_panel_set_vendor_specific_infoframe(void *input)
474{
475 int i;
476 u8 vs_iframe[9]; /* two header + length + 6 data */
477 u32 sum, reg_val;
478 u32 hdmi_vic, hdmi_video_format, s3d_struct = 0;
479 struct hdmi_panel *panel = input;
Sachin Bhayare5076e252018-01-18 14:56:45 +0530480 struct mdss_io_data *io = panel->io;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530481
482 /* HDMI Spec 1.4a Table 8-10 */
483 vs_iframe[0] = 0x81; /* type */
484 vs_iframe[1] = 0x1; /* version */
485 vs_iframe[2] = 0x8; /* length */
486
487 vs_iframe[3] = 0x0; /* PB0: checksum */
488
489 /* PB1..PB3: 24 Bit IEEE Registration Code 00_0C_03 */
490 vs_iframe[4] = 0x03;
491 vs_iframe[5] = 0x0C;
492 vs_iframe[6] = 0x00;
493
494 if ((panel->data->s3d_mode != HDMI_S3D_NONE) &&
495 panel->data->s3d_support) {
496 switch (panel->data->s3d_mode) {
497 case HDMI_S3D_SIDE_BY_SIDE:
498 s3d_struct = 0x8;
499 break;
500 case HDMI_S3D_TOP_AND_BOTTOM:
501 s3d_struct = 0x6;
502 break;
503 default:
504 s3d_struct = 0;
505 }
506 hdmi_video_format = 0x2;
507 hdmi_vic = 0;
508 /* PB5: 3D_Structure[7:4], Reserved[3:0] */
509 vs_iframe[8] = s3d_struct << 4;
510 } else {
511 hdmi_video_format = 0x1;
512 switch (panel->vic) {
513 case HDMI_EVFRMT_3840x2160p30_16_9:
514 hdmi_vic = 0x1;
515 break;
516 case HDMI_EVFRMT_3840x2160p25_16_9:
517 hdmi_vic = 0x2;
518 break;
519 case HDMI_EVFRMT_3840x2160p24_16_9:
520 hdmi_vic = 0x3;
521 break;
522 case HDMI_EVFRMT_4096x2160p24_16_9:
523 hdmi_vic = 0x4;
524 break;
525 default:
526 hdmi_video_format = 0x0;
527 hdmi_vic = 0x0;
528 }
529 /* PB5: HDMI_VIC */
530 vs_iframe[8] = hdmi_vic;
531 }
532 /* PB4: HDMI Video Format[7:5], Reserved[4:0] */
533 vs_iframe[7] = (hdmi_video_format << 5) & 0xE0;
534
535 /* compute checksum */
536 sum = 0;
537 for (i = 0; i < 9; i++)
538 sum += vs_iframe[i];
539
540 sum &= 0xFF;
541 sum = 256 - sum;
542 vs_iframe[3] = (u8)sum;
543
544 reg_val = (s3d_struct << 24) | (hdmi_vic << 16) |
545 (vs_iframe[3] << 8) | (hdmi_video_format << 5) |
546 vs_iframe[2];
547 DSS_REG_W(io, HDMI_VENSPEC_INFO0, reg_val);
548
549 /* vendor specific info-frame enable (every frame) */
550 DSS_REG_W(io, HDMI_INFOFRAME_CTRL0,
551 DSS_REG_R(io, HDMI_INFOFRAME_CTRL0) | BIT(13) | BIT(12));
552
553 reg_val = DSS_REG_R(io, HDMI_INFOFRAME_CTRL1);
554 reg_val &= ~0x3F000000;
555 reg_val |= (VENDOR_IFRAME_LINE_NUMBER << 24);
556 DSS_REG_W(io, HDMI_INFOFRAME_CTRL1, reg_val);
557}
558
559static void hdmi_panel_set_spd_infoframe(struct hdmi_panel *panel)
560{
561 u32 packet_header = 0;
562 u32 check_sum = 0;
563 u32 packet_payload = 0;
564 u32 packet_control = 0;
565 u8 *vendor_name = NULL;
566 u8 *product_description = NULL;
Sachin Bhayare5076e252018-01-18 14:56:45 +0530567 struct mdss_io_data *io = panel->io;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530568
569 vendor_name = panel->spd_vendor_name;
570 product_description = panel->spd_product_description;
571
572 /* Setup Packet header and payload */
573 /*
574 * 0x83 InfoFrame Type Code
575 * 0x01 InfoFrame Version Number
576 * 0x19 Length of Source Product Description InfoFrame
577 */
578 packet_header = 0x83 | (0x01 << 8) | (0x19 << 16);
579 DSS_REG_W(io, HDMI_GENERIC1_HDR, packet_header);
580 check_sum += IFRAME_CHECKSUM_32(packet_header);
581
582 packet_payload = (vendor_name[3] & 0x7f)
583 | ((vendor_name[4] & 0x7f) << 8)
584 | ((vendor_name[5] & 0x7f) << 16)
585 | ((vendor_name[6] & 0x7f) << 24);
586 DSS_REG_W(io, HDMI_GENERIC1_1, packet_payload);
587 check_sum += IFRAME_CHECKSUM_32(packet_payload);
588
589 /* Product Description (7-bit ASCII code) */
590 packet_payload = (vendor_name[7] & 0x7f)
591 | ((product_description[0] & 0x7f) << 8)
592 | ((product_description[1] & 0x7f) << 16)
593 | ((product_description[2] & 0x7f) << 24);
594 DSS_REG_W(io, HDMI_GENERIC1_2, packet_payload);
595 check_sum += IFRAME_CHECKSUM_32(packet_payload);
596
597 packet_payload = (product_description[3] & 0x7f)
598 | ((product_description[4] & 0x7f) << 8)
599 | ((product_description[5] & 0x7f) << 16)
600 | ((product_description[6] & 0x7f) << 24);
601 DSS_REG_W(io, HDMI_GENERIC1_3, packet_payload);
602 check_sum += IFRAME_CHECKSUM_32(packet_payload);
603
604 packet_payload = (product_description[7] & 0x7f)
605 | ((product_description[8] & 0x7f) << 8)
606 | ((product_description[9] & 0x7f) << 16)
607 | ((product_description[10] & 0x7f) << 24);
608 DSS_REG_W(io, HDMI_GENERIC1_4, packet_payload);
609 check_sum += IFRAME_CHECKSUM_32(packet_payload);
610
611 packet_payload = (product_description[11] & 0x7f)
612 | ((product_description[12] & 0x7f) << 8)
613 | ((product_description[13] & 0x7f) << 16)
614 | ((product_description[14] & 0x7f) << 24);
615 DSS_REG_W(io, HDMI_GENERIC1_5, packet_payload);
616 check_sum += IFRAME_CHECKSUM_32(packet_payload);
617
618 /*
619 * Source Device Information
620 * 00h unknown
621 * 01h Digital STB
622 * 02h DVD
623 * 03h D-VHS
624 * 04h HDD Video
625 * 05h DVC
626 * 06h DSC
627 * 07h Video CD
628 * 08h Game
629 * 09h PC general
630 */
631 packet_payload = (product_description[15] & 0x7f) | 0x00 << 8;
632 DSS_REG_W(io, HDMI_GENERIC1_6, packet_payload);
633 check_sum += IFRAME_CHECKSUM_32(packet_payload);
634
635 /* Vendor Name (7bit ASCII code) */
636 packet_payload = ((vendor_name[0] & 0x7f) << 8)
637 | ((vendor_name[1] & 0x7f) << 16)
638 | ((vendor_name[2] & 0x7f) << 24);
639 check_sum += IFRAME_CHECKSUM_32(packet_payload);
640 packet_payload |= ((0x100 - (0xff & check_sum)) & 0xff);
641 DSS_REG_W(io, HDMI_GENERIC1_0, packet_payload);
642
643 /*
644 * GENERIC1_LINE | GENERIC1_CONT | GENERIC1_SEND
645 * Setup HDMI TX generic packet control
646 * Enable this packet to transmit every frame
647 * Enable HDMI TX engine to transmit Generic packet 1
648 */
649 packet_control = DSS_REG_R_ND(io, HDMI_GEN_PKT_CTRL);
650 packet_control |= ((0x1 << 24) | (1 << 5) | (1 << 4));
651 DSS_REG_W(io, HDMI_GEN_PKT_CTRL, packet_control);
652}
653
654static int hdmi_panel_setup_infoframe(struct hdmi_panel *panel)
655{
656 int rc = 0;
657
658 if (!panel) {
659 pr_err("invalid input\n");
660 rc = -EINVAL;
661 goto end;
662 }
663
664 if (panel->data->infoframe) {
665 hdmi_panel_set_avi_infoframe(panel);
666 hdmi_panel_set_vendor_specific_infoframe(panel);
667 hdmi_panel_set_spd_infoframe(panel);
668 }
669end:
670 return rc;
671}
672
673static int hdmi_panel_setup_scrambler(struct hdmi_panel *panel)
674{
675 int rc = 0;
676 int timeout_hsync;
677 u32 reg_val = 0;
678 u32 tmds_clock_ratio = 0;
679 bool scrambler_on = false;
680 struct msm_hdmi_mode_timing_info *timing = NULL;
681
682 if (!panel) {
683 pr_err("invalid input\n");
684 return -EINVAL;
685 }
686
687 timing = panel->vid_cfg.timing;
688 if (!timing) {
689 pr_err("Invalid timing info\n");
690 return -EINVAL;
691 }
692
693 /* Scrambling is supported from HDMI TX 4.0 */
694 if (panel->version < HDMI_TX_SCRAMBLER_MIN_TX_VERSION) {
695 pr_debug("scrambling not supported by tx\n");
696 return 0;
697 }
698
699 if (timing->pixel_freq > HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ) {
700 scrambler_on = true;
701 tmds_clock_ratio = 1;
702 } else {
703 scrambler_on = panel->data->scrambler;
704 }
705
706 pr_debug("scrambler %s\n", scrambler_on ? "on" : "off");
707
708 if (scrambler_on) {
709 rc = hdmi_scdc_write(panel->ddc,
710 HDMI_TX_SCDC_TMDS_BIT_CLOCK_RATIO_UPDATE,
711 tmds_clock_ratio);
712 if (rc) {
713 pr_err("TMDS CLK RATIO ERR\n");
714 return rc;
715 }
716
717 reg_val = DSS_REG_R(panel->io, HDMI_CTRL);
718 reg_val |= BIT(31); /* Enable Update DATAPATH_MODE */
719 reg_val |= BIT(28); /* Set SCRAMBLER_EN bit */
720
721 DSS_REG_W(panel->io, HDMI_CTRL, reg_val);
722
723 rc = hdmi_scdc_write(panel->ddc,
724 HDMI_TX_SCDC_SCRAMBLING_ENABLE, 0x1);
725 if (!rc) {
726 panel->scrambler_enabled = true;
727 } else {
728 pr_err("failed to enable scrambling\n");
729 return rc;
730 }
731
732 /*
733 * Setup hardware to periodically check for scrambler
734 * status bit on the sink. Sink should set this bit
735 * with in 200ms after scrambler is enabled.
736 */
737 timeout_hsync = hdmi_utils_get_timeout_in_hysnc(
738 panel->vid_cfg.timing,
739 HDMI_TX_SCRAMBLER_TIMEOUT_MSEC);
740
741 if (timeout_hsync <= 0) {
742 pr_err("err in timeout hsync calc\n");
743 timeout_hsync = HDMI_DEFAULT_TIMEOUT_HSYNC;
744 }
745
746 pr_debug("timeout for scrambling en: %d hsyncs\n",
747 timeout_hsync);
748
749 rc = hdmi_setup_ddc_timers(panel->ddc,
750 HDMI_TX_DDC_TIMER_SCRAMBLER_STATUS, timeout_hsync);
751 } else {
752 hdmi_scdc_write(panel->ddc,
753 HDMI_TX_SCDC_SCRAMBLING_ENABLE, 0x0);
754
755 panel->scrambler_enabled = false;
756 }
757
758 return rc;
759}
760
761static int hdmi_panel_update_fps(void *input, u32 fps)
762{
763 struct hdmi_panel *panel = input;
764 struct mdss_panel_info *pinfo = panel->data->pinfo;
765 struct msm_hdmi_mode_timing_info *timing = panel->vid_cfg.timing;
766 u64 pclk;
767 int vic;
768
769 timing->back_porch_h = pinfo->lcdc.h_back_porch;
770 timing->front_porch_h = pinfo->lcdc.h_front_porch;
771 timing->pulse_width_h = pinfo->lcdc.h_pulse_width;
772
773 timing->back_porch_v = pinfo->lcdc.v_back_porch;
774 timing->front_porch_v = pinfo->lcdc.v_front_porch;
775 timing->pulse_width_v = pinfo->lcdc.v_pulse_width;
776
777 timing->refresh_rate = fps;
778
779 pclk = pinfo->clk_rate;
780 do_div(pclk, HDMI_TX_KHZ_TO_HZ);
781 timing->pixel_freq = (unsigned long) pclk;
782
783 if (hdmi_panel_setup_video(panel)) {
784 DEV_DBG("%s: no change in video timing\n", __func__);
785 goto end;
786 }
787
788 vic = hdmi_get_video_id_code(timing, panel->ds_data);
789
790 if (vic > 0 && panel->vic != vic) {
791 panel->vic = vic;
792 DEV_DBG("%s: switched to new resolution id %d\n",
793 __func__, vic);
794 }
795
796 pinfo->dynamic_fps = false;
797end:
798 return panel->vic;
799}
800
801static int hdmi_panel_power_on(void *input)
802{
803 int rc = 0;
804 bool res_changed = false;
805 struct hdmi_panel *panel = input;
806 struct mdss_panel_info *pinfo;
807 struct msm_hdmi_mode_timing_info *info;
808
809 if (!panel) {
810 pr_err("invalid input\n");
811 rc = -EINVAL;
812 goto err;
813 }
814
815 pinfo = panel->data->pinfo;
816 if (!pinfo) {
817 pr_err("invalid panel data\n");
818 rc = -EINVAL;
819 goto err;
820 }
821
822 if (panel->vic != panel->data->vic) {
823 res_changed = true;
824
825 pr_debug("switching from %d => %d\n",
826 panel->vic, panel->data->vic);
827
828 panel->vic = panel->data->vic;
829 }
830
831 if (pinfo->cont_splash_enabled) {
832 pinfo->cont_splash_enabled = false;
833
834 if (!res_changed) {
835 panel->on = true;
836
837 hdmi_panel_set_vendor_specific_infoframe(panel);
838 hdmi_panel_set_spd_infoframe(panel);
839
840 pr_debug("handoff done\n");
841
842 goto end;
843 }
844 }
845
846 rc = hdmi_panel_config_avi(panel);
847 if (rc) {
848 pr_err("avi config failed. rc=%d\n", rc);
849 goto err;
850 }
851
852 rc = hdmi_panel_setup_video(panel);
853 if (rc) {
854 pr_err("video setup failed. rc=%d\n", rc);
855 goto err;
856 }
857
858 rc = hdmi_panel_setup_infoframe(panel);
859 if (rc) {
860 pr_err("infoframe setup failed. rc=%d\n", rc);
861 goto err;
862 }
863
864 rc = hdmi_panel_setup_scrambler(panel);
865 if (rc) {
866 pr_err("scrambler setup failed. rc=%d\n", rc);
867 goto err;
868 }
869end:
870 panel->on = true;
871
872 info = panel->vid_cfg.timing;
873 pr_debug("%dx%d%s@%dHz %dMHz %s (%d)\n",
874 info->active_h, info->active_v,
875 info->interlaced ? "i" : "p",
876 info->refresh_rate / 1000,
877 info->pixel_freq / 1000,
878 pinfo->out_format == MDP_Y_CBCR_H2V2 ? "Y420" : "RGB",
879 info->video_format);
880err:
881 return rc;
882}
883
884static int hdmi_panel_power_off(void *input)
885{
886 struct hdmi_panel *panel = input;
887
888 panel->on = false;
889
890 pr_debug("panel off\n");
891 return 0;
892}
893
894void *hdmi_panel_init(struct hdmi_panel_init_data *data)
895{
896 struct hdmi_panel *panel = NULL;
897
898 if (!data) {
899 pr_err("invalid input\n");
900 goto end;
901 }
902
903 panel = kzalloc(sizeof(*panel), GFP_KERNEL);
904 if (!panel)
905 goto end;
906
907 panel->io = data->io;
908 panel->ds_data = data->ds_data;
909 panel->data = data->panel_data;
910 panel->spd_vendor_name = data->spd_vendor_name;
911 panel->spd_product_description = data->spd_product_description;
912 panel->version = data->version;
913 panel->ddc = data->ddc;
914 panel->vid_cfg.timing = data->timing;
915
916 if (data->ops) {
917 data->ops->on = hdmi_panel_power_on;
918 data->ops->off = hdmi_panel_power_off;
919 data->ops->get_vic = hdmi_panel_get_vic;
920 data->ops->vendor = hdmi_panel_set_vendor_specific_infoframe;
921 data->ops->update_fps = hdmi_panel_update_fps;
922 }
923end:
924 return panel;
925}
926
927void hdmi_panel_deinit(void *input)
928{
929 struct hdmi_panel *panel = input;
930
931 kfree(panel);
932}