Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: drivers/media/video/samsung/tv20/hdmi_s5pv210.c

Issue 2036011: V4L/DVB : Add S5PV210 TV out driver support (Closed) Base URL: swsolcc@12.23.106.100:kernel-samsung.git
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « drivers/media/video/samsung/tv20/hdmi_param.h ('k') | drivers/media/video/samsung/tv20/hpd.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* linux/drivers/media/video/samsung/tv20/hdmi_s5pv210.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV210 - hdmi raw ftn file for Samsung TVOut driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/i2c.h>
16 #include <linux/platform_device.h>
17 #include <linux/clk.h>
18 #include <linux/interrupt.h>
19 #include <linux/delay.h>
20
21 #include <plat/clock.h>
22 #include <linux/io.h>
23
24 #include "tv_out_s5pv210.h"
25
26 #include <mach/regs-hdmi.h>
27
28 #include <mach/regs-clock.h>
29
30 #include "hdmi_param.h"
31
32 #ifdef CONFIG_TVOUT_RAW_DBG
33 #define S5P_HDMI_DEBUG 1
34 #endif
35
36 #ifdef S5P_HDMI_DEBUG
37 #define HDMIPRINTK(fmt, args...) \
38 printk(KERN_INFO "\t\t[HDMI] %s: " fmt, __func__ , ## args)
39 #else
40 #define HDMIPRINTK(fmt, args...)
41 #endif
42
43 static struct resource *hdmi_mem;
44 void __iomem *hdmi_base;
45
46 static struct resource *i2c_hdmi_phy_mem;
47 void __iomem *i2c_hdmi_phy_base;
48
49
50 spinlock_t lock_hdmi;
51
52 /*
53 * i2c_hdmi_phy related
54 */
55
56 #define PHY_I2C_ADDRESS 0x70
57
58 #define I2C_ACK (1<<7)
59 #define I2C_INT (1<<5)
60 #define I2C_PEND (1<<4)
61
62 #define I2C_INT_CLEAR (0<<4)
63
64 #define I2C_CLK (0x41)
65 #define I2C_CLK_PEND_INT (I2C_CLK|I2C_INT_CLEAR|I2C_INT)
66
67 #define I2C_ENABLE (1<<4)
68 #define I2C_START (1<<5)
69
70 #define I2C_MODE_MTX 0xC0
71 #define I2C_MODE_MRX 0x80
72
73 #define I2C_IDLE 0
74
75 static struct {
76 s32 state;
77 u8 *buffer;
78 s32 bytes;
79 } i2c_hdmi_phy_context;
80
81 enum i2c_hdmi_phy_state {
82 STATE_IDLE,
83 STATE_TX_EDDC_SEGADDR,
84 STATE_TX_EDDC_SEGNUM,
85 STATE_TX_DDC_ADDR,
86 STATE_TX_DDC_OFFSET,
87 STATE_RX_DDC_ADDR,
88 STATE_RX_DDC_DATA,
89 STATE_RX_ADDR,
90 STATE_RX_DATA,
91 STATE_TX_ADDR,
92 STATE_TX_DATA,
93 STATE_TX_STOP,
94 STATE_RX_STOP
95 };
96
97 static s32 i2c_hdmi_phy_interruptwait(void)
98 {
99 u8 status, reg;
100 s32 retval = 0;
101
102 do {
103 status = readb(i2c_hdmi_phy_base + I2C_HDMI_CON);
104
105 if (status & I2C_PEND) {
106 /* check status flags */
107 reg = readb(i2c_hdmi_phy_base + I2C_HDMI_STAT);
108 break;
109 }
110
111 } while (1);
112
113 return retval;
114 }
115
116 s32 i2c_hdmi_phy_read(u8 addr, u8 nbytes, u8 *buffer)
117 {
118 u8 reg;
119 s32 ret = 0;
120 u32 i, proc = true;
121
122 i2c_hdmi_phy_context.state = STATE_RX_ADDR;
123
124 i2c_hdmi_phy_context.buffer = buffer;
125 i2c_hdmi_phy_context.bytes = nbytes;
126
127 writeb(I2C_CLK | I2C_INT | I2C_ACK,
128 i2c_hdmi_phy_base + I2C_HDMI_CON);
129 writeb(I2C_ENABLE | I2C_MODE_MRX,
130 i2c_hdmi_phy_base + I2C_HDMI_STAT);
131 writeb(addr & 0xFE,
132 i2c_hdmi_phy_base + I2C_HDMI_DS);
133
134 writeb(I2C_ENABLE | I2C_START | I2C_MODE_MRX,
135 i2c_hdmi_phy_base + I2C_HDMI_STAT);
136
137 while (proc) {
138
139 if (i2c_hdmi_phy_context.state != STATE_RX_STOP) {
140 if (i2c_hdmi_phy_interruptwait() != 0) {
141 HDMIPRINTK("interrupt wait failed!!!\n");
142 ret = EINVAL;
143 break;
144 }
145
146 }
147
148 switch (i2c_hdmi_phy_context.state) {
149
150 case STATE_RX_DATA:
151
152 reg = readb(i2c_hdmi_phy_base + I2C_HDMI_DS);
153 *(i2c_hdmi_phy_context.buffer) = reg;
154
155 i2c_hdmi_phy_context.buffer++;
156 --(i2c_hdmi_phy_context.bytes);
157
158 if (i2c_hdmi_phy_context.bytes == 1) {
159 i2c_hdmi_phy_context.state = STATE_RX_STOP;
160 writeb(I2C_CLK_PEND_INT,
161 i2c_hdmi_phy_base + I2C_HDMI_CON);
162 } else {
163 writeb(I2C_CLK_PEND_INT | I2C_ACK,
164 i2c_hdmi_phy_base + I2C_HDMI_CON);
165
166 }
167 break;
168
169 case STATE_RX_ADDR:
170 i2c_hdmi_phy_context.state = STATE_RX_DATA;
171
172 if (i2c_hdmi_phy_context.bytes == 1) {
173 i2c_hdmi_phy_context.state = STATE_RX_STOP;
174 writeb(I2C_CLK_PEND_INT,
175 i2c_hdmi_phy_base + I2C_HDMI_CON);
176 } else {
177 writeb(I2C_CLK_PEND_INT | I2C_ACK,
178 i2c_hdmi_phy_base + I2C_HDMI_CON);
179 }
180
181 break;
182
183 case STATE_RX_STOP:
184
185 i2c_hdmi_phy_context.state = STATE_IDLE;
186
187 for (i = 0 ; i < 10000 ; i++)
188 ;
189 reg = readb(i2c_hdmi_phy_base + I2C_HDMI_DS);
190
191 *(i2c_hdmi_phy_context.buffer) = reg;
192
193 writeb(I2C_MODE_MRX|I2C_ENABLE,
194 i2c_hdmi_phy_base + I2C_HDMI_STAT);
195
196 writeb(I2C_CLK_PEND_INT,
197 i2c_hdmi_phy_base + I2C_HDMI_CON);
198
199 writeb(I2C_MODE_MRX, i2c_hdmi_phy_base + I2C_HDMI_STAT);
200
201 while (readb(i2c_hdmi_phy_base + I2C_HDMI_STAT) &
202 (1<<5))
203 ;
204 proc = false;
205
206 break;
207
208 case STATE_IDLE:
209
210 default:
211 HDMIPRINTK("error state!!!\n");
212
213 ret = EINVAL;
214
215 proc = false;
216
217 break;
218 }
219 }
220
221 return ret;
222 }
223
224 s32 i2c_hdmi_phy_write(u8 addr, u8 nbytes, u8 *buffer)
225 {
226 u8 reg;
227 s32 ret = 0;
228 u32 proc = true;
229
230 i2c_hdmi_phy_context.state = STATE_TX_ADDR;
231
232 i2c_hdmi_phy_context.buffer = buffer;
233 i2c_hdmi_phy_context.bytes = nbytes;
234
235 writeb(I2C_CLK | I2C_INT | I2C_ACK,
236 i2c_hdmi_phy_base + I2C_HDMI_CON);
237 writeb(I2C_ENABLE | I2C_MODE_MTX,
238 i2c_hdmi_phy_base + I2C_HDMI_STAT);
239 writeb(addr & 0xFE,
240 i2c_hdmi_phy_base + I2C_HDMI_DS);
241 writeb(I2C_ENABLE | I2C_START | I2C_MODE_MTX,
242 i2c_hdmi_phy_base + I2C_HDMI_STAT);
243
244 while (proc) {
245
246 if (i2c_hdmi_phy_interruptwait() != 0) {
247 HDMIPRINTK("interrupt wait failed!!!\n");
248 ret = EINVAL;
249 break;
250 }
251
252
253 switch (i2c_hdmi_phy_context.state) {
254
255 case STATE_TX_ADDR:
256 case STATE_TX_DATA:
257 i2c_hdmi_phy_context.state = STATE_TX_DATA;
258
259 reg = *(i2c_hdmi_phy_context.buffer);
260
261 writeb(reg, i2c_hdmi_phy_base + I2C_HDMI_DS);
262
263 i2c_hdmi_phy_context.buffer++;
264 --(i2c_hdmi_phy_context.bytes);
265
266 if (i2c_hdmi_phy_context.bytes == 0) {
267 i2c_hdmi_phy_context.state = STATE_TX_STOP;
268 writeb(I2C_CLK_PEND_INT,
269 i2c_hdmi_phy_base + I2C_HDMI_CON);
270 } else
271 writeb(I2C_CLK_PEND_INT | I2C_ACK,
272 i2c_hdmi_phy_base + I2C_HDMI_CON);
273 break;
274
275 case STATE_TX_STOP:
276 i2c_hdmi_phy_context.state = STATE_IDLE;
277
278 writeb(I2C_MODE_MTX | I2C_ENABLE,
279 i2c_hdmi_phy_base + I2C_HDMI_STAT);
280
281 writeb(I2C_CLK_PEND_INT,
282 i2c_hdmi_phy_base + I2C_HDMI_CON);
283
284 writeb(I2C_MODE_MTX, i2c_hdmi_phy_base + I2C_HDMI_STAT);
285
286 while (readb(i2c_hdmi_phy_base +
287 I2C_HDMI_STAT) & (1<<5))
288 ;
289
290 proc = false;
291
292 break;
293
294 case STATE_IDLE:
295 default:
296 HDMIPRINTK("error state!!!\n");
297
298 ret = EINVAL;
299
300 proc = false;
301
302 break;
303 }
304 }
305
306 return ret;
307 }
308
309 int hdmi_phy_down(bool on, u8 addr, u8 offset, u8 *read_buffer)
310 {
311 u8 buff[2] = {0};
312
313 buff[0] = addr;
314 buff[1] = (on) ? (read_buffer[addr] & (~(1<<offset))) :
315 (read_buffer[addr] | (1<<offset));
316
317 if (i2c_hdmi_phy_write(PHY_I2C_ADDRESS, 2, buff) != 0)
318 return EINVAL;
319
320 return 0;
321 }
322
323
324 int tv_hdmi_phy_power(bool on)
325 {
326 u32 size;
327 u8 *buffer;
328 u8 read_buffer[0x40] = {0, };
329
330 size = sizeof(phy_config[0][0])
331 / sizeof(phy_config[0][0][0]);
332
333 buffer = (u8 *) phy_config[0][0];
334
335 /* write offset */
336 if (i2c_hdmi_phy_write(PHY_I2C_ADDRESS, 1, buffer) != 0)
337 return EINVAL;
338
339 /* read data */
340 if (i2c_hdmi_phy_read(PHY_I2C_ADDRESS, size, read_buffer) != 0) {
341 HDMIPRINTK("i2c_hdmi_phy_read failed.\n");
342 return EINVAL;
343 }
344
345 /* i can't get the information about phy setting */
346 if (on) {
347 /* on */
348 /* biaspd */
349 hdmi_phy_down(true, 0x1, 0x5, read_buffer);
350 /* clockgenpd */
351 hdmi_phy_down(true, 0x1, 0x7, read_buffer);
352 /* pllpd */
353 hdmi_phy_down(true, 0x5, 0x5, read_buffer);
354 /* pcgpd */
355 hdmi_phy_down(true, 0x17, 0x0, read_buffer);
356 /* txpd */
357 hdmi_phy_down(true, 0x17, 0x1, read_buffer);
358 } else {
359 /* off */
360 /* biaspd */
361 hdmi_phy_down(false, 0x1, 0x5, read_buffer);
362 /* clockgenpd */
363 hdmi_phy_down(false, 0x1, 0x7, read_buffer);
364 /* pllpd */
365 hdmi_phy_down(false, 0x5, 0x5, read_buffer);
366 /* pcgpd */
367 hdmi_phy_down(false, 0x17, 0x0, read_buffer);
368 /* txpd */
369 hdmi_phy_down(false, 0x17, 0x1, read_buffer);
370 }
371
372 return 0;
373 }
374
375 s32 hdmi_corereset(void)
376 {
377 u32 i;
378
379 writeb(0x0, hdmi_base + S5P_HDMI_CTRL_CORE_RSTOUT);
380
381 for (i = 0 ; i < 1000 ; i++)
382 ;
383
384 writeb(0x1, hdmi_base + S5P_HDMI_CTRL_CORE_RSTOUT);
385
386 return 0;
387 }
388
389 s32 hdmi_phy_config(enum phy_freq freq, enum s5p_hdmi_color_depth cd)
390 {
391 s32 index;
392 s32 size;
393 u8 buffer[32] = {0, };
394 u8 reg;
395
396 switch (cd) {
397
398 case HDMI_CD_24:
399 index = 0;
400 break;
401
402 case HDMI_CD_30:
403 index = 1;
404 break;
405
406 case HDMI_CD_36:
407 index = 2;
408 break;
409
410 default:
411 return false;
412 }
413
414
415 /* i2c_hdmi init - set i2c filtering */
416 buffer[0] = PHY_REG_MODE_SET_DONE;
417 buffer[1] = 0x00;
418
419 if (i2c_hdmi_phy_write(PHY_I2C_ADDRESS, 2, buffer) != 0) {
420 HDMIPRINTK("i2c_hdmi_phy_write failed.\n");
421 return EINVAL;
422 }
423
424 writeb(0x5, i2c_hdmi_phy_base + I2C_HDMI_LC);
425
426 size = sizeof(phy_config[freq][index])
427 / sizeof(phy_config[freq][index][0]);
428
429 memcpy(buffer, phy_config[freq][index], sizeof(buffer));
430
431 if (i2c_hdmi_phy_write(PHY_I2C_ADDRESS, size, buffer) != 0)
432 return EINVAL;
433
434 /* write offset */
435 buffer[0] = 0x01;
436
437 if (i2c_hdmi_phy_write(PHY_I2C_ADDRESS, 1, buffer) != 0) {
438 HDMIPRINTK("i2c_hdmi_phy_write failed.\n");
439 return EINVAL;
440 }
441
442 #ifdef S5P_HDMI_DEBUG
443 {
444 int i = 0;
445 u8 read_buffer[0x40] = {0, };
446
447 /* read data */
448 if (i2c_hdmi_phy_read(PHY_I2C_ADDRESS, size, read_buffer) != 0) {
449 HDMIPRINTK("i2c_hdmi_phy_read failed.\n");
450 return EINVAL;
451 }
452
453 HDMIPRINTK("read buffer :\n\t\t");
454
455 for (i = 1; i < size; i++) {
456
457
458 printk("0x%02x", read_buffer[i]);
459
460 if (i % 8)
461 printk(" ");
462 else
463 printk("\n\t\t");
464 }
465 printk("\n");
466 }
467 #endif
468 hdmi_corereset();
469
470 do {
471 reg = readb(hdmi_base + HDMI_PHY_STATUS);
472 } while (!(reg & HDMI_PHY_READY));
473
474 writeb(I2C_CLK_PEND_INT, i2c_hdmi_phy_base + I2C_HDMI_CON);
475 /* disable */
476 writeb(I2C_IDLE, i2c_hdmi_phy_base + I2C_HDMI_STAT);
477
478 return 0;
479 }
480
481 s32 hdmi_set_tg(enum s5p_hdmi_v_fmt mode)
482 {
483 u16 temp_reg;
484 u8 tc_cmd;
485
486 temp_reg = hdmi_tg_param[mode].h_fsz;
487 writeb((u8)(temp_reg&0xff), hdmi_base + S5P_TG_H_FSZ_L);
488 writeb((u8)(temp_reg >> 8), hdmi_base + S5P_TG_H_FSZ_H);
489
490 /* set Horizontal Active Start Position */
491 temp_reg = hdmi_tg_param[mode].hact_st ;
492 writeb((u8)(temp_reg&0xff), hdmi_base + S5P_TG_HACT_ST_L);
493 writeb((u8)(temp_reg >> 8), hdmi_base + S5P_TG_HACT_ST_H);
494
495 /* set Horizontal Active Size */
496 temp_reg = hdmi_tg_param[mode].hact_sz ;
497 writeb((u8)(temp_reg&0xff), hdmi_base + S5P_TG_HACT_SZ_L);
498 writeb((u8)(temp_reg >> 8), hdmi_base + S5P_TG_HACT_SZ_H);
499
500 /* set Vertical Full Size */
501 temp_reg = hdmi_tg_param[mode].v_fsz ;
502 writeb((u8)(temp_reg&0xff), hdmi_base + S5P_TG_V_FSZ_L);
503 writeb((u8)(temp_reg >> 8), hdmi_base + S5P_TG_V_FSZ_H);
504
505 /* set VSYNC Position */
506 temp_reg = hdmi_tg_param[mode].vsync ;
507 writeb((u8)(temp_reg&0xff), hdmi_base + S5P_TG_VSYNC_L);
508 writeb((u8)(temp_reg >> 8), hdmi_base + S5P_TG_VSYNC_H);
509
510 /* set Bottom Field VSYNC Position */
511 temp_reg = hdmi_tg_param[mode].vsync2;
512 writeb((u8)(temp_reg&0xff), hdmi_base + S5P_TG_VSYNC2_L);
513 writeb((u8)(temp_reg >> 8), hdmi_base + S5P_TG_VSYNC2_H);
514
515 /* set Vertical Active Start Position */
516 temp_reg = hdmi_tg_param[mode].vact_st ;
517 writeb((u8)(temp_reg&0xff), hdmi_base + S5P_TG_VACT_ST_L);
518 writeb((u8)(temp_reg >> 8), hdmi_base + S5P_TG_VACT_ST_H);
519
520 /* set Vertical Active Size */
521 temp_reg = hdmi_tg_param[mode].vact_sz ;
522 writeb((u8)(temp_reg&0xff), hdmi_base + S5P_TG_VACT_SZ_L);
523 writeb((u8)(temp_reg >> 8), hdmi_base + S5P_TG_VACT_SZ_H);
524
525 /* set Field Change Position */
526 temp_reg = hdmi_tg_param[mode].field_chg ;
527 writeb((u8)(temp_reg&0xff), hdmi_base + S5P_TG_FIELD_CHG_L);
528 writeb((u8)(temp_reg >> 8), hdmi_base + S5P_TG_FIELD_CHG_H);
529
530 /* set Bottom Field Vertical Active Start Position */
531 temp_reg = hdmi_tg_param[mode].vact_st2;
532 writeb((u8)(temp_reg&0xff), hdmi_base + S5P_TG_VACT_ST2_L);
533 writeb((u8)(temp_reg >> 8), hdmi_base + S5P_TG_VACT_ST2_H);
534
535 /* set VSYNC Position for HDMI */
536 temp_reg = hdmi_tg_param[mode].vsync_top_hdmi;
537 writeb((u8)(temp_reg&0xff), hdmi_base + S5P_TG_VSYNC_TOP_HDMI_L);
538 writeb((u8)(temp_reg >> 8), hdmi_base + S5P_TG_VSYNC_TOP_HDMI_H);
539
540 /* set Bottom Field VSYNC Position */
541 temp_reg = hdmi_tg_param[mode].vsync_bot_hdmi;
542 writeb((u8)(temp_reg&0xff), hdmi_base + S5P_TG_VSYNC_BOT_HDMI_L);
543 writeb((u8)(temp_reg >> 8), hdmi_base + S5P_TG_VSYNC_BOT_HDMI_H);
544
545 /* set Top Field Change Position for HDMI */
546 temp_reg = hdmi_tg_param[mode].field_top_hdmi ;
547 writeb((u8)(temp_reg&0xff), hdmi_base + S5P_TG_FIELD_TOP_HDMI_L);
548 writeb((u8)(temp_reg >> 8), hdmi_base + S5P_TG_FIELD_TOP_HDMI_H);
549
550 /* set Bottom Field Change Position for HDMI */
551 temp_reg = hdmi_tg_param[mode].field_bot_hdmi;
552 writeb((u8)(temp_reg&0xff), hdmi_base + S5P_TG_FIELD_BOT_HDMI_L);
553 writeb((u8)(temp_reg >> 8), hdmi_base + S5P_TG_FIELD_BOT_HDMI_H);
554
555 tc_cmd = readb(hdmi_base + S5P_TG_CMD);
556
557 if (video_params[mode].interlaced == 1)
558 /* Field Mode enable(interlace mode) */
559 tc_cmd |= (1<<1);
560 else
561 /* Field Mode disable */
562 tc_cmd &= ~(1<<1);
563
564 writeb(tc_cmd, hdmi_base + S5P_TG_CMD);
565
566 return 0;
567 }
568
569 /**
570 * Set registers related to color depth.
571 */
572 static s32 hdmi_set_clr_depth(enum s5p_hdmi_color_depth cd)
573 {
574 /* if color depth is supported by RX, set GCP packet */
575 switch (cd) {
576
577 case HDMI_CD_48:
578 writeb(GCP_CD_48BPP, hdmi_base + S5P_GCP_BYTE2);
579 break;
580
581 case HDMI_CD_36:
582 writeb(GCP_CD_36BPP, hdmi_base + S5P_GCP_BYTE2);
583 /* set DC register */
584 writeb(HDMI_DC_CTL_12, hdmi_base + S5P_HDMI_DC_CONTROL);
585 break;
586
587 case HDMI_CD_30:
588 writeb(GCP_CD_30BPP, hdmi_base + S5P_GCP_BYTE2);
589 /* set DC register */
590 writeb(HDMI_DC_CTL_10, hdmi_base + S5P_HDMI_DC_CONTROL);
591 break;
592
593 case HDMI_CD_24:
594 writeb(GCP_CD_24BPP, hdmi_base + S5P_GCP_BYTE2);
595 /* set DC register */
596 writeb(HDMI_DC_CTL_8, hdmi_base + S5P_HDMI_DC_CONTROL);
597 /* disable GCP */
598 writeb(DO_NOT_TRANSMIT, hdmi_base + S5P_GCP_CON);
599 break;
600
601 default:
602 HDMIPRINTK(
603 "HDMI core does not support requested Deep Color mode\n");
604 return -EINVAL;
605 }
606
607 return 0;
608 }
609
610 s32 hdmi_set_video_mode(enum s5p_hdmi_v_fmt mode, enum s5p_hdmi_color_depth cd,
611 enum s5p_tv_hdmi_pxl_aspect pxl_ratio)
612 {
613 u8 temp_reg8;
614 u16 temp_reg16;
615 u32 temp_reg32, temp_sync2, temp_sync3;
616
617 /* check if HDMI code support that mode */
618 if (mode > (sizeof(video_params)/sizeof(struct hdmi_v_params)) ||
619 (s32)mode < 0) {
620 HDMIPRINTK("This video mode is not Supported\n");
621 return -EINVAL;
622 }
623
624 hdmi_set_tg(mode);
625
626 /* set HBlank */
627 temp_reg16 = video_params[mode].h_blank;
628 writeb((u8)(temp_reg16&0xff), hdmi_base + S5P_H_BLANK_0);
629 writeb((u8)(temp_reg16 >> 8), hdmi_base + S5P_H_BLANK_1);
630
631 /* set VBlank */
632 temp_reg32 = video_params[mode].v_blank;
633 writeb((u8)(temp_reg32&0xff), hdmi_base + S5P_V_BLANK_0);
634 writeb((u8)(temp_reg32 >> 8), hdmi_base + S5P_V_BLANK_1);
635 writeb((u8)(temp_reg32 >> 16), hdmi_base + S5P_V_BLANK_2);
636
637 /* set HVLine */
638 temp_reg32 = video_params[mode].hvline;
639 writeb((u8)(temp_reg32&0xff), hdmi_base + S5P_H_V_LINE_0);
640 writeb((u8)(temp_reg32 >> 8), hdmi_base + S5P_H_V_LINE_1);
641 writeb((u8)(temp_reg32 >> 16), hdmi_base + S5P_H_V_LINE_2);
642
643 /* set VSYNC polarity */
644 writeb(video_params[mode].polarity, hdmi_base + S5P_SYNC_MODE);
645
646 /* set HSyncGen */
647 temp_reg32 = video_params[mode].h_sync_gen;
648 writeb((u8)(temp_reg32&0xff), hdmi_base + S5P_H_SYNC_GEN_0);
649 writeb((u8)(temp_reg32 >> 8), hdmi_base + S5P_H_SYNC_GEN_1);
650 writeb((u8)(temp_reg32 >> 16), hdmi_base + S5P_H_SYNC_GEN_2);
651
652 /* set VSyncGen1 */
653 temp_reg32 = video_params[mode].v_sync_gen;
654 writeb((u8)(temp_reg32&0xff), hdmi_base + S5P_V_SYNC_GEN_1_0);
655 writeb((u8)(temp_reg32 >> 8), hdmi_base + S5P_V_SYNC_GEN_1_1);
656 writeb((u8)(temp_reg32 >> 16), hdmi_base + S5P_V_SYNC_GEN_1_2);
657
658 if (video_params[mode].interlaced) {
659 /* set up v_blank_f, v_sync_gen2, v_sync_gen3 */
660 temp_reg32 = video_params[mode].v_blank_f;
661 temp_sync2 = video_params[mode].v_sync_gen2;
662 temp_sync3 = video_params[mode].v_sync_gen3;
663
664 writeb((u8)(temp_reg32 & 0xff), hdmi_base + S5P_V_BLANK_F_0);
665 writeb((u8)(temp_reg32 >> 8), hdmi_base + S5P_V_BLANK_F_1);
666 writeb((u8)(temp_reg32 >> 16), hdmi_base + S5P_V_BLANK_F_2);
667
668 writeb((u8)(temp_sync2 & 0xff), hdmi_base + S5P_V_SYNC_GEN_2_0);
669 writeb((u8)(temp_sync2 >> 8), hdmi_base + S5P_V_SYNC_GEN_2_1);
670 writeb((u8)(temp_sync2 >> 16), hdmi_base + S5P_V_SYNC_GEN_2_2);
671
672 writeb((u8)(temp_sync3 & 0xff), hdmi_base + S5P_V_SYNC_GEN_3_0);
673 writeb((u8)(temp_sync3 >> 8), hdmi_base + S5P_V_SYNC_GEN_3_1);
674 writeb((u8)(temp_sync3 >> 16), hdmi_base + S5P_V_SYNC_GEN_3_2);
675 } else {
676 /* progressive mode */
677 writeb(0x00, hdmi_base + S5P_V_BLANK_F_0);
678 writeb(0x00, hdmi_base + S5P_V_BLANK_F_1);
679 writeb(0x00, hdmi_base + S5P_V_BLANK_F_2);
680
681 writeb(0x01, hdmi_base + S5P_V_SYNC_GEN_2_0);
682 writeb(0x10, hdmi_base + S5P_V_SYNC_GEN_2_1);
683 writeb(0x00, hdmi_base + S5P_V_SYNC_GEN_2_2);
684
685 writeb(0x01, hdmi_base + S5P_V_SYNC_GEN_3_0);
686 writeb(0x10, hdmi_base + S5P_V_SYNC_GEN_3_1);
687 writeb(0x00, hdmi_base + S5P_V_SYNC_GEN_3_2);
688 }
689
690 /* set interlaced mode */
691 writeb(video_params[mode].interlaced, hdmi_base + S5P_INT_PRO_MODE);
692
693 /* pixel repetition */
694 temp_reg8 = readb(hdmi_base + S5P_HDMI_CON_1);
695
696 /* clear */
697 temp_reg8 &= ~HDMI_CON_PXL_REP_RATIO_MASK;
698
699 if (video_params[mode].repetition) {
700 /* set pixel repetition */
701 temp_reg8 |= HDMI_DOUBLE_PIXEL_REPETITION;
702 /* AVI Packet */
703 writeb(AVI_PIXEL_REPETITION_DOUBLE, hdmi_base + S5P_AVI_BYTE5);
704 } else/* clear pixel repetition */
705 writeb(0x00, hdmi_base + S5P_AVI_BYTE5); /* AVI Packet */
706
707 /* set pixel repetition */
708 writeb(temp_reg8, hdmi_base + S5P_HDMI_CON_1);
709
710 /* set AVI packet VIC */
711 if (pxl_ratio == HDMI_PIXEL_RATIO_16_9)
712 writeb(video_params[mode].avi_vic_16_9,
713 hdmi_base + S5P_AVI_BYTE4);
714 else
715 writeb(video_params[mode].avi_vic,
716 hdmi_base + S5P_AVI_BYTE4);
717
718 /* clear */
719 temp_reg8 = readb(hdmi_base + S5P_AVI_BYTE2) &
720 ~(AVI_PICTURE_ASPECT_4_3 | AVI_PICTURE_ASPECT_16_9);
721
722 if (pxl_ratio == HDMI_PIXEL_RATIO_16_9)
723 temp_reg8 |= AVI_PICTURE_ASPECT_16_9;
724 else
725 temp_reg8 |= AVI_PICTURE_ASPECT_4_3;
726
727 /* set AVI packet MM */
728 writeb(temp_reg8, hdmi_base + S5P_AVI_BYTE2);
729
730 /* set color depth */
731 if (hdmi_set_clr_depth(cd) != 0) {
732 HDMIPRINTK("[ERR] Can't set hdmi clr. depth.\n");
733 return -EINVAL;
734 }
735
736 if (video_params[mode].interlaced == 1) {
737 u32 gcp_con;
738
739 gcp_con = readb(hdmi_base + S5P_GCP_CON);
740 gcp_con |= (3<<2);
741
742 writeb(gcp_con, hdmi_base + S5P_GCP_CON);
743 } else {
744 u32 gcp_con;
745
746 gcp_con = readb(hdmi_base + S5P_GCP_CON);
747 gcp_con &= (~(3<<2));
748
749 writeb(gcp_con, hdmi_base + S5P_GCP_CON);
750 }
751
752 return 0;
753 }
754
755
756 void tv_hdmi_set_hpd_onoff(bool on_off)
757 {
758 HDMIPRINTK("hpd is %s\n\r", on_off ? "on" : "off");
759
760 if (on_off)
761 writel(SW_HPD_PLUGGED, hdmi_base + S5P_HPD);
762 else
763 writel(SW_HPD_UNPLUGGED, hdmi_base + S5P_HPD);
764
765 HDMIPRINTK("0x%08x\n\r", readl(hdmi_base + S5P_HPD));
766 }
767
768
769 void tv_hdmi_audio_set_config(enum s5p_tv_audio_codec_type audio_codec)
770 {
771
772 u32 data_type = (audio_codec == PCM) ? CONFIG_LINEAR_PCM_TYPE :
773 (audio_codec == AC3) ?
774 CONFIG_NON_LINEAR_PCM_TYPE : 0xff;
775
776 HDMIPRINTK("audio codec type = %s\n\r",
777 (audio_codec&PCM) ? "PCM" :
778 (audio_codec&AC3) ? "AC3" :
779 (audio_codec&MP3) ? "MP3" :
780 (audio_codec&WMA) ? "WMA" : "Unknown");
781
782 /* open SPDIF path on HDMI_I2S */
783 writel(0x01, hdmi_base + S5P_HDMI_I2S_CLK_CON);
784 writel(readl(hdmi_base + S5P_HDMI_I2S_MUX_CON) | 0x11,
785 hdmi_base + S5P_HDMI_I2S_MUX_CON);
786 writel(0xFF, hdmi_base + S5P_HDMI_I2S_MUX_CH);
787 writel(0x03, hdmi_base + S5P_HDMI_I2S_MUX_CUV);
788
789 writel(CONFIG_FILTER_2_SAMPLE | data_type
790 | CONFIG_PCPD_MANUAL_SET | CONFIG_WORD_LENGTH_MANUAL_SET
791 | CONFIG_U_V_C_P_REPORT | CONFIG_BURST_SIZE_2
792 | CONFIG_DATA_ALIGN_32BIT
793 , hdmi_base + S5P_SPDIFIN_CONFIG_1);
794 writel(0, hdmi_base + S5P_SPDIFIN_CONFIG_2);
795 }
796
797 void tv_hdmi_audio_set_acr(u32 sample_rate)
798 {
799 u32 value_n = (sample_rate == 32000) ? 4096 :
800 (sample_rate == 44100) ? 6272 :
801 (sample_rate == 88200) ? 12544 :
802 (sample_rate == 176400) ? 25088 :
803 (sample_rate == 48000) ? 6144 :
804 (sample_rate == 96000) ? 12288 :
805 (sample_rate == 192000) ? 24576 : 0;
806
807 u32 cts = (sample_rate == 32000) ? 27000 :
808 (sample_rate == 44100) ? 30000 :
809 (sample_rate == 88200) ? 30000 :
810 (sample_rate == 176400) ? 30000 :
811 (sample_rate == 48000) ? 27000 :
812 (sample_rate == 96000) ? 27000 :
813 (sample_rate == 192000) ? 27000 : 0;
814
815 HDMIPRINTK("sample rate = %d\n\r", sample_rate);
816 HDMIPRINTK("cts = %d\n\r", cts);
817
818 writel(value_n & 0xff, hdmi_base + S5P_ACR_N0);
819 writel((value_n >> 8) & 0xff, hdmi_base + S5P_ACR_N1);
820 writel((value_n >> 16) & 0xff, hdmi_base + S5P_ACR_N2);
821
822 writel(cts & 0xff, hdmi_base + S5P_ACR_MCTS0);
823 writel((cts >> 8) & 0xff, hdmi_base + S5P_ACR_MCTS1);
824 writel((cts >> 16) & 0xff, hdmi_base + S5P_ACR_MCTS2);
825
826 writel(cts & 0xff, hdmi_base + S5P_ACR_CTS0);
827 writel((cts >> 8) & 0xff, hdmi_base + S5P_ACR_CTS1);
828 writel((cts >> 16) & 0xff, hdmi_base + S5P_ACR_CTS2);
829
830 writel(4, hdmi_base + S5P_ACR_CON); /* TO-DO : what it is? */
831 }
832
833 void tv_hdmi_audio_set_asp(void)
834 {
835 writel(0x0, hdmi_base + S5P_ASP_CON);
836 /* All Subpackets contain audio samples */
837 writel(0x0, hdmi_base + S5P_ASP_SP_FLAT);
838
839 writel(1 << 3 | 0, hdmi_base + S5P_ASP_CHCFG0);
840 writel(1 << 3 | 0, hdmi_base + S5P_ASP_CHCFG1);
841 writel(1 << 3 | 0, hdmi_base + S5P_ASP_CHCFG2);
842 writel(1 << 3 | 0, hdmi_base + S5P_ASP_CHCFG3);
843 }
844
845 void tv_hdmi_audio_clock_enable(void)
846 {
847 writel(0x1, hdmi_base + S5P_SPDIFIN_CLK_CTRL);
848 /* HDMI operation mode */
849 writel(0x3, hdmi_base + S5P_SPDIFIN_OP_CTRL);
850 }
851
852
853 void tv_hdmi_audio_set_repetition_time(enum s5p_tv_audio_codec_type audio_codec,
854 u32 bits, u32 frame_size_code)
855 {
856 /* Only 4'b1011 24bit */
857 u32 wl = 5 << 1 | 1;
858 u32 rpt_cnt = (audio_codec == AC3) ? 1536 * 2 - 1 : 0;
859
860 HDMIPRINTK("repetition count = %d\n\r", rpt_cnt);
861
862 /* 24bit and manual mode */
863 writel(((rpt_cnt&0xf) << 4) | wl, hdmi_base + S5P_SPDIFIN_USER_VALUE_1);
864 /* if PCM this value is 0 */
865 writel((rpt_cnt >> 4)&0xff, hdmi_base + S5P_SPDIFIN_USER_VALUE_2);
866 /* if PCM this value is 0 */
867 writel(frame_size_code&0xff, hdmi_base + S5P_SPDIFIN_USER_VALUE_3);
868 /* if PCM this value is 0 */
869 writel((frame_size_code >> 8)&0xff,
870 hdmi_base + S5P_SPDIFIN_USER_VALUE_4);
871 }
872
873 void tv_hdmi_audio_irq_enable(u32 irq_en)
874 {
875 writel(irq_en, hdmi_base + S5P_SPDIFIN_IRQ_MASK);
876 }
877
878
879 void tv_hdmi_audio_set_aui(enum s5p_tv_audio_codec_type audio_codec,
880 u32 sample_rate,
881 u32 bits)
882 {
883 u8 sum_of_bits, bytes1, bytes2, bytes3, check_sum;
884 u32 bit_rate;
885 /* Ac3 16bit only */
886 u32 bps = (audio_codec == PCM) ? bits : 16;
887
888 /* AUI Packet set. */
889 u32 type = (audio_codec == PCM) ? 1 : /* PCM */
890 (audio_codec == AC3) ? 2 : 0;
891 /* AC3 or Refer stream header */
892 u32 ch = (audio_codec == PCM) ? 1 : 0;
893 /* 2ch or refer to stream header */
894
895 u32 sample = (sample_rate == 32000) ? 1 :
896 (sample_rate == 44100) ? 2 :
897 (sample_rate == 48000) ? 3 :
898 (sample_rate == 88200) ? 4 :
899 (sample_rate == 96000) ? 5 :
900 (sample_rate == 176400) ? 6 :
901 (sample_rate == 192000) ? 7 : 0;
902
903 u32 bpsType = (bps == 16) ? 1 :
904 (bps == 20) ? 2 :
905 (bps == 24) ? 3 : 0;
906
907
908 bpsType = (audio_codec == PCM) ? bpsType : 0;
909
910 sum_of_bits = (0x84 + 0x1 + 10); /* header */
911
912 bytes1 = (u8)((type << 4) | ch);
913
914 bytes2 = (u8)((sample << 2) | bpsType);
915
916 bit_rate = 256; /* AC3 Test */
917
918 bytes3 = (audio_codec == PCM) ? (u8)0 : (u8)(bit_rate / 8) ;
919
920
921 sum_of_bits += (bytes1 + bytes2 + bytes3);
922 check_sum = 256 - sum_of_bits;
923
924 /* AUI Packet set. */
925 writel(check_sum , hdmi_base + S5P_AUI_CHECK_SUM);
926 writel(bytes1 , hdmi_base + S5P_AUI_BYTE1);
927 writel(bytes2 , hdmi_base + S5P_AUI_BYTE2);
928 writel(bytes3 , hdmi_base + S5P_AUI_BYTE3); /* Pcm or stream */
929 writel(0x00 , hdmi_base + S5P_AUI_BYTE4); /* 2ch pcm or Stream */
930 writel(0x00 , hdmi_base + S5P_AUI_BYTE5); /* 2ch pcm or Stream */
931
932
933 writel(2 , hdmi_base + S5P_ACP_CON);
934 writel(1 , hdmi_base + S5P_ACP_TYPE);
935
936 writel(0x10 , hdmi_base + S5P_GCP_BYTE1);
937
938 }
939
940 void tv_hdmi_video_set_bluescreen(bool en,
941 u8 cb_b,
942 u8 y_g,
943 u8 cr_r)
944 {
945 HDMIPRINTK("%d,%d,%d,%d\n\r", en, cb_b, y_g, cr_r);
946
947 if (en) {
948 writel(SET_BLUESCREEN_0(cb_b), hdmi_base + S5P_BLUE_SCREEN_0);
949 writel(SET_BLUESCREEN_1(y_g), hdmi_base + S5P_BLUE_SCREEN_1);
950 writel(SET_BLUESCREEN_2(cr_r), hdmi_base + S5P_BLUE_SCREEN_2);
951 writel(readl(hdmi_base + S5P_HDMI_CON_0) | BLUE_SCR_EN,
952 hdmi_base + S5P_HDMI_CON_0);
953
954 HDMIPRINTK("HDMI_BLUE_SCREEN0 = 0x%08x \n\r",
955 readl(hdmi_base + S5P_BLUE_SCREEN_0));
956 HDMIPRINTK("HDMI_BLUE_SCREEN1 = 0x%08x \n\r",
957 readl(hdmi_base + S5P_BLUE_SCREEN_1));
958 HDMIPRINTK("HDMI_BLUE_SCREEN2 = 0x%08x \n\r",
959 readl(hdmi_base + S5P_BLUE_SCREEN_2));
960 } else {
961 writel(readl(hdmi_base + S5P_HDMI_CON_0)&~BLUE_SCR_EN,
962 hdmi_base + S5P_HDMI_CON_0);
963 }
964
965 HDMIPRINTK("HDMI_CON0 = 0x%08x \n\r",
966 readl(hdmi_base + S5P_HDMI_CON_0));
967 }
968
969
970 enum s5p_tv_hdmi_err tv_hdmi_init_spd_infoframe(
971 enum s5p_hdmi_transmit trans_type,
972 u8 *spd_header,
973 u8 *spd_data)
974 {
975 HDMIPRINTK("%d,%d,%d\n\r", (u32)trans_type,
976 (u32)spd_header,
977 (u32)spd_data);
978
979 switch (trans_type) {
980
981 case HDMI_DO_NOT_TANS:
982 writel(SPD_TX_CON_NO_TRANS, hdmi_base + S5P_SPD_CON);
983 break;
984
985 case HDMI_TRANS_ONCE:
986 writel(SPD_TX_CON_TRANS_ONCE, hdmi_base + S5P_SPD_CON);
987 break;
988
989 case HDMI_TRANS_EVERY_SYNC:
990 writel(SPD_TX_CON_TRANS_EVERY_VSYNC, hdmi_base + S5P_SPD_CON);
991 break;
992
993 default:
994 HDMIPRINTK(" invalid out_mode parameter(%d)\n\r", trans_type);
995 return S5P_TV_HDMI_ERR_INVALID_PARAM;
996 }
997
998 writel(SET_SPD_HEADER(*(spd_header)), hdmi_base + S5P_SPD_HEADER0);
999
1000 writel(SET_SPD_HEADER(*(spd_header + 1)) , hdmi_base + S5P_SPD_HEADER1);
1001 writel(SET_SPD_HEADER(*(spd_header + 2)) , hdmi_base + S5P_SPD_HEADER2);
1002
1003 writel(SET_SPD_DATA(*(spd_data)), hdmi_base + S5P_SPD_DATA0);
1004 writel(SET_SPD_DATA(*(spd_data + 1)) , hdmi_base + S5P_SPD_DATA1);
1005 writel(SET_SPD_DATA(*(spd_data + 2)) , hdmi_base + S5P_SPD_DATA2);
1006 writel(SET_SPD_DATA(*(spd_data + 3)) , hdmi_base + S5P_SPD_DATA3);
1007 writel(SET_SPD_DATA(*(spd_data + 4)) , hdmi_base + S5P_SPD_DATA4);
1008 writel(SET_SPD_DATA(*(spd_data + 5)) , hdmi_base + S5P_SPD_DATA5);
1009 writel(SET_SPD_DATA(*(spd_data + 6)) , hdmi_base + S5P_SPD_DATA6);
1010 writel(SET_SPD_DATA(*(spd_data + 7)) , hdmi_base + S5P_SPD_DATA7);
1011 writel(SET_SPD_DATA(*(spd_data + 8)) , hdmi_base + S5P_SPD_DATA8);
1012 writel(SET_SPD_DATA(*(spd_data + 9)) , hdmi_base + S5P_SPD_DATA9);
1013 writel(SET_SPD_DATA(*(spd_data + 10)) , hdmi_base + S5P_SPD_DATA10);
1014 writel(SET_SPD_DATA(*(spd_data + 11)) , hdmi_base + S5P_SPD_DATA11);
1015 writel(SET_SPD_DATA(*(spd_data + 12)) , hdmi_base + S5P_SPD_DATA12);
1016 writel(SET_SPD_DATA(*(spd_data + 13)) , hdmi_base + S5P_SPD_DATA13);
1017 writel(SET_SPD_DATA(*(spd_data + 14)) , hdmi_base + S5P_SPD_DATA14);
1018 writel(SET_SPD_DATA(*(spd_data + 15)) , hdmi_base + S5P_SPD_DATA15);
1019 writel(SET_SPD_DATA(*(spd_data + 16)) , hdmi_base + S5P_SPD_DATA16);
1020 writel(SET_SPD_DATA(*(spd_data + 17)) , hdmi_base + S5P_SPD_DATA17);
1021 writel(SET_SPD_DATA(*(spd_data + 18)) , hdmi_base + S5P_SPD_DATA18);
1022 writel(SET_SPD_DATA(*(spd_data + 19)) , hdmi_base + S5P_SPD_DATA19);
1023 writel(SET_SPD_DATA(*(spd_data + 20)) , hdmi_base + S5P_SPD_DATA20);
1024 writel(SET_SPD_DATA(*(spd_data + 21)) , hdmi_base + S5P_SPD_DATA21);
1025 writel(SET_SPD_DATA(*(spd_data + 22)) , hdmi_base + S5P_SPD_DATA22);
1026 writel(SET_SPD_DATA(*(spd_data + 23)) , hdmi_base + S5P_SPD_DATA23);
1027 writel(SET_SPD_DATA(*(spd_data + 24)) , hdmi_base + S5P_SPD_DATA24);
1028 writel(SET_SPD_DATA(*(spd_data + 25)) , hdmi_base + S5P_SPD_DATA25);
1029 writel(SET_SPD_DATA(*(spd_data + 26)) , hdmi_base + S5P_SPD_DATA26);
1030 writel(SET_SPD_DATA(*(spd_data + 27)) , hdmi_base + S5P_SPD_DATA27);
1031
1032 HDMIPRINTK("SPD_CON = 0x%08x \n\r",
1033 readl(hdmi_base + S5P_SPD_CON));
1034 HDMIPRINTK("SPD_HEADER0 = 0x%08x \n\r",
1035 readl(hdmi_base + S5P_SPD_HEADER0));
1036 HDMIPRINTK("SPD_HEADER1 = 0x%08x \n\r",
1037 readl(hdmi_base + S5P_SPD_HEADER1));
1038 HDMIPRINTK("SPD_HEADER2 = 0x%08x \n\r",
1039 readl(hdmi_base + S5P_SPD_HEADER2));
1040 HDMIPRINTK("SPD_DATA0 = 0x%08x \n\r",
1041 readl(hdmi_base + S5P_SPD_DATA0));
1042 HDMIPRINTK("SPD_DATA1 = 0x%08x \n\r",
1043 readl(hdmi_base + S5P_SPD_DATA1));
1044 HDMIPRINTK("SPD_DATA2 = 0x%08x \n\r",
1045 readl(hdmi_base + S5P_SPD_DATA2));
1046 HDMIPRINTK("SPD_DATA3 = 0x%08x \n\r",
1047 readl(hdmi_base + S5P_SPD_DATA3));
1048 HDMIPRINTK("SPD_DATA4 = 0x%08x \n\r",
1049 readl(hdmi_base + S5P_SPD_DATA4));
1050 HDMIPRINTK("SPD_DATA5 = 0x%08x \n\r",
1051 readl(hdmi_base + S5P_SPD_DATA5));
1052 HDMIPRINTK("SPD_DATA6 = 0x%08x \n\r",
1053 readl(hdmi_base + S5P_SPD_DATA6));
1054 HDMIPRINTK("SPD_DATA7 = 0x%08x \n\r",
1055 readl(hdmi_base + S5P_SPD_DATA7));
1056 HDMIPRINTK("SPD_DATA8 = 0x%08x \n\r",
1057 readl(hdmi_base + S5P_SPD_DATA8));
1058 HDMIPRINTK("SPD_DATA9 = 0x%08x \n\r",
1059 readl(hdmi_base + S5P_SPD_DATA9));
1060 HDMIPRINTK("SPD_DATA10 = 0x%08x \n\r",
1061 readl(hdmi_base + S5P_SPD_DATA10));
1062 HDMIPRINTK("SPD_DATA11 = 0x%08x \n\r",
1063 readl(hdmi_base + S5P_SPD_DATA11));
1064 HDMIPRINTK("SPD_DATA12 = 0x%08x \n\r",
1065 readl(hdmi_base + S5P_SPD_DATA12));
1066 HDMIPRINTK("SPD_DATA13 = 0x%08x \n\r",
1067 readl(hdmi_base + S5P_SPD_DATA13));
1068 HDMIPRINTK("SPD_DATA14 = 0x%08x \n\r",
1069 readl(hdmi_base + S5P_SPD_DATA14));
1070 HDMIPRINTK("SPD_DATA15 = 0x%08x \n\r",
1071 readl(hdmi_base + S5P_SPD_DATA15));
1072 HDMIPRINTK("SPD_DATA16 = 0x%08x \n\r",
1073 readl(hdmi_base + S5P_SPD_DATA16));
1074 HDMIPRINTK("SPD_DATA17 = 0x%08x \n\r",
1075 readl(hdmi_base + S5P_SPD_DATA17));
1076 HDMIPRINTK("SPD_DATA18 = 0x%08x \n\r",
1077 readl(hdmi_base + S5P_SPD_DATA18));
1078 HDMIPRINTK("SPD_DATA19 = 0x%08x \n\r",
1079 readl(hdmi_base + S5P_SPD_DATA19));
1080 HDMIPRINTK("SPD_DATA20 = 0x%08x \n\r",
1081 readl(hdmi_base + S5P_SPD_DATA20));
1082 HDMIPRINTK("SPD_DATA21 = 0x%08x \n\r",
1083 readl(hdmi_base + S5P_SPD_DATA21));
1084 HDMIPRINTK("SPD_DATA22 = 0x%08x \n\r",
1085 readl(hdmi_base + S5P_SPD_DATA22));
1086 HDMIPRINTK("SPD_DATA23 = 0x%08x \n\r",
1087 readl(hdmi_base + S5P_SPD_DATA23));
1088 HDMIPRINTK("SPD_DATA24 = 0x%08x \n\r",
1089 readl(hdmi_base + S5P_SPD_DATA24));
1090 HDMIPRINTK("SPD_DATA25 = 0x%08x \n\r",
1091 readl(hdmi_base + S5P_SPD_DATA25));
1092 HDMIPRINTK("SPD_DATA26 = 0x%08x \n\r",
1093 readl(hdmi_base + S5P_SPD_DATA26));
1094 HDMIPRINTK("SPD_DATA27 = 0x%08x \n\r",
1095 readl(hdmi_base + S5P_SPD_DATA27));
1096
1097 return HDMI_NO_ERROR;
1098 }
1099
1100 void tv_hdmi_init_hpd_onoff(bool on_off)
1101 {
1102 HDMIPRINTK("%d\n\r", on_off);
1103 tv_hdmi_set_hpd_onoff(on_off);
1104 HDMIPRINTK("0x%08x\n\r", readl(hdmi_base + S5P_HPD));
1105 }
1106
1107 #ifndef CONFIG_SND_S5P_SPDIF
1108 static void tv_hdmi_audio_i2s_config(
1109 enum s5p_tv_audio_codec_type audio_codec,
1110 u32 sample_rate,
1111 u32 bits_per_sample,
1112 u32 frame_size_code)
1113 {
1114 u32 data_num, bit_ch, sample_frq;
1115
1116 if (bits_per_sample == 20) {
1117 data_num = 2;
1118 bit_ch = 1;
1119 } else if (bits_per_sample == 24) {
1120 data_num = 3;
1121 bit_ch = 1;
1122 } else { /* bits_per_sample == 16 or default */
1123 data_num = 1;
1124 bit_ch = 0;
1125 }
1126
1127 sample_frq = (sample_rate == 44100) ? 0 :
1128 (sample_rate == 48000) ? 2 :
1129 (sample_rate == 32000) ? 3 :
1130 (sample_rate == 96000) ? 0xa : 0x0;
1131
1132 /* readl(hdmi_base + S5P_HDMI_YMAX) */
1133 writel(0x00, hdmi_base + S5P_HDMI_I2S_CLK_CON);
1134 writel(0x01, hdmi_base + S5P_HDMI_I2S_CLK_CON);
1135
1136 writel(readl(hdmi_base + S5P_HDMI_I2S_DSD_CON) | 0x01,
1137 hdmi_base + S5P_HDMI_I2S_DSD_CON);
1138
1139 /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1140 writel((readl(hdmi_base + S5P_HDMI_I2S_PIN_SEL_0) &
1141 ~(7<<4 | 7<<0)) | (5<<4|6<<0),
1142 hdmi_base + S5P_HDMI_I2S_PIN_SEL_0);
1143 writel((readl(hdmi_base + S5P_HDMI_I2S_PIN_SEL_1) &
1144 ~(7<<4 | 7<<0)) | (1<<4|4<<0),
1145 hdmi_base + S5P_HDMI_I2S_PIN_SEL_1);
1146 writel((readl(hdmi_base + S5P_HDMI_I2S_PIN_SEL_2) &
1147 ~(7<<4 | 7<<0)) | (1<<4|2<<0),
1148 hdmi_base + S5P_HDMI_I2S_PIN_SEL_2);
1149 writel((readl(hdmi_base + S5P_HDMI_I2S_PIN_SEL_3) &
1150 ~(7<<0)) | (0<<0),
1151 hdmi_base + S5P_HDMI_I2S_PIN_SEL_3);
1152
1153 /* I2S_CON_1 & 2 */
1154 writel((readl(hdmi_base + S5P_HDMI_I2S_CON_1) &
1155 ~(1<<1 | 1<<0)) | (1<<1|0<<0),
1156 hdmi_base + S5P_HDMI_I2S_CON_1);
1157 writel((readl(hdmi_base + S5P_HDMI_I2S_CON_2) &
1158 ~(1<<6 | 3<<4 | 3<<2 | 3<<0))
1159 | (0<<6 | bit_ch<<4 | data_num<<2 | 0<<0),
1160 hdmi_base + S5P_HDMI_I2S_CON_2);
1161
1162 /* Configure register related to CUV information */
1163 writel((readl(hdmi_base + S5P_HDMI_I2S_CH_ST_0) &
1164 ~(3<<6 | 7<<3 | 1<<2 | 1<<1 | 1<<0))
1165 | (0<<6 | 0<<3 | 0<<2 | 0<<1 | 1<<0),
1166 hdmi_base + S5P_HDMI_I2S_CH_ST_0);
1167 writel((readl(hdmi_base + S5P_HDMI_I2S_CH_ST_1) &
1168 ~(0xff<<0)) | (0<<0),
1169 hdmi_base + S5P_HDMI_I2S_CH_ST_1);
1170 writel((readl(hdmi_base + S5P_HDMI_I2S_CH_ST_2) &
1171 ~(0xff<<0)) | (0<<0),
1172 hdmi_base + S5P_HDMI_I2S_CH_ST_2);
1173 writel((readl(hdmi_base + S5P_HDMI_I2S_CH_ST_3) &
1174 ~(3<<4 | 0xf<<0))
1175 | (1<<4 | sample_frq<<0),
1176 hdmi_base + S5P_HDMI_I2S_CH_ST_3);
1177 writel((readl(hdmi_base + S5P_HDMI_I2S_CH_ST_4) &
1178 ~(0xf<<4 | 7<<1 | 1<<0))
1179 | (0xf<<4 | 5<<1 | 1<<0),
1180 hdmi_base + S5P_HDMI_I2S_CH_ST_4);
1181
1182 writel(0x00, hdmi_base + S5P_HDMI_I2S_CH_ST_SH_0);
1183 writel(0x00, hdmi_base + S5P_HDMI_I2S_CH_ST_SH_1);
1184 writel(0x00, hdmi_base + S5P_HDMI_I2S_CH_ST_SH_2);
1185 writel(0x02, hdmi_base + S5P_HDMI_I2S_CH_ST_SH_3);
1186 writel(0x00, hdmi_base + S5P_HDMI_I2S_CH_ST_SH_4);
1187
1188 writel((readl(hdmi_base + S5P_HDMI_I2S_CH_ST_CON) &
1189 ~(1<<0)) | (1<<0),
1190 hdmi_base + S5P_HDMI_I2S_CH_ST_CON);
1191
1192 writel((readl(hdmi_base + S5P_HDMI_I2S_MUX_CON) &
1193 ~(1<<4 | 3<<2 | 1<<1 | 1<<0))
1194 | (1<<4 | 1<<2 | 1<<1 | 1<<0),
1195 hdmi_base + S5P_HDMI_I2S_MUX_CON);
1196
1197 writel((readl(hdmi_base + S5P_HDMI_I2S_MUX_CH) &
1198 ~(0xff<<0)) | (0x3f<<0),
1199 hdmi_base + S5P_HDMI_I2S_MUX_CH);
1200
1201 writel((readl(hdmi_base + S5P_HDMI_I2S_MUX_CUV) &
1202 ~(0x3<<0)) | (0x3<<0),
1203 hdmi_base + S5P_HDMI_I2S_MUX_CUV);
1204 }
1205 #endif
1206
1207 enum s5p_tv_hdmi_err tv_hdmi_audio_init(
1208 enum s5p_tv_audio_codec_type audio_codec,
1209 u32 sample_rate, u32 bits,
1210 u32 frame_size_code)
1211 {
1212 #ifdef CONFIG_SND_S5P_SPDIF
1213 tv_hdmi_audio_set_config(audio_codec);
1214 tv_hdmi_audio_set_repetition_time(audio_codec, bits,
1215 frame_size_code);
1216 tv_hdmi_audio_irq_enable(IRQ_BUFFER_OVERFLOW_ENABLE);
1217 tv_hdmi_audio_clock_enable();
1218 #else
1219 tv_hdmi_audio_i2s_config(audio_codec, sample_rate,
1220 bits, frame_size_code);
1221 #endif
1222 tv_hdmi_audio_set_asp();
1223 tv_hdmi_audio_set_acr(sample_rate);
1224
1225 tv_hdmi_audio_set_aui(audio_codec, sample_rate, bits);
1226
1227 return HDMI_NO_ERROR;
1228 }
1229
1230 enum s5p_tv_hdmi_err tv_hdmi_video_init_display_mode(
1231 enum s5p_tv_disp_mode disp_mode,
1232 enum s5p_tv_o_mode out_mode)
1233 {
1234 enum s5p_hdmi_v_fmt hdmi_v_fmt;
1235
1236 HDMIPRINTK("disp mode %d, output mode%d\n\r", disp_mode, out_mode);
1237
1238 switch (disp_mode) {
1239 /* 480p */
1240 case TVOUT_480P_60_16_9:
1241 case TVOUT_480P_60_4_3:
1242 hdmi_v_fmt = v720x480p_60Hz;
1243 break;
1244 case TVOUT_480P_59:
1245 hdmi_v_fmt = v720x480p_59Hz;
1246 break;
1247
1248 /* 576p */
1249 case TVOUT_576P_50_16_9:
1250 case TVOUT_576P_50_4_3:
1251 hdmi_v_fmt = v720x576p_50Hz;
1252 break;
1253
1254 /* 720p */
1255 case TVOUT_720P_60:
1256 hdmi_v_fmt = v1280x720p_60Hz;
1257 break;
1258
1259 case TVOUT_720P_59:
1260 hdmi_v_fmt = v1280x720p_59Hz;
1261 break;
1262
1263 case TVOUT_720P_50:
1264 hdmi_v_fmt = v1280x720p_50Hz;
1265 break;
1266
1267 /* 1080p */
1268 case TVOUT_1080P_30:
1269 hdmi_v_fmt = v1920x1080p_30Hz;
1270 break;
1271
1272 case TVOUT_1080P_60:
1273 hdmi_v_fmt = v1920x1080p_60Hz;
1274 break;
1275
1276 case TVOUT_1080P_59:
1277 hdmi_v_fmt = v1920x1080p_59Hz;
1278 break;
1279
1280 case TVOUT_1080P_50:
1281 hdmi_v_fmt = v1920x1080p_50Hz;
1282 break;
1283
1284 /* 1080i */
1285 case TVOUT_1080I_60:
1286 hdmi_v_fmt = v1920x1080i_60Hz;
1287 break;
1288
1289 case TVOUT_1080I_59:
1290 hdmi_v_fmt = v1920x1080i_59Hz;
1291 break;
1292
1293 case TVOUT_1080I_50:
1294 hdmi_v_fmt = v1920x1080i_50Hz;
1295 break;
1296
1297 default:
1298 HDMIPRINTK(" invalid disp_mode parameter(%d)\n\r", disp_mode);
1299 return S5P_TV_HDMI_ERR_INVALID_PARAM;
1300 }
1301
1302 if (hdmi_phy_config(video_params[hdmi_v_fmt].pixel_clock,
1303 HDMI_CD_24) == EINVAL) {
1304 HDMIPRINTK("[ERR] hdmi_phy_config() failed.\n");
1305 return EINVAL;
1306 }
1307
1308 switch (out_mode) {
1309 case TVOUT_OUTPUT_HDMI_RGB:
1310 writel(PX_LMT_CTRL_RGB, hdmi_base + S5P_HDMI_CON_1);
1311 writel(VID_PREAMBLE_EN | GUARD_BAND_EN,
1312 hdmi_base + S5P_HDMI_CON_2);
1313 writel(HDMI_MODE_EN | DVI_MODE_DIS, hdmi_base + S5P_MODE_SEL);
1314
1315 /* there's no ACP packet api */
1316 writel(HDMI_DO_NOT_TANS , hdmi_base + S5P_ACP_CON);
1317 writel(HDMI_TRANS_EVERY_SYNC , hdmi_base + S5P_AUI_CON);
1318 break;
1319
1320 case TVOUT_OUTPUT_HDMI:
1321 writel(PX_LMT_CTRL_BYPASS, hdmi_base + S5P_HDMI_CON_1);
1322 writel(VID_PREAMBLE_EN | GUARD_BAND_EN,
1323 hdmi_base + S5P_HDMI_CON_2);
1324 writel(HDMI_MODE_EN | DVI_MODE_DIS, hdmi_base + S5P_MODE_SEL);
1325
1326 /* there's no ACP packet api */
1327 writel(HDMI_DO_NOT_TANS , hdmi_base + S5P_ACP_CON);
1328 writel(HDMI_TRANS_EVERY_SYNC , hdmi_base + S5P_AUI_CON);
1329 break;
1330
1331 case TVOUT_OUTPUT_DVI:
1332 writel(PX_LMT_CTRL_RGB, hdmi_base + S5P_HDMI_CON_1);
1333 writel(VID_PREAMBLE_DIS | GUARD_BAND_DIS,
1334 hdmi_base + S5P_HDMI_CON_2);
1335 writel(HDMI_MODE_DIS | DVI_MODE_EN,
1336 hdmi_base + S5P_MODE_SEL);
1337
1338 /* disable ACP & Audio Info.frame packet */
1339 writel(HDMI_DO_NOT_TANS , hdmi_base + S5P_ACP_CON);
1340 writel(HDMI_DO_NOT_TANS , hdmi_base + S5P_AUI_CON);
1341 break;
1342
1343 default:
1344 HDMIPRINTK("invalid out_mode parameter(%d)\n\r", out_mode);
1345 return S5P_TV_HDMI_ERR_INVALID_PARAM;
1346 }
1347
1348 hdmi_set_video_mode(hdmi_v_fmt, HDMI_CD_24, HDMI_PIXEL_RATIO_16_9);
1349
1350 return HDMI_NO_ERROR;
1351 }
1352
1353 void tv_hdmi_video_init_bluescreen(bool en,
1354 u8 cb_b,
1355 u8 y_g,
1356 u8 cr_r)
1357 {
1358 tv_hdmi_video_set_bluescreen(en, cb_b, y_g, cr_r);
1359
1360 }
1361
1362 void tv_hdmi_video_init_color_range(u8 y_min,
1363 u8 y_max,
1364 u8 c_min,
1365 u8 c_max)
1366 {
1367 HDMIPRINTK("%d,%d,%d,%d\n\r", y_max, y_min, c_max, c_min);
1368
1369 writel(y_max, hdmi_base + S5P_HDMI_YMAX);
1370 writel(y_min, hdmi_base + S5P_HDMI_YMIN);
1371 writel(c_max, hdmi_base + S5P_HDMI_CMAX);
1372 writel(c_min, hdmi_base + S5P_HDMI_CMIN);
1373
1374 HDMIPRINTK("HDMI_YMAX = 0x%08x \n\r",
1375 readl(hdmi_base + S5P_HDMI_YMAX));
1376 HDMIPRINTK("HDMI_YMIN = 0x%08x \n\r",
1377 readl(hdmi_base + S5P_HDMI_YMIN));
1378 HDMIPRINTK("HDMI_CMAX = 0x%08x \n\r",
1379 readl(hdmi_base + S5P_HDMI_CMAX));
1380 HDMIPRINTK("HDMI_CMIN = 0x%08x \n\r",
1381 readl(hdmi_base + S5P_HDMI_CMIN));
1382 }
1383
1384 enum s5p_tv_hdmi_err tv_hdmi_video_init_csc(enum s5p_tv_hdmi_csc_type csc_type)
1385 {
1386 unsigned short us_csc_coeff[10];
1387
1388 HDMIPRINTK("%d)\n\r", csc_type);
1389
1390 switch (csc_type) {
1391
1392 case HDMI_CSC_YUV601_TO_RGB_LR:
1393 us_csc_coeff[0] = 0x23;
1394 us_csc_coeff[1] = 256;
1395 us_csc_coeff[2] = 938;
1396 us_csc_coeff[3] = 846;
1397 us_csc_coeff[4] = 256;
1398 us_csc_coeff[5] = 443;
1399 us_csc_coeff[6] = 0;
1400 us_csc_coeff[7] = 256;
1401 us_csc_coeff[8] = 0;
1402 us_csc_coeff[9] = 350;
1403 break;
1404
1405 case HDMI_CSC_YUV601_TO_RGB_FR:
1406 us_csc_coeff[0] = 0x03;
1407 us_csc_coeff[1] = 298;
1408 us_csc_coeff[2] = 924;
1409 us_csc_coeff[3] = 816;
1410 us_csc_coeff[4] = 298;
1411 us_csc_coeff[5] = 516;
1412 us_csc_coeff[6] = 0;
1413 us_csc_coeff[7] = 298;
1414 us_csc_coeff[8] = 0;
1415 us_csc_coeff[9] = 408;
1416 break;
1417
1418 case HDMI_CSC_YUV709_TO_RGB_LR:
1419 us_csc_coeff[0] = 0x23;
1420 us_csc_coeff[1] = 256;
1421 us_csc_coeff[2] = 978;
1422 us_csc_coeff[3] = 907;
1423 us_csc_coeff[4] = 256;
1424 us_csc_coeff[5] = 464;
1425 us_csc_coeff[6] = 0;
1426 us_csc_coeff[7] = 256;
1427 us_csc_coeff[8] = 0;
1428 us_csc_coeff[9] = 394;
1429 break;
1430
1431 case HDMI_CSC_YUV709_TO_RGB_FR:
1432 us_csc_coeff[0] = 0x03;
1433 us_csc_coeff[1] = 298;
1434 us_csc_coeff[2] = 970;
1435 us_csc_coeff[3] = 888;
1436 us_csc_coeff[4] = 298;
1437 us_csc_coeff[5] = 540;
1438 us_csc_coeff[6] = 0;
1439 us_csc_coeff[7] = 298;
1440 us_csc_coeff[8] = 0;
1441 us_csc_coeff[9] = 458;
1442 break;
1443
1444 case HDMI_CSC_YUV601_TO_YUV709:
1445 us_csc_coeff[0] = 0x33;
1446 us_csc_coeff[1] = 256;
1447 us_csc_coeff[2] = 995;
1448 us_csc_coeff[3] = 971;
1449 us_csc_coeff[4] = 0;
1450 us_csc_coeff[5] = 260;
1451 us_csc_coeff[6] = 29;
1452 us_csc_coeff[7] = 0;
1453 us_csc_coeff[8] = 19;
1454 us_csc_coeff[9] = 262;
1455 break;
1456
1457 case HDMI_CSC_RGB_FR_TO_RGB_LR:
1458 us_csc_coeff[0] = 0x20;
1459 us_csc_coeff[1] = 220;
1460 us_csc_coeff[2] = 0;
1461 us_csc_coeff[3] = 0;
1462 us_csc_coeff[4] = 0;
1463 us_csc_coeff[5] = 220;
1464 us_csc_coeff[6] = 0;
1465 us_csc_coeff[7] = 0;
1466 us_csc_coeff[8] = 0;
1467 us_csc_coeff[9] = 220;
1468 break;
1469
1470 case HDMI_CSC_RGB_FR_TO_YUV601:
1471 us_csc_coeff[0] = 0x30;
1472 us_csc_coeff[1] = 129;
1473 us_csc_coeff[2] = 25;
1474 us_csc_coeff[3] = 65;
1475 us_csc_coeff[4] = 950; /* -74 */
1476 us_csc_coeff[5] = 112;
1477 us_csc_coeff[6] = 986; /* -38 */
1478 us_csc_coeff[7] = 930; /* -94 */
1479 us_csc_coeff[8] = 1006; /* -18 */
1480 us_csc_coeff[9] = 112;
1481 break;
1482
1483 case HDMI_CSC_RGB_FR_TO_YUV709:
1484 us_csc_coeff[0] = 0x30;
1485 us_csc_coeff[1] = 157;
1486 us_csc_coeff[2] = 16;
1487 us_csc_coeff[3] = 47;
1488 us_csc_coeff[4] = 937; /* -87 */
1489 us_csc_coeff[5] = 112;
1490 us_csc_coeff[6] = 999; /* -25 */
1491 us_csc_coeff[7] = 922; /* -102 */
1492 us_csc_coeff[8] = 1014; /* -10 */
1493 us_csc_coeff[9] = 112;
1494 break;
1495
1496 case HDMI_BYPASS:
1497 us_csc_coeff[0] = 0x33;
1498 us_csc_coeff[1] = 256;
1499 us_csc_coeff[2] = 0;
1500 us_csc_coeff[3] = 0;
1501 us_csc_coeff[4] = 0;
1502 us_csc_coeff[5] = 256;
1503 us_csc_coeff[6] = 0;
1504 us_csc_coeff[7] = 0;
1505 us_csc_coeff[8] = 0;
1506 us_csc_coeff[9] = 256;
1507 break;
1508
1509 default:
1510 HDMIPRINTK("invalid out_mode parameter(%d)\n\r", csc_type);
1511 return S5P_TV_HDMI_ERR_INVALID_PARAM;
1512 }
1513
1514 return HDMI_NO_ERROR;
1515 }
1516
1517 enum s5p_tv_hdmi_err tv_hdmi_video_init_avi_infoframe(
1518 enum s5p_hdmi_transmit trans_type,
1519 u8 check_sum,
1520 u8 *avi_data)
1521 {
1522 HDMIPRINTK("%d,%d,%d\n\r",
1523 (u32)trans_type, (u32)check_sum, (u32)avi_data);
1524
1525 switch (trans_type) {
1526
1527 case HDMI_DO_NOT_TANS:
1528 writel(AVI_TX_CON_NO_TRANS, hdmi_base + S5P_AVI_CON);
1529 break;
1530
1531 case HDMI_TRANS_ONCE:
1532 writel(AVI_TX_CON_TRANS_ONCE, hdmi_base + S5P_AVI_CON);
1533 break;
1534
1535 case HDMI_TRANS_EVERY_SYNC:
1536 writel(AVI_TX_CON_TRANS_EVERY_VSYNC, hdmi_base + S5P_AVI_CON);
1537 break;
1538
1539 default:
1540 HDMIPRINTK(" invalid out_mode parameter(%d)\n\r", trans_type);
1541 return S5P_TV_HDMI_ERR_INVALID_PARAM;
1542 }
1543
1544 writel(SET_AVI_CHECK_SUM(check_sum), hdmi_base + S5P_AVI_CHECK_SUM);
1545
1546 writel(SET_AVI_BYTE(*(avi_data)), hdmi_base + S5P_AVI_BYTE1);
1547 writel(SET_AVI_BYTE(*(avi_data + 1)), hdmi_base + S5P_AVI_BYTE2);
1548 writel(SET_AVI_BYTE(*(avi_data + 2)), hdmi_base + S5P_AVI_BYTE3);
1549 writel(SET_AVI_BYTE(*(avi_data + 3)), hdmi_base + S5P_AVI_BYTE4);
1550 writel(SET_AVI_BYTE(*(avi_data + 4)), hdmi_base + S5P_AVI_BYTE5);
1551 writel(SET_AVI_BYTE(*(avi_data + 5)), hdmi_base + S5P_AVI_BYTE6);
1552 writel(SET_AVI_BYTE(*(avi_data + 6)), hdmi_base + S5P_AVI_BYTE7);
1553 writel(SET_AVI_BYTE(*(avi_data + 7)), hdmi_base + S5P_AVI_BYTE8);
1554 writel(SET_AVI_BYTE(*(avi_data + 8)), hdmi_base + S5P_AVI_BYTE9);
1555 writel(SET_AVI_BYTE(*(avi_data + 9)), hdmi_base + S5P_AVI_BYTE10);
1556 writel(SET_AVI_BYTE(*(avi_data + 10)), hdmi_base + S5P_AVI_BYTE11);
1557 writel(SET_AVI_BYTE(*(avi_data + 11)), hdmi_base + S5P_AVI_BYTE12);
1558 writel(SET_AVI_BYTE(*(avi_data + 12)), hdmi_base + S5P_AVI_BYTE13);
1559
1560 HDMIPRINTK("AVI_CON = 0x%08x \n\r", readl(hdmi_base + S5P_AVI_CON));
1561 HDMIPRINTK("AVI_CHECK_SUM = 0x%08x \n\r",
1562 readl(hdmi_base + S5P_AVI_CHECK_SUM));
1563 HDMIPRINTK("AVI_BYTE1 = 0x%08x \n\r",
1564 readl(hdmi_base + S5P_AVI_BYTE1));
1565 HDMIPRINTK("AVI_BYTE2 = 0x%08x \n\r",
1566 readl(hdmi_base + S5P_AVI_BYTE2));
1567 HDMIPRINTK("AVI_BYTE3 = 0x%08x \n\r",
1568 readl(hdmi_base + S5P_AVI_BYTE3));
1569 HDMIPRINTK("AVI_BYTE4 = 0x%08x \n\r",
1570 readl(hdmi_base + S5P_AVI_BYTE4));
1571 HDMIPRINTK("AVI_BYTE5 = 0x%08x \n\r",
1572 readl(hdmi_base + S5P_AVI_BYTE5));
1573 HDMIPRINTK("AVI_BYTE6 = 0x%08x \n\r",
1574 readl(hdmi_base + S5P_AVI_BYTE6));
1575 HDMIPRINTK("AVI_BYTE7 = 0x%08x \n\r",
1576 readl(hdmi_base + S5P_AVI_BYTE7));
1577 HDMIPRINTK("AVI_BYTE8 = 0x%08x \n\r",
1578 readl(hdmi_base + S5P_AVI_BYTE8));
1579 HDMIPRINTK("AVI_BYTE9 = 0x%08x \n\r",
1580 readl(hdmi_base + S5P_AVI_BYTE9));
1581 HDMIPRINTK("AVI_BYTE10 = 0x%08x \n\r",
1582 readl(hdmi_base + S5P_AVI_BYTE10));
1583 HDMIPRINTK("AVI_BYTE11 = 0x%08x \n\r",
1584 readl(hdmi_base + S5P_AVI_BYTE11));
1585 HDMIPRINTK("AVI_BYTE12 = 0x%08x \n\r",
1586 readl(hdmi_base + S5P_AVI_BYTE12));
1587 HDMIPRINTK("AVI_BYTE13 = 0x%08x \n\r",
1588 readl(hdmi_base + S5P_AVI_BYTE13));
1589
1590 return HDMI_NO_ERROR;
1591 }
1592
1593 enum s5p_tv_hdmi_err tv_hdmi_video_init_mpg_infoframe(
1594 enum s5p_hdmi_transmit trans_type,
1595 u8 check_sum,
1596 u8 *mpg_data)
1597 {
1598 HDMIPRINTK("trans_type : %d,%d,%d\n\r", (u32)trans_type,
1599 (u32)check_sum, (u32)mpg_data);
1600
1601 switch (trans_type) {
1602
1603 case HDMI_DO_NOT_TANS:
1604 writel(MPG_TX_CON_NO_TRANS,
1605 hdmi_base + S5P_MPG_CON);
1606 break;
1607
1608 case HDMI_TRANS_ONCE:
1609 writel(MPG_TX_CON_TRANS_ONCE,
1610 hdmi_base + S5P_MPG_CON);
1611 break;
1612
1613 case HDMI_TRANS_EVERY_SYNC:
1614 writel(MPG_TX_CON_TRANS_EVERY_VSYNC,
1615 hdmi_base + S5P_MPG_CON);
1616 break;
1617
1618 default:
1619 HDMIPRINTK("invalid out_mode parameter(%d)\n\r",
1620 trans_type);
1621 return S5P_TV_HDMI_ERR_INVALID_PARAM;
1622 }
1623
1624 writel(SET_MPG_CHECK_SUM(check_sum),
1625
1626 hdmi_base + S5P_MPG_CHECK_SUM);
1627
1628 writel(SET_MPG_BYTE(*(mpg_data)),
1629 hdmi_base + S5P_MPEG_BYTE1);
1630 writel(SET_MPG_BYTE(*(mpg_data + 1)),
1631 hdmi_base + S5P_MPEG_BYTE2);
1632 writel(SET_MPG_BYTE(*(mpg_data + 2)),
1633 hdmi_base + S5P_MPEG_BYTE3);
1634 writel(SET_MPG_BYTE(*(mpg_data + 3)),
1635 hdmi_base + S5P_MPEG_BYTE4);
1636 writel(SET_MPG_BYTE(*(mpg_data + 4)),
1637 hdmi_base + S5P_MPEG_BYTE5);
1638
1639 HDMIPRINTK("MPG_CON = 0x%08x \n\r",
1640 readl(hdmi_base + S5P_MPG_CON));
1641 HDMIPRINTK("MPG_CHECK_SUM = 0x%08x \n\r",
1642 readl(hdmi_base + S5P_MPG_CHECK_SUM));
1643 HDMIPRINTK("MPEG_BYTE1 = 0x%08x \n\r",
1644 readl(hdmi_base + S5P_MPEG_BYTE1));
1645 HDMIPRINTK("MPEG_BYTE2 = 0x%08x \n\r",
1646 readl(hdmi_base + S5P_MPEG_BYTE2));
1647 HDMIPRINTK("MPEG_BYTE3 = 0x%08x \n\r",
1648 readl(hdmi_base + S5P_MPEG_BYTE3));
1649 HDMIPRINTK("MPEG_BYTE4 = 0x%08x \n\r",
1650 readl(hdmi_base + S5P_MPEG_BYTE4));
1651 HDMIPRINTK("MPEG_BYTE5 = 0x%08x \n\r",
1652 readl(hdmi_base + S5P_MPEG_BYTE5));
1653
1654 return HDMI_NO_ERROR;
1655 }
1656
1657 void tv_hdmi_video_init_tg_cmd(bool time_c_e,
1658 bool bt656_sync_en,
1659 bool tg_en)
1660 {
1661 u32 temp_reg = 0;
1662
1663 temp_reg = readl(hdmi_base + S5P_TG_CMD);
1664
1665 if (time_c_e)
1666 temp_reg |= GETSYNC_TYPE_EN;
1667 else
1668 temp_reg &= GETSYNC_TYPE_DIS;
1669
1670 if (bt656_sync_en)
1671 temp_reg |= GETSYNC_EN;
1672 else
1673 temp_reg &= GETSYNC_DIS;
1674
1675 if (tg_en)
1676 temp_reg |= TG_EN;
1677 else
1678 temp_reg &= TG_DIS;
1679
1680 writel(temp_reg, hdmi_base + S5P_TG_CMD);
1681
1682 HDMIPRINTK("TG_CMD = 0x%08x \n\r", readl(hdmi_base + S5P_TG_CMD));
1683 }
1684
1685
1686 bool tv_hdmi_start(enum s5p_hdmi_audio_type hdmi_audio_type,
1687 bool hdcp_en,
1688 struct i2c_client *ddc_port)
1689 {
1690 u32 temp_reg = HDMI_EN;
1691
1692 HDMIPRINTK("aud type : %d, hdcp enable : %d\n\r",
1693 hdmi_audio_type, hdcp_en);
1694
1695 switch (hdmi_audio_type) {
1696
1697 case HDMI_AUDIO_PCM:
1698 temp_reg |= ASP_EN;
1699 break;
1700
1701 case HDMI_AUDIO_NO:
1702 break;
1703
1704 default:
1705 HDMIPRINTK(" invalid hdmi_audio_type(%d)\n\r",
1706 hdmi_audio_type);
1707 return false;
1708 }
1709
1710 writel(readl(hdmi_base + S5P_HDMI_CON_0) | temp_reg,
1711 hdmi_base + S5P_HDMI_CON_0);
1712
1713 if (hdcp_en) {
1714 if (!tv_start_hdcp())
1715 HDMIPRINTK("HDCP start failed\n");
1716 }
1717
1718 HDMIPRINTK("HPD : 0x%08x, HDMI_CON_0 : 0x%08x\n\r",
1719 readl(hdmi_base + S5P_HPD),
1720 readl(hdmi_base + S5P_HDMI_CON_0));
1721
1722 return true;
1723 }
1724
1725
1726
1727 /*
1728 * stop - stop functions are only called under running HDMI
1729 */
1730 void tv_hdmi_stop(void)
1731 {
1732 u32 temp = 0, result = 0;
1733 HDMIPRINTK("\n\r");
1734
1735 tv_stop_hdcp();
1736
1737 /*
1738 * Before stopping hdmi, stop the hdcp first. However,
1739 * if there's no delay between hdcp stop & hdmi stop,
1740 * re-opening would be failed.
1741 */
1742 mdelay(100);
1743
1744 temp = readl(hdmi_base + S5P_HDMI_CON_0);
1745 result = temp & HDMI_EN;
1746
1747 if (result)
1748 writel(temp & ~(HDMI_EN | ASP_EN),
1749 hdmi_base + S5P_HDMI_CON_0);
1750
1751 do {
1752 temp = readl(hdmi_base + S5P_HDMI_CON_0);
1753 } while (temp & HDMI_EN);
1754
1755 HDMIPRINTK("HPD 0x%08x,HDMI_CON_0 0x%08x\n\r",
1756 readl(hdmi_base + S5P_HPD),
1757 readl(hdmi_base + S5P_HDMI_CON_0));
1758 }
1759
1760 int __init tv_hdmi_probe(struct platform_device *pdev,
1761 u32 res_num, u32 res_num2)
1762 {
1763 struct resource *res;
1764 size_t size;
1765 u32 reg;
1766
1767 spin_lock_init(&lock_hdmi);
1768
1769 res = platform_get_resource(pdev, IORESOURCE_MEM, res_num);
1770
1771 if (res == NULL) {
1772 dev_err(&pdev->dev,
1773 "failed to get memory region resource\n");
1774 goto error;
1775 }
1776
1777 size = (res->end - res->start) + 1;
1778
1779 hdmi_mem = request_mem_region(res->start, size, pdev->name);
1780
1781 if (hdmi_mem == NULL) {
1782 dev_err(&pdev->dev,
1783 "failed to get memory region\n");
1784 goto error;
1785 }
1786
1787 hdmi_base = ioremap(res->start, size);
1788
1789 if (hdmi_base == NULL) {
1790 dev_err(&pdev->dev,
1791 "failed to ioremap address region\n");
1792 goto error;
1793 }
1794
1795 res = platform_get_resource(pdev, IORESOURCE_MEM, res_num2);
1796
1797 if (res == NULL) {
1798 dev_err(&pdev->dev,
1799 "failed to get memory region resource\n");
1800 goto error;
1801 }
1802
1803 size = (res->end - res->start) + 1;
1804
1805 i2c_hdmi_phy_mem = request_mem_region(res->start, size, pdev->name);
1806
1807 if (i2c_hdmi_phy_mem == NULL) {
1808 dev_err(&pdev->dev,
1809 "failed to get memory region\n");
1810 goto error;
1811 }
1812
1813 i2c_hdmi_phy_base = ioremap(res->start, size);
1814
1815 if (i2c_hdmi_phy_base == NULL) {
1816 dev_err(&pdev->dev,
1817 "failed to ioremap address region\n");
1818 goto error;
1819 }
1820
1821 /* PMU Block : HDMI PHY Enable */
1822 reg = readl(S3C_VA_SYS+0xE804);
1823 reg |= (1<<0);
1824 writel(reg, S3C_VA_SYS+0xE804);
1825
1826 /* i2c_hdmi init - set i2c filtering */
1827 writeb(0x5, i2c_hdmi_phy_base + I2C_HDMI_LC);
1828
1829 /* temp for test - hdmi intr. global enable */
1830 reg = readb(hdmi_base+S5P_HDMI_CTRL_INTC_CON);
1831 writeb(reg | (1<<HDMI_IRQ_GLOBAL), hdmi_base+S5P_HDMI_CTRL_INTC_CON);
1832
1833 return 0;
1834 error:
1835 return -ENOENT;
1836
1837 }
1838
1839 int __init tv_hdmi_release(struct platform_device *pdev)
1840 {
1841 iounmap(hdmi_base);
1842
1843 /* remove memory region */
1844 if (hdmi_mem != NULL) {
1845 if (release_resource(hdmi_mem))
1846 dev_err(&pdev->dev,
1847 "Can't remove tvout drv !!\n");
1848
1849 kfree(hdmi_mem);
1850
1851 hdmi_mem = NULL;
1852 }
1853
1854 return 0;
1855 }
1856
1857 /*
1858 * HDCP ISR.
1859 * If HDCP IRQ occurs, set hdcp_event and wake up the waitqueue.
1860 */
1861
1862 #define HDMI_IRQ_TOTAL_NUM 6
1863
1864 hdmi_isr hdmi_isr_ftn[HDMI_IRQ_TOTAL_NUM];
1865
1866 int s5p_hdmi_register_isr(hdmi_isr isr, u8 irq_num)
1867 {
1868 HDMIPRINTK("Try to register ISR for IRQ number (%d)\n", irq_num);
1869
1870 if (isr == NULL) {
1871 HDMIPRINTK("Invaild ISR\n");
1872 return -EINVAL;
1873 }
1874
1875 /* check IRQ number */
1876 if (irq_num > HDMI_IRQ_TOTAL_NUM) {
1877 HDMIPRINTK("irq_num exceeds allowed IRQ number(%d)\n",
1878 HDMI_IRQ_TOTAL_NUM);
1879 return -EINVAL;
1880 }
1881
1882 /* check if is the number already registered? */
1883 if (hdmi_isr_ftn[irq_num]) {
1884 HDMIPRINTK("the %d th ISR is already registered\n",
1885 irq_num);
1886 }
1887
1888 hdmi_isr_ftn[irq_num] = isr;
1889
1890 HDMIPRINTK("Success to register ISR for IRQ number (%d)\n",
1891 irq_num);
1892
1893 return 0;
1894 }
1895
1896 irqreturn_t tv_hdmi_irq(int irq, void *dev_id)
1897 {
1898 u8 irq_state, irq_num;
1899
1900 spin_lock_irq(&lock_hdmi);
1901
1902 irq_state = readb(hdmi_base+S5P_HDMI_CTRL_INTC_FLAG);
1903
1904 HDMIPRINTK("S5P_HDMI_CTRL_INTC_FLAG = 0x%02x\n", irq_state);
1905
1906 /* Check interrupt happened */
1907 /* Priority of Interrupt HDCP> I2C > Audio > CEC ( Not implemented) */
1908
1909 if (irq_state) {
1910 /* HDCP IRQ*/
1911 irq_num = 0;
1912 /* check if ISR is null or not */
1913 while (irq_num < HDMI_IRQ_TOTAL_NUM) {
1914 if (irq_state & (1<<irq_num)) {
1915 if (hdmi_isr_ftn[irq_num] != NULL) {
1916 (hdmi_isr_ftn[irq_num])(irq_num);
1917 } else {
1918 HDMIPRINTK(
1919 "No registered ISR for IRQ[%d]\n",
1920 irq_num);
1921 }
1922 }
1923 ++irq_num;
1924 }
1925
1926 } else {
1927 HDMIPRINTK("Undefined IRQ happened[%x]\n", irq_state);
1928 }
1929
1930 spin_unlock_irq(&lock_hdmi);
1931
1932 /* Because of HW Problem,
1933 after processing INT we should INT enable again.
1934 HdmiOutp8(
1935 S5P_HDMI_INTC_CON, 1 << HDMI_IRQ_HDCP | 1 << HDMI_IRQ_GLOBAL );
1936 INTC_ClearVectAddr(); */
1937
1938 return IRQ_HANDLED;
1939 }
1940
1941 void s5p_hdmi_enable_interrupts(enum s5p_tv_hdmi_interrrupt intr)
1942 {
1943 u8 reg;
1944 reg = readb(hdmi_base+S5P_HDMI_CTRL_INTC_CON);
1945 writeb(reg | (1<<intr) | (1<<HDMI_IRQ_GLOBAL),
1946 hdmi_base+S5P_HDMI_CTRL_INTC_CON);
1947 }
1948
1949 void s5p_hdmi_disable_interrupts(enum s5p_tv_hdmi_interrrupt intr)
1950 {
1951 u8 reg;
1952 reg = readb(hdmi_base+S5P_HDMI_CTRL_INTC_CON);
1953 writeb(reg & ~(1<<intr), hdmi_base+S5P_HDMI_CTRL_INTC_CON);
1954 }
1955
1956 void s5p_hdmi_clear_pending(enum s5p_tv_hdmi_interrrupt intr)
1957 {
1958 u8 reg;
1959 reg = readb(hdmi_base+S5P_HDMI_CTRL_INTC_FLAG);
1960 writeb(reg | (1<<intr), hdmi_base+S5P_HDMI_CTRL_INTC_FLAG);
1961 }
1962
1963 u8 s5p_hdmi_get_interrupts(void)
1964 {
1965 u8 reg;
1966 reg = readb(hdmi_base+S5P_HDMI_CTRL_INTC_FLAG);
1967 return reg;
1968 }
1969
1970 u8 s5p_hdmi_get_swhpd_status(void)
1971 {
1972 u8 reg;
1973 reg = readb(hdmi_base+S5P_HPD) & HPD_SW_ENABLE;
1974 return reg;
1975 }
1976
1977 u8 s5p_hdmi_get_hpd_status(void)
1978 {
1979 u8 reg;
1980 reg = readb(hdmi_base+S5P_HDMI_CTRL_HPD);
1981 return reg;
1982 }
1983
1984 void s5p_hdmi_swhpd_disable(void)
1985 {
1986 u8 reg;
1987 reg = writeb(HPD_SW_DISABLE, hdmi_base+S5P_HPD);
1988 }
1989
1990 void s5p_hdmi_hpd_gen(void)
1991 {
1992 writeb(0xFF, hdmi_base+S5P_HDMI_HPD_GEN);
1993 }
1994
OLDNEW
« no previous file with comments | « drivers/media/video/samsung/tv20/hdmi_param.h ('k') | drivers/media/video/samsung/tv20/hpd.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698