summaryrefslogtreecommitdiff
path: root/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c (plain)
blob: c2a2fd6b1bbe2e967e1710adb7d70c0b4e8514c6
1/*
2 * drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c
3 *
4 * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 */
17
18#include <linux/version.h>
19#include <linux/module.h>
20#include <linux/types.h>
21#include <linux/kernel.h>
22#include <linux/delay.h>
23#include <linux/interrupt.h>
24#include <linux/fs.h>
25#include <linux/init.h>
26#include <linux/device.h>
27#include <linux/mm.h>
28#include <linux/major.h>
29#include <linux/platform_device.h>
30#include <linux/mutex.h>
31#include <linux/cdev.h>
32#include <linux/slab.h>
33/* #include <linux/amports/canvas.h> */
34#include <linux/uaccess.h>
35#include <linux/delay.h>
36#include <linux/clk.h>
37#include <linux/amlogic/cpu_version.h>
38#include <linux/amlogic/media/vout/vinfo.h>
39#include <linux/amlogic/media/vout/hdmi_tx/enc_clk_config.h>
40#include <linux/amlogic/media/vout/hdmi_tx/hdmi_info_global.h>
41#include <linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h>
42#include <linux/amlogic/media/vout/hdmi_tx/hdmi_tx_ddc.h>
43#include <linux/amlogic/cpu_version.h>
44#include <linux/reset.h>
45#include <linux/compiler.h>
46#include "mach_reg.h"
47#include "hdmi_tx_reg.h"
48
49#if 0 /* todo */
50#include "../hdmi_tx_hdcp.h"
51#include "../hdmi_tx_compliance.h"
52#endif
53#include "tvenc_conf.h"
54#include "common.h"
55#include "hdcpVerify.h"
56#include "hw_clk.h"
57
58#define EDID_RAM_ADDR_SIZE (8)
59
60static void hdmi_audio_init(unsigned int spdif_flag);
61static void hdmitx_dump_tvenc_reg(int cur_VIC, int pr_info_flag);
62
63static void mode420_half_horizontal_para(void);
64static void hdmi_phy_suspend(void);
65static void hdmi_phy_wakeup(struct hdmitx_dev *hdev);
66static void hdmitx_set_phy(struct hdmitx_dev *hdev);
67static void hdmitx_set_hw(struct hdmitx_dev *hdev);
68static void set_hdmi_audio_source(unsigned int src);
69static void hdmitx_csc_config(unsigned char input_color_format,
70 unsigned char output_color_format, unsigned char color_depth);
71static int hdmitx_hdmi_dvi_config(struct hdmitx_dev *hdev,
72 unsigned int dvi_mode);
73static void hdmitx_set_avi_colorimetry(struct hdmi_format_para *para);
74
75unsigned char hdmi_pll_mode; /* 1, use external clk as hdmi pll source */
76
77/* HSYNC polarity: active high */
78#define HSYNC_POLARITY 1
79/* VSYNC polarity: active high */
80#define VSYNC_POLARITY 1
81/* Pixel format: 0=RGB444; 1=YCbCr444; 2=Rsrv; 3=YCbCr422. */
82#define TX_INPUT_COLOR_FORMAT COLORSPACE_YUV444
83/* Pixel range: 0=16-235/240; 1=16-240; 2=1-254; 3=0-255. */
84#define TX_INPUT_COLOR_RANGE 0
85/* Pixel bit width: 4=24-bit; 5=30-bit; 6=36-bit; 7=48-bit. */
86#define TX_COLOR_DEPTH COLORDEPTH_24B
87/* Pixel format: 0=RGB444; 1=YCbCr422; 2=YCbCr444; 3=YCbCr420. */
88#define TX_OUTPUT_COLOR_FORMAT COLORSPACE_YUV444
89#define TX_OUTPUT_COLOR_RANGE 0
90
91#if 1
92/* 0=I2S 2-channel; 1=I2S 4 x 2-channel. */
93#define TX_I2S_8_CHANNEL 0
94#endif
95
96static unsigned int tx_aud_src; /* 0: SPDIF 1: I2S */
97
98/* store downstream ksv lists */
99static char *rptx_ksvs;
100static char rptx_ksv_prbuf[1271]; /* 127 * 5 * 2 + 1 */
101MODULE_PARM_DESC(rptx_ksvs, "\n downstream ksvs\n");
102module_param(rptx_ksvs, charp, 0444);
103static int rptx_ksv_no;
104static int rptx_ksvlist_retry;
105static char rptx_ksv_buf[635];
106
107/* static struct tasklet_struct EDID_tasklet; */
108static unsigned int delay_flag;
109static unsigned long serial_reg_val = 0x1;
110static unsigned char i2s_to_spdif_flag = 1;
111static unsigned long color_depth_f;
112static unsigned long COLORSPACE_f;
113static unsigned char new_reset_sequence_flag = 1;
114static unsigned char power_mode = 1;
115static unsigned char power_off_vdac_flag;
116/* 0, do not use fixed tvenc val for all mode;
117 * 1, use fixed tvenc val mode for 480i;
118 * 2, use fixed tvenc val mode for all modes
119 */
120static unsigned char use_tvenc_conf_flag = 1;
121
122static void hdmitx_set_packet(int type, unsigned char *DB, unsigned char *HB);
123static void hdmitx_setaudioinfoframe(unsigned char *AUD_DB,
124 unsigned char *CHAN_STAT_BUF);
125static int hdmitx_set_dispmode(struct hdmitx_dev *hdev);
126static int hdmitx_set_audmode(struct hdmitx_dev *hdev,
127 struct hdmitx_audpara *audio_param);
128static void hdmitx_setupirq(struct hdmitx_dev *hdev);
129static void hdmitx_debug(struct hdmitx_dev *hdev, const char *buf);
130static void hdmitx_uninit(struct hdmitx_dev *hdev);
131static int hdmitx_cntl(struct hdmitx_dev *hdev, unsigned int cmd,
132 unsigned int argv);
133static int hdmitx_cntl_ddc(struct hdmitx_dev *hdev, unsigned int cmd,
134 unsigned long argv);
135static int hdmitx_get_state(struct hdmitx_dev *hdev, unsigned int cmd,
136 unsigned int argv);
137static int hdmitx_cntl_config(struct hdmitx_dev *hdev, unsigned int cmd,
138 unsigned int argv);
139static int hdmitx_cntl_misc(struct hdmitx_dev *hdev, unsigned int cmd,
140 unsigned int argv);
141static void digital_clk_on(unsigned char flag);
142static void digital_clk_off(unsigned char flag);
143
144static int hdmitx_hpd_hw_op(enum hpd_op cmd)
145{
146 switch (get_cpu_type()) {
147 case MESON_CPU_MAJOR_ID_GXBB:
148 return hdmitx_hpd_hw_op_gxbb(cmd);
149 case MESON_CPU_MAJOR_ID_GXTVBB:
150 return hdmitx_hpd_hw_op_gxtvbb(cmd);
151 case MESON_CPU_MAJOR_ID_GXL:
152 case MESON_CPU_MAJOR_ID_GXM:
153 return hdmitx_hpd_hw_op_gxl(cmd);
154 case MESON_CPU_MAJOR_ID_TXLX:
155 return hdmitx_hpd_hw_op_txlx(cmd);
156 default:
157 break;
158 }
159 return 0;
160}
161
162int read_hpd_gpio(void)
163{
164 switch (get_cpu_type()) {
165 case MESON_CPU_MAJOR_ID_GXBB:
166 return read_hpd_gpio_gxbb();
167 case MESON_CPU_MAJOR_ID_GXTVBB:
168 return read_hpd_gpio_gxtvbb();
169 case MESON_CPU_MAJOR_ID_GXL:
170 case MESON_CPU_MAJOR_ID_GXM:
171 return read_hpd_gpio_gxl();
172 case MESON_CPU_MAJOR_ID_TXLX:
173 return read_hpd_gpio_txlx();
174 default:
175 break;
176 }
177 return 0;
178}
179EXPORT_SYMBOL(read_hpd_gpio);
180
181int hdmitx_ddc_hw_op(enum ddc_op cmd)
182{
183 switch (get_cpu_type()) {
184 case MESON_CPU_MAJOR_ID_GXBB:
185 return hdmitx_ddc_hw_op_gxbb(cmd);
186 case MESON_CPU_MAJOR_ID_GXTVBB:
187 return hdmitx_ddc_hw_op_gxtvbb(cmd);
188 case MESON_CPU_MAJOR_ID_GXL:
189 case MESON_CPU_MAJOR_ID_GXM:
190 return hdmitx_ddc_hw_op_gxl(cmd);
191 case MESON_CPU_MAJOR_ID_TXLX:
192 return hdmitx_ddc_hw_op_txlx(cmd);
193 default:
194 break;
195 }
196 return 0;
197}
198
199int hdmitx_hdcp_opr(unsigned int val)
200{
201 if (val == 1) { /* HDCP14_ENABLE */
202 register long x0 asm("x0") = 0x82000010;
203 asm volatile(
204 __asmeq("%0", "x0")
205 "smc #0\n"
206 : : "r"(x0)
207 );
208 }
209 if (val == 2) { /* HDCP14_RESULT */
210 register long x0 asm("x0") = 0x82000011;
211 asm volatile(
212 __asmeq("%0", "x0")
213 "smc #0\n"
214 : "+r"(x0)
215 );
216 return (unsigned int)(x0&0xffffffff);
217 }
218 if (val == 0) { /* HDCP14_INIT */
219 register long x0 asm("x0") = 0x82000012;
220 asm volatile(
221 __asmeq("%0", "x0")
222 "smc #0\n"
223 : : "r"(x0)
224 );
225 }
226 if (val == 3) { /* HDCP14_EN_ENCRYPT */
227 register long x0 asm("x0") = 0x82000013;
228 asm volatile(
229 __asmeq("%0", "x0")
230 "smc #0\n"
231 : : "r"(x0)
232 );
233 }
234 if (val == 4) { /* HDCP14_OFF */
235 register long x0 asm("x0") = 0x82000014;
236 asm volatile(
237 __asmeq("%0", "x0")
238 "smc #0\n"
239 : : "r"(x0)
240 );
241 }
242 if (val == 5) { /* HDCP_MUX_22 */
243 register long x0 asm("x0") = 0x82000015;
244 asm volatile(
245 __asmeq("%0", "x0")
246 "smc #0\n"
247 : : "r"(x0)
248 );
249 }
250 if (val == 6) { /* HDCP_MUX_14 */
251 register long x0 asm("x0") = 0x82000016;
252 asm volatile(
253 __asmeq("%0", "x0")
254 "smc #0\n"
255 : : "r"(x0)
256 );
257 }
258 if (val == 7) { /* HDCP22_RESULT */
259 register long x0 asm("x0") = 0x82000017;
260 asm volatile(
261 __asmeq("%0", "x0")
262 "smc #0\n"
263 : "+r"(x0)
264 );
265 return (unsigned int)(x0&0xffffffff);
266 }
267 if (val == 0xa) { /* HDCP14_KEY_LSTORE */
268 register long x0 asm("x0") = 0x8200001a;
269 asm volatile(
270 __asmeq("%0", "x0")
271 "smc #0\n"
272 : "+r"(x0)
273 );
274 return (unsigned int)(x0&0xffffffff);
275 }
276 if (val == 0xb) { /* HDCP22_KEY_LSTORE */
277 register long x0 asm("x0") = 0x8200001b;
278 asm volatile(
279 __asmeq("%0", "x0")
280 "smc #0\n"
281 : "+r"(x0)
282 );
283 return (unsigned int)(x0&0xffffffff);
284 }
285 if (val == 0xc) { /* HDCP22_KEY_SET_DUK */
286 register long x0 asm("x0") = 0x8200001c;
287 asm volatile(
288 __asmeq("%0", "x0")
289 "smc #0\n"
290 : "+r"(x0)
291 );
292 return (unsigned int)(x0&0xffffffff);
293 }
294 return -1;
295}
296
297static void config_avmute(unsigned int val)
298{
299 pr_info("avmute set to %d\n", val);
300 switch (val) {
301 case SET_AVMUTE:
302 hdmitx_set_reg_bits(HDMITX_DWC_FC_GCP, 1, 1, 1);
303 hdmitx_set_reg_bits(HDMITX_DWC_FC_GCP, 0, 0, 1);
304 break;
305 case CLR_AVMUTE:
306 hdmitx_set_reg_bits(HDMITX_DWC_FC_GCP, 0, 1, 1);
307 hdmitx_set_reg_bits(HDMITX_DWC_FC_GCP, 1, 0, 1);
308 break;
309 case OFF_AVMUTE:
310 default:
311 hdmitx_set_reg_bits(HDMITX_DWC_FC_GCP, 0, 1, 1);
312 hdmitx_set_reg_bits(HDMITX_DWC_FC_GCP, 0, 0, 1);
313 break;
314 }
315}
316
317static void config_video_mapping(enum hdmi_color_space cs,
318 enum hdmi_color_depth cd)
319{
320 unsigned int val = 0;
321
322 pr_info("hdmitx: config: cs = %d cd = %d\n", cs, cd);
323 switch (cs) {
324 case COLORSPACE_RGB444:
325 switch (cd) {
326 case COLORDEPTH_24B:
327 val = 0x1;
328 break;
329 case COLORDEPTH_30B:
330 val = 0x3;
331 break;
332 case COLORDEPTH_36B:
333 val = 0x5;
334 break;
335 case COLORDEPTH_48B:
336 val = 0x7;
337 break;
338 default:
339 break;
340 }
341 break;
342 case COLORSPACE_YUV444:
343 case COLORSPACE_YUV420:
344 switch (cd) {
345 case COLORDEPTH_24B:
346 val = 0x9;
347 break;
348 case COLORDEPTH_30B:
349 val = 0xb;
350 break;
351 case COLORDEPTH_36B:
352 val = 0xd;
353 break;
354 case COLORDEPTH_48B:
355 val = 0xf;
356 break;
357 default:
358 break;
359 }
360 break;
361 case COLORSPACE_YUV422:
362 switch (cd) {
363 case COLORDEPTH_24B:
364 val = 0x16;
365 break;
366 case COLORDEPTH_30B:
367 val = 0x14;
368 break;
369 case COLORDEPTH_36B:
370 val = 0x12;
371 break;
372 case COLORDEPTH_48B:
373 pr_info("hdmitx: y422 no 48bits mode\n");
374 break;
375 default:
376 break;
377 }
378 break;
379 default:
380 break;
381 }
382 hdmitx_set_reg_bits(HDMITX_DWC_TX_INVID0, val, 0, 4);
383
384 switch (cd) {
385 case COLORDEPTH_24B:
386 val = 0x4;
387 break;
388 case COLORDEPTH_30B:
389 val = 0x5;
390 break;
391 case COLORDEPTH_36B:
392 val = 0x6;
393 break;
394 case COLORDEPTH_48B:
395 val = 0x7;
396 break;
397 default:
398 break;
399 }
400 hdmitx_set_reg_bits(HDMITX_DWC_VP_PR_CD, val, 4, 4);
401
402 switch (cd) {
403 case COLORDEPTH_30B:
404 case COLORDEPTH_36B:
405 case COLORDEPTH_48B:
406 hdmitx_set_reg_bits(HDMITX_DWC_VP_CONF, 0, 6, 1);
407 hdmitx_set_reg_bits(HDMITX_DWC_VP_CONF, 1, 5, 1);
408 hdmitx_set_reg_bits(HDMITX_DWC_VP_CONF, 1, 2, 1);
409 hdmitx_set_reg_bits(HDMITX_DWC_VP_CONF, 0, 0, 2);
410 break;
411 case COLORDEPTH_24B:
412 break;
413 default:
414 break;
415 }
416 hdmitx_set_reg_bits(HDMITX_DWC_VP_PR_CD, val, 4, 4);
417}
418
419/* record HDMITX current format, matched with uboot */
420/* ISA_DEBUG_REG0 0x2600
421 * bit[11]: Y420
422 * bit[10:8]: HDMI VIC
423 * bit[7:0]: CEA VIC
424 */
425static unsigned int get_hdmitx_format(void)
426{
427 return hd_read_reg(P_ISA_DEBUG_REG0);
428}
429
430static int hdmitx_uboot_already_display(void)
431{
432 if ((hd_read_reg(P_HHI_HDMI_CLK_CNTL) & (1 << 8))
433 && (hd_read_reg(P_HHI_HDMI_PLL_CNTL) & (1 << 31))
434 && (get_hdmitx_format())) {
435 pr_info("hdmitx: alread display in uboot 0x%x\n",
436 get_hdmitx_format());
437 return 1;
438 } else
439 return 0;
440}
441
442/* for 30bits colordepth */
443static void set_vmode_clk(struct hdmitx_dev *hdev)
444{
445 hdmitx_set_clk(hdev);
446}
447
448static void hdmi_hwp_init(struct hdmitx_dev *hdev)
449{
450 /* Enable clocks and bring out of reset */
451
452 /* Enable hdmitx_sys_clk */
453 /* .clk0 ( cts_oscin_clk ), */
454 /* .clk1 ( fclk_div4 ), */
455 /* .clk2 ( fclk_div3 ), */
456 /* .clk3 ( fclk_div5 ), */
457/* [10: 9] clk_sel. select cts_oscin_clk=24MHz */
458/* [ 8] clk_en. Enable gated clock */
459/* [ 6: 0] clk_div. Divide by 1. = 24/1 = 24 MHz */
460 hd_set_reg_bits(P_HHI_HDMI_CLK_CNTL, 0x100, 0, 16);
461
462 hd_write_reg(P_HHI_HDCP22_CLK_CNTL, 0x01000100);
463 hd_set_reg_bits(P_HHI_GCLK_MPEG2, 1, 3, 1);
464
465/* Enable clk81_hdmitx_pclk */
466 hd_set_reg_bits(P_HHI_GCLK_MPEG2, 1, 4, 1);
467 /* wire wr_enable = control[3]; */
468 /* wire fifo_enable = control[2]; */
469 /* assign phy_clk_en = control[1]; */
470/* Bring HDMITX MEM output of power down */
471 hd_set_reg_bits(P_HHI_MEM_PD_REG0, 0, 8, 8);
472 if (hdmitx_uboot_already_display()) {
473 /* Get uboot output color space from AVI */
474 switch (hdmitx_rd_reg(HDMITX_DWC_FC_AVICONF0) & 0x3) {
475 case 0:
476 hdev->para->cs = COLORSPACE_RGB444;
477 break;
478 case 1:
479 hdev->para->cs = COLORSPACE_YUV422;
480 break;
481 case 2:
482 hdev->para->cs = COLORSPACE_YUV444;
483 break;
484 case 3:
485 hdev->para->cs = COLORSPACE_YUV420;
486 break;
487 default:
488 break;
489 }
490 /* If color space is not 422, then get depth from VP_PR_CD */
491 if (hdev->para->cs != COLORSPACE_YUV422) {
492 switch ((hdmitx_rd_reg(HDMITX_DWC_VP_PR_CD) >> 4) &
493 0xf) {
494 case 5:
495 hdev->para->cd = COLORDEPTH_30B;
496 break;
497 case 6:
498 hdev->para->cd = COLORDEPTH_36B;
499 break;
500 case 7:
501 hdev->para->cd = COLORDEPTH_48B;
502 break;
503 case 0:
504 case 4:
505 default:
506 hdev->para->cd = COLORDEPTH_24B;
507 break;
508 }
509 } else {
510 /* If colorspace is 422, then get depth from VP_REMAP */
511 switch (hdmitx_rd_reg(HDMITX_DWC_VP_REMAP) & 0x3) {
512 case 1:
513 hdev->para->cd = COLORDEPTH_30B;
514 break;
515 case 2:
516 hdev->para->cd = COLORDEPTH_36B;
517 break;
518 case 0:
519 default:
520 hdev->para->cd = COLORDEPTH_24B;
521 break;
522 }
523 }
524 return;
525 }
526
527 hdev->para->cd = COLORDEPTH_RESERVED;
528 hdev->para->cs = COLORSPACE_RESERVED;
529 /* reset HDMITX APB & TX & PHY */
530 hd_set_reg_bits(P_RESET0_REGISTER, 1, 19, 1);
531 hd_set_reg_bits(P_RESET2_REGISTER, 1, 15, 1);
532 hd_set_reg_bits(P_RESET2_REGISTER, 1, 2, 1);
533 /* Enable APB3 fail on error */
534 hd_set_reg_bits(P_HDMITX_CTRL_PORT, 1, 15, 1);
535 hd_set_reg_bits((P_HDMITX_CTRL_PORT + 0x10), 1, 15, 1);
536 /* Bring out of reset */
537 hdmitx_wr_reg(HDMITX_TOP_SW_RESET, 0);
538 udelay(200);
539 hdmitx_set_reg_bits(HDMITX_TOP_CLK_CNTL, 3, 0, 2);
540 hdmitx_set_reg_bits(HDMITX_TOP_CLK_CNTL, 3, 4, 2);
541 hdmitx_wr_reg(HDMITX_DWC_MC_LOCKONCLOCK, 0xff);
542 hdmitx_wr_reg(HDMITX_TOP_INTR_MASKN, 0x1f);
543}
544
545static void hdmi_hwi_init(struct hdmitx_dev *hdev)
546{
547 unsigned int data32 = 0;
548
549 hdmitx_set_reg_bits(HDMITX_DWC_FC_INVIDCONF, 1, 7, 1);
550 hdmitx_wr_reg(HDMITX_DWC_A_HDCPCFG1, 0x7);
551 hdmitx_wr_reg(HDMITX_DWC_A_HDCPCFG0, 0x53);
552 /* Enable skpclk to HDCP2.2 IP */
553 hdmitx_set_reg_bits(HDMITX_TOP_CLK_CNTL, 1, 7, 1);
554 /* Enable esmclk to HDCP2.2 IP */
555 hdmitx_set_reg_bits(HDMITX_TOP_CLK_CNTL, 1, 6, 1);
556 /* Enable tmds_clk to HDCP2.2 IP */
557 hdmitx_set_reg_bits(HDMITX_TOP_CLK_CNTL, 1, 5, 1);
558
559 hdmitx_hpd_hw_op(HPD_INIT_DISABLE_PULLUP);
560 hdmitx_hpd_hw_op(HPD_INIT_SET_FILTER);
561 hdmitx_ddc_hw_op(DDC_INIT_DISABLE_PULL_UP_DN);
562 hdmitx_ddc_hw_op(DDC_MUX_DDC);
563
564/* Configure E-DDC interface */
565 data32 = 0;
566 data32 |= (1 << 24); /* [26:24] infilter_ddc_intern_clk_divide */
567 data32 |= (0 << 16); /* [23:16] infilter_ddc_sample_clk_divide */
568 data32 |= (0 << 8); /* [10: 8] infilter_cec_intern_clk_divide */
569 data32 |= (1 << 0); /* [ 7: 0] infilter_cec_sample_clk_divide */
570 hdmitx_wr_reg(HDMITX_TOP_INFILTER, data32);
571
572 data32 = 0;
573 data32 |= (0 << 6); /* [ 6] read_req_mask */
574 data32 |= (0 << 2); /* [ 2] done_mask */
575 hdmitx_wr_reg(HDMITX_DWC_I2CM_INT, data32);
576
577 data32 = 0;
578 data32 |= (0 << 6); /* [ 6] nack_mask */
579 data32 |= (0 << 2); /* [ 2] arbitration_error_mask */
580 hdmitx_wr_reg(HDMITX_DWC_I2CM_CTLINT, data32);
581
582/* [ 3] i2c_fast_mode: 0=standard mode; 1=fast mode. */
583 data32 = 0;
584 data32 |= (0 << 3);
585 hdmitx_wr_reg(HDMITX_DWC_I2CM_DIV, data32);
586
587 hdmitx_wr_reg(HDMITX_DWC_I2CM_SS_SCL_HCNT_1, 0);
588 hdmitx_wr_reg(HDMITX_DWC_I2CM_SS_SCL_HCNT_0, 0x67);
589 hdmitx_wr_reg(HDMITX_DWC_I2CM_SS_SCL_LCNT_1, 0);
590 hdmitx_wr_reg(HDMITX_DWC_I2CM_SS_SCL_LCNT_0, 0x78);
591 hdmitx_wr_reg(HDMITX_DWC_I2CM_FS_SCL_HCNT_1, 0);
592 hdmitx_wr_reg(HDMITX_DWC_I2CM_FS_SCL_HCNT_0, 0x0f);
593 hdmitx_wr_reg(HDMITX_DWC_I2CM_FS_SCL_LCNT_1, 0);
594 hdmitx_wr_reg(HDMITX_DWC_I2CM_FS_SCL_LCNT_0, 0x20);
595 hdmitx_wr_reg(HDMITX_DWC_I2CM_SDA_HOLD, 0x08);
596
597 data32 = 0;
598 data32 |= (0 << 5); /* [ 5] updt_rd_vsyncpoll_en */
599 data32 |= (0 << 4); /* [ 4] read_request_en // scdc */
600 data32 |= (0 << 0); /* [ 0] read_update */
601 hdmitx_wr_reg(HDMITX_DWC_I2CM_SCDC_UPDATE, data32);
602}
603
604void HDMITX_Meson_Init(struct hdmitx_dev *hdev)
605{
606 hdev->HWOp.SetPacket = hdmitx_set_packet;
607 hdev->HWOp.SetAudioInfoFrame = hdmitx_setaudioinfoframe;
608 hdev->HWOp.SetDispMode = hdmitx_set_dispmode;
609 hdev->HWOp.SetAudMode = hdmitx_set_audmode;
610 hdev->HWOp.SetupIRQ = hdmitx_setupirq;
611 hdev->HWOp.DebugFun = hdmitx_debug;
612 hdev->HWOp.UnInit = hdmitx_uninit;
613 hdev->HWOp.Cntl = hdmitx_cntl; /* todo */
614 hdev->HWOp.CntlDDC = hdmitx_cntl_ddc;
615 hdev->HWOp.GetState = hdmitx_get_state;
616 hdev->HWOp.CntlPacket = hdmitx_cntl;
617 hdev->HWOp.CntlConfig = hdmitx_cntl_config;
618 hdev->HWOp.CntlMisc = hdmitx_cntl_misc;
619 init_reg_map(hdev->chip_type);
620 digital_clk_on(0xff);
621 hdmi_hwp_init(hdev);
622 hdmi_hwi_init(hdev);
623 config_avmute(CLR_AVMUTE);
624 hdmitx_set_audmode(NULL, NULL);
625 rptx_ksvs = &rptx_ksv_prbuf[0];
626}
627
628static irqreturn_t intr_handler(int irq, void *dev)
629{
630 unsigned int data32 = 0;
631 struct hdmitx_dev *hdev = (struct hdmitx_dev *)dev;
632 /* get interrupt status */
633 data32 = hdmitx_rd_reg(HDMITX_TOP_INTR_STAT);
634 hdmi_print(IMP, SYS "irq %x\n", data32);
635 if (hdev->hpd_lock == 1) {
636 hdmitx_wr_reg(HDMITX_TOP_INTR_STAT_CLR, 0xf);
637 hdmi_print(IMP, HPD "HDMI hpd locked\n");
638 goto next;
639 }
640 /* check HPD status */
641 if ((data32 & (1 << 1)) && (data32 & (1 << 2))) {
642 if (hdmitx_hpd_hw_op(HPD_READ_HPD_GPIO))
643 data32 &= ~(1 << 2);
644 else
645 data32 &= ~(1 << 1);
646 }
647 /* HPD rising */
648 if (data32 & (1 << 1)) {
649 hdev->hdmitx_event |= HDMI_TX_HPD_PLUGIN;
650 hdev->hdmitx_event &= ~HDMI_TX_HPD_PLUGOUT;
651 queue_delayed_work(hdev->hdmi_wq,
652 &hdev->work_hpd_plugin, HZ / 2);
653 }
654 /* HPD falling */
655 if (data32 & (1 << 2)) {
656 hdev->hdmitx_event |= HDMI_TX_HPD_PLUGOUT;
657 hdev->hdmitx_event &= ~HDMI_TX_HPD_PLUGIN;
658 queue_delayed_work(hdev->hdmi_wq,
659 &hdev->work_hpd_plugout, 0);
660 }
661next:
662 /* internal interrupt */
663 if (data32 & (1 << 0)) {
664 hdev->hdmitx_event |= HDMI_TX_INTERNAL_INTR;
665 queue_work(hdev->hdmi_wq, &hdev->work_internal_intr);
666 }
667 if (data32 & (1 << 3)) {
668 unsigned int rd_nonce_mode =
669 hdmitx_rd_reg(HDMITX_TOP_SKP_CNTL_STAT) & 0x1;
670 pr_info("hdcp22: Nonce %s Vld: %d\n",
671 rd_nonce_mode ? "HW" : "SW",
672 ((hdmitx_rd_reg(HDMITX_TOP_SKP_CNTL_STAT) >> 31) & 1));
673 if (rd_nonce_mode)
674 hdmitx_wr_reg(HDMITX_TOP_INTR_STAT_CLR, (1 << 3));
675 else {
676 hdmitx_wr_reg(HDMITX_TOP_NONCE_0, 0x32107654);
677 hdmitx_wr_reg(HDMITX_TOP_NONCE_1, 0xba98fedc);
678 hdmitx_wr_reg(HDMITX_TOP_NONCE_2, 0xcdef89ab);
679 hdmitx_wr_reg(HDMITX_TOP_NONCE_3, 0x45670123);
680 hdmitx_wr_reg(HDMITX_TOP_NONCE_0, 0x76543210);
681 hdmitx_wr_reg(HDMITX_TOP_NONCE_1, 0xfedcba98);
682 hdmitx_wr_reg(HDMITX_TOP_NONCE_2, 0x89abcdef);
683 hdmitx_wr_reg(HDMITX_TOP_NONCE_3, 0x01234567);
684 }
685 }
686 if (data32 & (1 << 30)) {
687 pr_info("hdcp22: reg stat: 0x%x\n",
688 hdmitx_rd_reg(HDMITX_DWC_HDCP22REG_STAT));
689 hdmitx_wr_reg(HDMITX_DWC_HDCP22REG_STAT, 0xff);
690 }
691 /* ack INTERNAL_INTR or else we stuck with no interrupts at all */
692 hdmitx_wr_reg(HDMITX_TOP_INTR_STAT_CLR, data32 | 0x7);
693 return IRQ_HANDLED;
694}
695
696static unsigned long modulo(unsigned long a, unsigned long b)
697{
698 if (a >= b)
699 return a - b;
700 else
701 return a;
702}
703
704static signed int to_signed(unsigned int a)
705{
706 if (a <= 7)
707 return a;
708 else
709 return a - 16;
710}
711
712static void delay_us(int us)
713{
714 /* udelay(us); */
715 if (delay_flag&0x1)
716 mdelay((us+999)/1000);
717} /* delay_us */
718
719/*
720 * mode: 1 means Progressive; 0 means interlaced
721 */
722static void enc_vpu_bridge_reset(int mode)
723{
724 unsigned int wr_clk = 0;
725
726 wr_clk = (hd_read_reg(P_VPU_HDMI_SETTING) & 0xf00) >> 8;
727 if (mode) {
728 hd_write_reg(P_ENCP_VIDEO_EN, 0);
729 hd_set_reg_bits(P_VPU_HDMI_SETTING, 0, 0, 2);
730 hd_set_reg_bits(P_VPU_HDMI_SETTING, 0, 8, 4);
731 mdelay(1);
732 hd_write_reg(P_ENCP_VIDEO_EN, 1);
733 mdelay(1);
734 hd_set_reg_bits(P_VPU_HDMI_SETTING, wr_clk, 8, 4);
735 mdelay(1);
736 hd_set_reg_bits(P_VPU_HDMI_SETTING, 2, 0, 2);
737 } else {
738 hd_write_reg(P_ENCI_VIDEO_EN, 0);
739 hd_set_reg_bits(P_VPU_HDMI_SETTING, 0, 0, 2);
740 hd_set_reg_bits(P_VPU_HDMI_SETTING, 0, 8, 4);
741 mdelay(1);
742 hd_write_reg(P_ENCI_VIDEO_EN, 1);
743 mdelay(1);
744 hd_set_reg_bits(P_VPU_HDMI_SETTING, wr_clk, 8, 4);
745 mdelay(1);
746 hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 0, 2);
747 }
748}
749
750static void hdmi_tvenc1080i_set(struct hdmitx_vidpara *param)
751{
752 unsigned long VFIFO2VD_TO_HDMI_LATENCY = 2;
753 unsigned long TOTAL_PIXELS = 0, PIXEL_REPEAT_HDMI = 0,
754 PIXEL_REPEAT_VENC = 0, ACTIVE_PIXELS = 0;
755 unsigned int FRONT_PORCH = 88, HSYNC_PIXELS = 0, ACTIVE_LINES = 0,
756 INTERLACE_MODE = 0, TOTAL_LINES = 0, SOF_LINES = 0,
757 VSYNC_LINES = 0;
758 unsigned int LINES_F0 = 0, LINES_F1 = 563, BACK_PORCH = 0,
759 EOF_LINES = 2, TOTAL_FRAMES = 0;
760
761 unsigned long total_pixels_venc = 0;
762 unsigned long active_pixels_venc = 0;
763 unsigned long front_porch_venc = 0;
764 unsigned long hsync_pixels_venc = 0;
765
766 unsigned long de_h_begin = 0, de_h_end = 0;
767 unsigned long de_v_begin_even = 0, de_v_end_even = 0,
768 de_v_begin_odd = 0, de_v_end_odd = 0;
769 unsigned long hs_begin = 0, hs_end = 0;
770 unsigned long vs_adjust = 0;
771 unsigned long vs_bline_evn = 0, vs_eline_evn = 0,
772 vs_bline_odd = 0, vs_eline_odd = 0;
773 unsigned long vso_begin_evn = 0, vso_begin_odd = 0;
774
775 if (param->VIC == HDMI_1080i60) {
776 INTERLACE_MODE = 1;
777 PIXEL_REPEAT_VENC = 1;
778 PIXEL_REPEAT_HDMI = 0;
779 ACTIVE_PIXELS = (1920*(1+PIXEL_REPEAT_HDMI));
780 ACTIVE_LINES = (1080/(1+INTERLACE_MODE));
781 LINES_F0 = 562;
782 LINES_F1 = 563;
783 FRONT_PORCH = 88;
784 HSYNC_PIXELS = 44;
785 BACK_PORCH = 148;
786 EOF_LINES = 2;
787 VSYNC_LINES = 5;
788 SOF_LINES = 15;
789 TOTAL_FRAMES = 4;
790 } else if (param->VIC == HDMI_1080i50) {
791 INTERLACE_MODE = 1;
792 PIXEL_REPEAT_VENC = 1;
793 PIXEL_REPEAT_HDMI = 0;
794 ACTIVE_PIXELS = (1920*(1+PIXEL_REPEAT_HDMI));
795 ACTIVE_LINES = (1080/(1+INTERLACE_MODE));
796 LINES_F0 = 562;
797 LINES_F1 = 563;
798 FRONT_PORCH = 528;
799 HSYNC_PIXELS = 44;
800 BACK_PORCH = 148;
801 EOF_LINES = 2;
802 VSYNC_LINES = 5;
803 SOF_LINES = 15;
804 TOTAL_FRAMES = 4;
805 }
806 TOTAL_PIXELS = (FRONT_PORCH+HSYNC_PIXELS+BACK_PORCH+ACTIVE_PIXELS);
807 TOTAL_LINES = (LINES_F0+(LINES_F1*INTERLACE_MODE));
808
809 total_pixels_venc = (TOTAL_PIXELS / (1+PIXEL_REPEAT_HDMI)) *
810 (1+PIXEL_REPEAT_VENC);
811 active_pixels_venc = (ACTIVE_PIXELS / (1+PIXEL_REPEAT_HDMI)) *
812 (1+PIXEL_REPEAT_VENC);
813 front_porch_venc = (FRONT_PORCH / (1+PIXEL_REPEAT_HDMI)) *
814 (1+PIXEL_REPEAT_VENC);
815 hsync_pixels_venc =
816 (HSYNC_PIXELS / (1+PIXEL_REPEAT_HDMI)) * (1+PIXEL_REPEAT_VENC);
817
818 hd_write_reg(P_ENCP_VIDEO_MODE, hd_read_reg(P_ENCP_VIDEO_MODE)|(1<<14));
819
820 /* Program DE timing */
821 de_h_begin = modulo(hd_read_reg(P_ENCP_VIDEO_HAVON_BEGIN) +
822 VFIFO2VD_TO_HDMI_LATENCY, total_pixels_venc);
823 de_h_end = modulo(de_h_begin + active_pixels_venc, total_pixels_venc);
824 hd_write_reg(P_ENCP_DE_H_BEGIN, de_h_begin);
825 hd_write_reg(P_ENCP_DE_H_END, de_h_end);
826 /* Program DE timing for even field */
827 de_v_begin_even = hd_read_reg(P_ENCP_VIDEO_VAVON_BLINE);
828 de_v_end_even = de_v_begin_even + ACTIVE_LINES;
829 hd_write_reg(P_ENCP_DE_V_BEGIN_EVEN, de_v_begin_even);
830 hd_write_reg(P_ENCP_DE_V_END_EVEN, de_v_end_even);
831 /* Program DE timing for odd field if needed */
832 if (INTERLACE_MODE) {
833 de_v_begin_odd = to_signed((
834 hd_read_reg(P_ENCP_VIDEO_OFLD_VOAV_OFST) & 0xf0)>>4)
835 + de_v_begin_even + (TOTAL_LINES-1)/2;
836 de_v_end_odd = de_v_begin_odd + ACTIVE_LINES;
837 hd_write_reg(P_ENCP_DE_V_BEGIN_ODD, de_v_begin_odd);/* 583 */
838 hd_write_reg(P_ENCP_DE_V_END_ODD, de_v_end_odd); /* 1123 */
839 }
840
841 /* Program Hsync timing */
842 if (de_h_end + front_porch_venc >= total_pixels_venc) {
843 hs_begin = de_h_end + front_porch_venc - total_pixels_venc;
844 vs_adjust = 1;
845 } else {
846 hs_begin = de_h_end + front_porch_venc;
847 vs_adjust = 0;
848 }
849 hs_end = modulo(hs_begin + hsync_pixels_venc, total_pixels_venc);
850 hd_write_reg(P_ENCP_DVI_HSO_BEGIN, hs_begin);
851 hd_write_reg(P_ENCP_DVI_HSO_END, hs_end);
852
853 /* Program Vsync timing for even field */
854 if (de_v_begin_even >= SOF_LINES + VSYNC_LINES + (1-vs_adjust))
855 vs_bline_evn = de_v_begin_even - SOF_LINES - VSYNC_LINES
856 - (1-vs_adjust);
857 else
858 vs_bline_evn = TOTAL_LINES + de_v_begin_even - SOF_LINES
859 - VSYNC_LINES - (1-vs_adjust);
860
861 vs_eline_evn = modulo(vs_bline_evn + VSYNC_LINES, TOTAL_LINES);
862 hd_write_reg(P_ENCP_DVI_VSO_BLINE_EVN, vs_bline_evn); /* 0 */
863 hd_write_reg(P_ENCP_DVI_VSO_ELINE_EVN, vs_eline_evn); /* 5 */
864 vso_begin_evn = hs_begin; /* 2 */
865 hd_write_reg(P_ENCP_DVI_VSO_BEGIN_EVN, vso_begin_evn); /* 2 */
866 hd_write_reg(P_ENCP_DVI_VSO_END_EVN, vso_begin_evn); /* 2 */
867 /* Program Vsync timing for odd field if needed */
868 if (INTERLACE_MODE) {
869 vs_bline_odd = de_v_begin_odd-1 - SOF_LINES - VSYNC_LINES;
870 vs_eline_odd = de_v_begin_odd-1 - SOF_LINES;
871 vso_begin_odd = modulo(hs_begin + (total_pixels_venc>>1),
872 total_pixels_venc);
873 hd_write_reg(P_ENCP_DVI_VSO_BLINE_ODD, vs_bline_odd);
874 hd_write_reg(P_ENCP_DVI_VSO_ELINE_ODD, vs_eline_odd);
875 hd_write_reg(P_ENCP_DVI_VSO_BEGIN_ODD, vso_begin_odd);
876 hd_write_reg(P_ENCP_DVI_VSO_END_ODD, vso_begin_odd);
877 }
878
879 hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) |
880 (0 << 1) |
881 (HSYNC_POLARITY << 2) |
882 (VSYNC_POLARITY << 3) |
883 (0 << 4) |
884 (4 << 5) |
885 (1 << 8) |
886 (0 << 12)
887 );
888 hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1);
889}
890
891static void hdmi_tvenc4k2k_set(struct hdmitx_vidpara *param)
892{
893 unsigned long VFIFO2VD_TO_HDMI_LATENCY = 2;
894 unsigned long TOTAL_PIXELS = 4400, PIXEL_REPEAT_HDMI = 0,
895 PIXEL_REPEAT_VENC = 0, ACTIVE_PIXELS = 3840;
896 unsigned int FRONT_PORCH = 1020, HSYNC_PIXELS = 0, ACTIVE_LINES = 2160,
897 INTERLACE_MODE = 0U, TOTAL_LINES = 0, SOF_LINES = 0,
898 VSYNC_LINES = 0;
899 unsigned int LINES_F0 = 2250, LINES_F1 = 2250, BACK_PORCH = 0,
900 EOF_LINES = 8, TOTAL_FRAMES = 0;
901
902 unsigned long total_pixels_venc = 0;
903 unsigned long active_pixels_venc = 0;
904 unsigned long front_porch_venc = 0;
905 unsigned long hsync_pixels_venc = 0;
906
907 unsigned long de_h_begin = 0, de_h_end = 0;
908 unsigned long de_v_begin_even = 0, de_v_end_even = 0;
909 unsigned long hs_begin = 0, hs_end = 0;
910 unsigned long vs_adjust = 0;
911 unsigned long vs_bline_evn = 0, vs_eline_evn = 0;
912 unsigned long vso_begin_evn = 0;
913
914 switch (param->VIC) {
915 case HDMI_4k2k_30:
916 case HDMI_3840x2160p60_16x9:
917 case HDMI_3840x2160p60_16x9_Y420:
918 INTERLACE_MODE = 0U;
919 PIXEL_REPEAT_VENC = 0;
920 PIXEL_REPEAT_HDMI = 0;
921 ACTIVE_PIXELS = (3840*(1+PIXEL_REPEAT_HDMI));
922 ACTIVE_LINES = (2160/(1+INTERLACE_MODE));
923 LINES_F0 = 2250;
924 LINES_F1 = 2250;
925 FRONT_PORCH = 176;
926 HSYNC_PIXELS = 88;
927 BACK_PORCH = 296;
928 EOF_LINES = 8 + 1;
929 VSYNC_LINES = 10;
930 SOF_LINES = 72 + 1;
931 TOTAL_FRAMES = 3;
932 break;
933 case HDMI_4k2k_25:
934 case HDMI_3840x2160p50_16x9:
935 case HDMI_3840x2160p50_16x9_Y420:
936 INTERLACE_MODE = 0U;
937 PIXEL_REPEAT_VENC = 0;
938 PIXEL_REPEAT_HDMI = 0;
939 ACTIVE_PIXELS = (3840*(1+PIXEL_REPEAT_HDMI));
940 ACTIVE_LINES = (2160/(1+INTERLACE_MODE));
941 LINES_F0 = 2250;
942 LINES_F1 = 2250;
943 FRONT_PORCH = 1056;
944 HSYNC_PIXELS = 88;
945 BACK_PORCH = 296;
946 EOF_LINES = 8 + 1;
947 VSYNC_LINES = 10;
948 SOF_LINES = 72 + 1;
949 TOTAL_FRAMES = 3;
950 break;
951 case HDMI_4k2k_24:
952 INTERLACE_MODE = 0U;
953 PIXEL_REPEAT_VENC = 0;
954 PIXEL_REPEAT_HDMI = 0;
955 ACTIVE_PIXELS = (3840*(1+PIXEL_REPEAT_HDMI));
956 ACTIVE_LINES = (2160/(1+INTERLACE_MODE));
957 LINES_F0 = 2250;
958 LINES_F1 = 2250;
959 FRONT_PORCH = 1276;
960 HSYNC_PIXELS = 88;
961 BACK_PORCH = 296;
962 EOF_LINES = 8 + 1;
963 VSYNC_LINES = 10;
964 SOF_LINES = 72 + 1;
965 TOTAL_FRAMES = 3;
966 break;
967 case HDMI_4k2k_smpte_24:
968 INTERLACE_MODE = 0U;
969 PIXEL_REPEAT_VENC = 0;
970 PIXEL_REPEAT_HDMI = 0;
971 ACTIVE_PIXELS = (4096*(1+PIXEL_REPEAT_HDMI));
972 ACTIVE_LINES = (2160/(1+INTERLACE_MODE));
973 LINES_F0 = 2250;
974 LINES_F1 = 2250;
975 FRONT_PORCH = 1020;
976 HSYNC_PIXELS = 88;
977 BACK_PORCH = 296;
978 EOF_LINES = 8 + 1;
979 VSYNC_LINES = 10;
980 SOF_LINES = 72 + 1;
981 TOTAL_FRAMES = 3;
982 break;
983 case HDMI_4096x2160p25_256x135:
984 case HDMI_4096x2160p50_256x135:
985 case HDMI_4096x2160p50_256x135_Y420:
986 INTERLACE_MODE = 0U;
987 PIXEL_REPEAT_VENC = 0;
988 PIXEL_REPEAT_HDMI = 0;
989 ACTIVE_PIXELS = (4096*(1+PIXEL_REPEAT_HDMI));
990 ACTIVE_LINES = (2160/(1+INTERLACE_MODE));
991 LINES_F0 = 2250;
992 LINES_F1 = 2250;
993 FRONT_PORCH = 968;
994 HSYNC_PIXELS = 88;
995 BACK_PORCH = 128;
996 EOF_LINES = 8;
997 VSYNC_LINES = 10;
998 SOF_LINES = 72;
999 TOTAL_FRAMES = 3;
1000 break;
1001 case HDMI_4096x2160p30_256x135:
1002 case HDMI_4096x2160p60_256x135:
1003 case HDMI_4096x2160p60_256x135_Y420:
1004 INTERLACE_MODE = 0U;
1005 PIXEL_REPEAT_VENC = 0;
1006 PIXEL_REPEAT_HDMI = 0;
1007 ACTIVE_PIXELS = (4096*(1+PIXEL_REPEAT_HDMI));
1008 ACTIVE_LINES = (2160/(1+INTERLACE_MODE));
1009 LINES_F0 = 2250;
1010 LINES_F1 = 2250;
1011 FRONT_PORCH = 88;
1012 HSYNC_PIXELS = 88;
1013 BACK_PORCH = 128;
1014 EOF_LINES = 8;
1015 VSYNC_LINES = 10;
1016 SOF_LINES = 72;
1017 TOTAL_FRAMES = 3;
1018 break;
1019 default:
1020 pr_info("hdmitx20: no setting for VIC = %d\n", param->VIC);
1021 break;
1022 }
1023
1024 TOTAL_PIXELS = (FRONT_PORCH+HSYNC_PIXELS+BACK_PORCH+ACTIVE_PIXELS);
1025 TOTAL_LINES = (LINES_F0+(LINES_F1*INTERLACE_MODE));
1026
1027 total_pixels_venc = (TOTAL_PIXELS / (1+PIXEL_REPEAT_HDMI)) *
1028 (1+PIXEL_REPEAT_VENC);
1029 active_pixels_venc = (ACTIVE_PIXELS / (1+PIXEL_REPEAT_HDMI)) *
1030 (1+PIXEL_REPEAT_VENC);
1031 front_porch_venc = (FRONT_PORCH / (1+PIXEL_REPEAT_HDMI)) *
1032 (1+PIXEL_REPEAT_VENC);
1033 hsync_pixels_venc = (HSYNC_PIXELS / (1+PIXEL_REPEAT_HDMI)) *
1034 (1+PIXEL_REPEAT_VENC);
1035
1036 de_h_begin = modulo(hd_read_reg(P_ENCP_VIDEO_HAVON_BEGIN) +
1037 VFIFO2VD_TO_HDMI_LATENCY, total_pixels_venc);
1038 de_h_end = modulo(de_h_begin + active_pixels_venc, total_pixels_venc);
1039 hd_write_reg(P_ENCP_DE_H_BEGIN, de_h_begin);
1040 hd_write_reg(P_ENCP_DE_H_END, de_h_end);
1041 /* Program DE timing for even field */
1042 de_v_begin_even = hd_read_reg(P_ENCP_VIDEO_VAVON_BLINE);
1043 de_v_end_even = modulo(de_v_begin_even + ACTIVE_LINES, TOTAL_LINES);
1044 hd_write_reg(P_ENCP_DE_V_BEGIN_EVEN, de_v_begin_even);
1045 hd_write_reg(P_ENCP_DE_V_END_EVEN, de_v_end_even);
1046
1047 /* Program Hsync timing */
1048 if (de_h_end + front_porch_venc >= total_pixels_venc) {
1049 hs_begin = de_h_end + front_porch_venc - total_pixels_venc;
1050 vs_adjust = 1;
1051 } else {
1052 hs_begin = de_h_end + front_porch_venc;
1053 vs_adjust = 1;
1054 }
1055 hs_end = modulo(hs_begin + hsync_pixels_venc, total_pixels_venc);
1056 hd_write_reg(P_ENCP_DVI_HSO_BEGIN, hs_begin);
1057 hd_write_reg(P_ENCP_DVI_HSO_END, hs_end);
1058
1059 /* Program Vsync timing for even field */
1060 if (de_v_begin_even >= SOF_LINES + VSYNC_LINES + (1-vs_adjust))
1061 vs_bline_evn = de_v_begin_even - SOF_LINES - VSYNC_LINES
1062 - (1-vs_adjust);
1063 else
1064 vs_bline_evn = TOTAL_LINES + de_v_begin_even - SOF_LINES
1065 - VSYNC_LINES - (1-vs_adjust);
1066 vs_eline_evn = modulo(vs_bline_evn + VSYNC_LINES, TOTAL_LINES);
1067 hd_write_reg(P_ENCP_DVI_VSO_BLINE_EVN, vs_bline_evn);
1068 hd_write_reg(P_ENCP_DVI_VSO_ELINE_EVN, vs_eline_evn);
1069 vso_begin_evn = hs_begin;
1070 hd_write_reg(P_ENCP_DVI_VSO_BEGIN_EVN, vso_begin_evn);
1071 hd_write_reg(P_ENCP_DVI_VSO_END_EVN, vso_begin_evn);
1072 hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) |
1073 (0 << 1) |
1074 (HSYNC_POLARITY << 2) |
1075 (VSYNC_POLARITY << 3) |
1076 (0 << 4) |
1077 (4 << 5) |
1078 (0 << 8) |
1079 (0 << 12)
1080 );
1081 hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1);
1082 hd_write_reg(P_ENCP_VIDEO_EN, 1);
1083}
1084
1085static void hdmi_tvenc480i_set(struct hdmitx_vidpara *param)
1086{
1087 unsigned long VFIFO2VD_TO_HDMI_LATENCY = 1;
1088 unsigned long TOTAL_PIXELS = 0, PIXEL_REPEAT_HDMI = 0,
1089 PIXEL_REPEAT_VENC = 0, ACTIVE_PIXELS = 0;
1090 unsigned int FRONT_PORCH = 38, HSYNC_PIXELS = 124, ACTIVE_LINES = 0,
1091 INTERLACE_MODE = 0, TOTAL_LINES = 0, SOF_LINES = 0,
1092 VSYNC_LINES = 0;
1093 unsigned int LINES_F0 = 262, LINES_F1 = 263, BACK_PORCH = 114,
1094 EOF_LINES = 2, TOTAL_FRAMES = 0;
1095
1096 unsigned long total_pixels_venc = 0;
1097 unsigned long active_pixels_venc = 0;
1098 unsigned long front_porch_venc = 0;
1099 unsigned long hsync_pixels_venc = 0;
1100
1101 unsigned long de_h_begin = 0, de_h_end = 0;
1102 unsigned long de_v_begin_even = 0, de_v_end_even = 0,
1103 de_v_begin_odd = 0, de_v_end_odd = 0;
1104 unsigned long hs_begin = 0, hs_end = 0;
1105 unsigned long vs_adjust = 0;
1106 unsigned long vs_bline_evn = 0, vs_eline_evn = 0,
1107 vs_bline_odd = 0, vs_eline_odd = 0;
1108 unsigned long vso_begin_evn = 0, vso_begin_odd = 0;
1109
1110 hd_set_reg_bits(P_HHI_GCLK_OTHER, 1, 8, 1);
1111 switch (param->VIC) {
1112 case HDMI_480i60:
1113 case HDMI_480i60_16x9:
1114 case HDMI_480i60_16x9_rpt:
1115 INTERLACE_MODE = 1;
1116 PIXEL_REPEAT_VENC = 1;
1117 PIXEL_REPEAT_HDMI = 1;
1118 ACTIVE_PIXELS = (720*(1+PIXEL_REPEAT_HDMI));
1119 ACTIVE_LINES = (480/(1+INTERLACE_MODE));
1120 LINES_F0 = 262;
1121 LINES_F1 = 263;
1122 FRONT_PORCH = 38;
1123 HSYNC_PIXELS = 124;
1124 BACK_PORCH = 114;
1125 EOF_LINES = 4;
1126 VSYNC_LINES = 3;
1127 SOF_LINES = 15;
1128 TOTAL_FRAMES = 4;
1129 break;
1130 case HDMI_576i50:
1131 case HDMI_576i50_16x9:
1132 case HDMI_576i50_16x9_rpt:
1133 INTERLACE_MODE = 1;
1134 PIXEL_REPEAT_VENC = 1;
1135 PIXEL_REPEAT_HDMI = 1;
1136 ACTIVE_PIXELS = (720*(1+PIXEL_REPEAT_HDMI));
1137 ACTIVE_LINES = (576/(1+INTERLACE_MODE));
1138 LINES_F0 = 312;
1139 LINES_F1 = 313;
1140 FRONT_PORCH = 24;
1141 HSYNC_PIXELS = 126;
1142 BACK_PORCH = 138;
1143 EOF_LINES = 2;
1144 VSYNC_LINES = 3;
1145 SOF_LINES = 19;
1146 TOTAL_FRAMES = 4;
1147 break;
1148 default:
1149 break;
1150 }
1151
1152 TOTAL_PIXELS = (FRONT_PORCH+HSYNC_PIXELS+BACK_PORCH+ACTIVE_PIXELS);
1153 TOTAL_LINES = (LINES_F0+(LINES_F1*INTERLACE_MODE));
1154
1155 total_pixels_venc = (TOTAL_PIXELS / (1+PIXEL_REPEAT_HDMI)) *
1156 (1+PIXEL_REPEAT_VENC); /* 1716 / 2 * 2 = 1716 */
1157 active_pixels_venc = (ACTIVE_PIXELS / (1+PIXEL_REPEAT_HDMI)) *
1158 (1+PIXEL_REPEAT_VENC);
1159 front_porch_venc = (FRONT_PORCH / (1+PIXEL_REPEAT_HDMI)) *
1160 (1+PIXEL_REPEAT_VENC); /* 38 / 2 * 2 = 38 */
1161 hsync_pixels_venc = (HSYNC_PIXELS / (1+PIXEL_REPEAT_HDMI)) *
1162 (1+PIXEL_REPEAT_VENC); /* 124 / 2 * 2 = 124 */
1163
1164 de_h_begin = modulo(hd_read_reg(P_ENCI_VFIFO2VD_PIXEL_START) +
1165 VFIFO2VD_TO_HDMI_LATENCY, total_pixels_venc);
1166 de_h_end = modulo(de_h_begin + active_pixels_venc, total_pixels_venc);
1167 hd_write_reg(P_ENCI_DE_H_BEGIN, de_h_begin); /* 235 */
1168 hd_write_reg(P_ENCI_DE_H_END, de_h_end); /* 1675 */
1169
1170 de_v_begin_even = hd_read_reg(P_ENCI_VFIFO2VD_LINE_TOP_START);
1171 de_v_end_even = de_v_begin_even + ACTIVE_LINES;
1172 de_v_begin_odd = hd_read_reg(P_ENCI_VFIFO2VD_LINE_BOT_START);
1173 de_v_end_odd = de_v_begin_odd + ACTIVE_LINES;
1174 hd_write_reg(P_ENCI_DE_V_BEGIN_EVEN, de_v_begin_even);
1175 hd_write_reg(P_ENCI_DE_V_END_EVEN, de_v_end_even);
1176 hd_write_reg(P_ENCI_DE_V_BEGIN_ODD, de_v_begin_odd);
1177 hd_write_reg(P_ENCI_DE_V_END_ODD, de_v_end_odd);
1178
1179 /* Program Hsync timing */
1180 if (de_h_end + front_porch_venc >= total_pixels_venc) {
1181 hs_begin = de_h_end + front_porch_venc - total_pixels_venc;
1182 vs_adjust = 1;
1183 } else {
1184 hs_begin = de_h_end + front_porch_venc;
1185 vs_adjust = 0;
1186 }
1187 hs_end = modulo(hs_begin + hsync_pixels_venc, total_pixels_venc);
1188 hd_write_reg(P_ENCI_DVI_HSO_BEGIN, hs_begin); /* 1713 */
1189 hd_write_reg(P_ENCI_DVI_HSO_END, hs_end); /* 121 */
1190
1191 /* Program Vsync timing for even field */
1192 if (de_v_end_odd-1 + EOF_LINES + vs_adjust >= LINES_F1) {
1193 vs_bline_evn = de_v_end_odd-1 + EOF_LINES + vs_adjust
1194 - LINES_F1;
1195 vs_eline_evn = vs_bline_evn + VSYNC_LINES;
1196 hd_write_reg(P_ENCI_DVI_VSO_BLINE_EVN, vs_bline_evn);
1197 /* vso_bline_evn_reg_wr_cnt ++; */
1198 hd_write_reg(P_ENCI_DVI_VSO_ELINE_EVN, vs_eline_evn);
1199 /* vso_eline_evn_reg_wr_cnt ++; */
1200 hd_write_reg(P_ENCI_DVI_VSO_BEGIN_EVN, hs_begin);
1201 hd_write_reg(P_ENCI_DVI_VSO_END_EVN, hs_begin);
1202 } else {
1203 vs_bline_odd = de_v_end_odd-1 + EOF_LINES + vs_adjust;
1204 hd_write_reg(P_ENCI_DVI_VSO_BLINE_ODD, vs_bline_odd);
1205 /* vso_bline_odd_reg_wr_cnt ++; */
1206 hd_write_reg(P_ENCI_DVI_VSO_BEGIN_ODD, hs_begin);
1207 if (vs_bline_odd + VSYNC_LINES >= LINES_F1) {
1208 vs_eline_evn = vs_bline_odd + VSYNC_LINES - LINES_F1;
1209 hd_write_reg(P_ENCI_DVI_VSO_ELINE_EVN, vs_eline_evn);
1210 /* vso_eline_evn_reg_wr_cnt ++; */
1211 hd_write_reg(P_ENCI_DVI_VSO_END_EVN, hs_begin);
1212 } else {
1213 vs_eline_odd = vs_bline_odd + VSYNC_LINES;
1214 hd_write_reg(P_ENCI_DVI_VSO_ELINE_ODD, vs_eline_odd);
1215 /* vso_eline_odd_reg_wr_cnt ++; */
1216 hd_write_reg(P_ENCI_DVI_VSO_END_ODD, hs_begin);
1217 }
1218 }
1219 /* Program Vsync timing for odd field */
1220 if (de_v_end_even-1 + EOF_LINES + 1 >= LINES_F0) {
1221 vs_bline_odd = de_v_end_even-1 + EOF_LINES + 1 - LINES_F0;
1222 vs_eline_odd = vs_bline_odd + VSYNC_LINES;
1223 hd_write_reg(P_ENCI_DVI_VSO_BLINE_ODD, vs_bline_odd);
1224 /* vso_bline_odd_reg_wr_cnt ++; */
1225 hd_write_reg(P_ENCI_DVI_VSO_ELINE_ODD, vs_eline_odd);
1226 /* vso_eline_odd_reg_wr_cnt ++; */
1227 vso_begin_odd = modulo(hs_begin + (total_pixels_venc>>1),
1228 total_pixels_venc);
1229 hd_write_reg(P_ENCI_DVI_VSO_BEGIN_ODD, vso_begin_odd);
1230 hd_write_reg(P_ENCI_DVI_VSO_END_ODD, vso_begin_odd);
1231 } else {
1232 vs_bline_evn = de_v_end_even-1 + EOF_LINES + 1;
1233 hd_write_reg(P_ENCI_DVI_VSO_BLINE_EVN, vs_bline_evn); /* 261 */
1234 /* vso_bline_evn_reg_wr_cnt ++; */
1235 vso_begin_evn = modulo(hs_begin + (total_pixels_venc>>1),
1236 total_pixels_venc);
1237 hd_write_reg(P_ENCI_DVI_VSO_BEGIN_EVN, vso_begin_evn);
1238 if (vs_bline_evn + VSYNC_LINES >= LINES_F0) {
1239 vs_eline_odd = vs_bline_evn + VSYNC_LINES - LINES_F0;
1240 hd_write_reg(P_ENCI_DVI_VSO_ELINE_ODD, vs_eline_odd);
1241 /* vso_eline_odd_reg_wr_cnt ++; */
1242 hd_write_reg(P_ENCI_DVI_VSO_END_ODD, vso_begin_evn);
1243 } else {
1244 vs_eline_evn = vs_bline_evn + VSYNC_LINES;
1245 hd_write_reg(P_ENCI_DVI_VSO_ELINE_EVN, vs_eline_evn);
1246 /* vso_eline_evn_reg_wr_cnt ++; */
1247 hd_write_reg(P_ENCI_DVI_VSO_END_EVN, vso_begin_evn);
1248 }
1249 }
1250
1251 hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) |
1252 (0 << 1) |
1253 (0 << 2) |
1254 (0 << 3) |
1255 (0 << 4) |
1256 (4 << 5) |
1257 (1 << 8) |
1258 (1 << 12)
1259 );
1260 if ((param->VIC == HDMI_480i60_16x9_rpt) ||
1261 (param->VIC == HDMI_576i50_16x9_rpt))
1262 hd_set_reg_bits(P_VPU_HDMI_SETTING, 3, 12, 4);
1263 hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 0, 1);
1264}
1265
1266static void hdmi_tvenc_set(struct hdmitx_vidpara *param)
1267{
1268 unsigned long VFIFO2VD_TO_HDMI_LATENCY = 2;
1269 unsigned long TOTAL_PIXELS = 0, PIXEL_REPEAT_HDMI = 0,
1270 PIXEL_REPEAT_VENC = 0, ACTIVE_PIXELS = 0;
1271 unsigned int FRONT_PORCH = 0, HSYNC_PIXELS = 0, ACTIVE_LINES = 0,
1272 INTERLACE_MODE = 0U, TOTAL_LINES = 0, SOF_LINES = 0,
1273 VSYNC_LINES = 0;
1274 unsigned int LINES_F0 = 0, LINES_F1 = 0, BACK_PORCH = 0,
1275 EOF_LINES = 0, TOTAL_FRAMES = 0;
1276
1277 unsigned long total_pixels_venc = 0;
1278 unsigned long active_pixels_venc = 0;
1279 unsigned long front_porch_venc = 0;
1280 unsigned long hsync_pixels_venc = 0;
1281
1282 unsigned long de_h_begin = 0, de_h_end = 0;
1283 unsigned long de_v_begin_even = 0, de_v_end_even = 0;
1284 unsigned long hs_begin = 0, hs_end = 0;
1285 unsigned long vs_adjust = 0;
1286 unsigned long vs_bline_evn = 0, vs_eline_evn = 0;
1287 unsigned long vso_begin_evn = 0;
1288
1289 switch (param->VIC) {
1290 case HDMI_3840x1080p120hz:
1291 INTERLACE_MODE = 0U;
1292 PIXEL_REPEAT_VENC = 0;
1293 PIXEL_REPEAT_HDMI = 0;
1294 ACTIVE_PIXELS = 3840;
1295 ACTIVE_LINES = 1080;
1296 LINES_F0 = 1125;
1297 LINES_F1 = 1125;
1298 FRONT_PORCH = 176;
1299 HSYNC_PIXELS = 88;
1300 BACK_PORCH = 296;
1301 EOF_LINES = 4;
1302 VSYNC_LINES = 5;
1303 SOF_LINES = 36;
1304 TOTAL_FRAMES = 0;
1305 break;
1306 case HDMI_3840x1080p100hz:
1307 INTERLACE_MODE = 0U;
1308 PIXEL_REPEAT_VENC = 0;
1309 PIXEL_REPEAT_HDMI = 0;
1310 ACTIVE_PIXELS = 3840;
1311 ACTIVE_LINES = 1080;
1312 LINES_F0 = 1125;
1313 LINES_F1 = 1125;
1314 FRONT_PORCH = 1056;
1315 HSYNC_PIXELS = 88;
1316 BACK_PORCH = 296;
1317 EOF_LINES = 4;
1318 VSYNC_LINES = 5;
1319 SOF_LINES = 36;
1320 TOTAL_FRAMES = 0;
1321 break;
1322 case HDMI_3840x540p240hz:
1323 INTERLACE_MODE = 0U;
1324 PIXEL_REPEAT_VENC = 0;
1325 PIXEL_REPEAT_HDMI = 0;
1326 ACTIVE_PIXELS = 3840;
1327 ACTIVE_LINES = 1080;
1328 LINES_F0 = 562;
1329 LINES_F1 = 562;
1330 FRONT_PORCH = 176;
1331 HSYNC_PIXELS = 88;
1332 BACK_PORCH = 296;
1333 EOF_LINES = 2;
1334 VSYNC_LINES = 2;
1335 SOF_LINES = 18;
1336 TOTAL_FRAMES = 0;
1337 break;
1338 case HDMI_3840x540p200hz:
1339 INTERLACE_MODE = 0U;
1340 PIXEL_REPEAT_VENC = 0;
1341 PIXEL_REPEAT_HDMI = 0;
1342 ACTIVE_PIXELS = 3840;
1343 ACTIVE_LINES = 1080;
1344 LINES_F0 = 562;
1345 LINES_F1 = 562;
1346 FRONT_PORCH = 1056;
1347 HSYNC_PIXELS = 88;
1348 BACK_PORCH = 296;
1349 EOF_LINES = 2;
1350 VSYNC_LINES = 2;
1351 SOF_LINES = 18;
1352 TOTAL_FRAMES = 0;
1353 break;
1354 case HDMI_480p60:
1355 case HDMI_480p60_16x9:
1356 case HDMI_480p60_16x9_rpt:
1357 INTERLACE_MODE = 0U;
1358 PIXEL_REPEAT_VENC = 1;
1359 PIXEL_REPEAT_HDMI = 0;
1360 ACTIVE_PIXELS = (720*(1+PIXEL_REPEAT_HDMI));
1361 ACTIVE_LINES = (480/(1+INTERLACE_MODE));
1362 LINES_F0 = 525;
1363 LINES_F1 = 525;
1364 FRONT_PORCH = 16;
1365 HSYNC_PIXELS = 62;
1366 BACK_PORCH = 60;
1367 EOF_LINES = 9;
1368 VSYNC_LINES = 6;
1369 SOF_LINES = 30;
1370 TOTAL_FRAMES = 4;
1371 break;
1372 case HDMI_576p50:
1373 case HDMI_576p50_16x9:
1374 case HDMI_576p50_16x9_rpt:
1375 INTERLACE_MODE = 0U;
1376 PIXEL_REPEAT_VENC = 1;
1377 PIXEL_REPEAT_HDMI = 0;
1378 ACTIVE_PIXELS = (720*(1+PIXEL_REPEAT_HDMI));
1379 ACTIVE_LINES = (576/(1+INTERLACE_MODE));
1380 LINES_F0 = 625;
1381 LINES_F1 = 625;
1382 FRONT_PORCH = 12;
1383 HSYNC_PIXELS = 64;
1384 BACK_PORCH = 68;
1385 EOF_LINES = 5;
1386 VSYNC_LINES = 5;
1387 SOF_LINES = 39;
1388 TOTAL_FRAMES = 4;
1389 break;
1390 case HDMI_720p60:
1391 INTERLACE_MODE = 0U;
1392 PIXEL_REPEAT_VENC = 1;
1393 PIXEL_REPEAT_HDMI = 0;
1394 ACTIVE_PIXELS = (1280*(1+PIXEL_REPEAT_HDMI));
1395 ACTIVE_LINES = (720/(1+INTERLACE_MODE));
1396 LINES_F0 = 750;
1397 LINES_F1 = 750;
1398 FRONT_PORCH = 110;
1399 HSYNC_PIXELS = 40;
1400 BACK_PORCH = 220;
1401 EOF_LINES = 5;
1402 VSYNC_LINES = 5;
1403 SOF_LINES = 20;
1404 TOTAL_FRAMES = 4;
1405 break;
1406 case HDMI_720p50:
1407 INTERLACE_MODE = 0U;
1408 PIXEL_REPEAT_VENC = 1;
1409 PIXEL_REPEAT_HDMI = 0;
1410 ACTIVE_PIXELS = (1280*(1+PIXEL_REPEAT_HDMI));
1411 ACTIVE_LINES = (720/(1+INTERLACE_MODE));
1412 LINES_F0 = 750;
1413 LINES_F1 = 750;
1414 FRONT_PORCH = 440;
1415 HSYNC_PIXELS = 40;
1416 BACK_PORCH = 220;
1417 EOF_LINES = 5;
1418 VSYNC_LINES = 5;
1419 SOF_LINES = 20;
1420 TOTAL_FRAMES = 4;
1421 break;
1422 case HDMI_1080p50:
1423 case HDMI_1080p25:
1424 INTERLACE_MODE = 0U;
1425 PIXEL_REPEAT_VENC = 0;
1426 PIXEL_REPEAT_HDMI = 0;
1427 ACTIVE_PIXELS = (1920*(1+PIXEL_REPEAT_HDMI));
1428 ACTIVE_LINES = (1080/(1+INTERLACE_MODE));
1429 LINES_F0 = 1125;
1430 LINES_F1 = 1125;
1431 FRONT_PORCH = 528;
1432 HSYNC_PIXELS = 44;
1433 BACK_PORCH = 148;
1434 EOF_LINES = 4;
1435 VSYNC_LINES = 5;
1436 SOF_LINES = 36;
1437 TOTAL_FRAMES = 4;
1438 break;
1439 case HDMI_1080p24:
1440 INTERLACE_MODE = 0U;
1441 PIXEL_REPEAT_VENC = 0;
1442 PIXEL_REPEAT_HDMI = 0;
1443 ACTIVE_PIXELS = (1920*(1+PIXEL_REPEAT_HDMI));
1444 ACTIVE_LINES = (1080/(1+INTERLACE_MODE));
1445 LINES_F0 = 1125;
1446 LINES_F1 = 1125;
1447 FRONT_PORCH = 638;
1448 HSYNC_PIXELS = 44;
1449 BACK_PORCH = 148;
1450 EOF_LINES = 4;
1451 VSYNC_LINES = 5;
1452 SOF_LINES = 36;
1453 TOTAL_FRAMES = 4;
1454 break;
1455 case HDMI_1080p60:
1456 case HDMI_1080p30:
1457 INTERLACE_MODE = 0U;
1458 PIXEL_REPEAT_VENC = 0;
1459 PIXEL_REPEAT_HDMI = 0;
1460 ACTIVE_PIXELS = (1920*(1+PIXEL_REPEAT_HDMI));
1461 ACTIVE_LINES = (1080/(1+INTERLACE_MODE));
1462 LINES_F0 = 1125;
1463 LINES_F1 = 1125;
1464 FRONT_PORCH = 88;
1465 HSYNC_PIXELS = 44;
1466 BACK_PORCH = 148;
1467 EOF_LINES = 4;
1468 VSYNC_LINES = 5;
1469 SOF_LINES = 36;
1470 TOTAL_FRAMES = 4;
1471 break;
1472 default:
1473 break;
1474 }
1475
1476 TOTAL_PIXELS = (FRONT_PORCH+HSYNC_PIXELS+BACK_PORCH+ACTIVE_PIXELS);
1477 TOTAL_LINES = (LINES_F0+(LINES_F1*INTERLACE_MODE));
1478
1479 total_pixels_venc = (TOTAL_PIXELS / (1+PIXEL_REPEAT_HDMI)) *
1480 (1+PIXEL_REPEAT_VENC);
1481 active_pixels_venc = (ACTIVE_PIXELS / (1+PIXEL_REPEAT_HDMI)) *
1482 (1+PIXEL_REPEAT_VENC);
1483 front_porch_venc = (FRONT_PORCH / (1+PIXEL_REPEAT_HDMI)) *
1484 (1+PIXEL_REPEAT_VENC);
1485 hsync_pixels_venc = (HSYNC_PIXELS / (1+PIXEL_REPEAT_HDMI)) *
1486 (1+PIXEL_REPEAT_VENC);
1487
1488 hd_write_reg(P_ENCP_VIDEO_MODE, hd_read_reg(P_ENCP_VIDEO_MODE)|(1<<14));
1489 /* Program DE timing */
1490 de_h_begin = modulo(hd_read_reg(P_ENCP_VIDEO_HAVON_BEGIN) +
1491 VFIFO2VD_TO_HDMI_LATENCY, total_pixels_venc);
1492 de_h_end = modulo(de_h_begin + active_pixels_venc, total_pixels_venc);
1493 hd_write_reg(P_ENCP_DE_H_BEGIN, de_h_begin); /* 220 */
1494 hd_write_reg(P_ENCP_DE_H_END, de_h_end); /* 1660 */
1495 /* Program DE timing for even field */
1496 de_v_begin_even = hd_read_reg(P_ENCP_VIDEO_VAVON_BLINE);
1497 de_v_end_even = de_v_begin_even + ACTIVE_LINES;
1498 hd_write_reg(P_ENCP_DE_V_BEGIN_EVEN, de_v_begin_even);
1499 hd_write_reg(P_ENCP_DE_V_END_EVEN, de_v_end_even); /* 522 */
1500
1501 /* Program Hsync timing */
1502 if (de_h_end + front_porch_venc >= total_pixels_venc) {
1503 hs_begin = de_h_end + front_porch_venc - total_pixels_venc;
1504 vs_adjust = 1;
1505 } else {
1506 hs_begin = de_h_end + front_porch_venc;
1507 vs_adjust = 0;
1508 }
1509 hs_end = modulo(hs_begin + hsync_pixels_venc, total_pixels_venc);
1510 hd_write_reg(P_ENCP_DVI_HSO_BEGIN, hs_begin);
1511 hd_write_reg(P_ENCP_DVI_HSO_END, hs_end);
1512
1513 /* Program Vsync timing for even field */
1514 if (de_v_begin_even >= SOF_LINES + VSYNC_LINES + (1-vs_adjust))
1515 vs_bline_evn = de_v_begin_even - SOF_LINES - VSYNC_LINES -
1516 (1-vs_adjust);
1517 else
1518 vs_bline_evn = TOTAL_LINES + de_v_begin_even - SOF_LINES -
1519 VSYNC_LINES - (1-vs_adjust);
1520 vs_eline_evn = modulo(vs_bline_evn + VSYNC_LINES, TOTAL_LINES);
1521 hd_write_reg(P_ENCP_DVI_VSO_BLINE_EVN, vs_bline_evn); /* 5 */
1522 hd_write_reg(P_ENCP_DVI_VSO_ELINE_EVN, vs_eline_evn); /* 11 */
1523 vso_begin_evn = hs_begin; /* 1692 */
1524 hd_write_reg(P_ENCP_DVI_VSO_BEGIN_EVN, vso_begin_evn); /* 1692 */
1525 hd_write_reg(P_ENCP_DVI_VSO_END_EVN, vso_begin_evn); /* 1692 */
1526
1527 if ((param->VIC == HDMI_3840x540p240hz) ||
1528 (param->VIC == HDMI_3840x540p200hz))
1529 hd_write_reg(P_ENCP_DE_V_END_EVEN, 0x230);
1530 switch (param->VIC) {
1531 case HDMI_3840x1080p120hz:
1532 case HDMI_3840x1080p100hz:
1533 case HDMI_3840x540p240hz:
1534 case HDMI_3840x540p200hz:
1535 hd_write_reg(P_VPU_HDMI_SETTING, 0x8e);
1536 break;
1537 case HDMI_480i60:
1538 case HDMI_480i60_16x9:
1539 case HDMI_576i50:
1540 case HDMI_576i50_16x9:
1541 case HDMI_480i60_16x9_rpt:
1542 case HDMI_576i50_16x9_rpt:
1543 hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) |
1544 (0 << 1) |
1545 (0 << 2) |
1546 (0 << 3) |
1547 (0 << 4) |
1548 (4 << 5) |
1549 (1 << 8) |
1550 (1 << 12)
1551 );
1552 if ((param->VIC == HDMI_480i60_16x9_rpt) ||
1553 (param->VIC == HDMI_576i50_16x9_rpt))
1554 hd_set_reg_bits(P_VPU_HDMI_SETTING, 3, 12, 4);
1555 hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 0, 1);
1556 break;
1557 case HDMI_1080i60:
1558 case HDMI_1080i50:
1559 hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) |
1560 (0 << 1) |
1561 (HSYNC_POLARITY << 2) |
1562 (VSYNC_POLARITY << 3) |
1563 (0 << 4) |
1564 (0 << 5) |
1565 (1 << 8) |
1566 (0 << 12)
1567 );
1568 hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1);
1569 break;
1570 case HDMI_4k2k_30:
1571 case HDMI_4k2k_25:
1572 case HDMI_4k2k_24:
1573 case HDMI_4k2k_smpte_24:
1574 case HDMI_4096x2160p25_256x135:
1575 case HDMI_4096x2160p30_256x135:
1576 case HDMI_4096x2160p50_256x135:
1577 case HDMI_4096x2160p60_256x135:
1578 case HDMI_4096x2160p50_256x135_Y420:
1579 case HDMI_4096x2160p60_256x135_Y420:
1580 case HDMI_3840x2160p50_16x9:
1581 case HDMI_3840x2160p60_16x9:
1582 case HDMI_3840x2160p50_16x9_Y420:
1583 case HDMI_3840x2160p60_16x9_Y420:
1584 hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) |
1585 (0 << 1) |
1586 (HSYNC_POLARITY << 2) |
1587 (VSYNC_POLARITY << 3) |
1588 (0 << 4) |
1589 (4 << 5) |
1590 (0 << 8) |
1591 (0 << 12)
1592 );
1593 hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1);
1594 hd_write_reg(P_ENCP_VIDEO_EN, 1); /* Enable VENC */
1595 break;
1596 case HDMI_480p60_16x9_rpt:
1597 case HDMI_576p50_16x9_rpt:
1598 case HDMI_480p60:
1599 case HDMI_480p60_16x9:
1600 case HDMI_576p50:
1601 case HDMI_576p50_16x9:
1602 hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) |
1603 (0 << 1) |
1604 (0 << 2) |
1605 (0 << 3) |
1606 (0 << 4) |
1607 (4 << 5) |
1608 (1 << 8) |
1609 (0 << 12)
1610 );
1611 if ((param->VIC == HDMI_480p60_16x9_rpt) ||
1612 (param->VIC == HDMI_576p50_16x9_rpt))
1613 hd_set_reg_bits(P_VPU_HDMI_SETTING, 3, 12, 4);
1614 hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1);
1615 break;
1616 case HDMI_720p60:
1617 case HDMI_720p50:
1618 hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) |
1619 (0 << 1) |
1620 (HSYNC_POLARITY << 2) |
1621 (VSYNC_POLARITY << 3) |
1622 (0 << 4) |
1623 (4 << 5) |
1624 (1 << 8) |
1625 (0 << 12)
1626 );
1627 hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1);
1628 break;
1629 default:
1630 hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) |
1631 (0 << 1) | /* [ 1] src_sel_encp */
1632 (HSYNC_POLARITY << 2) |
1633 (VSYNC_POLARITY << 3) |
1634 (0 << 4) |
1635 (4 << 5) |
1636 (0 << 8) |
1637 (0 << 12)
1638 );
1639 hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1);
1640 }
1641 if ((param->VIC == HDMI_480p60_16x9_rpt) ||
1642 (param->VIC == HDMI_576p50_16x9_rpt))
1643 hd_set_reg_bits(P_VPU_HDMI_SETTING, 3, 12, 4);
1644 hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1);
1645}
1646
1647static void digital_clk_off(unsigned char flag)
1648{
1649 /* TODO */
1650}
1651
1652static void digital_clk_on(unsigned char flag)
1653{
1654/* clk81_set(); */
1655 if (flag&4) {
1656 hd_set_reg_bits(P_HHI_HDMI_CLK_CNTL, 0, 0, 7);
1657 hd_set_reg_bits(P_HHI_HDMI_CLK_CNTL, 0, 9, 3);
1658 hd_set_reg_bits(P_HHI_HDMI_CLK_CNTL, 1, 8, 1);
1659 }
1660 if (flag&2) {
1661 /* on hdmi pixel clock */
1662 hd_write_reg(P_HHI_GCLK_MPEG2,
1663 hd_read_reg(P_HHI_GCLK_MPEG2) | (1<<4));
1664 hd_write_reg(P_HHI_GCLK_OTHER,
1665 hd_read_reg(P_HHI_GCLK_OTHER)|(1<<17));
1666 }
1667}
1668
1669void phy_pll_off(void)
1670{
1671 hdmi_phy_suspend();
1672}
1673
1674static void hdmi_audio_init(unsigned int spdif_flag)
1675{
1676 return;
1677 /* TODO */
1678}
1679
1680/************************************
1681 * hdmitx hardware level interface
1682 *************************************/
1683
1684static void hdmitx_dump_tvenc_reg(int cur_VIC, int pr_info_flag)
1685{
1686}
1687
1688static void hdmitx_config_tvenc_reg(int vic, unsigned int reg,
1689 unsigned int val)
1690{
1691}
1692
1693static void hdmitx_set_pll(struct hdmitx_dev *hdev)
1694{
1695 hdmi_print(IMP, SYS "set pll\n");
1696 hdmi_print(IMP, SYS "param->VIC:%d\n", hdev->cur_video_param->VIC);
1697
1698 set_vmode_clk(hdev);
1699}
1700
1701static void set_phy_by_mode(unsigned int mode)
1702{
1703 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) {
1704 switch (mode) {
1705 case 1: /* 5.94Gbps, 3.7125Gbsp */
1706 hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x333d3282);
1707 hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2136315b);
1708 break;
1709 case 2: /* 2.97Gbps */
1710 hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33303382);
1711 hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2036315b);
1712 break;
1713 case 3: /* 1.485Gbps */
1714 hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33303042);
1715 hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2016315b);
1716 break;
1717 default: /* 742.5Mbps, and below */
1718 hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33604132);
1719 hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x0016315b);
1720 break;
1721 }
1722 return;
1723 }
1724
1725 /* other than GXL */
1726 switch (mode) {
1727 case 1: /* 5.94Gbps, 3.7125Gbsp */
1728 hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33353245);
1729 hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2100115b);
1730 break;
1731 case 2: /* 2.97Gbps */
1732 hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33634283);
1733 hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0xb000115b);
1734 break;
1735 case 3: /* 1.485Gbps, and below */
1736 default:
1737 hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33632122);
1738 hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2000115b);
1739 break;
1740 }
1741}
1742
1743static void hdmitx_set_phy(struct hdmitx_dev *hdev)
1744{
1745 if (!hdev)
1746 return;
1747 hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x0);
1748#if 1
1749/* P_HHI_HDMI_PHY_CNTL1 bit[1]: enable clock bit[0]: soft reset */
1750#define RESET_HDMI_PHY() \
1751do { \
1752 hd_set_reg_bits(P_HHI_HDMI_PHY_CNTL1, 0xf, 0, 4); \
1753 mdelay(2); \
1754 hd_set_reg_bits(P_HHI_HDMI_PHY_CNTL1, 0xe, 0, 4); \
1755 mdelay(2); \
1756} while (0)
1757
1758 hd_set_reg_bits(P_HHI_HDMI_PHY_CNTL1, 0x0390, 16, 16);
1759 hd_set_reg_bits(P_HHI_HDMI_PHY_CNTL1, 0x1, 17, 1);
1760 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)
1761 hd_set_reg_bits(P_HHI_HDMI_PHY_CNTL1, 0x0, 17, 1);
1762 hd_set_reg_bits(P_HHI_HDMI_PHY_CNTL1, 0x0, 0, 4);
1763 msleep(100);
1764 RESET_HDMI_PHY();
1765 RESET_HDMI_PHY();
1766 RESET_HDMI_PHY();
1767#undef RESET_HDMI_PHY
1768#endif
1769 switch (hdev->cur_VIC) {
1770 case HDMI_4k2k_24:
1771 case HDMI_4k2k_25:
1772 case HDMI_4k2k_30:
1773 case HDMI_4k2k_smpte_24:
1774 case HDMI_4096x2160p25_256x135:
1775 case HDMI_4096x2160p30_256x135:
1776 if ((hdev->para->cs == COLORSPACE_YUV422)
1777 || (hdev->para->cd == COLORDEPTH_24B))
1778 set_phy_by_mode(2);
1779 else
1780 set_phy_by_mode(1);
1781 break;
1782 case HDMI_3840x2160p50_16x9:
1783 case HDMI_3840x2160p60_16x9:
1784 case HDMI_4096x2160p50_256x135:
1785 case HDMI_4096x2160p60_256x135:
1786 if (hdev->para->cs == COLORSPACE_YUV420)
1787 set_phy_by_mode(2);
1788 else
1789 set_phy_by_mode(1);
1790 break;
1791 case HDMI_3840x2160p50_16x9_Y420:
1792 case HDMI_3840x2160p60_16x9_Y420:
1793 case HDMI_4096x2160p50_256x135_Y420:
1794 case HDMI_4096x2160p60_256x135_Y420:
1795 if (hdev->para->cd == COLORDEPTH_24B)
1796 set_phy_by_mode(2);
1797 else
1798 set_phy_by_mode(1);
1799 break;
1800 case HDMI_1080p60:
1801 case HDMI_1080p50:
1802 if (hdev->flag_3dfp)
1803 set_phy_by_mode(2);
1804 else
1805 set_phy_by_mode(3);
1806 break;
1807 default:
1808 if (hdev->flag_3dfp)
1809 set_phy_by_mode(3);
1810 else
1811 set_phy_by_mode(4);
1812 break;
1813 }
1814}
1815
1816static void set_tmds_clk_div40(unsigned int div40)
1817{
1818 pr_info("hdmitx div40: %d\n", div40);
1819 if (div40) {
1820 hdmitx_wr_reg(HDMITX_TOP_TMDS_CLK_PTTN_01, 0);
1821 hdmitx_wr_reg(HDMITX_TOP_TMDS_CLK_PTTN_23, 0x03ff03ff);
1822 } else {
1823 hdmitx_wr_reg(HDMITX_TOP_TMDS_CLK_PTTN_01, 0x001f001f);
1824 hdmitx_wr_reg(HDMITX_TOP_TMDS_CLK_PTTN_23, 0x001f001f);
1825 }
1826 hdmitx_set_reg_bits(HDMITX_DWC_FC_SCRAMBLER_CTRL, !!div40, 0, 1);
1827 hdmitx_wr_reg(HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x1);
1828 msleep(20);
1829 hdmitx_wr_reg(HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x2);
1830}
1831
1832static void hdmitx_set_scdc(struct hdmitx_dev *hdev)
1833{
1834 switch (hdev->cur_video_param->VIC) {
1835 case HDMI_3840x2160p50_16x9:
1836 case HDMI_3840x2160p60_16x9:
1837 case HDMI_4096x2160p50_256x135:
1838 case HDMI_4096x2160p60_256x135:
1839 if ((hdev->para->cs == COLORSPACE_YUV420)
1840 && (hdev->para->cd == COLORDEPTH_24B))
1841 hdev->para->tmds_clk_div40 = 0;
1842 else
1843 hdev->para->tmds_clk_div40 = 1;
1844 break;
1845 case HDMI_3840x2160p50_16x9_Y420:
1846 case HDMI_3840x2160p60_16x9_Y420:
1847 case HDMI_4096x2160p50_256x135_Y420:
1848 case HDMI_4096x2160p60_256x135_Y420:
1849 case HDMI_3840x2160p50_64x27_Y420:
1850 case HDMI_3840x2160p60_64x27_Y420:
1851 if (hdev->para->cd == COLORDEPTH_24B)
1852 hdev->para->tmds_clk_div40 = 0;
1853 else
1854 hdev->para->tmds_clk_div40 = 1;
1855 break;
1856 case HDMI_3840x2160p24_16x9:
1857 case HDMI_3840x2160p24_64x27:
1858 case HDMI_4096x2160p24_256x135:
1859 case HDMI_3840x2160p25_16x9:
1860 case HDMI_3840x2160p25_64x27:
1861 case HDMI_4096x2160p25_256x135:
1862 case HDMI_3840x2160p30_16x9:
1863 case HDMI_3840x2160p30_64x27:
1864 case HDMI_4096x2160p30_256x135:
1865 if ((hdev->para->cs == COLORSPACE_YUV422)
1866 || (hdev->para->cd == COLORDEPTH_24B))
1867 hdev->para->tmds_clk_div40 = 0;
1868 else
1869 hdev->para->tmds_clk_div40 = 1;
1870 break;
1871 default:
1872 hdev->para->tmds_clk_div40 = 0;
1873 break;
1874 }
1875 set_tmds_clk_div40(hdev->para->tmds_clk_div40);
1876 if (hdev->RXCap.scdc_present)
1877 scdc_config(hdev);
1878}
1879
1880static int hdmitx_set_dispmode(struct hdmitx_dev *hdev)
1881{
1882 struct hdmi_format_para *para = NULL;
1883
1884 if (hdev->cur_video_param == NULL) /* disable HDMI */
1885 return 0;
1886 if (!hdmitx_edid_VIC_support(hdev->cur_video_param->VIC))
1887 return -1;
1888 hdev->cur_VIC = hdev->cur_video_param->VIC;
1889
1890 hdmitx_set_scdc(hdev);
1891
1892 if (color_depth_f == 24)
1893 hdev->cur_video_param->color_depth = COLORDEPTH_24B;
1894 else if (color_depth_f == 30)
1895 hdev->cur_video_param->color_depth = COLORDEPTH_30B;
1896 else if (color_depth_f == 36)
1897 hdev->cur_video_param->color_depth = COLORDEPTH_36B;
1898 else if (color_depth_f == 48)
1899 hdev->cur_video_param->color_depth = COLORDEPTH_48B;
1900 hdmi_print(INF, SYS "set mode VIC %d (cd%d,cs%d,pm%d,vd%d,%x)\n",
1901 hdev->cur_video_param->VIC, color_depth_f, COLORSPACE_f,
1902 power_mode, power_off_vdac_flag, serial_reg_val);
1903 if (COLORSPACE_f != 0)
1904 hdev->cur_video_param->color = COLORSPACE_f;
1905 hdmitx_set_pll(hdev);
1906 /*hdmitx_set_phy(hdev);*/
1907 if (hdev->flag_3dfp)
1908 set_vmode_3dfp_enc_hw(hdev->cur_video_param->VIC);
1909 else
1910 set_vmode_enc_hw(hdev->cur_video_param->VIC);
1911 para = hdmi_get_fmt_paras(hdev->cur_video_param->VIC);
1912 if (para == NULL) {
1913 pr_info("error at %s[%d] vic = %d\n", __func__, __LINE__,
1914 hdev->cur_video_param->VIC);
1915 } else {
1916 hd_write_reg(P_VPP_POSTBLEND_H_SIZE, para->hdmitx_vinfo.width);
1917 }
1918
1919 if (hdev->flag_3dfp) {
1920 hd_write_reg(P_VPU_HDMI_SETTING, 0x8e);
1921 goto next;
1922 }
1923 switch (hdev->cur_video_param->VIC) {
1924 case HDMI_480i60:
1925 case HDMI_480i60_16x9:
1926 case HDMI_576i50:
1927 case HDMI_576i50_16x9:
1928 case HDMI_480i60_16x9_rpt:
1929 case HDMI_576i50_16x9_rpt:
1930 hdmi_tvenc480i_set(hdev->cur_video_param);
1931 break;
1932 case HDMI_1080i60:
1933 case HDMI_1080i50:
1934 hdmi_tvenc1080i_set(hdev->cur_video_param);
1935 break;
1936 case HDMI_4k2k_30:
1937 case HDMI_4k2k_25:
1938 case HDMI_4k2k_24:
1939 case HDMI_4k2k_smpte_24:
1940 case HDMI_4096x2160p25_256x135:
1941 case HDMI_4096x2160p30_256x135:
1942 case HDMI_4096x2160p50_256x135:
1943 case HDMI_4096x2160p60_256x135:
1944 case HDMI_3840x2160p50_16x9:
1945 case HDMI_3840x2160p60_16x9:
1946 case HDMI_3840x2160p50_16x9_Y420:
1947 case HDMI_3840x2160p60_16x9_Y420:
1948 case HDMI_4096x2160p50_256x135_Y420:
1949 case HDMI_4096x2160p60_256x135_Y420:
1950 hdmi_tvenc4k2k_set(hdev->cur_video_param);
1951 break;
1952 default:
1953 hdmi_tvenc_set(hdev->cur_video_param);
1954 }
1955next:
1956/* [ 3: 2] chroma_dnsmp. 0=use pixel 0; 1=use pixel 1; 2=use average. */
1957/* [ 5] hdmi_dith_md: random noise selector. */
1958 hd_write_reg(P_VPU_HDMI_FMT_CTRL, (((TX_INPUT_COLOR_FORMAT ==
1959 COLORSPACE_YUV420) ? 2 : 0) << 0) | (2 << 2) |
1960 (0 << 4) | /* [4]dith_en: disable dithering */
1961 (0 << 5) |
1962 (0 << 6)); /* [ 9: 6] hdmi_dith10_cntl. */
1963 if (hdev->para->cs == COLORSPACE_YUV420) {
1964 hd_set_reg_bits(P_VPU_HDMI_FMT_CTRL, 2, 0, 2);
1965 hd_set_reg_bits(P_VPU_HDMI_SETTING, 0, 4, 4);
1966 hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 8, 1);
1967 }
1968 switch (hdev->para->cd) {
1969 case COLORDEPTH_30B:
1970 case COLORDEPTH_36B:
1971 case COLORDEPTH_48B:
1972 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXM) {
1973 unsigned int hs_flag = 0;
1974 /* 12-10 dithering on */
1975 hd_set_reg_bits(P_VPU_HDMI_FMT_CTRL, 1, 4, 1);
1976 /* hsync/vsync not invert */
1977 hs_flag = (hd_read_reg(P_VPU_HDMI_SETTING) >> 2) & 0x3;
1978 hd_set_reg_bits(P_VPU_HDMI_SETTING, 0, 2, 2);
1979 /* 12-10 rounding off */
1980 hd_set_reg_bits(P_VPU_HDMI_FMT_CTRL, 0, 10, 1);
1981 /* 10-8 dithering off (2x2 old dither) */
1982 hd_set_reg_bits(P_VPU_HDMI_DITH_CNTL, 0, 4, 1);
1983 /* set hsync/vsync */
1984 hd_set_reg_bits(P_VPU_HDMI_DITH_CNTL, hs_flag, 2, 2);
1985 } else {
1986 hd_set_reg_bits(P_VPU_HDMI_FMT_CTRL, 0, 4, 1);
1987 hd_set_reg_bits(P_VPU_HDMI_FMT_CTRL, 0, 10, 1);
1988 }
1989 break;
1990 default:
1991 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXM) {
1992 /* 12-10 dithering off */
1993 hd_set_reg_bits(P_VPU_HDMI_FMT_CTRL, 0, 4, 1);
1994 /* 12-10 rounding on */
1995 hd_set_reg_bits(P_VPU_HDMI_FMT_CTRL, 1, 10, 1);
1996 /* 10-8 dithering on (2x2 old dither) */
1997 hd_set_reg_bits(P_VPU_HDMI_DITH_CNTL, 1, 4, 1);
1998 /* set hsync/vsync as default 0 */
1999 hd_set_reg_bits(P_VPU_HDMI_DITH_CNTL, 0, 2, 2);
2000 } else {
2001 hd_set_reg_bits(P_VPU_HDMI_FMT_CTRL, 0, 4, 1);
2002 hd_set_reg_bits(P_VPU_HDMI_FMT_CTRL, 1, 10, 1);
2003 }
2004 break;
2005 }
2006
2007 hdmitx_set_hw(hdev);
2008
2009 /* move hdmitx_set_pll() to the end of this function. */
2010 /* hdmitx_set_pll(param); */
2011 hdev->cur_VIC = hdev->cur_video_param->VIC;
2012 /* For 3D, enable phy by SystemControl at last step */
2013 if ((!hdev->flag_3dfp) && (!hdev->flag_3dtb) && (!hdev->flag_3dss))
2014 hdmitx_set_phy(hdev);
2015 switch (hdev->cur_video_param->VIC) {
2016 case HDMI_480i60:
2017 case HDMI_480i60_16x9:
2018 case HDMI_576i50:
2019 case HDMI_576i50_16x9:
2020 case HDMI_480i60_16x9_rpt:
2021 case HDMI_576i50_16x9_rpt:
2022 enc_vpu_bridge_reset(0);
2023 break;
2024 default:
2025 enc_vpu_bridge_reset(1);
2026 break;
2027 }
2028
2029 if (hdev->para->cs == COLORSPACE_YUV420) {
2030 /* change AVI packet */
2031 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF0, 0x3, 0, 2);
2032 mode420_half_horizontal_para();
2033 } else {
2034 /* change AVI packet */
2035 unsigned int indicator = 0;
2036 unsigned int data32 = 0x0;
2037
2038 switch (hdev->para->cs) {
2039 case COLORSPACE_RGB444:
2040 indicator = 0x0;
2041 break;
2042 case COLORSPACE_YUV422:
2043 indicator = 0x1;
2044 break;
2045 case COLORSPACE_YUV444:
2046 default:
2047 indicator = 0x2;
2048 break;
2049 case COLORSPACE_YUV420:
2050 indicator = 0x3;
2051 break;
2052 }
2053 data32 = (0x40 | ((indicator&0x4)<<5) | (indicator&0x3));
2054 hdmitx_wr_reg(HDMITX_DWC_FC_AVICONF0, data32);
2055 }
2056
2057 hdmitx_set_reg_bits(HDMITX_DWC_FC_INVIDCONF, 0, 3, 1);
2058 mdelay(1);
2059 hdmitx_set_reg_bits(HDMITX_DWC_FC_INVIDCONF, 1, 3, 1);
2060
2061 return 0;
2062}
2063
2064static void hdmitx_set_packet(int type, unsigned char *DB, unsigned char *HB)
2065{
2066 int i;
2067 int pkt_data_len = 0;
2068
2069 switch (type) {
2070 case HDMI_PACKET_AVI:
2071 break;
2072 case HDMI_PACKET_VEND:
2073 if ((!DB) || (!HB)) {
2074 hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO0, 0, 3, 1);
2075 return;
2076 }
2077 hdmitx_wr_reg(HDMITX_DWC_FC_VSDIEEEID0, DB[0]);
2078 hdmitx_wr_reg(HDMITX_DWC_FC_VSDIEEEID1, DB[1]);
2079 hdmitx_wr_reg(HDMITX_DWC_FC_VSDIEEEID2, DB[2]);
2080 hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD0, DB[3]);
2081 hdmitx_wr_reg(HDMITX_DWC_FC_VSDSIZE, HB[2]);
2082 if (DB[3] == 0x20) { /* set HDMI VIC */
2083 hdmitx_wr_reg(HDMITX_DWC_FC_AVIVID, 0);
2084 hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD1, DB[4]);
2085 }
2086 if (DB[3] == 0x40) { /* 3D VSI */
2087 hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD1, DB[4]);
2088 hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD2, DB[5]);
2089 if ((DB[4] >> 4) == T3D_FRAME_PACKING)
2090 hdmitx_wr_reg(HDMITX_DWC_FC_VSDSIZE, 5);
2091 else
2092 hdmitx_wr_reg(HDMITX_DWC_FC_VSDSIZE, 6);
2093 }
2094 /* Enable VSI packet */
2095 hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO0, 1, 3, 1);
2096 hdmitx_wr_reg(HDMITX_DWC_FC_DATAUTO1, 0);
2097 hdmitx_wr_reg(HDMITX_DWC_FC_DATAUTO2, 0x10);
2098 hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 4, 1);
2099 break;
2100 case HDMI_PACKET_DRM:
2101 pkt_data_len = 26;
2102 if ((!DB) || (!HB)) {
2103 hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO3, 0, 6, 1);
2104 hdmitx_set_reg_bits(
2105 HDMITX_DWC_FC_PACKET_TX_EN, 0, 7, 1);
2106 return;
2107 }
2108 /* Ignore HB[0] */
2109 hdmitx_wr_reg(HDMITX_DWC_FC_DRM_HB01, HB[1]);
2110 hdmitx_wr_reg(HDMITX_DWC_FC_DRM_HB02, HB[2]);
2111 for (i = 0; i < pkt_data_len; i++)
2112 hdmitx_wr_reg(HDMITX_DWC_FC_DRM_PB00 + i, DB[i]);
2113 hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO3, 1, 6, 1);
2114 hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 7, 1);
2115 break;
2116 case HDMI_AUDIO_INFO:
2117 pkt_data_len = 9;
2118 break;
2119 case HDMI_SOURCE_DESCRIPTION:
2120 pkt_data_len = 25;
2121 for (i = 0; i < 25; i++)
2122 hdmitx_wr_reg(HDMITX_DWC_FC_SPDVENDORNAME0 + i, DB[i]);
2123 hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO0, 1, 4, 1);
2124 hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO2, 0x1, 4, 4);
2125 hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 4, 1);
2126 break;
2127 default:
2128 break;
2129 }
2130}
2131
2132
2133static void hdmitx_setaudioinfoframe(unsigned char *AUD_DB,
2134 unsigned char *CHAN_STAT_BUF)
2135{
2136}
2137
2138
2139/* set_hdmi_audio_source(unsigned int src) */
2140/* Description: */
2141/* Select HDMI audio clock source, and I2S input data source. */
2142/* Parameters: */
2143/* src -- 0=no audio clock to HDMI; 1=pcmout to HDMI; 2=Aiu I2S out to HDMI. */
2144static void set_hdmi_audio_source(unsigned int src)
2145{
2146 unsigned long data32;
2147
2148 /* Disable HDMI audio clock input and its I2S input */
2149 data32 = 0;
2150 data32 |= (0 << 4);
2151 data32 |= (0 << 0);
2152 hd_write_reg(P_AIU_HDMI_CLK_DATA_CTRL, data32);
2153
2154 /* Enable HDMI I2S input from the selected source */
2155 data32 = 0;
2156 data32 |= (src << 4);
2157 data32 |= (src << 0);
2158 hd_write_reg(P_AIU_HDMI_CLK_DATA_CTRL, data32);
2159} /* set_hdmi_audio_source */
2160
2161/* 60958-3 bit 27-24 */
2162static unsigned char aud_csb_sampfreq[FS_MAX + 1] = {
2163 [FS_REFER_TO_STREAM] = 0x1, /* not indicated */
2164 [FS_32K] = 0x3, /* FS_32K */
2165 [FS_44K1] = 0x0, /* FS_44K1 */
2166 [FS_48K] = 0x2, /* FS_48K */
2167 [FS_88K2] = 0x8, /* FS_88K2 */
2168 [FS_96K] = 0xa, /* FS_96K */
2169 [FS_176K4] = 0xc, /* FS_176K4 */
2170 [FS_192K] = 0xe, /* FS_192K */
2171 [FS_768K] = 0x9, /* FS_768K */
2172};
2173
2174/* 60958-3 bit 39:36 */
2175static unsigned char aud_csb_ori_sampfreq[FS_MAX + 1] = {
2176 [FS_REFER_TO_STREAM] = 0x0, /* not indicated */
2177 [FS_32K] = 0xc, /* FS_32K */
2178 [FS_44K1] = 0xf, /* FS_44K1 */
2179 [FS_48K] = 0xd, /* FS_48K */
2180 [FS_88K2] = 0x7, /* FS_88K2 */
2181 [FS_96K] = 0xa, /* FS_96K */
2182 [FS_176K4] = 0x3, /* FS_176K4 */
2183 [FS_192K] = 0x1, /* FS_192K */
2184};
2185
2186static void set_aud_chnls(struct hdmitx_dev *hdev,
2187 struct hdmitx_audpara *audio_param)
2188{
2189 int i;
2190
2191 pr_info("hdmitx set channel status\n");
2192 for (i = 0; i < 9; i++)
2193 /* First, set all status to 0 */
2194 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS0+i, 0x00);
2195 /* set default 48k 2ch pcm */
2196 if ((audio_param->type == CT_PCM) &&
2197 (audio_param->channel_num == (2 - 1))) {
2198 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSV, 0x11);
2199 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS7, 0x02);
2200 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS8, 0xd2);
2201 } else {
2202 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSV, 0xff);
2203 }
2204 switch (audio_param->type) {
2205 case CT_AC_3:
2206 case CT_DOLBY_D:
2207 case CT_DST:
2208 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS3, 0x01); /* CSB 20 */
2209 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS5, 0x02); /* CSB 21 */
2210 break;
2211 default:
2212 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS3, 0x00);
2213 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS5, 0x00);
2214 break;
2215 }
2216 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCHNLS7,
2217 aud_csb_sampfreq[audio_param->sample_rate], 0, 4); /*CSB 27:24*/
2218 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCHNLS7, 0x0, 6, 2); /*CSB 31:30*/
2219 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCHNLS7, 0x0, 4, 2); /*CSB 29:28*/
2220 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCHNLS8, 0x2, 0, 4); /*CSB 35:32*/
2221 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCHNLS8, /* CSB 39:36 */
2222 aud_csb_ori_sampfreq[audio_param->sample_rate], 4, 4);
2223}
2224
2225#define GET_OUTCHN_NO(a) (((a) >> 4) & 0xf)
2226#define GET_OUTCHN_MSK(a) ((a) & 0xf)
2227
2228static void set_aud_info_pkt(struct hdmitx_dev *hdev,
2229 struct hdmitx_audpara *audio_param)
2230{
2231 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDICONF0, 0, 0, 4); /* CT */
2232 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDICONF0, audio_param->channel_num,
2233 4, 3); /* CC */
2234 if (GET_OUTCHN_NO(hdev->aud_output_ch))
2235 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDICONF0,
2236 GET_OUTCHN_NO(hdev->aud_output_ch) - 1, 4, 3);
2237 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDICONF1, 0, 0, 3); /* SF */
2238 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDICONF1, 0, 4, 2); /* SS */
2239 switch (audio_param->type) {
2240 case CT_MAT:
2241 case CT_DTS_HD_MA:
2242 /* CC: 8ch */
2243 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDICONF0, 7, 4, 3);
2244 hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF2, 0x13);
2245 break;
2246 case CT_PCM:
2247 if (!hdev->aud_output_ch)
2248 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDICONF0,
2249 audio_param->channel_num, 4, 3);
2250 if ((audio_param->channel_num == 0x7) && (!hdev->aud_output_ch))
2251 hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF2, 0x13);
2252 else
2253 hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF2, 0x00);
2254 /* Refer to CEA861-D P90 */
2255 switch (GET_OUTCHN_NO(hdev->aud_output_ch)) {
2256 case 2:
2257 hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF2, 0x00);
2258 break;
2259 case 4:
2260 hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF2, 0x03);
2261 break;
2262 case 6:
2263 hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF2, 0x0b);
2264 break;
2265 case 8:
2266 hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF2, 0x13);
2267 break;
2268 default:
2269 break;
2270 }
2271 break;
2272 case CT_DTS:
2273 case CT_DTS_HD:
2274 default:
2275 /* CC: 2ch */
2276 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDICONF0, 1, 4, 3);
2277 hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF2, 0x0);
2278 break;
2279 }
2280 hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF3, 0);
2281}
2282
2283static void set_aud_acr_pkt(struct hdmitx_dev *hdev,
2284 struct hdmitx_audpara *audio_param)
2285{
2286 unsigned int data32;
2287 unsigned int aud_n_para;
2288 unsigned int char_rate;
2289
2290 /* audio packetizer config */
2291 hdmitx_wr_reg(HDMITX_DWC_AUD_INPUTCLKFS, tx_aud_src ? 4 : 0);
2292
2293 if ((audio_param->type == CT_MAT)
2294 || (audio_param->type == CT_DTS_HD_MA))
2295 hdmitx_wr_reg(HDMITX_DWC_AUD_INPUTCLKFS, 2);
2296
2297 if ((hdev->frac_rate_policy) && (hdev->para->timing.frac_freq))
2298 char_rate = hdev->para->timing.frac_freq;
2299 else
2300 char_rate = hdev->para->timing.pixel_freq;
2301 if (hdev->para->cs == COLORSPACE_YUV422)
2302 aud_n_para = hdmi_get_aud_n_paras(audio_param->sample_rate,
2303 COLORDEPTH_24B, char_rate);
2304 else
2305 aud_n_para = hdmi_get_aud_n_paras(audio_param->sample_rate,
2306 hdev->para->cd, char_rate);
2307 /* N must mutiples 4 for DD+ */
2308 switch (audio_param->type) {
2309 case CT_DOLBY_D:
2310 aud_n_para *= 4;
2311 break;
2312 default:
2313 break;
2314 }
2315 pr_info("hdmitx aud_n_para = %d\n", aud_n_para);
2316
2317 /* ACR packet configuration */
2318 data32 = 0;
2319 data32 |= (1 << 7); /* [ 7] ncts_atomic_write */
2320 data32 |= (0 << 0); /* [3:0] AudN[19:16] */
2321 hdmitx_wr_reg(HDMITX_DWC_AUD_N3, data32);
2322
2323 data32 = 0;
2324 data32 |= (0 << 7); /* [7:5] N_shift */
2325 data32 |= (0 << 4); /* [ 4] CTS_manual */
2326 data32 |= (0 << 0); /* [3:0] manual AudCTS[19:16] */
2327 hdmitx_wr_reg(HDMITX_DWC_AUD_CTS3, data32);
2328
2329 hdmitx_wr_reg(HDMITX_DWC_AUD_CTS2, 0); /* manual AudCTS[15:8] */
2330 hdmitx_wr_reg(HDMITX_DWC_AUD_CTS1, 0); /* manual AudCTS[7:0] */
2331
2332 data32 = 0;
2333 data32 |= (1 << 7); /* [ 7] ncts_atomic_write */
2334 data32 |= (((aud_n_para>>16)&0xf) << 0); /* [3:0] AudN[19:16] */
2335 hdmitx_wr_reg(HDMITX_DWC_AUD_N3, data32);
2336 hdmitx_wr_reg(HDMITX_DWC_AUD_N2, (aud_n_para>>8)&0xff); /* AudN[15:8] */
2337 hdmitx_wr_reg(HDMITX_DWC_AUD_N1, aud_n_para&0xff); /* AudN[7:0] */
2338}
2339
2340static void set_aud_fifo_rst(void)
2341{
2342 /* reset audio fifo */
2343 hdmitx_set_reg_bits(HDMITX_DWC_AUD_CONF0, 1, 7, 1);
2344 hdmitx_set_reg_bits(HDMITX_DWC_AUD_CONF0, 0, 7, 1);
2345 hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF0, 1, 7, 1);
2346 hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF0, 0, 7, 1);
2347 hdmitx_wr_reg(HDMITX_DWC_MC_SWRSTZREQ, 0xe7);
2348 /* need reset again */
2349 hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF0, 1, 7, 1);
2350 hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF0, 0, 7, 1);
2351}
2352
2353static void set_aud_samp_pkt(struct hdmitx_dev *hdev,
2354 struct hdmitx_audpara *audio_param)
2355{
2356 switch (audio_param->type) {
2357 case CT_MAT: /* HBR */
2358 case CT_DTS_HD_MA:
2359 hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF1, 1, 7, 1);
2360 hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF1, 1, 6, 1);
2361 hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF1, 24, 0, 5);
2362 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCONF, 1, 0, 1);
2363 break;
2364 case CT_PCM: /* AudSamp */
2365 hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF1, 0, 7, 1);
2366 hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF1, 0, 6, 1);
2367 hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF1, 24, 0, 5);
2368 if ((audio_param->channel_num == 0x7) && (!hdev->aud_output_ch))
2369 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCONF, 1, 0, 1);
2370 else
2371 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCONF, 0, 0, 1);
2372 switch (GET_OUTCHN_NO(hdev->aud_output_ch)) {
2373 case 2:
2374 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCONF, 0, 0, 1);
2375 break;
2376 case 4:
2377 case 6:
2378 case 8:
2379 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCONF, 1, 0, 1);
2380 break;
2381 default:
2382 break;
2383 }
2384 break;
2385 case CT_AC_3:
2386 case CT_DOLBY_D:
2387 case CT_DTS:
2388 case CT_DTS_HD:
2389 default:
2390 hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF1, 0, 7, 1);
2391 hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF1, 0, 6, 1);
2392 hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF1, 24, 0, 5);
2393 hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCONF, 0, 0, 1);
2394 break;
2395 }
2396}
2397
2398static void audio_mute_op(bool flag)
2399{
2400 if (flag == 0) {
2401 hdmitx_set_reg_bits(HDMITX_TOP_CLK_CNTL, 0, 2, 2);
2402 hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 0, 0, 1);
2403 hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 0, 3, 1);
2404 } else {
2405 hdmitx_set_reg_bits(HDMITX_TOP_CLK_CNTL, 3, 2, 2);
2406 hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 0, 1);
2407 hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 3, 1);
2408 }
2409}
2410
2411static int hdmitx_set_audmode(struct hdmitx_dev *hdev,
2412 struct hdmitx_audpara *audio_param)
2413{
2414 unsigned int data32;
2415
2416 if (!hdev)
2417 return 0;
2418 if (!audio_param)
2419 return 0;
2420 pr_info("hdmtix: set audio\n");
2421 audio_mute_op(hdev->tx_aud_cfg);
2422 /* PCM & 8 ch */
2423 if ((audio_param->type == CT_PCM) &&
2424 (audio_param->channel_num == (8 - 1)))
2425 tx_aud_src = 1;
2426 else
2427 tx_aud_src = 0;
2428
2429 /* if hdev->aud_output_ch is true, select I2S as 8ch in, 2ch out */
2430 if (hdev->aud_output_ch)
2431 tx_aud_src = 1;
2432
2433 pr_info("hdmitx tx_aud_src = %d\n", tx_aud_src);
2434
2435 /* set_hdmi_audio_source(tx_aud_src ? 1 : 2); */
2436 set_hdmi_audio_source(2);
2437
2438/* config IP */
2439/* Configure audio */
2440 /* I2S Sampler config */
2441 data32 = 0;
2442/* [ 3] fifo_empty_mask: 0=enable int; 1=mask int. */
2443 data32 |= (1 << 3);
2444/* [ 2] fifo_full_mask: 0=enable int; 1=mask int. */
2445 data32 |= (1 << 2);
2446 hdmitx_wr_reg(HDMITX_DWC_AUD_INT, data32);
2447
2448 data32 = 0;
2449/* [ 4] fifo_overrun_mask: 0=enable int; 1=mask int.
2450 * Enable it later when audio starts.
2451 */
2452 data32 |= (1 << 4);
2453 hdmitx_wr_reg(HDMITX_DWC_AUD_INT1, data32);
2454/* [ 5] 0=select SPDIF; 1=select I2S. */
2455 data32 = 0;
2456 data32 |= (0 << 7); /* [ 7] sw_audio_fifo_rst */
2457 data32 |= (tx_aud_src << 5);
2458 data32 |= (0 << 0); /* [3:0] i2s_in_en: enable it later in test.c */
2459/* if enable it now, fifo_overrun will happen, because packet don't get sent
2460 * out until initial DE detected.
2461 */
2462 hdmitx_wr_reg(HDMITX_DWC_AUD_CONF0, data32);
2463
2464 data32 = 0;
2465 data32 |= (0 << 5); /* [7:5] i2s_mode: 0=standard I2S mode */
2466 data32 |= (24 << 0); /* [4:0] i2s_width */
2467 hdmitx_wr_reg(HDMITX_DWC_AUD_CONF1, data32);
2468
2469 data32 = 0;
2470 data32 |= (0 << 1); /* [ 1] NLPCM */
2471 data32 |= (0 << 0); /* [ 0] HBR */
2472 hdmitx_wr_reg(HDMITX_DWC_AUD_CONF2, data32);
2473
2474 /* spdif sampler config */
2475/* [ 2] SPDIF fifo_full_mask: 0=enable int; 1=mask int. */
2476/* [ 3] SPDIF fifo_empty_mask: 0=enable int; 1=mask int. */
2477 data32 = 0;
2478 data32 |= (1 << 3);
2479 data32 |= (1 << 2);
2480 hdmitx_wr_reg(HDMITX_DWC_AUD_SPDIFINT, data32);
2481 /* [ 4] SPDIF fifo_overrun_mask: 0=enable int; 1=mask int. */
2482 data32 = 0;
2483 data32 |= (0 << 4);
2484 hdmitx_wr_reg(HDMITX_DWC_AUD_SPDIFINT1, data32);
2485
2486 data32 = 0;
2487 data32 |= (0 << 7); /* [ 7] sw_audio_fifo_rst */
2488 hdmitx_wr_reg(HDMITX_DWC_AUD_SPDIF0, data32);
2489
2490 set_aud_info_pkt(hdev, audio_param);
2491 set_aud_acr_pkt(hdev, audio_param);
2492 set_aud_samp_pkt(hdev, audio_param);
2493
2494 set_aud_chnls(hdev, audio_param);
2495
2496 hdmitx_set_reg_bits(HDMITX_DWC_AUD_CONF0, tx_aud_src, 5, 1);
2497 if (tx_aud_src == 1) {
2498 if (GET_OUTCHN_MSK(hdev->aud_output_ch))
2499 hdmitx_set_reg_bits(HDMITX_DWC_AUD_CONF0,
2500 GET_OUTCHN_MSK(hdev->aud_output_ch), 0, 4);
2501 else
2502 hdmitx_set_reg_bits(HDMITX_DWC_AUD_CONF0, 0xf, 0, 4);
2503 /* Enable audi2s_fifo_overrun interrupt */
2504 hdmitx_wr_reg(HDMITX_DWC_AUD_INT1,
2505 hdmitx_rd_reg(HDMITX_DWC_AUD_INT1) & (~(1<<4)));
2506 /* Wait for 40 us for TX I2S decoder to settle */
2507 msleep(20);
2508 }
2509 set_aud_fifo_rst();
2510 udelay(10);
2511 hdmitx_wr_reg(HDMITX_DWC_AUD_N1, hdmitx_rd_reg(HDMITX_DWC_AUD_N1));
2512 hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO3, 1, 0, 1);
2513
2514 return 1;
2515}
2516
2517static void hdmitx_setupirq(struct hdmitx_dev *phdev)
2518{
2519 int r;
2520
2521 hdmitx_wr_reg(HDMITX_TOP_INTR_STAT_CLR, 0x7);
2522 r = request_irq(phdev->irq_hpd, &intr_handler,
2523 IRQF_SHARED, "hdmitx",
2524 (void *)phdev);
2525}
2526
2527static void hdmitx_uninit(struct hdmitx_dev *phdev)
2528{
2529 free_irq(phdev->irq_hpd, (void *)phdev);
2530 hdmi_print(1, "power off hdmi, unmux hpd\n");
2531
2532 phy_pll_off();
2533 digital_clk_off(7); /* off sys clk */
2534 hdmitx_hpd_hw_op(HPD_UNMUX_HPD);
2535}
2536
2537static void hw_reset_dbg(void)
2538{
2539 uint32_t val1 = hdmitx_rd_reg(HDMITX_DWC_MC_CLKDIS);
2540 uint32_t val2 = hdmitx_rd_reg(HDMITX_DWC_FC_INVIDCONF);
2541 uint32_t val3 = hdmitx_rd_reg(HDMITX_DWC_FC_VSYNCINWIDTH);
2542
2543 hdmitx_wr_reg(HDMITX_DWC_MC_CLKDIS, 0xff);
2544 udelay(10);
2545 hdmitx_wr_reg(HDMITX_DWC_MC_CLKDIS, val1);
2546 udelay(10);
2547 hdmitx_wr_reg(HDMITX_DWC_MC_SWRSTZREQ, 0);
2548 udelay(10);
2549 hdmitx_wr_reg(HDMITX_DWC_FC_INVIDCONF, 0);
2550 udelay(10);
2551 hdmitx_wr_reg(HDMITX_DWC_FC_INVIDCONF, val2);
2552 udelay(10);
2553 hdmitx_wr_reg(HDMITX_DWC_FC_VSYNCINWIDTH, val3);
2554}
2555
2556static int hdmitx_cntl(struct hdmitx_dev *hdev, unsigned int cmd,
2557 unsigned int argv)
2558{
2559 if (cmd == HDMITX_AVMUTE_CNTL) {
2560 return 0;
2561 } else if (cmd == HDMITX_EARLY_SUSPEND_RESUME_CNTL) {
2562 if (argv == HDMITX_EARLY_SUSPEND) {
2563 hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL, 0, 30, 1);
2564 hdmi_phy_suspend();
2565 }
2566 if (argv == HDMITX_LATE_RESUME) {
2567 hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL, 1, 30, 1);
2568 hw_reset_dbg();
2569 pr_info("hdmitx: swrstzreq\n");
2570 }
2571 return 0;
2572 } else if (cmd == HDMITX_HWCMD_MUX_HPD_IF_PIN_HIGH) {
2573 /* turnon digital module if gpio is high */
2574 if (hdmitx_hpd_hw_op(HPD_IS_HPD_MUXED) == 0) {
2575 if (hdmitx_hpd_hw_op(HPD_READ_HPD_GPIO)) {
2576 msleep(500);
2577 if (hdmitx_hpd_hw_op(HPD_READ_HPD_GPIO)) {
2578 hdmi_print(IMP, HPD "mux hpd\n");
2579 digital_clk_on(4);
2580 delay_us(1000*100);
2581 hdmitx_hpd_hw_op(HPD_MUX_HPD);
2582 }
2583 }
2584 }
2585 } else if (cmd == HDMITX_HWCMD_MUX_HPD)
2586 hdmitx_hpd_hw_op(HPD_MUX_HPD);
2587/* For test only. */
2588 else if (cmd == HDMITX_HWCMD_TURNOFF_HDMIHW) {
2589 int unmux_hpd_flag = argv;
2590
2591 if (unmux_hpd_flag) {
2592 hdmi_print(IMP, SYS "power off hdmi, unmux hpd\n");
2593 phy_pll_off();
2594 digital_clk_off(4); /* off sys clk */
2595 hdmitx_hpd_hw_op(HPD_UNMUX_HPD);
2596 } else {
2597 hdmi_print(IMP, SYS "power off hdmi\n");
2598 digital_clk_on(6);
2599 phy_pll_off();
2600 digital_clk_off(3); /* do not off sys clk */
2601 }
2602 }
2603 return 0;
2604}
2605
2606static void hdmitx_print_info(struct hdmitx_dev *hdev, int pr_info_flag)
2607{
2608 hdmi_print(INF, "------------------\nHdmitx driver version: ");
2609 hdmi_print(INF, "%s\nSerial %x\nColor Depth %d\n", HDMITX_VER,
2610 serial_reg_val, color_depth_f);
2611 hdmi_print(INF, "reset sequence %d\n", new_reset_sequence_flag);
2612 hdmi_print(INF, "power mode %d\n", power_mode);
2613 hdmi_print(INF, "%spowerdown when unplug\n",
2614 hdev->unplug_powerdown?"":"do not ");
2615 hdmi_print(INF, "use_tvenc_conf_flag=%d\n", use_tvenc_conf_flag);
2616 hdmi_print(INF, "vdac %s\n", power_off_vdac_flag?"off":"on");
2617 hdmi_print(INF, "hdmi audio %s\n", hdmi_audio_off_flag?"off":"on");
2618 if (!hdmi_audio_off_flag)
2619 hdmi_print(INF, "audio out type %s\n",
2620 i2s_to_spdif_flag?"spdif":"i2s");
2621 hdmi_print(INF, "delay flag %d\n", delay_flag);
2622 hdmi_print(INF, "------------------\n");
2623}
2624
2625struct aud_cts_log {
2626 unsigned int val:20;
2627};
2628
2629static inline unsigned int get_msr_cts(void)
2630{
2631 unsigned int ret = 0;
2632
2633 ret = hdmitx_rd_reg(HDMITX_DWC_AUD_CTS1);
2634 ret += (hdmitx_rd_reg(HDMITX_DWC_AUD_CTS2) << 8);
2635 ret += ((hdmitx_rd_reg(HDMITX_DWC_AUD_CTS3) & 0xf) << 16);
2636
2637 return ret;
2638}
2639
2640#define AUD_CTS_LOG_NUM 1000
2641struct aud_cts_log cts_buf[AUD_CTS_LOG_NUM];
2642static void cts_test(struct hdmitx_dev *hdev)
2643{
2644 int i;
2645 unsigned int min = 0, max = 0, total = 0;
2646
2647 pr_info("\nhdmitx: audio: cts test\n");
2648 memset(cts_buf, 0, sizeof(cts_buf));
2649 for (i = 0; i < AUD_CTS_LOG_NUM; i++) {
2650 cts_buf[i].val = get_msr_cts();
2651 mdelay(1);
2652 }
2653
2654 pr_info("\ncts change:\n");
2655 for (i = 1; i < AUD_CTS_LOG_NUM; i++) {
2656 if (cts_buf[i].val > cts_buf[i-1].val)
2657 pr_info("dis: +%d [%d] %d [%d] %d\n",
2658 cts_buf[i].val - cts_buf[i-1].val, i,
2659 cts_buf[i].val, i - 1, cts_buf[i - 1].val);
2660 if (cts_buf[i].val < cts_buf[i-1].val)
2661 pr_info("dis: %d [%d] %d [%d] %d\n",
2662 cts_buf[i].val - cts_buf[i-1].val, i,
2663 cts_buf[i].val, i - 1, cts_buf[i - 1].val);
2664 }
2665
2666 for (i = 0, min = max = cts_buf[0].val; i < AUD_CTS_LOG_NUM; i++) {
2667 total += cts_buf[i].val;
2668 if (min > cts_buf[i].val)
2669 min = cts_buf[i].val;
2670 if (max < cts_buf[i].val)
2671 max = cts_buf[i].val;
2672 }
2673 pr_info("\nCTS Min: %d Max: %d Avg: %d/1000\n\n", min, max, total);
2674}
2675
2676void hdmitx_dump_inter_timing(void)
2677{
2678 unsigned int tmp = 0;
2679#define CONNECT2REG(reg) ((hdmitx_rd_reg(reg)) + (hdmitx_rd_reg(reg + 1) << 8))
2680 tmp = CONNECT2REG(HDMITX_DWC_FC_INHACTV0);
2681 pr_info("Hactive = %d\n", tmp);
2682
2683 tmp = CONNECT2REG(HDMITX_DWC_FC_INHBLANK0);
2684 pr_info("Hblank = %d\n", tmp);
2685
2686 tmp = CONNECT2REG(HDMITX_DWC_FC_INVACTV0);
2687 pr_info("Vactive = %d\n", tmp);
2688
2689 tmp = hdmitx_rd_reg(HDMITX_DWC_FC_INVBLANK);
2690 pr_info("Vblank = %d\n", tmp);
2691
2692 tmp = CONNECT2REG(HDMITX_DWC_FC_HSYNCINDELAY0);
2693 pr_info("Hfront = %d\n", tmp);
2694
2695 tmp = CONNECT2REG(HDMITX_DWC_FC_HSYNCINWIDTH0);
2696 pr_info("Hsync = %d\n", tmp);
2697
2698 tmp = hdmitx_rd_reg(HDMITX_DWC_FC_VSYNCINDELAY);
2699 pr_info("Vfront = %d\n", tmp);
2700
2701 tmp = hdmitx_rd_reg(HDMITX_DWC_FC_VSYNCINWIDTH);
2702 pr_info("Vsync = %d\n", tmp);
2703
2704 /* HDMITX_DWC_FC_INFREQ0 ??? */
2705}
2706
2707#define DUMP_CVREG_SECTION(start, end) \
2708do { \
2709 if (start > end) { \
2710 pr_info("Error start = 0x%x > end = 0x%x\n", \
2711 ((start & 0xffff) >> 2), ((end & 0xffff) >> 2)); \
2712 break; \
2713 } \
2714 pr_info("Start = 0x%x[0x%x] End = 0x%x[0x%x]\n", \
2715 start, ((start & 0xffff) >> 2), end, ((end & 0xffff) >> 2)); \
2716 for (addr = start; addr < end + 1; addr += 4) { \
2717 val = hd_read_reg(addr); \
2718 if (val) \
2719 pr_info("0x%08x[0x%04x]: 0x%08x\n", addr, \
2720 ((addr & 0xffff) >> 2), val); \
2721 } \
2722} while (0)
2723
2724static void hdmitx_dump_all_cvregs(void)
2725{
2726#if 0
2727 unsigned int addr = 0, val = 0;
2728
2729 DUMP_CVREG_SECTION(P_STB_TOP_CONFIG, P_CIPLUS_ENDIAN);
2730 DUMP_CVREG_SECTION(P_PREG_CTLREG0_ADDR, P_AHB_BRIDGE_CNTL_REG2);
2731 DUMP_CVREG_SECTION(P_BT_CTRL, P_BT656_ADDR_END);
2732 DUMP_CVREG_SECTION(P_VERSION_CTRL, P_RESET7_LEVEL);
2733 DUMP_CVREG_SECTION(P_SCR_HIU, P_HHI_HDMIRX_AUD_PLL_CNTL6);
2734 DUMP_CVREG_SECTION(P_PARSER_CONTROL, P_PARSER_AV2_WRAP_COUNT);
2735 DUMP_CVREG_SECTION(P_DVIN_FRONT_END_CTRL, P_DVIN_CTRL_STAT);
2736 DUMP_CVREG_SECTION(P_AIU_958_BPF, P_AIU_I2S_CBUS_DDR_ADDR);
2737 DUMP_CVREG_SECTION(P_GE2D_GEN_CTRL0, P_GE2D_GEN_CTRL4);
2738 DUMP_CVREG_SECTION(P_AUDIO_COP_CTL2, P_EE_ASSIST_MBOX3_FIQ_SEL);
2739 DUMP_CVREG_SECTION(P_AUDIN_SPDIF_MODE, P_AUDIN_ADDR_END);
2740 DUMP_CVREG_SECTION(P_VDIN_SCALE_COEF_IDX, P_VDIN0_SCALE_COEF_IDX);
2741 DUMP_CVREG_SECTION(P_VDIN0_SCALE_COEF, P_VDIN1_ASFIFO_CTRL3);
2742 DUMP_CVREG_SECTION(P_L_GAMMA_CNTL_PORT, P_MLVDS_RESET_CONFIG_LO);
2743 DUMP_CVREG_SECTION(P_VPP2_DUMMY_DATA, P_DI_CHAN2_URGENT_CTRL);
2744 DUMP_CVREG_SECTION(P_DI_PRE_CTRL, P_DI_CANVAS_URGENT2);
2745 DUMP_CVREG_SECTION(P_ENCP_VFIFO2VD_CTL, P_VIU2_VD1_FMT_W);
2746 DUMP_CVREG_SECTION(P_VPU_OSD1_MMC_CTRL, P_VPU_PROT3_REQ_ONOFF);
2747 DUMP_CVREG_SECTION(P_D2D3_GLB_CTRL, P_D2D3_RESEV_STATUS2);
2748 DUMP_CVREG_SECTION(P_VI_HIST_CTRL, P_DEMO_CRTL);
2749 DUMP_CVREG_SECTION(P_AO_RTI_STATUS_REG0, P_AO_SAR_ADC_REG12);
2750 DUMP_CVREG_SECTION(P_STB_VERSION, P_DEMUX_SECTION_RESET_3);
2751#endif
2752}
2753
2754#define DUMP_HDMITXREG_SECTION(start, end) \
2755do { \
2756 if (start > end) { \
2757 pr_info("Error start = 0x%lx > end = 0x%lx\n", start, end); \
2758 break; \
2759 } \
2760 pr_info("Start = 0x%lx End = 0x%lx\n", start, end); \
2761 for (addr = start; addr < end + 1; addr++) { \
2762 val = hdmitx_rd_reg(addr); \
2763 if (val) \
2764 pr_info("[0x%08x]: 0x%08x\n", addr, val); \
2765 } \
2766} while (0)
2767
2768static void hdmitx_dump_intr(void)
2769{
2770 unsigned int addr = 0, val = 0;
2771
2772 DUMP_HDMITXREG_SECTION(HDMITX_DWC_IH_FC_STAT0, HDMITX_DWC_IH_MUTE);
2773}
2774
2775static void mode420_half_horizontal_para(void)
2776{
2777 unsigned int hactive = 0;
2778 unsigned int hblank = 0;
2779 unsigned int hfront = 0;
2780 unsigned int hsync = 0;
2781
2782 hactive = hdmitx_rd_reg(HDMITX_DWC_FC_INHACTV0);
2783 hactive += (hdmitx_rd_reg(HDMITX_DWC_FC_INHACTV1) & 0x3f) << 8;
2784 hblank = hdmitx_rd_reg(HDMITX_DWC_FC_INHBLANK0);
2785 hblank += (hdmitx_rd_reg(HDMITX_DWC_FC_INHBLANK1) & 0x1f) << 8;
2786 hfront = hdmitx_rd_reg(HDMITX_DWC_FC_HSYNCINDELAY0);
2787 hfront += (hdmitx_rd_reg(HDMITX_DWC_FC_HSYNCINDELAY1) & 0x1f) << 8;
2788 hsync = hdmitx_rd_reg(HDMITX_DWC_FC_HSYNCINWIDTH0);
2789 hsync += (hdmitx_rd_reg(HDMITX_DWC_FC_HSYNCINWIDTH1) & 0x3) << 8;
2790
2791 hactive = hactive / 2;
2792 hblank = hblank / 2;
2793 hfront = hfront / 2;
2794 hsync = hsync / 2;
2795
2796 hdmitx_wr_reg(HDMITX_DWC_FC_INHACTV0, (hactive & 0xff));
2797 hdmitx_wr_reg(HDMITX_DWC_FC_INHACTV1, ((hactive >> 8) & 0x3f));
2798 hdmitx_wr_reg(HDMITX_DWC_FC_INHBLANK0, (hblank & 0xff));
2799 hdmitx_wr_reg(HDMITX_DWC_FC_INHBLANK1, ((hblank >> 8) & 0x1f));
2800 hdmitx_wr_reg(HDMITX_DWC_FC_HSYNCINDELAY0, (hfront & 0xff));
2801 hdmitx_wr_reg(HDMITX_DWC_FC_HSYNCINDELAY1, ((hfront >> 8) & 0x1f));
2802 hdmitx_wr_reg(HDMITX_DWC_FC_HSYNCINWIDTH0, (hsync & 0xff));
2803 hdmitx_wr_reg(HDMITX_DWC_FC_HSYNCINWIDTH1, ((hsync >> 8) & 0x3));
2804}
2805
2806static void hdmitx_set_fake_vic(struct hdmitx_dev *hdev)
2807{
2808 hdev->para->cs = COLORSPACE_YUV444;
2809 hdev->cur_VIC = HDMI_VIC_FAKE;
2810 set_vmode_clk(hdev);
2811}
2812
2813static void hdmitx_debug(struct hdmitx_dev *hdev, const char *buf)
2814{
2815 char tmpbuf[128];
2816 int i = 0;
2817 int ret;
2818 unsigned long adr = 0;
2819 unsigned long value = 0;
2820
2821 while ((buf[i]) && (buf[i] != ',') && (buf[i] != ' ')) {
2822 tmpbuf[i] = buf[i];
2823 i++;
2824 }
2825 tmpbuf[i] = 0;
2826
2827 if ((strncmp(tmpbuf, "dumpreg", 7) == 0) ||
2828 (strncmp(tmpbuf, "dumptvencreg", 12) == 0)) {
2829 hdmitx_dump_tvenc_reg(hdev->cur_VIC, 1);
2830 return;
2831 } else if (strncmp(tmpbuf, "testhpll", 8) == 0) {
2832 ret = kstrtoul(tmpbuf + 8, 10, &value);
2833 hdev->cur_VIC = value;
2834 set_vmode_clk(hdev);
2835 return;
2836 } else if (strncmp(tmpbuf, "testpll", 7) == 0)
2837 return;
2838 else if (strncmp(tmpbuf, "testedid", 8) == 0) {
2839 dd();
2840 hdev->HWOp.CntlDDC(hdev, DDC_RESET_EDID, 0);
2841 hdev->HWOp.CntlDDC(hdev, DDC_EDID_READ_DATA, 0);
2842 return;
2843 } else if (strncmp(tmpbuf, "bist", 4) == 0) {
2844 if (strncmp(tmpbuf + 4, "off", 3) == 0) {
2845 hd_set_reg_bits(P_ENCP_VIDEO_MODE_ADV, 1, 3, 1);
2846 hd_write_reg(P_VENC_VIDEO_TST_EN, 0);
2847 return;
2848 }
2849 hd_set_reg_bits(P_HHI_GCLK_OTHER, 1, 3, 1);
2850 hd_set_reg_bits(P_ENCP_VIDEO_MODE_ADV, 0, 3, 1);
2851 hd_write_reg(P_VENC_VIDEO_TST_EN, 1);
2852 if (strncmp(tmpbuf+4, "line", 4) == 0) {
2853 hd_write_reg(P_VENC_VIDEO_TST_MDSEL, 2);
2854 return;
2855 }
2856 if (strncmp(tmpbuf+4, "dot", 3) == 0) {
2857 hd_write_reg(P_VENC_VIDEO_TST_MDSEL, 3);
2858 return;
2859 }
2860 if (strncmp(tmpbuf+4, "start", 5) == 0) {
2861 ret = kstrtoul(tmpbuf + 9, 10, &value);
2862 hd_write_reg(P_VENC_VIDEO_TST_CLRBAR_STRT, value);
2863 return;
2864 }
2865 if (strncmp(tmpbuf+4, "shift", 5) == 0) {
2866 ret = kstrtoul(tmpbuf + 9, 10, &value);
2867 hd_write_reg(P_VENC_VIDEO_TST_VDCNT_STSET, value);
2868 return;
2869 }
2870 hd_write_reg(P_VENC_VIDEO_TST_MDSEL, 1);
2871 value = 1920;
2872 ret = kstrtoul(tmpbuf + 4, 10, &value);
2873 hd_write_reg(P_VENC_VIDEO_TST_CLRBAR_WIDTH, value / 8);
2874 return;
2875 } else if (strncmp(tmpbuf, "dumptiming", 10) == 0) {
2876 hdmitx_dump_inter_timing();
2877 return;
2878 } else if (strncmp(tmpbuf, "testaudio", 9) == 0) {
2879 hdmitx_set_audmode(hdev, NULL);
2880 } else if (strncmp(tmpbuf, "dumpintr", 8) == 0) {
2881 hdmitx_dump_intr();
2882 } else if (strncmp(tmpbuf, "testhdcp", 8) == 0) {
2883 int i;
2884
2885 i = tmpbuf[8] - '0';
2886 if (i == 2)
2887 pr_info("hdcp rslt = %d", hdmitx_hdcp_opr(2));
2888 if (i == 1)
2889 hdev->HWOp.CntlDDC(hdev, DDC_HDCP_OP, HDCP14_ON);
2890 return;
2891 } else if (strncmp(tmpbuf, "dumpallregs", 11) == 0) {
2892 hdmitx_dump_all_cvregs();
2893 return;
2894 } else if (strncmp(tmpbuf, "chkfmt", 6) == 0) {
2895 check_detail_fmt();
2896 return;
2897 } else if (strncmp(tmpbuf, "testcts", 7) == 0) {
2898 cts_test(hdev);
2899 return;
2900 } else if (strncmp(tmpbuf, "ss", 2) == 0) {
2901 pr_info("hdev->output_blank_flag: 0x%x\n",
2902 hdev->output_blank_flag);
2903 pr_info("hdev->hpd_state: 0x%x\n", hdev->hpd_state);
2904 pr_info("hdev->cur_VIC: 0x%x\n", hdev->cur_VIC);
2905 } else if (strncmp(tmpbuf, "hpd_lock", 8) == 0) {
2906 if (tmpbuf[8] == '1') {
2907 hdev->hpd_lock = 1;
2908 hdmi_print(INF, HPD "hdmitx: lock hpd\n");
2909 } else {
2910 hdev->hpd_lock = 0;
2911 hdmi_print(INF, HPD "hdmitx: unlock hpd\n");
2912 }
2913 return;
2914 } else if (strncmp(tmpbuf, "hpd_stick", 9) == 0) {
2915 if (tmpbuf[9] == '1')
2916 hdev->hdcp_hpd_stick = 1;
2917 else
2918 hdev->hdcp_hpd_stick = 0;
2919 pr_info("hdmitx: %sstick hpd\n",
2920 (hdev->hdcp_hpd_stick) ? "" : "un");
2921 } else if (strncmp(tmpbuf, "vic", 3) == 0) {
2922 pr_info("hdmi vic count = %d\n", hdev->vic_count);
2923 if ((tmpbuf[3] >= '0') && (tmpbuf[3] <= '9')) {
2924 hdev->vic_count = tmpbuf[3] - '0';
2925 hdmi_print(INF, SYS "set hdmi vic count = %d\n",
2926 hdev->vic_count);
2927 }
2928 } else if (strncmp(tmpbuf, "cec", 3) == 0)
2929 return;
2930 else if (strncmp(tmpbuf, "dumphdmireg", 11) == 0) {
2931 unsigned char reg_val = 0;
2932 unsigned int reg_adr = 0;
2933
2934#define DUMP_HDMITX_SECTION(a, b) \
2935 for (reg_adr = a; reg_adr < b+1; reg_adr++) { \
2936 reg_val = hdmitx_rd_reg(reg_adr); \
2937 if (reg_val) \
2938 pr_info("[0x%x]: 0x%x\n", reg_adr, reg_val); \
2939 }
2940
2941#define DUMP_HDMITX_HDCP_SECTION(a, b) \
2942 for (reg_adr = a; reg_adr < b+1; reg_adr++) { \
2943 hdmitx_wr_reg(HDMITX_DWC_A_KSVMEMCTRL, 0x1); \
2944 hdmitx_poll_reg(HDMITX_DWC_A_KSVMEMCTRL, (1<<1), 2 * HZ); \
2945 reg_val = hdmitx_rd_reg(reg_adr); \
2946 if (reg_val) \
2947 pr_info("[0x%x]: 0x%x\n", reg_adr, reg_val); \
2948 }
2949
2950 DUMP_HDMITX_SECTION(HDMITX_TOP_SW_RESET,
2951 HDMITX_TOP_DONT_TOUCH1);
2952 DUMP_HDMITX_SECTION(HDMITX_TOP_SKP_CNTL_STAT,
2953 HDMITX_TOP_SEC_SCRATCH);
2954 DUMP_HDMITX_SECTION(HDMITX_DWC_DESIGN_ID,
2955 HDMITX_DWC_A_KSVMEMCTRL);
2956 DUMP_HDMITX_HDCP_SECTION(HDMITX_DWC_HDCP_BSTATUS_0,
2957 HDMITX_DWC_HDCPREG_BKSV0 - 1);
2958 DUMP_HDMITX_SECTION(HDMITX_DWC_HDCPREG_ANCONF,
2959 HDMITX_DWC_HDCP22REG_MUTE);
2960 DUMP_HDMITX_SECTION(HDMITX_DWC_A_HDCPCFG0,
2961 HDMITX_DWC_A_HDCPCFG1);
2962 DUMP_HDMITX_SECTION(HDMITX_DWC_HDCPREG_SEED0,
2963 HDMITX_DWC_HDCPREG_DPK6);
2964 DUMP_HDMITX_SECTION(HDMITX_DWC_HDCP22REG_CTRL,
2965 HDMITX_DWC_HDCP22REG_CTRL);
2966 return;
2967 } else if (strncmp(tmpbuf, "dumpcecreg", 10) == 0) {
2968 unsigned char cec_val = 0;
2969 unsigned int cec_adr = 0;
2970 /* HDMI CEC Regs address range:0xc000~0xc01c;0xc080~0xc094 */
2971 for (cec_adr = 0xc000; cec_adr < 0xc01d; cec_adr++) {
2972 cec_val = hdmitx_rd_reg(cec_adr);
2973 hdmi_print(INF, "HDMI CEC Regs[0x%x]: 0x%x\n",
2974 cec_adr, cec_val);
2975 }
2976 for (cec_adr = 0xc080; cec_adr < 0xc095; cec_adr++) {
2977 cec_val = hdmitx_rd_reg(cec_adr);
2978 hdmi_print(INF, "HDMI CEC Regs[0x%x]: 0x%x\n",
2979 cec_adr, cec_val);
2980 }
2981 return;
2982 } else if (strncmp(tmpbuf, "dumpcbusreg", 11) == 0) {
2983 unsigned int i, val;
2984
2985 for (i = 0; i < 0x3000; i++) {
2986 val = hd_read_reg(CBUS_REG_ADDR(i));
2987 if (val)
2988 pr_info("CBUS[0x%x]: 0x%x\n", i, val);
2989 }
2990 return;
2991 } else if (strncmp(tmpbuf, "dumpvcbusreg", 12) == 0) {
2992 unsigned int i, val;
2993
2994 for (i = 0; i < 0x3000; i++) {
2995 val = hd_read_reg(VCBUS_REG_ADDR(i));
2996 if (val)
2997 pr_info("VCBUS[0x%x]: 0x%x\n", i, val);
2998 }
2999 return;
3000 } else if (strncmp(tmpbuf, "log", 3) == 0) {
3001 if (strncmp(tmpbuf+3, "hdcp", 4) == 0) {
3002 static unsigned int i = 1;
3003
3004 if (i & 1)
3005 hdev->log |= HDMI_LOG_HDCP;
3006 else
3007 hdev->log &= ~HDMI_LOG_HDCP;
3008 i++;
3009 }
3010 return;
3011 } else if (strncmp(tmpbuf, "pllcalc", 7) == 0) {
3012 /* TODO clk_measure(0xff); */
3013 return;
3014 } else if (strncmp(tmpbuf, "hdmiaudio", 9) == 0) {
3015 ret = kstrtoul(tmpbuf+9, 16, &value);
3016 if (value == 1) {
3017 hdmi_audio_off_flag = 0;
3018 hdmi_audio_init(i2s_to_spdif_flag);
3019 } else if (value == 0)
3020 ;
3021 return;
3022 } else if (strncmp(tmpbuf, "cfgreg", 6) == 0) {
3023 ret = kstrtoul(tmpbuf+6, 16, &adr);
3024 ret = kstrtoul(buf+i+1, 16, &value);
3025 hdmitx_config_tvenc_reg(hdev->cur_VIC, adr, value);
3026 return;
3027 } else if (strncmp(tmpbuf, "tvenc_flag", 10) == 0) {
3028 use_tvenc_conf_flag = tmpbuf[10]-'0';
3029 hdmi_print(INF, "set use_tvenc_conf_flag = %d\n",
3030 use_tvenc_conf_flag);
3031 } else if (strncmp(tmpbuf, "reset", 5) == 0) {
3032 if (tmpbuf[5] == '0')
3033 new_reset_sequence_flag = 0;
3034 else
3035 new_reset_sequence_flag = 1;
3036 return;
3037 } else if (strncmp(tmpbuf, "delay_flag", 10) == 0)
3038 delay_flag = tmpbuf[10]-'0';
3039 else if (tmpbuf[0] == 'v') {
3040 hdmitx_print_info(hdev, 1);
3041 return;
3042 } else if (tmpbuf[0] == 's') {
3043 ret = kstrtoul(tmpbuf+1, 16, &serial_reg_val);
3044 return;
3045 } else if (tmpbuf[0] == 'c') {
3046 if (tmpbuf[1] == 'd') {
3047 ret = kstrtoul(tmpbuf+2, 10, &color_depth_f);
3048 if ((color_depth_f != 24) && (color_depth_f != 30) &&
3049 (color_depth_f != 36)) {
3050 pr_info("Color depth %lu is not supported\n",
3051 color_depth_f);
3052 color_depth_f = 0;
3053 }
3054 return;
3055 } else if (tmpbuf[1] == 's') {
3056 ret = kstrtoul(tmpbuf+2, 10, &COLORSPACE_f);
3057 if (COLORSPACE_f > 2) {
3058 pr_info("Color space %lu is not supported\n",
3059 COLORSPACE_f);
3060 COLORSPACE_f = 0;
3061 }
3062 }
3063 } else if (strncmp(tmpbuf, "i2s", 2) == 0) {
3064 if (strncmp(tmpbuf+3, "off", 3) == 0)
3065 i2s_to_spdif_flag = 1;
3066 else
3067 i2s_to_spdif_flag = 0;
3068 } else if (strncmp(tmpbuf, "pattern_on", 10) == 0) {
3069 /* turn_on_shift_pattern(); */
3070 hdmi_print(INF, "Shift Pattern On\n");
3071 return;
3072 } else if (strncmp(tmpbuf, "pattern_off", 11) == 0) {
3073 hdmi_print(INF, "Shift Pattern Off\n");
3074 return;
3075 } else if (strncmp(tmpbuf, "prbs", 4) == 0)
3076 /* int prbs_mode =kstrtoul(tmpbuf+4, NULL, 10); */
3077 return;
3078 else if (tmpbuf[0] == 'w') {
3079 unsigned int read_back = 0;
3080
3081 ret = kstrtoul(tmpbuf+2, 16, &adr);
3082 ret = kstrtoul(buf+i+1, 16, &value);
3083 if (buf[1] == 'h') {
3084 hdmitx_wr_reg((unsigned int)adr, (unsigned int)value);
3085 read_back = hdmitx_rd_reg(adr);
3086 }
3087 hdmi_print(INF, "write %x to %s reg[%x]\n", value, "HDMI", adr);
3088/* Add read back function in order to judge writing is OK or NG. */
3089 hdmi_print(INF, "Read Back %s reg[%x]=%x\n", "HDMI",
3090 adr, read_back);
3091 } else if (tmpbuf[0] == 'r') {
3092 ret = kstrtoul(tmpbuf+2, 16, &adr);
3093 if (buf[1] == 'h')
3094 value = hdmitx_rd_reg(adr);
3095 hdmi_print(INF, "%s reg[%x]=%x\n", "HDMI", adr, value);
3096 }
3097}
3098
3099
3100static void hdmitx_getediddata(unsigned char *des, unsigned char *src)
3101{
3102 int i = 0;
3103 unsigned int blk = src[126] + 1;
3104
3105 if (blk > 4)
3106 blk = 4;
3107
3108 for (i = 0; i < 128 * blk; i++)
3109 des[i] = src[i];
3110}
3111
3112/*
3113 * Note: read 8 Bytes of EDID data every time
3114 */
3115static void hdmitx_read_edid(unsigned char *rx_edid)
3116{
3117 unsigned int timeout = 0;
3118 unsigned int i;
3119 unsigned int byte_num = 0;
3120 unsigned char blk_no = 1;
3121
3122 /* Program SLAVE/ADDR */
3123 hdmitx_wr_reg(HDMITX_DWC_I2CM_SLAVE, 0x50);
3124 /* Read complete EDID data sequentially */
3125 while (byte_num < 128 * blk_no) {
3126 hdmitx_wr_reg(HDMITX_DWC_I2CM_ADDRESS, byte_num&0xff);
3127 if ((byte_num >= 256) && (byte_num < 512) && (blk_no > 2)) {
3128 /* Program SEGMENT/SEGPTR */
3129 hdmitx_wr_reg(HDMITX_DWC_I2CM_SEGADDR, 0x30);
3130 hdmitx_wr_reg(HDMITX_DWC_I2CM_SEGPTR, 0x1);
3131 hdmitx_wr_reg(HDMITX_DWC_I2CM_OPERATION, 1<<3);
3132 } else
3133 hdmitx_wr_reg(HDMITX_DWC_I2CM_OPERATION, 1<<2);
3134 /* Wait until I2C done */
3135 timeout = 0;
3136 while ((!(hdmitx_rd_reg(HDMITX_DWC_IH_I2CM_STAT0) & (1 << 1)))
3137 && (timeout < 3)) {
3138 mdelay(2);
3139 timeout++;
3140 }
3141 if (timeout == 3)
3142 pr_info("hdmitx: ddc timeout\n");
3143 hdmitx_wr_reg(HDMITX_DWC_IH_I2CM_STAT0, 1 << 1);
3144 /* Read back 8 bytes */
3145 for (i = 0; i < 8; i++) {
3146 rx_edid[byte_num] =
3147 hdmitx_rd_reg(HDMITX_DWC_I2CM_READ_BUFF0 + i);
3148 if (byte_num == 126) {
3149 blk_no = rx_edid[126] + 1;
3150 if (blk_no > 4) {
3151 pr_info("edid extension block number:");
3152 pr_info(" %d, reset to MAX 3\n",
3153 blk_no - 1);
3154 blk_no = 4; /* Max extended block */
3155 }
3156 }
3157 byte_num++;
3158 }
3159 }
3160} /* hdmi20_tx_read_edid */
3161
3162static unsigned char tmp_edid_buf[128*EDID_MAX_BLOCK] = { 0 };
3163
3164#define HDCP_NMOOFDEVICES 127
3165
3166static int get_hdcp_depth(void)
3167{
3168 int ret;
3169
3170 hdmitx_set_reg_bits(HDMITX_DWC_A_KSVMEMCTRL, 1, 0, 1);
3171 hdmitx_poll_reg(HDMITX_DWC_A_KSVMEMCTRL, (1<<1), 2 * HZ);
3172 ret = hdmitx_rd_reg(HDMITX_DWC_HDCP_BSTATUS_1) & 0x7;
3173 hdmitx_set_reg_bits(HDMITX_DWC_A_KSVMEMCTRL, 0, 0, 1);
3174
3175 return ret;
3176}
3177
3178static bool get_hdcp_max_cascade(void)
3179{
3180 bool ret;
3181
3182 hdmitx_set_reg_bits(HDMITX_DWC_A_KSVMEMCTRL, 1, 0, 1);
3183 hdmitx_poll_reg(HDMITX_DWC_A_KSVMEMCTRL, (1<<1), 2 * HZ);
3184 ret = (hdmitx_rd_reg(HDMITX_DWC_HDCP_BSTATUS_1) >> 3) & 0x1;
3185 hdmitx_set_reg_bits(HDMITX_DWC_A_KSVMEMCTRL, 0, 0, 1);
3186
3187 return ret;
3188}
3189
3190static bool get_hdcp_max_devs(void)
3191{
3192 bool ret;
3193
3194 hdmitx_set_reg_bits(HDMITX_DWC_A_KSVMEMCTRL, 1, 0, 1);
3195 hdmitx_poll_reg(HDMITX_DWC_A_KSVMEMCTRL, (1<<1), 2 * HZ);
3196 ret = (hdmitx_rd_reg(HDMITX_DWC_HDCP_BSTATUS_0) >> 7) & 0x1;
3197 hdmitx_set_reg_bits(HDMITX_DWC_A_KSVMEMCTRL, 0, 0, 1);
3198
3199 return ret;
3200}
3201
3202static int get_hdcp_device_count(void)
3203{
3204 int ret;
3205
3206 hdmitx_set_reg_bits(HDMITX_DWC_A_KSVMEMCTRL, 1, 0, 1);
3207 hdmitx_poll_reg(HDMITX_DWC_A_KSVMEMCTRL, (1<<1), 2 * HZ);
3208 ret = hdmitx_rd_reg(HDMITX_DWC_HDCP_BSTATUS_0) & 0x7f;
3209 hdmitx_set_reg_bits(HDMITX_DWC_A_KSVMEMCTRL, 0, 0, 1);
3210
3211 return ret;
3212}
3213
3214static void get_hdcp_bstatus(void)
3215{
3216 int ret1 = 0;
3217 int ret2 = 0;
3218
3219 hdmitx_set_reg_bits(HDMITX_DWC_A_KSVMEMCTRL, 1, 0, 1);
3220 hdmitx_poll_reg(HDMITX_DWC_A_KSVMEMCTRL, (1<<1), 2 * HZ);
3221 ret1 = hdmitx_rd_reg(HDMITX_DWC_HDCP_BSTATUS_0);
3222 ret2 = hdmitx_rd_reg(HDMITX_DWC_HDCP_BSTATUS_1);
3223 hdmitx_set_reg_bits(HDMITX_DWC_A_KSVMEMCTRL, 0, 0, 1);
3224 pr_info("BSTATUS0 = 0x%x BSTATUS1 = 0x%x\n", ret1, ret2);
3225}
3226
3227static void hdcp_ksv_store(unsigned char *dat, int no)
3228{
3229 int i;
3230
3231 for (i = 0; i < no; i++) {
3232 rptx_ksv_buf[rptx_ksv_no] = dat[i];
3233 rptx_ksv_no++;
3234 }
3235}
3236
3237static void hdcp_ksv_print(void)
3238{
3239 unsigned int i, pos;
3240 unsigned char *tmp_buf = NULL;
3241
3242 tmp_buf = kmalloc(2000, GFP_KERNEL);
3243 if (!tmp_buf)
3244 return;
3245
3246 pos = 0;
3247 memset(tmp_buf, 0, sizeof(2000));
3248 pos += sprintf(tmp_buf + pos, "Dump ksv test START\n");
3249 for (i = 0; (i < rptx_ksv_no) && (i < 635); i++) {
3250 pos += sprintf(tmp_buf + pos, "%02x", rptx_ksv_buf[i]);
3251 if (((i+1) % 40) == 0) /* print 40bytes a line */
3252 pos += sprintf(tmp_buf + pos, "\n");
3253 }
3254 pos += sprintf(tmp_buf + pos, "\n");
3255 pos += sprintf(tmp_buf + pos, "Dump ksv test END\n");
3256 pr_info("%s\n", tmp_buf);
3257 kfree(tmp_buf);
3258}
3259
3260static uint8_t *hdcp_mKsvListBuf;
3261static void hdcp_ksv_sha1_calc(struct hdmitx_dev *hdev)
3262{
3263 size_t list = 0;
3264 size_t size = 0;
3265 size_t i = 0;
3266 int valid = HDCP_IDLE;
3267 unsigned char ksvs[635] = {0}; /* Max 127 * 5 */
3268 int j = 0;
3269
3270 /* 0x165e: Page 95 */
3271 hdcp_mKsvListBuf = kmalloc(0x1660, GFP_KERNEL);
3272 if (hdcp_mKsvListBuf) {
3273 /* KSV_LEN; */
3274 list = hdmitx_rd_reg(HDMITX_DWC_HDCP_BSTATUS_0) & KSV_MSK;
3275 if (list <= HDCP_NMOOFDEVICES) {
3276 size = (list * KSV_LEN) + HEADER + SHAMAX;
3277 for (i = 0; i < size; i++) {
3278 if (i < HEADER) { /* BSTATUS & M0 */
3279 hdcp_mKsvListBuf[(list * KSV_LEN) + i]
3280 = hdmitx_rd_reg(
3281 HDMITX_DWC_HDCP_BSTATUS_0 + i);
3282 } else if (i < (HEADER + (list * KSV_LEN))) {
3283 /* KSV list */
3284 hdcp_mKsvListBuf[i - HEADER] =
3285 hdmitx_rd_reg(
3286 HDMITX_DWC_HDCP_BSTATUS_0 + i);
3287 ksvs[j] = hdcp_mKsvListBuf[i - HEADER];
3288 j++;
3289 } else { /* SHA */
3290 hdcp_mKsvListBuf[i] = hdmitx_rd_reg(
3291 HDMITX_DWC_HDCP_BSTATUS_0 + i);
3292 }
3293 }
3294 valid = hdcpVerify_KSV(hdcp_mKsvListBuf, size)
3295 == TRUE ? HDCP_KSV_LIST_READY :
3296 HDCP_ERR_KSV_LIST_NOT_VALID;
3297 }
3298 hdmitx_set_reg_bits(HDMITX_DWC_A_KSVMEMCTRL, 0, 0, 1);
3299 hdmitx_set_reg_bits(HDMITX_DWC_A_KSVMEMCTRL,
3300 (valid == HDCP_KSV_LIST_READY) ? 0 : 1, 3, 1);
3301 if (valid == HDCP_KSV_LIST_READY)
3302 hdcp_ksv_store(ksvs, j);
3303 hdmitx_set_reg_bits(HDMITX_DWC_A_KSVMEMCTRL, 1, 2, 1);
3304 hdmitx_set_reg_bits(HDMITX_DWC_A_KSVMEMCTRL, 0, 2, 1);
3305 kfree(hdcp_mKsvListBuf);
3306 } else
3307 pr_info("hdcptx14: KSV List memory not valid\n");
3308}
3309
3310static void hdcptx_events_handle(unsigned long arg)
3311{
3312 struct hdmitx_dev *hdev = (struct hdmitx_dev *)arg;
3313 unsigned char ksv[5] = {0};
3314 int pos, i;
3315 unsigned int bcaps_6_rp;
3316 static unsigned int st_flag = -1;
3317
3318 bcaps_6_rp = !!(hdmitx_rd_reg(HDMITX_DWC_A_HDCPOBS3) & (1 << 6));
3319 if (st_flag != hdmitx_rd_reg(HDMITX_DWC_A_APIINTSTAT)) {
3320 st_flag = hdmitx_rd_reg(HDMITX_DWC_A_APIINTSTAT);
3321 pr_info("hdcp14: instat: 0x%x\n", st_flag);
3322 }
3323 if (st_flag & (1 << 7)) {
3324 hdmitx_wr_reg(HDMITX_DWC_A_APIINTCLR, 1 << 7);
3325 hdmitx_hdcp_opr(3);
3326 for (i = 0; i < 5; i++)
3327 ksv[i] = (unsigned char)
3328 hdmitx_rd_reg(HDMITX_DWC_HDCPREG_BKSV0 + i);
3329 hdcp_ksv_store(ksv, 5);
3330 get_hdcp_bstatus();
3331 if (hdev->repeater_tx) {
3332 rx_set_receive_hdcp(rptx_ksv_buf, (rptx_ksv_no + 1) / 5,
3333 (bcaps_6_rp ? get_hdcp_depth() : 0) + 1,
3334 bcaps_6_rp ? get_hdcp_max_cascade() : 0,
3335 bcaps_6_rp ? get_hdcp_max_devs() : 0);
3336 pr_info("%s[%d] ksvs Num = %d device_count = %d\n",
3337 __func__, __LINE__,
3338 (rptx_ksv_no + 1) / 5,
3339 bcaps_6_rp ? get_hdcp_device_count() : 0);
3340 memset(rptx_ksv_prbuf, 0, sizeof(rptx_ksv_prbuf));
3341 for (pos = 0, i = 0; i < rptx_ksv_no; i++)
3342 pos += sprintf(rptx_ksv_prbuf + pos,
3343 "%02x", rptx_ksv_buf[i]);
3344 rptx_ksv_prbuf[pos + 1] = '\0';
3345 if (1)
3346 hdcp_ksv_print();
3347 }
3348 }
3349 if (st_flag & (1 << 1)) {
3350 hdmitx_wr_reg(HDMITX_DWC_A_APIINTCLR, (1 << 1));
3351 hdmitx_wr_reg(HDMITX_DWC_A_KSVMEMCTRL, 0x1);
3352 hdmitx_poll_reg(HDMITX_DWC_A_KSVMEMCTRL, (1<<1), 2 * HZ);
3353 if (hdmitx_rd_reg(HDMITX_DWC_A_KSVMEMCTRL) & (1 << 1))
3354 hdcp_ksv_sha1_calc(hdev);
3355 else {
3356 pr_info("hdcptx14: KSV List memory access denied\n");
3357 return;
3358 }
3359 hdmitx_wr_reg(HDMITX_DWC_A_KSVMEMCTRL, 0x4);
3360 if (hdev->repeater_tx) {
3361 rptx_ksvlist_retry++;
3362 if (rptx_ksvlist_retry % 4 == 0) {
3363 for (i = 0; i < 5; i++)
3364 ksv[i] = (unsigned char) hdmitx_rd_reg(
3365 HDMITX_DWC_HDCPREG_BKSV0 + i);
3366 hdcp_ksv_store(ksv, 5);
3367 rx_set_receive_hdcp(&ksv[0], 1, 127, 1, 1);
3368 }
3369 }
3370 }
3371 if (hdev->repeater_tx && bcaps_6_rp && (get_hdcp_max_devs() ||
3372 get_hdcp_max_cascade())) {
3373 for (i = 0; i < 5; i++)
3374 ksv[i] = (unsigned char)
3375 hdmitx_rd_reg(HDMITX_DWC_HDCPREG_BKSV0 + i);
3376 hdcp_ksv_store(ksv, 5);
3377 rx_set_receive_hdcp(&ksv[0], 1, 127, 1, 1);
3378 }
3379 if (hdev->hdcp_try_times)
3380 mod_timer(&hdev->hdcp_timer, jiffies + HZ / 100);
3381 else
3382 return;
3383 hdev->hdcp_try_times--;
3384}
3385
3386static void hdcp_start_timer(struct hdmitx_dev *hdev)
3387{
3388 static int init_flag;
3389
3390 if (!init_flag) {
3391 init_flag = 1;
3392 init_timer(&hdev->hdcp_timer);
3393 hdev->hdcp_timer.data = (ulong)hdev;
3394 hdev->hdcp_timer.function = hdcptx_events_handle;
3395 hdev->hdcp_timer.expires = jiffies + HZ / 100;
3396 add_timer(&hdev->hdcp_timer);
3397 hdev->hdcp_try_times = 500;
3398 return;
3399 }
3400 hdev->hdcp_try_times = 500;
3401 hdev->hdcp_timer.expires = jiffies + HZ / 100;
3402 mod_timer(&hdev->hdcp_timer, jiffies + HZ / 100);
3403}
3404
3405static void set_pkf_duk_nonce(void)
3406{
3407 static int nonce_mode = 1; /* 1: use HW nonce 0: use SW nonce */
3408
3409 /* Configure duk/pkf */
3410 hdmitx_hdcp_opr(0xc);
3411 if (nonce_mode == 1)
3412 hdmitx_wr_reg(HDMITX_TOP_SKP_CNTL_STAT, 0xf);
3413 else {
3414 hdmitx_wr_reg(HDMITX_TOP_SKP_CNTL_STAT, 0xe);
3415/* Configure nonce[127:0].
3416 * MSB must be written the last to assert nonce_vld signal.
3417 */
3418 hdmitx_wr_reg(HDMITX_TOP_NONCE_0, 0x32107654);
3419 hdmitx_wr_reg(HDMITX_TOP_NONCE_1, 0xba98fedc);
3420 hdmitx_wr_reg(HDMITX_TOP_NONCE_2, 0xcdef89ab);
3421 hdmitx_wr_reg(HDMITX_TOP_NONCE_3, 0x45670123);
3422 hdmitx_wr_reg(HDMITX_TOP_NONCE_0, 0x76543210);
3423 hdmitx_wr_reg(HDMITX_TOP_NONCE_1, 0xfedcba98);
3424 hdmitx_wr_reg(HDMITX_TOP_NONCE_2, 0x89abcdef);
3425 hdmitx_wr_reg(HDMITX_TOP_NONCE_3, 0x01234567);
3426 }
3427 udelay(10);
3428}
3429
3430static int hdmitx_cntl_ddc(struct hdmitx_dev *hdev, unsigned int cmd,
3431 unsigned long argv)
3432{
3433 int i = 0;
3434 unsigned char *tmp_char = NULL;
3435
3436 if ((cmd & CMD_DDC_OFFSET) != CMD_DDC_OFFSET) {
3437 hdmi_print(ERR, "ddc: w: invalid cmd 0x%x\n", cmd);
3438 return -1;
3439 }
3440
3441 switch (cmd) {
3442 case DDC_RESET_EDID:
3443 hdmitx_wr_reg(HDMITX_DWC_I2CM_SOFTRSTZ, 0);
3444 memset(tmp_edid_buf, 0, ARRAY_SIZE(tmp_edid_buf));
3445 break;
3446 case DDC_IS_EDID_DATA_READY:
3447
3448 break;
3449 case DDC_EDID_READ_DATA:
3450 hdmitx_read_edid(tmp_edid_buf);
3451 break;
3452 case DDC_EDID_GET_DATA:
3453 if (argv == 0)
3454 hdmitx_getediddata(&hdev->EDID_buf[0], tmp_edid_buf);
3455 else
3456 hdmitx_getediddata(&hdev->EDID_buf1[0], tmp_edid_buf);
3457 break;
3458 case DDC_PIN_MUX_OP:
3459 if (argv == PIN_MUX)
3460 hdmitx_ddc_hw_op(DDC_MUX_DDC);
3461 if (argv == PIN_UNMUX)
3462 hdmitx_ddc_hw_op(DDC_UNMUX_DDC);
3463 break;
3464 case DDC_EDID_CLEAR_RAM:
3465 for (i = 0; i < EDID_RAM_ADDR_SIZE; i++)
3466 hdmitx_wr_reg(HDMITX_DWC_I2CM_READ_BUFF0 + i, 0);
3467 break;
3468 case DDC_RESET_HDCP:
3469 hdmitx_set_reg_bits(HDMITX_TOP_SW_RESET, 1, 5, 1);
3470 udelay(10);
3471 hdmitx_set_reg_bits(HDMITX_TOP_SW_RESET, 0, 5, 1);
3472 udelay(10);
3473 break;
3474 case DDC_HDCP_MUX_INIT:
3475 if (argv == 2) {
3476 hdmitx_ddc_hw_op(DDC_MUX_DDC);
3477 hdmitx_set_reg_bits(HDMITX_DWC_MC_CLKDIS, 1, 6, 1);
3478 udelay(5);
3479 hdmitx_wr_reg(HDMITX_DWC_HDCP22REG_CTRL, 0x6);
3480 hdmitx_set_reg_bits(HDMITX_TOP_SW_RESET, 1, 5, 1);
3481 udelay(10);
3482 hdmitx_set_reg_bits(HDMITX_TOP_SW_RESET, 0, 5, 1);
3483 udelay(10);
3484 hdmitx_wr_reg(HDMITX_DWC_HDCP22REG_MASK, 0);
3485 hdmitx_wr_reg(HDMITX_DWC_HDCP22REG_MUTE, 0);
3486 set_pkf_duk_nonce();
3487 }
3488 if (argv == 1)
3489 hdmitx_hdcp_opr(6);
3490 break;
3491 case DDC_HDCP_OP:
3492 if (argv == HDCP14_ON) {
3493 rptx_ksvlist_retry = 0;
3494 rptx_ksv_no = 0;
3495 memset(rptx_ksv_buf, 0, sizeof(rptx_ksv_buf));
3496 hdmitx_ddc_hw_op(DDC_MUX_DDC);
3497 hdmitx_hdcp_opr(6);
3498 hdmitx_hdcp_opr(1);
3499 hdcp_start_timer(hdev);
3500 }
3501 if (argv == HDCP14_OFF) {
3502 rptx_ksvlist_retry = 0;
3503 hdmitx_hdcp_opr(4);
3504 }
3505 if (argv == HDCP22_ON) {
3506 hdmitx_ddc_hw_op(DDC_MUX_DDC);
3507 hdmitx_hdcp_opr(5);
3508 /* wait for start hdcp22app */
3509 }
3510 if (argv == HDCP22_OFF)
3511 hdmitx_hdcp_opr(6);
3512 break;
3513 case DDC_IS_HDCP_ON:
3514/* argv = !!((hdmitx_rd_reg(TX_HDCP_MODE)) & (1 << 7)); */
3515 break;
3516 case DDC_HDCP_GET_BKSV:
3517 tmp_char = (unsigned char *) argv;
3518 for (i = 0; i < 5; i++)
3519 tmp_char[i] = (unsigned char)
3520 hdmitx_rd_reg(HDMITX_DWC_HDCPREG_BKSV0 + 4 - i);
3521 break;
3522 case DDC_HDCP_GET_AUTH:
3523 if (hdev->hdcp_mode == 1)
3524 return hdmitx_hdcp_opr(2);
3525 if (hdev->hdcp_mode == 2)
3526 return hdmitx_hdcp_opr(7);
3527 else
3528 return 0;
3529 break;
3530 case DDC_HDCP_14_LSTORE:
3531 return hdmitx_hdcp_opr(0xa);
3532 case DDC_HDCP_22_LSTORE:
3533 return hdmitx_hdcp_opr(0xb);
3534 case DDC_SCDC_DIV40_SCRAMB:
3535 if (argv == 1) {
3536 scdc_wr_sink(TMDS_CFG, 0x3); /* TMDS 1/40 & Scramble */
3537 scdc_wr_sink(TMDS_CFG, 0x3); /* TMDS 1/40 & Scramble */
3538 hdmitx_wr_reg(HDMITX_DWC_FC_SCRAMBLER_CTRL, 1);
3539 } else {
3540 scdc_wr_sink(TMDS_CFG, 0x0); /* TMDS 1/40 & Scramble */
3541 scdc_wr_sink(TMDS_CFG, 0x0); /* TMDS 1/40 & Scramble */
3542 hdmitx_wr_reg(HDMITX_DWC_FC_SCRAMBLER_CTRL, 0);
3543 }
3544 break;
3545 case DDC_HDCP14_GET_BCAPS_RP:
3546 return !!(hdmitx_rd_reg(HDMITX_DWC_A_HDCPOBS3) & (1 << 6));
3547 default:
3548 hdmi_print(INF, "ddc: unknown cmd: 0x%x\n", cmd);
3549 break;
3550 }
3551 return 1;
3552}
3553
3554static int hdmitx_hdmi_dvi_config(struct hdmitx_dev *hdev,
3555 unsigned int dvi_mode)
3556{
3557 if (dvi_mode == 1) {
3558 hdmitx_csc_config(TX_INPUT_COLOR_FORMAT,
3559 COLORSPACE_RGB444, TX_COLOR_DEPTH);
3560
3561 /* set dvi flag */
3562 hdmitx_set_reg_bits(HDMITX_DWC_FC_INVIDCONF, 0, 3, 1);
3563
3564 } else {
3565 /* set hdmi flag */
3566 hdmitx_set_reg_bits(HDMITX_DWC_FC_INVIDCONF, 1, 3, 1);
3567 }
3568
3569 return 0;
3570}
3571
3572static int hdmitx_get_hdmi_dvi_config(struct hdmitx_dev *hdev)
3573{
3574 int value = hdmitx_rd_reg(HDMITX_DWC_FC_INVIDCONF) & 0x8;
3575
3576 return (value == 0)?DVI_MODE:HDMI_MODE;
3577}
3578
3579static int hdmitx_cntl_config(struct hdmitx_dev *hdev, unsigned int cmd,
3580 unsigned int argv)
3581{
3582 int ret = 0;
3583
3584 if ((cmd & CMD_CONF_OFFSET) != CMD_CONF_OFFSET) {
3585 hdmi_print(ERR, "config: hdmitx: w: invalid cmd 0x%x\n", cmd);
3586 return -1;
3587 }
3588
3589 switch (cmd) {
3590 case CONF_HDMI_DVI_MODE:
3591 hdmitx_hdmi_dvi_config(hdev, (argv == DVI_MODE)?1:0);
3592 break;
3593 case CONF_GET_HDMI_DVI_MODE:
3594 ret = hdmitx_get_hdmi_dvi_config(hdev);
3595 break;
3596 case CONF_SYSTEM_ST:
3597 break;
3598 case CONF_AUDIO_MUTE_OP:
3599 audio_mute_op(argv == AUDIO_MUTE ? 0 : 1);
3600 break;
3601 case CONF_VIDEO_MUTE_OP:
3602 if (argv == VIDEO_MUTE) {
3603 hd_set_reg_bits(P_HHI_GCLK_OTHER, 1, 3, 1);
3604 hd_set_reg_bits(P_ENCP_VIDEO_MODE_ADV, 0, 3, 1);
3605 hd_write_reg(P_VENC_VIDEO_TST_EN, 1);
3606 hd_write_reg(P_VENC_VIDEO_TST_MDSEL, 0);
3607 /*_Y/CB/CR, 10bits Unsigned/Signed/Signed */
3608 hd_write_reg(P_VENC_VIDEO_TST_Y, 0x0);
3609 hd_write_reg(P_VENC_VIDEO_TST_CB, 0x200);
3610 hd_write_reg(P_VENC_VIDEO_TST_CR, 0x200);
3611 }
3612 if (argv == VIDEO_UNMUTE) {
3613 hd_set_reg_bits(P_ENCP_VIDEO_MODE_ADV, 1, 3, 1);
3614 hd_write_reg(P_VENC_VIDEO_TST_EN, 0);
3615 }
3616 break;
3617 case CONF_CLR_AVI_PACKET:
3618 hdmitx_wr_reg(HDMITX_DWC_FC_AVIVID, 0);
3619 if (hdmitx_rd_reg(HDMITX_DWC_FC_VSDPAYLOAD0) == 0x20)
3620 hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD1, 0);
3621 hd_write_reg(P_ISA_DEBUG_REG0, 0);
3622 break;
3623 case CONF_CLR_VSDB_PACKET:
3624 if (hdmitx_rd_reg(HDMITX_DWC_FC_VSDPAYLOAD0) == 0x20)
3625 hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD1, 0);
3626 break;
3627 case CONF_VIDEO_MAPPING:
3628 config_video_mapping(hdev->para->cs, hdev->para->cd);
3629 break;
3630 case CONF_CLR_AUDINFO_PACKET:
3631 break;
3632 case CONF_AVI_BT2020:
3633 if (argv == SET_AVI_BT2020) {
3634 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF1, 3, 6, 2);
3635 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF2, 6, 4, 3);
3636 }
3637 if (argv == CLR_AVI_BT2020)
3638 hdmitx_set_avi_colorimetry(hdev->para);
3639 break;
3640 case CONF_AVI_RGBYCC_INDIC:
3641 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF0, argv, 0, 2);
3642 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF0, 0, 7, 1);
3643 break;
3644 case CONF_AVI_Q01:
3645 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF2, argv, 2, 2);
3646 break;
3647 case CONF_AVI_YQ01:
3648 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF3, argv, 2, 2);
3649 break;
3650 default:
3651 hdmi_print(ERR, "config: hdmitx: unknown cmd: 0x%x\n", cmd);
3652 }
3653
3654 return ret;
3655}
3656
3657static int hdmitx_tmds_rxsense(void)
3658{
3659 unsigned int curr0, curr3;
3660 int ret = 0;
3661
3662 switch (get_cpu_type()) {
3663 case MESON_CPU_MAJOR_ID_GXBB:
3664 curr0 = hd_read_reg(P_HHI_HDMI_PHY_CNTL0);
3665 curr3 = hd_read_reg(P_HHI_HDMI_PHY_CNTL3);
3666 if (curr0 == 0)
3667 hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33632122);
3668 hd_set_reg_bits(P_HHI_HDMI_PHY_CNTL3, 0x9a, 16, 8);
3669 ret = hd_read_reg(P_HHI_HDMI_PHY_CNTL2) & 0x1;
3670 hd_write_reg(P_HHI_HDMI_PHY_CNTL3, curr3);
3671 if (curr0 == 0)
3672 hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0);
3673 break;
3674 case MESON_CPU_MAJOR_ID_GXL:
3675 case MESON_CPU_MAJOR_ID_GXM:
3676 default:
3677 curr0 = hd_read_reg(P_HHI_HDMI_PHY_CNTL0);
3678 curr3 = hd_read_reg(P_HHI_HDMI_PHY_CNTL3);
3679 if (curr0 == 0)
3680 hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33604142);
3681 hd_set_reg_bits(P_HHI_HDMI_PHY_CNTL3, 0x1, 4, 1);
3682 ret = hd_read_reg(P_HHI_HDMI_PHY_CNTL2) & 0x1;
3683 hd_write_reg(P_HHI_HDMI_PHY_CNTL3, curr3);
3684 if (curr0 == 0)
3685 hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0);
3686 break;
3687 }
3688
3689 return ret;
3690}
3691
3692static int hdmitx_cntl_misc(struct hdmitx_dev *hdev, unsigned int cmd,
3693 unsigned int argv)
3694{
3695 if ((cmd & CMD_MISC_OFFSET) != CMD_MISC_OFFSET) {
3696 hdmi_print(ERR, "misc: hdmitx: w: invalid cmd 0x%x\n", cmd);
3697 return -1;
3698 }
3699
3700 switch (cmd) {
3701 case MISC_HPD_MUX_OP:
3702 if (argv == PIN_MUX)
3703 argv = HPD_MUX_HPD;
3704 else
3705 argv = HPD_UNMUX_HPD;
3706 return hdmitx_hpd_hw_op(argv);
3707 case MISC_HPD_GPI_ST:
3708 return hdmitx_hpd_hw_op(HPD_READ_HPD_GPIO);
3709 case MISC_HPLL_OP:
3710 if (argv == HPLL_ENABLE)
3711 hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL, 1, 30, 1);
3712 if (argv == HPLL_DISABLE)
3713 hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL, 0, 30, 1);
3714 break;
3715 case MISC_HPLL_FAKE:
3716 hdmitx_set_fake_vic(hdev);
3717 break;
3718 case MISC_TMDS_PHY_OP:
3719 if (argv == TMDS_PHY_ENABLE)
3720 hdmi_phy_wakeup(hdev); /* TODO */
3721 if (argv == TMDS_PHY_DISABLE)
3722 hdmi_phy_suspend();
3723 break;
3724 case MISC_TMDS_RXSENSE:
3725 return hdmitx_tmds_rxsense();
3726 case MISC_ESM_RESET:
3727 if (hdev->hdcp_hpd_stick == 1) {
3728 pr_info("hdcp: stick mode\n");
3729 break;
3730 }
3731 hdmitx_hdcp_opr(6);
3732 break;
3733 case MISC_VIID_IS_USING:
3734 break;
3735 case MISC_TMDS_CLK_DIV40:
3736 set_tmds_clk_div40(argv);
3737 break;
3738 case MISC_AVMUTE_OP:
3739 config_avmute(argv);
3740 break;
3741 case MISC_HDCP_CLKDIS:
3742 hdmitx_set_reg_bits(HDMITX_DWC_MC_CLKDIS, !!argv, 6, 1);
3743 break;
3744 case MISC_I2C_REACTIVE:
3745 hdmitx_set_reg_bits(HDMITX_DWC_A_HDCPCFG1, 0, 0, 1);
3746 hdmitx_set_reg_bits(HDMITX_DWC_HDCP22REG_CTRL, 0, 2, 1);
3747 hdmitx_wr_reg(HDMITX_DWC_I2CM_SS_SCL_HCNT_1, 0xff);
3748 hdmitx_wr_reg(HDMITX_DWC_I2CM_SS_SCL_HCNT_0, 0xf6);
3749 edid_read_head_8bytes();
3750 hdmi_hwi_init(hdev);
3751 break;
3752 default:
3753 hdmi_print(ERR, "misc: hdmitx: unknown cmd: 0x%x\n", cmd);
3754 }
3755 return 1;
3756}
3757
3758static enum hdmi_vic get_vic_from_pkt(void)
3759{
3760 enum hdmi_vic vic = HDMI_Unknown;
3761 unsigned int rgb_ycc = hdmitx_rd_reg(HDMITX_DWC_FC_AVICONF0);
3762
3763 vic = hdmitx_rd_reg(HDMITX_DWC_FC_AVIVID);
3764 if (vic == HDMI_Unknown) {
3765 vic = (enum hdmi_vic)hdmitx_rd_reg(HDMITX_DWC_FC_VSDPAYLOAD1);
3766 if (vic == 1)
3767 vic = HDMI_3840x2160p30_16x9;
3768 else if (vic == 2)
3769 vic = HDMI_3840x2160p25_16x9;
3770 else if (vic == 3)
3771 vic = HDMI_3840x2160p24_16x9;
3772 else if (vic == 4)
3773 vic = HDMI_4096x2160p24_256x135;
3774 else
3775 vic = hd_read_reg(P_ISA_DEBUG_REG0);
3776 }
3777
3778 rgb_ycc &= 0x3;
3779 switch (vic) {
3780 case HDMI_3840x2160p50_16x9:
3781 if (rgb_ycc == 0x3)
3782 vic = HDMI_3840x2160p50_16x9_Y420;
3783 break;
3784 case HDMI_4096x2160p50_256x135:
3785 if (rgb_ycc == 0x3)
3786 vic = HDMI_4096x2160p50_256x135_Y420;
3787 break;
3788 case HDMI_3840x2160p60_16x9:
3789 if (rgb_ycc == 0x3)
3790 vic = HDMI_3840x2160p60_16x9_Y420;
3791 break;
3792 case HDMI_4096x2160p60_256x135:
3793 if (rgb_ycc == 0x3)
3794 vic = HDMI_4096x2160p60_256x135_Y420;
3795 break;
3796 break;
3797 default:
3798 break;
3799 }
3800
3801 return vic;
3802}
3803
3804static int hdmitx_get_state(struct hdmitx_dev *hdev, unsigned int cmd,
3805 unsigned int argv)
3806{
3807 if ((cmd & CMD_STAT_OFFSET) != CMD_STAT_OFFSET) {
3808 hdmi_print(ERR, "stat: hdmitx: w: invalid cmd 0x%x\n", cmd);
3809 return -1;
3810 }
3811
3812 switch (cmd) {
3813 case STAT_VIDEO_VIC:
3814 return (int)get_vic_from_pkt();
3815 case STAT_VIDEO_CLK:
3816 break;
3817 default:
3818 break;
3819 }
3820 return 0;
3821}
3822
3823static void hdmi_phy_suspend(void)
3824{
3825 hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x0);
3826}
3827
3828static void hdmi_phy_wakeup(struct hdmitx_dev *hdev)
3829{
3830 hdmitx_set_phy(hdev);
3831 /* hdmi_print(INF, SYS "phy wakeup\n"); */
3832}
3833
3834/* CRT_VIDEO SETTING FUNCTIONS
3835 * input :
3836 * vIdx: 0:V1; 1:V2; there have 2 parallel set clock generator: V1 and V2
3837 * inSel : 0:vid_pll_clk; 1:fclk_div4; 2:flck_div3; 3:fclk_div5;
3838 * 4:vid_pll2_clk; 5:fclk_div7; 6:vid_pll2_clk;
3839 * DivN : clock divider for enci_clk/encp_clk/encl_clk/vda_clk
3840 * /hdmi_tx_pixel_clk;
3841 */
3842void set_crt_video_enc(uint32_t vIdx, uint32_t inSel, uint32_t DivN)
3843{
3844 if (vIdx == 0) {
3845 hd_set_reg_bits(P_HHI_VID_CLK_CNTL, 0, 19, 1);
3846
3847 hd_set_reg_bits(P_HHI_VID_CLK_CNTL, inSel, 16, 3);
3848 hd_set_reg_bits(P_HHI_VID_CLK_DIV, (DivN-1), 0, 8);
3849
3850 hd_set_reg_bits(P_HHI_VID_CLK_CNTL, 1, 19, 1);
3851
3852 } else { /* V2 */
3853 hd_set_reg_bits(P_HHI_VIID_CLK_CNTL, 0, 19, 1);
3854
3855 hd_set_reg_bits(P_HHI_VIID_CLK_CNTL, inSel, 16, 3);
3856 hd_set_reg_bits(P_HHI_VIID_CLK_DIV, (DivN-1), 0, 8);
3857
3858 hd_set_reg_bits(P_HHI_VIID_CLK_CNTL, 1, 19, 1);
3859 }
3860}
3861
3862void hdmitx_set_avi_colorimetry(struct hdmi_format_para *para)
3863{
3864 if (!para)
3865 return;
3866
3867 /* set Colorimetry in AVIInfo */
3868 switch (para->vic) {
3869 case HDMI_640x480p60_4x3:
3870 case HDMI_720x480p60_4x3:
3871 case HDMI_720x480p60_16x9:
3872 case HDMI_720x480i60_4x3:
3873 case HDMI_720x480i60_16x9:
3874 case HDMI_720x240p60_4x3:
3875 case HDMI_720x240p60_16x9:
3876 case HDMI_2880x480i60_4x3:
3877 case HDMI_2880x480i60_16x9:
3878 case HDMI_2880x240p60_4x3:
3879 case HDMI_2880x240p60_16x9:
3880 case HDMI_1440x480p60_4x3:
3881 case HDMI_1440x480p60_16x9:
3882 case HDMI_720x576p50_4x3:
3883 case HDMI_720x576p50_16x9:
3884 case HDMI_720x576i50_4x3:
3885 case HDMI_720x576i50_16x9:
3886 case HDMI_720x288p_4x3:
3887 case HDMI_720x288p_16x9:
3888 case HDMI_2880x576i50_4x3:
3889 case HDMI_2880x576i50_16x9:
3890 case HDMI_2880x288p50_4x3:
3891 case HDMI_2880x288p50_16x9:
3892 case HDMI_1440x576p_4x3:
3893 case HDMI_1440x576p_16x9:
3894 case HDMI_2880x480p60_4x3:
3895 case HDMI_2880x480p60_16x9:
3896 case HDMI_2880x576p50_4x3:
3897 case HDMI_2880x576p50_16x9:
3898 case HDMI_720x576p100_4x3:
3899 case HDMI_720x576p100_16x9:
3900 case HDMI_720x576i100_4x3:
3901 case HDMI_720x576i100_16x9:
3902 case HDMI_720x480p120_4x3:
3903 case HDMI_720x480p120_16x9:
3904 case HDMI_720x480i120_4x3:
3905 case HDMI_720x480i120_16x9:
3906 case HDMI_720x576p200_4x3:
3907 case HDMI_720x576p200_16x9:
3908 case HDMI_720x576i200_4x3:
3909 case HDMI_720x576i200_16x9:
3910 case HDMI_720x480p240_4x3:
3911 case HDMI_720x480p240_16x9:
3912 case HDMI_720x480i240_4x3:
3913 case HDMI_720x480i240_16x9:
3914 /* C1C0 601 */
3915 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF1, 1, 6, 2);
3916 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF2, 0, 4, 3);
3917 break;
3918 default:
3919 /* C1C0 709 */
3920 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF1, 2, 6, 2);
3921 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF2, 0, 4, 3);
3922 break;
3923 }
3924}
3925
3926/*
3927 * color_depth: Pixel bit width: 4=24-bit; 5=30-bit; 6=36-bit; 7=48-bit.
3928 * input_color_format: 0=RGB444; 1=YCbCr422; 2=YCbCr444; 3=YCbCr420.
3929 * input_color_range: 0=limited; 1=full.
3930 * output_color_format: 0=RGB444; 1=YCbCr422; 2=YCbCr444; 3=YCbCr420
3931 */
3932static void config_hdmi20_tx(enum hdmi_vic vic,
3933 struct hdmitx_dev *hdev,
3934 unsigned char color_depth,
3935 unsigned char input_color_format,
3936 unsigned char output_color_format)
3937{
3938 struct hdmi_format_para *para = hdev->para;
3939 struct hdmi_cea_timing *t = &para->timing;
3940 unsigned long data32;
3941 unsigned char vid_map;
3942 unsigned char csc_en;
3943 unsigned char default_phase = 0;
3944 unsigned int tmp = 0;
3945
3946#define GET_TIMING(name) (t->name)
3947
3948 /* Enable clocks and bring out of reset */
3949
3950 /* Enable hdmitx_sys_clk */
3951 /* .clk0 ( cts_oscin_clk ), */
3952 /* .clk1 ( fclk_div4 ), */
3953 /* .clk2 ( fclk_div3 ), */
3954 /* .clk3 ( fclk_div5 ), */
3955 hd_set_reg_bits(P_HHI_HDMI_CLK_CNTL, 0x0100, 0, 16);
3956
3957 /* Enable clk81_hdmitx_pclk */
3958 hd_set_reg_bits(P_HHI_GCLK_MPEG2, 1, 4, 1);
3959
3960 /* wire wr_enable = control[3]; */
3961 /* wire fifo_enable = control[2]; */
3962 /* assign phy_clk_en = control[1]; */
3963 /* Enable tmds_clk */
3964 /* Bring HDMITX MEM output of power down */
3965 hd_set_reg_bits(P_HHI_MEM_PD_REG0, 0, 8, 8);
3966
3967 /* Bring out of reset */
3968 hdmitx_wr_reg(HDMITX_TOP_SW_RESET, 0);
3969
3970 /* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */
3971 hdmitx_set_reg_bits(HDMITX_TOP_CLK_CNTL, 3, 0, 2);
3972 hdmitx_set_reg_bits(HDMITX_TOP_CLK_CNTL, 3, 4, 2);
3973 hdmitx_wr_reg(HDMITX_DWC_MC_LOCKONCLOCK, 0xff);
3974
3975/* But keep spdif_clk and i2s_clk disable
3976 * until later enable by test.c
3977 */
3978 data32 = 0;
3979 hdmitx_wr_reg(HDMITX_DWC_MC_CLKDIS, data32);
3980
3981 /* Enable normal output to PHY */
3982
3983 data32 = 0;
3984 data32 |= (1 << 12);
3985 data32 |= (0 << 8);
3986 data32 |= (0 << 0);
3987 hdmitx_wr_reg(HDMITX_TOP_BIST_CNTL, data32);
3988
3989 /* Configure video */
3990
3991 vid_map = (input_color_format == COLORSPACE_RGB444) ?
3992 ((color_depth == COLORDEPTH_24B) ? 0x01 :
3993 (color_depth == COLORDEPTH_30B) ? 0x03 :
3994 (color_depth == COLORDEPTH_36B) ? 0x05 :
3995 0x07) :
3996 ((input_color_format == COLORSPACE_YUV444) ||
3997 (input_color_format == COLORSPACE_YUV420)) ?
3998 ((color_depth == COLORDEPTH_24B) ? 0x09 :
3999 (color_depth == COLORDEPTH_30B) ? 0x0b :
4000 (color_depth == COLORDEPTH_36B) ? 0x0d :
4001 0x0f) :
4002 ((color_depth == COLORDEPTH_24B) ? 0x16 :
4003 (color_depth == COLORDEPTH_30B) ? 0x14 :
4004 0x12);
4005
4006 data32 = 0;
4007 data32 |= (0 << 7);
4008 data32 |= (vid_map << 0);
4009 hdmitx_wr_reg(HDMITX_DWC_TX_INVID0, data32);
4010
4011 data32 = 0;
4012 data32 |= (0 << 2);
4013 data32 |= (0 << 1);
4014 data32 |= (0 << 0);
4015 hdmitx_wr_reg(HDMITX_DWC_TX_INSTUFFING, data32);
4016 hdmitx_wr_reg(HDMITX_DWC_TX_GYDATA0, 0x00);
4017 hdmitx_wr_reg(HDMITX_DWC_TX_GYDATA1, 0x00);
4018 hdmitx_wr_reg(HDMITX_DWC_TX_RCRDATA0, 0x00);
4019 hdmitx_wr_reg(HDMITX_DWC_TX_RCRDATA1, 0x00);
4020 hdmitx_wr_reg(HDMITX_DWC_TX_BCBDATA0, 0x00);
4021 hdmitx_wr_reg(HDMITX_DWC_TX_BCBDATA1, 0x00);
4022
4023 /* Configure Color Space Converter */
4024
4025 csc_en = (input_color_format != output_color_format) ? 1 : 0;
4026
4027 data32 = 0;
4028 data32 |= (csc_en << 0);
4029 hdmitx_wr_reg(HDMITX_DWC_MC_FLOWCTRL, data32);
4030
4031 data32 = 0;
4032 data32 |= ((((input_color_format == COLORSPACE_YUV422) &&
4033 (output_color_format != COLORSPACE_YUV422)) ? 2 : 0) << 4);
4034 data32 |= ((((input_color_format != COLORSPACE_YUV422) &&
4035 (output_color_format == COLORSPACE_YUV422)) ? 1 : 0) << 0);
4036 hdmitx_wr_reg(HDMITX_DWC_CSC_CFG, data32);
4037 hdmitx_csc_config(input_color_format, output_color_format, color_depth);
4038
4039 /* Configure video packetizer */
4040
4041 /* Video Packet color depth and pixel repetition */
4042 data32 = 0;
4043 data32 |= (((output_color_format == COLORSPACE_YUV422) ?
4044 COLORDEPTH_24B : color_depth) << 4);
4045 data32 |= (0 << 0);
4046 if ((data32 & 0xf0) == 0x40)
4047 data32 &= ~(0xf << 4);
4048 hdmitx_wr_reg(HDMITX_DWC_VP_PR_CD, data32);
4049 if (output_color_format == COLORSPACE_YUV422) {
4050 if (color_depth == COLORDEPTH_24B)
4051 hdmitx_set_reg_bits(HDMITX_DWC_VP_PR_CD, 0x4, 4, 4);
4052 else
4053 hdmitx_set_reg_bits(HDMITX_DWC_VP_PR_CD, 0, 4, 4);
4054 }
4055
4056 /* Video Packet Stuffing */
4057 data32 = 0;
4058 data32 |= (default_phase << 5);
4059 data32 |= (0 << 2);
4060 data32 |= (0 << 1);
4061 data32 |= (0 << 0);
4062 hdmitx_wr_reg(HDMITX_DWC_VP_STUFF, data32);
4063
4064 /* Video Packet YCC color remapping */
4065 data32 = 0;
4066 data32 |= (((color_depth == COLORDEPTH_30B) ? 1 :
4067 (color_depth == COLORDEPTH_36B) ? 2 : 0) << 0);
4068 hdmitx_wr_reg(HDMITX_DWC_VP_REMAP, data32);
4069 if (output_color_format == COLORSPACE_YUV422) {
4070 switch (color_depth) {
4071 case COLORDEPTH_36B:
4072 tmp = 2;
4073 break;
4074 case COLORDEPTH_30B:
4075 tmp = 1;
4076 break;
4077 case COLORDEPTH_24B:
4078 tmp = 0;
4079 break;
4080 }
4081 }
4082 /* [1:0] ycc422_size */
4083 hdmitx_set_reg_bits(HDMITX_DWC_VP_REMAP, tmp, 0, 2);
4084
4085 /* Video Packet configuration */
4086 data32 = 0;
4087 data32 |= ((((output_color_format != COLORSPACE_YUV422) &&
4088 (color_depth == COLORDEPTH_24B)) ? 1 : 0) << 6);
4089 data32 |= ((((output_color_format == COLORSPACE_YUV422) ||
4090 (color_depth == COLORDEPTH_24B)) ? 0 : 1) << 5);
4091 data32 |= (0 << 4);
4092 data32 |= (((output_color_format == COLORSPACE_YUV422) ? 1 : 0)
4093 << 3);
4094 data32 |= (1 << 2);
4095 data32 |= (((output_color_format == COLORSPACE_YUV422) ? 1 :
4096 (color_depth == COLORDEPTH_24B) ? 2 : 0) << 0);
4097 hdmitx_wr_reg(HDMITX_DWC_VP_CONF, data32);
4098
4099 data32 = 0;
4100 data32 |= (1 << 7);
4101 data32 |= (1 << 6);
4102 data32 |= (1 << 5);
4103 data32 |= (1 << 4);
4104 data32 |= (1 << 3);
4105 data32 |= (1 << 2);
4106 data32 |= (1 << 1);
4107 data32 |= (1 << 0);
4108 hdmitx_wr_reg(HDMITX_DWC_VP_MASK, data32);
4109
4110 /* Configure audio */
4111 /* I2S Sampler config */
4112
4113 data32 = 0;
4114 data32 |= (1 << 3);
4115 data32 |= (1 << 2);
4116 hdmitx_wr_reg(HDMITX_DWC_AUD_INT, data32);
4117
4118 data32 = 0;
4119 data32 |= (1 << 4);
4120 hdmitx_wr_reg(HDMITX_DWC_AUD_INT1, data32);
4121
4122 hdmitx_wr_reg(HDMITX_DWC_FC_MULTISTREAM_CTRL, 0);
4123
4124/* if enable it now, fifo_overrun will happen, because packet don't get
4125 * sent out until initial DE detected.
4126 */
4127 data32 = 0;
4128 data32 |= (0 << 7);
4129 data32 |= (tx_aud_src << 5);
4130 data32 |= (0 << 0);
4131 hdmitx_wr_reg(HDMITX_DWC_AUD_CONF0, data32);
4132
4133 data32 = 0;
4134 data32 |= (0 << 5);
4135 data32 |= (24 << 0);
4136 hdmitx_wr_reg(HDMITX_DWC_AUD_CONF1, data32);
4137
4138 data32 = 0;
4139 data32 |= (0 << 1);
4140 data32 |= (0 << 0);
4141 hdmitx_wr_reg(HDMITX_DWC_AUD_CONF2, data32);
4142
4143 /* spdif sampler config */
4144
4145 data32 = 0;
4146 data32 |= (1 << 3);
4147 data32 |= (1 << 2);
4148 hdmitx_wr_reg(HDMITX_DWC_AUD_SPDIFINT, data32);
4149
4150 data32 = 0;
4151 data32 |= (0 << 4);
4152 hdmitx_wr_reg(HDMITX_DWC_AUD_SPDIFINT1, data32);
4153
4154 data32 = 0;
4155 data32 |= (0 << 7);
4156 hdmitx_wr_reg(HDMITX_DWC_AUD_SPDIF0, data32);
4157
4158 data32 = 0;
4159 data32 |= (0 << 7);
4160 data32 |= (0 << 6);
4161 data32 |= (24 << 0);
4162 hdmitx_wr_reg(HDMITX_DWC_AUD_SPDIF1, data32);
4163
4164 /* Frame Composer configuration */
4165
4166 /* Video definitions, as per output video(for packet gen/schedulling) */
4167
4168 data32 = 0;
4169 data32 |= (1 << 7);
4170 data32 |= (GET_TIMING(vsync_polarity) << 6);
4171 data32 |= (GET_TIMING(hsync_polarity) << 5);
4172 data32 |= (1 << 4);
4173 data32 |= (1 << 3);
4174 data32 |= (!(para->progress_mode) << 1);
4175 data32 |= (!(para->progress_mode) << 0);
4176 hdmitx_wr_reg(HDMITX_DWC_FC_INVIDCONF, data32);
4177
4178 data32 = GET_TIMING(h_active)&0xff;
4179 hdmitx_wr_reg(HDMITX_DWC_FC_INHACTV0, data32);
4180 data32 = (GET_TIMING(h_active)>>8) & 0x3f;
4181 hdmitx_wr_reg(HDMITX_DWC_FC_INHACTV1, data32);
4182
4183 data32 = GET_TIMING(h_blank) & 0xff;
4184 hdmitx_wr_reg(HDMITX_DWC_FC_INHBLANK0, data32);
4185 data32 = (GET_TIMING(h_blank)>>8)&0x1f;
4186 hdmitx_wr_reg(HDMITX_DWC_FC_INHBLANK1, data32);
4187
4188 if (hdev->flag_3dfp) {
4189 data32 = (((GET_TIMING(v_active)) * 2) + (GET_TIMING(v_blank)));
4190 hdmitx_wr_reg(HDMITX_DWC_FC_INVACTV0, data32 & 0xff);
4191 hdmitx_wr_reg(HDMITX_DWC_FC_INVACTV1, (data32 >> 8) & 0x1f);
4192 } else {
4193 data32 = GET_TIMING(v_active) & 0xff;
4194 hdmitx_wr_reg(HDMITX_DWC_FC_INVACTV0, data32);
4195 data32 = (GET_TIMING(v_active) >> 8) & 0x1f;
4196 hdmitx_wr_reg(HDMITX_DWC_FC_INVACTV1, data32);
4197 }
4198 data32 = GET_TIMING(v_blank)&0xff;
4199 hdmitx_wr_reg(HDMITX_DWC_FC_INVBLANK, data32);
4200
4201 data32 = GET_TIMING(h_front)&0xff;
4202 hdmitx_wr_reg(HDMITX_DWC_FC_HSYNCINDELAY0, data32);
4203 data32 = (GET_TIMING(h_front)>>8)&0x1f;
4204 hdmitx_wr_reg(HDMITX_DWC_FC_HSYNCINDELAY1, data32);
4205
4206 data32 = GET_TIMING(h_sync)&0xff;
4207 hdmitx_wr_reg(HDMITX_DWC_FC_HSYNCINWIDTH0, data32);
4208 data32 = (GET_TIMING(h_sync)>>8)&0x3;
4209 hdmitx_wr_reg(HDMITX_DWC_FC_HSYNCINWIDTH1, data32);
4210
4211 data32 = GET_TIMING(v_front)&0xff;
4212 hdmitx_wr_reg(HDMITX_DWC_FC_VSYNCINDELAY, data32);
4213
4214 data32 = GET_TIMING(v_sync)&0x3f;
4215 hdmitx_wr_reg(HDMITX_DWC_FC_VSYNCINWIDTH, data32);
4216
4217 /* control period duration (typ 12 tmds periods) */
4218 hdmitx_wr_reg(HDMITX_DWC_FC_CTRLDUR, 12);
4219 /* extended control period duration (typ 32 tmds periods) */
4220 hdmitx_wr_reg(HDMITX_DWC_FC_EXCTRLDUR, 32);
4221 /* max interval betwen extended control period duration (typ 50) */
4222 hdmitx_wr_reg(HDMITX_DWC_FC_EXCTRLSPAC, 1);
4223 /* preamble filler */
4224 hdmitx_wr_reg(HDMITX_DWC_FC_CH0PREAM, 0x0b);
4225 hdmitx_wr_reg(HDMITX_DWC_FC_CH1PREAM, 0x16);
4226 hdmitx_wr_reg(HDMITX_DWC_FC_CH2PREAM, 0x21);
4227
4228 /* write GCP packet configuration */
4229 data32 = 0;
4230 data32 |= (default_phase << 2);
4231 data32 |= (0 << 1);
4232 data32 |= (0 << 0);
4233 hdmitx_wr_reg(HDMITX_DWC_FC_GCP, data32);
4234
4235 /* write AVI Infoframe packet configuration */
4236
4237 data32 = 0;
4238 data32 |= (((output_color_format>>2)&0x1) << 7);
4239 data32 |= (1 << 6);
4240 data32 |= (0 << 4);
4241 data32 |= (0 << 2);
4242 data32 |= (0x2 << 0); /* FIXED YCBCR 444 */
4243 hdmitx_wr_reg(HDMITX_DWC_FC_AVICONF0, data32);
4244 switch (output_color_format) {
4245 case COLORSPACE_RGB444:
4246 tmp = 0;
4247 break;
4248 case COLORSPACE_YUV422:
4249 tmp = 1;
4250 break;
4251 case COLORSPACE_YUV420:
4252 tmp = 3;
4253 break;
4254 case COLORSPACE_YUV444:
4255 default:
4256 tmp = 2;
4257 break;
4258 }
4259 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF0, tmp, 0, 2);
4260
4261 hdmitx_wr_reg(HDMITX_DWC_FC_AVICONF1, 0x8);
4262 hdmitx_wr_reg(HDMITX_DWC_FC_AVICONF2, 0);
4263
4264 /* set Aspect Ratio in AVIInfo */
4265 switch (para->vic) {
4266 case HDMI_640x480p60_4x3:
4267 case HDMI_720x480p60_4x3:
4268 case HDMI_720x480i60_4x3:
4269 case HDMI_720x240p60_4x3:
4270 case HDMI_2880x480i60_4x3:
4271 case HDMI_2880x240p60_4x3:
4272 case HDMI_1440x480p60_4x3:
4273 case HDMI_720x576p50_4x3:
4274 case HDMI_720x576i50_4x3:
4275 case HDMI_720x288p_4x3:
4276 case HDMI_2880x576i50_4x3:
4277 case HDMI_2880x288p50_4x3:
4278 case HDMI_1440x576p_4x3:
4279 case HDMI_2880x480p60_4x3:
4280 case HDMI_2880x576p50_4x3:
4281 case HDMI_720x576p100_4x3:
4282 case HDMI_720x576i100_4x3:
4283 case HDMI_720x480p120_4x3:
4284 case HDMI_720x480i120_4x3:
4285 case HDMI_720x576p200_4x3:
4286 case HDMI_720x576i200_4x3:
4287 case HDMI_720x480p240_4x3:
4288 case HDMI_720x480i240_4x3:
4289 /* Picture Aspect Ratio M1/M0 4:3 */
4290 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF1, 0x1, 4, 2);
4291 break;
4292 default:
4293 /* Picture Aspect Ratio M1/M0 16:9 */
4294 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF1, 0x2, 4, 2);
4295 break;
4296 }
4297 /* Active Format Aspect Ratio R3~R0 Same as picture aspect ratio */
4298 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF1, 0x8, 0, 4);
4299
4300 hdmitx_set_avi_colorimetry(para);
4301 if (hdev->hdr_color_feature == C_BT2020)
4302 hdev->HWOp.CntlConfig(hdev, CONF_AVI_BT2020, SET_AVI_BT2020);
4303
4304 data32 = 0;
4305 data32 |= (((0 == COLORRANGE_FUL) ? 1 : 0) << 2);
4306 data32 |= (0 << 0);
4307 hdmitx_wr_reg(HDMITX_DWC_FC_AVICONF3, data32);
4308
4309 hdmitx_wr_reg(HDMITX_DWC_FC_AVIVID, (para->vic & HDMITX_VIC_MASK));
4310
4311 /* write Audio Infoframe packet configuration */
4312
4313 data32 = 0;
4314 data32 |= (1 << 4);
4315 data32 |= (0 << 0);
4316 hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF0, data32);
4317
4318 data32 = 0;
4319 data32 |= (3 << 4);
4320 data32 |= (0 << 0);
4321 hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF1, data32);
4322
4323 hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF2, 0x00);
4324
4325 data32 = 0;
4326 data32 |= (1 << 5);
4327 data32 |= (0 << 4);
4328 data32 |= (0 << 0);
4329 hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF3, data32);
4330
4331 /* write audio packet configuration */
4332 data32 = 0;
4333 data32 |= (0 << 4);
4334 data32 |= (0 << 0);
4335 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCONF, data32);
4336
4337/* the audio setting bellow are only used for I2S audio IEC60958-3 frame
4338 * insertion
4339 */
4340 data32 = 0;
4341 data32 |= (0 << 7);
4342 data32 |= (0 << 6);
4343 data32 |= (0 << 5);
4344 data32 |= (1 << 4);
4345 data32 |= (0 << 3);
4346 data32 |= (0 << 2);
4347 data32 |= (0 << 1);
4348 data32 |= (1 << 0);
4349 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSV, data32);
4350
4351 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSU, 0);
4352
4353 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS0, 0x01);
4354 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS1, 0x23);
4355 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS2, 0x45);
4356 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS3, 0x67);
4357 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS4, 0x89);
4358 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS5, 0xab);
4359 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS6, 0xcd);
4360 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS7, 0x2f);
4361 hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS8, 0xf0);
4362
4363 /* packet queue priority (auto mode) */
4364 hdmitx_wr_reg(HDMITX_DWC_FC_CTRLQHIGH, 15);
4365 hdmitx_wr_reg(HDMITX_DWC_FC_CTRLQLOW, 3);
4366
4367 /* packet scheduller configuration for SPD, VSD, ISRC1/2, ACP. */
4368 hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO0, 0, 0, 3);
4369 hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO0, 0, 4, 4);
4370 hdmitx_wr_reg(HDMITX_DWC_FC_DATAUTO1, 0);
4371 hdmitx_wr_reg(HDMITX_DWC_FC_DATMAN, 0);
4372
4373 /* packet scheduller configuration for AVI, GCP, AUDI, ACR. */
4374 hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO3, 0xe, 0, 6);
4375 /* If RX support 2084 or hlg , and the hdr_src_feature is 2020
4376 * then enable HDR send out
4377 */
4378 if ((hdev->RXCap.hdr_sup_eotf_smpte_st_2084 ||
4379 hdev->RXCap.hdr_sup_eotf_hlg) &&
4380 (hdev->hdr_color_feature == C_BT2020)) {
4381 hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO3, 1, 6, 1);
4382 hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 7, 1);
4383 } else {
4384 /* If RX don't support HDR, then enable HDR send out*/
4385 hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO3, 0, 6, 1);
4386 hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 0, 7, 1);
4387 }
4388
4389 hdmitx_wr_reg(HDMITX_DWC_FC_RDRB0, 0);
4390 hdmitx_wr_reg(HDMITX_DWC_FC_RDRB1, 0);
4391 hdmitx_wr_reg(HDMITX_DWC_FC_RDRB2, 0);
4392 hdmitx_wr_reg(HDMITX_DWC_FC_RDRB3, 0);
4393 hdmitx_wr_reg(HDMITX_DWC_FC_RDRB4, 0);
4394 hdmitx_wr_reg(HDMITX_DWC_FC_RDRB5, 0);
4395 hdmitx_wr_reg(HDMITX_DWC_FC_RDRB6, 0);
4396 hdmitx_wr_reg(HDMITX_DWC_FC_RDRB7, 0);
4397 hdmitx_wr_reg(HDMITX_DWC_FC_RDRB8, 0);
4398 hdmitx_wr_reg(HDMITX_DWC_FC_RDRB9, 0);
4399 hdmitx_wr_reg(HDMITX_DWC_FC_RDRB10, 0);
4400 hdmitx_wr_reg(HDMITX_DWC_FC_RDRB11, 0);
4401
4402 /* Packet transmission enable */
4403 hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 1, 1);
4404 hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 2, 1);
4405
4406 /* For 3D video */
4407 data32 = 0;
4408 data32 |= (0 << 1);
4409 data32 |= (0 << 0);
4410 hdmitx_wr_reg(HDMITX_DWC_FC_ACTSPC_HDLR_CFG, data32);
4411
4412 data32 = GET_TIMING(v_active)&0xff;
4413 hdmitx_wr_reg(HDMITX_DWC_FC_INVACT_2D_0, data32);
4414 data32 = (GET_TIMING(v_active)>>8)&0xf;
4415 hdmitx_wr_reg(HDMITX_DWC_FC_INVACT_2D_1, data32);
4416
4417 /* Do not enable these interrupt below, we can check them at RX side. */
4418 data32 = 0;
4419 data32 |= (1 << 7);
4420 data32 |= (1 << 6);
4421 data32 |= (1 << 5);
4422 data32 |= (1 << 2);
4423 data32 |= (1 << 1);
4424 data32 |= (1 << 0);
4425 hdmitx_wr_reg(HDMITX_DWC_FC_MASK0, data32);
4426
4427 data32 = 0;
4428 data32 |= (1 << 7);
4429 data32 |= (1 << 6);
4430 data32 |= (1 << 5);
4431 data32 |= (1 << 4);
4432 data32 |= (1 << 3);
4433 data32 |= (1 << 1);
4434 data32 |= (1 << 0);
4435 hdmitx_wr_reg(HDMITX_DWC_FC_MASK1, data32);
4436
4437 data32 = 0;
4438 data32 |= (1 << 2);
4439 data32 |= (1 << 1);
4440 data32 |= (1 << 0);
4441 hdmitx_wr_reg(HDMITX_DWC_FC_MASK2, data32);
4442
4443 /* Pixel repetition ratio the input and output video */
4444 data32 = 0;
4445 data32 |= ((para->pixel_repetition_factor+1) << 4);
4446 data32 |= (para->pixel_repetition_factor << 0);
4447 hdmitx_wr_reg(HDMITX_DWC_FC_PRCONF, data32);
4448
4449 /* Configure HDCP */
4450 data32 = 0;
4451 data32 |= (0 << 7);
4452 data32 |= (0 << 6);
4453 data32 |= (0 << 4);
4454 data32 |= (0 << 3);
4455 data32 |= (0 << 2);
4456 data32 |= (0 << 1);
4457 data32 |= (1 << 0);
4458 hdmitx_wr_reg(HDMITX_DWC_A_APIINTMSK, data32);
4459
4460 data32 = 0;
4461 data32 |= (0 << 5);
4462 data32 |= (1 << 4);
4463 data32 |= (1 << 3);
4464 data32 |= (1 << 1);
4465 hdmitx_wr_reg(HDMITX_DWC_A_VIDPOLCFG, data32);
4466
4467 hdmitx_wr_reg(HDMITX_DWC_A_OESSWCFG, 0x40);
4468 if (hdmitx_hdcp_opr(0xa))
4469 hdmitx_hdcp_opr(0);
4470 /* Interrupts */
4471 /* Clear interrupts */
4472 hdmitx_wr_reg(HDMITX_DWC_IH_FC_STAT0, 0xff);
4473 hdmitx_wr_reg(HDMITX_DWC_IH_FC_STAT1, 0xff);
4474 hdmitx_wr_reg(HDMITX_DWC_IH_FC_STAT2, 0xff);
4475 hdmitx_wr_reg(HDMITX_DWC_IH_AS_STAT0, 0xff);
4476 hdmitx_wr_reg(HDMITX_DWC_IH_PHY_STAT0, 0xff);
4477 hdmitx_wr_reg(HDMITX_DWC_IH_I2CM_STAT0, 0xff);
4478 hdmitx_wr_reg(HDMITX_DWC_IH_CEC_STAT0, 0xff);
4479 hdmitx_wr_reg(HDMITX_DWC_IH_VP_STAT0, 0xff);
4480 hdmitx_wr_reg(HDMITX_DWC_IH_I2CMPHY_STAT0, 0xff);
4481 hdmitx_wr_reg(HDMITX_DWC_A_APIINTCLR, 0xff);
4482 hdmitx_wr_reg(HDMITX_DWC_HDCP22REG_STAT, 0xff);
4483
4484 hdmitx_wr_reg(HDMITX_TOP_INTR_STAT_CLR, 0x0000001f);
4485
4486 /* Selectively enable/mute interrupt sources */
4487 data32 = 0;
4488 data32 |= (1 << 7);
4489 data32 |= (1 << 6);
4490 data32 |= (1 << 5);
4491 data32 |= (1 << 4);
4492 data32 |= (1 << 3);
4493 data32 |= (1 << 2);
4494 data32 |= (1 << 1);
4495 data32 |= (1 << 0);
4496 hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_FC_STAT0, data32);
4497
4498 data32 = 0;
4499 data32 |= (1 << 7);
4500 data32 |= (1 << 6);
4501 data32 |= (1 << 5);
4502 data32 |= (1 << 4);
4503 data32 |= (1 << 3);
4504 data32 |= (1 << 2);
4505 data32 |= (1 << 1);
4506 data32 |= (1 << 0);
4507 hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_FC_STAT1, data32);
4508
4509 data32 = 0;
4510 data32 |= (1 << 1);
4511 data32 |= (1 << 0);
4512 hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_FC_STAT2, data32);
4513
4514 data32 = 0;
4515 data32 |= (0 << 4);
4516 data32 |= (0 << 3);
4517 data32 |= (1 << 2);
4518 data32 |= (1 << 1);
4519 data32 |= (1 << 0);
4520 hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_AS_STAT0, data32);
4521
4522 hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_PHY_STAT0, 0x3f);
4523
4524 data32 = 0;
4525 data32 |= (0 << 2);
4526 data32 |= (1 << 1);
4527 data32 |= (0 << 0);
4528 hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_I2CM_STAT0, data32);
4529
4530 data32 = 0;
4531 data32 |= (0 << 6);
4532 data32 |= (0 << 5);
4533 data32 |= (0 << 4);
4534 data32 |= (0 << 3);
4535 data32 |= (0 << 2);
4536 data32 |= (0 << 1);
4537 data32 |= (0 << 0);
4538 hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_CEC_STAT0, data32);
4539
4540 hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_VP_STAT0, 0xff);
4541
4542 hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_I2CMPHY_STAT0, 0x03);
4543
4544 data32 = 0;
4545 data32 |= (0 << 1);
4546 data32 |= (0 << 0);
4547 hdmitx_wr_reg(HDMITX_DWC_IH_MUTE, data32);
4548
4549 data32 = 0;
4550 data32 |= (1 << 4);
4551 data32 |= (1 << 3);
4552 data32 |= (1 << 2);
4553 data32 |= (1 << 1);
4554 data32 |= (1 << 0);
4555 hdmitx_wr_reg(HDMITX_TOP_INTR_MASKN, data32);
4556
4557 /* Reset pulse */
4558 hdmitx_rd_check_reg(HDMITX_DWC_MC_LOCKONCLOCK, 0xff, 0x9f);
4559 hdmitx_wr_reg(HDMITX_DWC_MC_SWRSTZREQ, 0);
4560 mdelay(10);
4561
4562 data32 = 0;
4563 data32 |= (1 << 7);
4564 data32 |= (1 << 6);
4565 data32 |= (1 << 4);
4566 data32 |= (1 << 3);
4567 data32 |= (1 << 2);
4568 data32 |= (0 << 1);
4569 data32 |= (1 << 0);
4570 hdmitx_wr_reg(HDMITX_DWC_MC_SWRSTZREQ, data32);
4571 hdmitx_wr_reg(HDMITX_DWC_FC_VSYNCINWIDTH,
4572 hdmitx_rd_reg(HDMITX_DWC_FC_VSYNCINWIDTH));
4573} /* config_hdmi20_tx */
4574
4575/* TODO */
4576static void hdmitx_csc_config(unsigned char input_color_format,
4577 unsigned char output_color_format,
4578 unsigned char color_depth)
4579{
4580 unsigned char conv_en;
4581 unsigned char csc_scale;
4582 unsigned char rgb_ycc_indicator;
4583 unsigned long csc_coeff_a1, csc_coeff_a2, csc_coeff_a3, csc_coeff_a4;
4584 unsigned long csc_coeff_b1, csc_coeff_b2, csc_coeff_b3, csc_coeff_b4;
4585 unsigned long csc_coeff_c1, csc_coeff_c2, csc_coeff_c3, csc_coeff_c4;
4586 unsigned long data32;
4587
4588 conv_en = (((input_color_format == COLORSPACE_RGB444) ||
4589 (output_color_format == COLORSPACE_RGB444)) &&
4590 (input_color_format != output_color_format)) ? 1 : 0;
4591
4592 if (conv_en) {
4593 if (output_color_format == COLORSPACE_RGB444) {
4594 csc_coeff_a1 = 0x2000;
4595 csc_coeff_a2 = 0x6926;
4596 csc_coeff_a3 = 0x74fd;
4597 csc_coeff_a4 = (color_depth == COLORDEPTH_24B) ?
4598 0x010e :
4599 (color_depth == COLORDEPTH_30B) ? 0x043b :
4600 (color_depth == COLORDEPTH_36B) ? 0x10ee :
4601 (color_depth == COLORDEPTH_48B) ? 0x10ee : 0x010e;
4602 csc_coeff_b1 = 0x2000;
4603 csc_coeff_b2 = 0x2cdd;
4604 csc_coeff_b3 = 0x0000;
4605 csc_coeff_b4 = (color_depth == COLORDEPTH_24B) ? 0x7e9a :
4606 (color_depth == COLORDEPTH_30B) ? 0x7a65 :
4607 (color_depth == COLORDEPTH_36B) ? 0x6992 :
4608 (color_depth == COLORDEPTH_48B) ? 0x6992 : 0x7e9a;
4609 csc_coeff_c1 = 0x2000;
4610 csc_coeff_c2 = 0x0000;
4611 csc_coeff_c3 = 0x38b4;
4612 csc_coeff_c4 = (color_depth == COLORDEPTH_24B) ? 0x7e3b :
4613 (color_depth == COLORDEPTH_30B) ? 0x78ea :
4614 (color_depth == COLORDEPTH_36B) ? 0x63a6 :
4615 (color_depth == COLORDEPTH_48B) ? 0x63a6 : 0x7e3b;
4616 csc_scale = 1;
4617 } else { /* input_color_format == COLORSPACE_RGB444 */
4618 csc_coeff_a1 = 0x2591;
4619 csc_coeff_a2 = 0x1322;
4620 csc_coeff_a3 = 0x074b;
4621 csc_coeff_a4 = 0x0000;
4622 csc_coeff_b1 = 0x6535;
4623 csc_coeff_b2 = 0x2000;
4624 csc_coeff_b3 = 0x7acc;
4625 csc_coeff_b4 = (color_depth == COLORDEPTH_24B) ? 0x0200 :
4626 (color_depth == COLORDEPTH_30B) ? 0x0800 :
4627 (color_depth == COLORDEPTH_36B) ? 0x2000 :
4628 (color_depth == COLORDEPTH_48B) ? 0x2000 : 0x0200;
4629 csc_coeff_c1 = 0x6acd;
4630 csc_coeff_c2 = 0x7534;
4631 csc_coeff_c3 = 0x2000;
4632 csc_coeff_c4 = (color_depth == COLORDEPTH_24B) ? 0x0200 :
4633 (color_depth == COLORDEPTH_30B) ? 0x0800 :
4634 (color_depth == COLORDEPTH_36B) ? 0x2000 :
4635 (color_depth == COLORDEPTH_48B) ? 0x2000 : 0x0200;
4636 csc_scale = 0;
4637 }
4638 } else {
4639 csc_coeff_a1 = 0x2000;
4640 csc_coeff_a2 = 0x0000;
4641 csc_coeff_a3 = 0x0000;
4642 csc_coeff_a4 = 0x0000;
4643 csc_coeff_b1 = 0x0000;
4644 csc_coeff_b2 = 0x2000;
4645 csc_coeff_b3 = 0x0000;
4646 csc_coeff_b4 = 0x0000;
4647 csc_coeff_c1 = 0x0000;
4648 csc_coeff_c2 = 0x0000;
4649 csc_coeff_c3 = 0x2000;
4650 csc_coeff_c4 = 0x0000;
4651 csc_scale = 1;
4652 }
4653
4654 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_A1_MSB, (csc_coeff_a1>>8)&0xff);
4655 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_A1_LSB, csc_coeff_a1&0xff);
4656 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_A2_MSB, (csc_coeff_a2>>8)&0xff);
4657 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_A2_LSB, csc_coeff_a2&0xff);
4658 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_A3_MSB, (csc_coeff_a3>>8)&0xff);
4659 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_A3_LSB, csc_coeff_a3&0xff);
4660 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_A4_MSB, (csc_coeff_a4>>8)&0xff);
4661 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_A4_LSB, csc_coeff_a4&0xff);
4662 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_B1_MSB, (csc_coeff_b1>>8)&0xff);
4663 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_B1_LSB, csc_coeff_b1&0xff);
4664 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_B2_MSB, (csc_coeff_b2>>8)&0xff);
4665 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_B2_LSB, csc_coeff_b2&0xff);
4666 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_B3_MSB, (csc_coeff_b3>>8)&0xff);
4667 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_B3_LSB, csc_coeff_b3&0xff);
4668 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_B4_MSB, (csc_coeff_b4>>8)&0xff);
4669 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_B4_LSB, csc_coeff_b4&0xff);
4670 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_C1_MSB, (csc_coeff_c1>>8)&0xff);
4671 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_C1_LSB, csc_coeff_c1&0xff);
4672 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_C2_MSB, (csc_coeff_c2>>8)&0xff);
4673 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_C2_LSB, csc_coeff_c2&0xff);
4674 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_C3_MSB, (csc_coeff_c3>>8)&0xff);
4675 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_C3_LSB, csc_coeff_c3&0xff);
4676 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_C4_MSB, (csc_coeff_c4>>8)&0xff);
4677 hdmitx_wr_reg(HDMITX_DWC_CSC_COEF_C4_LSB, csc_coeff_c4&0xff);
4678
4679 data32 = 0;
4680 data32 |= (color_depth << 4); /* [7:4] csc_color_depth */
4681 data32 |= (csc_scale << 0); /* [1:0] cscscale */
4682 hdmitx_wr_reg(HDMITX_DWC_CSC_SCALE, data32);
4683
4684 /* set csc in video path */
4685 hdmitx_wr_reg(HDMITX_DWC_MC_FLOWCTRL, (conv_en == 1)?0x1:0x0);
4686
4687 /* set rgb_ycc indicator */
4688 switch (output_color_format) {
4689 case COLORSPACE_RGB444:
4690 rgb_ycc_indicator = 0x0;
4691 break;
4692 case COLORSPACE_YUV422:
4693 rgb_ycc_indicator = 0x1;
4694 break;
4695 case COLORSPACE_YUV420:
4696 rgb_ycc_indicator = 0x3;
4697 break;
4698 case COLORSPACE_YUV444:
4699 default:
4700 rgb_ycc_indicator = 0x2;
4701 break;
4702 }
4703 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF0,
4704 ((rgb_ycc_indicator & 0x4) >> 2), 7, 1);
4705 hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF0,
4706 (rgb_ycc_indicator & 0x3), 0, 2);
4707} /* hdmitx_csc_config */
4708
4709static void hdmitx_set_hw(struct hdmitx_dev *hdev)
4710{
4711 enum hdmi_vic vic = HDMI_Unknown;
4712 struct hdmi_format_para *para = NULL;
4713
4714 if (hdev->cur_video_param == NULL) {
4715 pr_info("error at null vidpara!\n");
4716 return;
4717 }
4718
4719 vic = (enum hdmi_vic)hdev->cur_video_param->VIC;
4720 para = hdmi_get_fmt_paras(vic);
4721 if (para == NULL) {
4722 pr_info("error at %s[%d] vic = %d\n", __func__, __LINE__, vic);
4723 return;
4724 }
4725
4726 config_hdmi20_tx(vic, hdev,
4727 hdev->para->cd,
4728 TX_INPUT_COLOR_FORMAT,
4729 hdev->para->cs);
4730}
4731