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