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

Side by Side Diff: drivers/media/video/samsung/tv20/hdcp_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/ddc.c ('k') | drivers/media/video/samsung/tv20/hdmi_param.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/hdcp_s5pv210.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV210 - hdcp 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/delay.h>
16 #include <linux/device.h>
17 #include <linux/wait.h>
18 #include <linux/interrupt.h>
19 #include <linux/workqueue.h>
20 #include <linux/delay.h>
21 #include <linux/i2c.h>
22 #include <linux/irq.h>
23
24 #include <linux/io.h>
25 #include <mach/gpio.h>
26
27 #include "ddc.h"
28 #include "tv_out_s5pv210.h"
29 #include <mach/regs-hdmi.h>
30
31 #include <plat/gpio-cfg.h>
32
33 /* for Operation check */
34 #ifdef CONFIG_TVOUT_RAW_DBG
35 #define S5P_HDCP_DEBUG 1
36 #define S5P_HDCP_I2C_DEBUG 1
37 #define S5P_HDCP_AUTH_DEBUG 1
38 #endif
39
40 #ifdef S5P_HDCP_DEBUG
41 #define HDCPPRINTK(fmt, args...) \
42 printk(KERN_INFO "\t\t[HDCP] %s: " fmt, __func__ , ## args)
43 #else
44 #define HDCPPRINTK(fmt, args...)
45 #endif
46
47 /* for authentication key check */
48 #ifdef S5P_HDCP_AUTH_DEBUG
49 #define AUTHPRINTK(fmt, args...) \
50 printk(KERN_INFO "\t\t\t[AUTHKEY] %s: " fmt, __func__ , ## args)
51 #else
52 #define AUTHPRINTK(fmt, args...)
53 #endif
54
55 enum hdmi_run_mode {
56 DVI_MODE,
57 HDMI_MODE
58 };
59
60 enum hdmi_resolution {
61 SD480P,
62 SD480I,
63 WWSD480P,
64 HD720P,
65 SD576P,
66 WWSD576P,
67 HD1080I
68 };
69
70 enum hdmi_color_bar_type {
71 HORIZONTAL,
72 VERTICAL
73 };
74
75 enum hdcp_event {
76 /* Stop HDCP */
77 HDCP_EVENT_STOP,
78 /* Start HDCP*/
79 HDCP_EVENT_START,
80 /* Start to read Bksv,Bcaps */
81 HDCP_EVENT_READ_BKSV_START,
82 /* Start to write Aksv,An */
83 HDCP_EVENT_WRITE_AKSV_START,
84 /* Start to check if Ri is equal to Rj */
85 HDCP_EVENT_CHECK_RI_START,
86 /* Start 2nd authentication process */
87 HDCP_EVENT_SECOND_AUTH_START
88 };
89
90 enum hdcp_state {
91 NOT_AUTHENTICATED,
92 RECEIVER_READ_READY,
93 BCAPS_READ_DONE,
94 BKSV_READ_DONE,
95 AN_WRITE_DONE,
96 AKSV_WRITE_DONE,
97 FIRST_AUTHENTICATION_DONE,
98 SECOND_AUTHENTICATION_RDY,
99 RECEIVER_FIFOLSIT_READY,
100 SECOND_AUTHENTICATION_DONE,
101 };
102
103 /*
104 * Below CSC_TYPE is temporary. CSC_TYPE enum.
105 * may be included in SetSD480pVars_60Hz etc.
106 *
107 * LR : Limited Range (16~235)
108 * FR : Full Range (0~255)
109 */
110 enum hdmi_intr_src {
111 WAIT_FOR_ACTIVE_RX,
112 WDT_FOR_REPEATER,
113 EXCHANGE_KSV,
114 UPDATE_P_VAL,
115 UPDATE_R_VAL,
116 AUDIO_OVERFLOW,
117 AUTHEN_ACK,
118 UNKNOWN_INT
119 };
120
121 struct s5p_hdcp_info {
122 bool is_repeater;
123 bool hpd_status;
124 u32 time_out;
125 u32 hdcp_enable;
126
127 spinlock_t lock;
128
129 struct i2c_client *client;
130
131 wait_queue_head_t waitq;
132 enum hdcp_event event;
133 enum hdcp_state auth_status;
134
135 struct work_struct work;
136 };
137
138 static struct s5p_hdcp_info hdcp_info = {
139 .is_repeater = false,
140 .time_out = 0,
141 .hdcp_enable = false,
142 .client = NULL,
143 .event = HDCP_EVENT_STOP,
144 .auth_status = NOT_AUTHENTICATED,
145
146 };
147
148 #define HDCP_RI_OFFSET 0x08
149 #define INFINITE 0xffffffff
150
151 #define HDMI_SYS_ENABLE (1 << 0)
152 #define HDMI_ASP_ENABLE (1 << 2)
153 #define HDMI_ASP_DISABLE (~HDMI_ASP_ENABLE)
154
155 #define MAX_DEVS_EXCEEDED (0x1 << 7)
156 #define MAX_CASCADE_EXCEEDED (0x1 << 3)
157
158 #define MAX_CASCADE_EXCEEDED_ERROR (-1)
159 #define MAX_DEVS_EXCEEDED_ERROR (-2)
160 #define REPEATER_ILLEGAL_DEVICE_ERROR (-3)
161
162 #define AINFO_SIZE 1
163 #define BCAPS_SIZE 1
164 #define BSTATUS_SIZE 2
165 #define SHA_1_HASH_SIZE 20
166
167 #define KSV_FIFO_READY (0x1 << 5)
168
169 /* spmoon for test : it's not in manual */
170 #define SET_HDCP_KSV_WRITE_DONE (0x1 << 3)
171 #define CLEAR_HDCP_KSV_WRITE_DONE (~SET_HDCP_KSV_WRITE_DONE)
172
173 #define SET_HDCP_KSV_LIST_EMPTY (0x1 << 2)
174 #define CLEAR_HDCP_KSV_LIST_EMPTY (~SET_HDCP_KSV_LIST_EMPTY)
175 #define SET_HDCP_KSV_END (0x1 << 1)
176 #define CLEAR_HDCP_KSV_END (~SET_HDCP_KSV_END)
177 #define SET_HDCP_KSV_READ (0x1 << 0)
178 #define CLEAR_HDCP_KSV_READ (~SET_HDCP_KSV_READ)
179
180 #define SET_HDCP_SHA_VALID_READY (0x1 << 1)
181 #define CLEAR_HDCP_SHA_VALID_READY (~SET_HDCP_SHA_VALID_READY)
182 #define SET_HDCP_SHA_VALID (0x1 << 0)
183 #define CLEAR_HDCP_SHA_VALID (~SET_HDCP_SHA_VALID)
184
185 #define TRANSMIT_EVERY_VSYNC (0x1 << 1)
186
187 /*
188 * 1st Authentication step func.
189 * Write the Ainfo data to Rx
190 */
191 static bool write_ainfo(void)
192 {
193 int ret = 0;
194 u8 ainfo[2];
195
196 ainfo[0] = HDCP_Ainfo;
197 ainfo[1] = 0;
198
199 ret = ddc_write(ainfo, 2);
200 if (ret < 0)
201 HDCPPRINTK("Can't write ainfo data through i2c bus\n");
202
203 return (ret < 0) ? false : true;
204 }
205
206 /*
207 * Write the An data to Rx
208 */
209 static bool write_an(void)
210 {
211 int ret = 0;
212 u8 an[AN_SIZE+1];
213
214 an[0] = HDCP_An;
215
216 /* Read An from HDMI */
217 an[1] = readb(hdmi_base + S5P_HDCP_An_0_0);
218 an[2] = readb(hdmi_base + S5P_HDCP_An_0_1);
219 an[3] = readb(hdmi_base + S5P_HDCP_An_0_2);
220 an[4] = readb(hdmi_base + S5P_HDCP_An_0_3);
221 an[5] = readb(hdmi_base + S5P_HDCP_An_1_0);
222 an[6] = readb(hdmi_base + S5P_HDCP_An_1_1);
223 an[7] = readb(hdmi_base + S5P_HDCP_An_1_2);
224 an[8] = readb(hdmi_base + S5P_HDCP_An_1_3);
225
226 ret = ddc_write(an, AN_SIZE + 1);
227 if (ret < 0)
228 HDCPPRINTK("Can't write an data through i2c bus\n");
229
230 #ifdef S5P_HDCP_AUTH_DEBUG
231 {
232 u16 i = 0;
233 for (i = 1; i < AN_SIZE + 1; i++)
234 AUTHPRINTK("HDCPAn[%d]: 0x%x \n", i, an[i]);
235 }
236 #endif
237
238 return (ret < 0) ? false : true;
239 }
240
241 /*
242 * Write the Aksv data to Rx
243 */
244 static bool write_aksv(void)
245 {
246 int ret = 0;
247 u8 aksv[AKSV_SIZE+1];
248
249 aksv[0] = HDCP_Aksv;
250
251 /* Read Aksv from HDMI */
252 aksv[1] = readb(hdmi_base + S5P_HDCP_AKSV_0_0);
253 aksv[2] = readb(hdmi_base + S5P_HDCP_AKSV_0_1);
254 aksv[3] = readb(hdmi_base + S5P_HDCP_AKSV_0_2);
255 aksv[4] = readb(hdmi_base + S5P_HDCP_AKSV_0_3);
256 aksv[5] = readb(hdmi_base + S5P_HDCP_AKSV_1);
257
258 ret = ddc_write(aksv, AKSV_SIZE + 1);
259 if (ret < 0)
260 HDCPPRINTK("Can't write aksv data through i2c bus\n");
261
262 #ifdef S5P_HDCP_AUTH_DEBUG
263 {
264 u16 i = 0;
265 for (i = 1; i < AKSV_SIZE + 1; i++)
266 AUTHPRINTK("HDCPAksv[%d]: 0x%x\n", i, aksv[i]);
267 }
268 #endif
269
270 return (ret < 0) ? false : true;
271 }
272
273 static bool read_bcaps(void)
274 {
275 int ret = 0;
276 u8 bcaps[BCAPS_SIZE] = {0};
277
278 ret = ddc_read(HDCP_Bcaps, bcaps, BCAPS_SIZE);
279
280 if (ret < 0) {
281 HDCPPRINTK("Can't read bcaps data from i2c bus\n");
282 return false;
283 }
284
285 writel(bcaps[0], hdmi_base + S5P_HDCP_BCAPS);
286
287 HDCPPRINTK("BCAPS(from i2c) : 0x%08x\n", bcaps[0]);
288
289 if (bcaps[0] & REPEATER_SET)
290 hdcp_info.is_repeater = true;
291 else
292 hdcp_info.is_repeater = false;
293
294 HDCPPRINTK("attached device type : %s !! \n\r",
295 hdcp_info.is_repeater ? "REPEATER" : "SINK");
296 HDCPPRINTK("BCAPS(from sfr) = 0x%08x\n",
297 readl(hdmi_base + S5P_HDCP_BCAPS));
298
299 return true;
300 }
301
302 static bool read_again_bksv(void)
303 {
304 u8 bk_sv[BKSV_SIZE] = {0, 0, 0, 0, 0};
305 u8 i = 0;
306 u8 j = 0;
307 u32 no_one = 0;
308 u32 no_zero = 0;
309 u32 result = 0;
310 int ret = 0;
311
312 ret = ddc_read(HDCP_Bksv, bk_sv, BKSV_SIZE);
313
314 if (ret < 0) {
315 HDCPPRINTK("Can't read bk_sv data from i2c bus\n");
316 return false;
317 }
318
319 #ifdef S5P_HDCP_AUTH_DEBUG
320 for (i = 0; i < BKSV_SIZE; i++)
321 AUTHPRINTK("i2c read : Bksv[%d]: 0x%x\n", i, bk_sv[i]);
322 #endif
323
324 for (i = 0; i < BKSV_SIZE; i++) {
325
326 for (j = 0; j < 8; j++) {
327
328 result = bk_sv[i] & (0x1 << j);
329
330 if (result == 0)
331 no_zero += 1;
332 else
333 no_one += 1;
334 }
335 }
336
337 if ((no_zero == 20) && (no_one == 20)) {
338 HDCPPRINTK("Suucess: no_zero, and no_one is 20\n");
339
340 writel(bk_sv[0], hdmi_base + S5P_HDCP_BKSV_0_0);
341 writel(bk_sv[1], hdmi_base + S5P_HDCP_BKSV_0_1);
342 writel(bk_sv[2], hdmi_base + S5P_HDCP_BKSV_0_2);
343 writel(bk_sv[3], hdmi_base + S5P_HDCP_BKSV_0_3);
344 writel(bk_sv[4], hdmi_base + S5P_HDCP_BKSV_1);
345
346 #ifdef S5P_HDCP_AUTH_DEBUG
347 for (i = 0; i < BKSV_SIZE; i++)
348 AUTHPRINTK("set reg : Bksv[%d]: 0x%x\n", i, bk_sv[i]);
349
350 /* writel(HDCP_ENC_ENABLE, hdmi_base + S5P_ENC_EN); */
351 #endif
352 return true;
353 } else {
354 HDCPPRINTK("Failed: no_zero or no_one is NOT 20\n");
355 return false;
356 }
357 }
358
359 static bool read_bksv(void)
360 {
361 u8 bk_sv[BKSV_SIZE] = {0, 0, 0, 0, 0};
362
363 int i = 0;
364 int j = 0;
365
366 u32 no_one = 0;
367 u32 no_zero = 0;
368 u32 result = 0;
369 u32 count = 0;
370 int ret = 0;
371
372 ret = ddc_read(HDCP_Bksv, bk_sv, BKSV_SIZE);
373
374 if (ret < 0) {
375 HDCPPRINTK("Can't read bk_sv data from i2c bus\n");
376 return false;
377 }
378
379 #ifdef S5P_HDCP_AUTH_DEBUG
380 for (i = 0; i < BKSV_SIZE; i++)
381 AUTHPRINTK("i2c read : Bksv[%d]: 0x%x\n", i, bk_sv[i]);
382 #endif
383
384 for (i = 0; i < BKSV_SIZE; i++) {
385
386 for (j = 0; j < 8; j++) {
387
388 result = bk_sv[i] & (0x1 << j);
389
390 if (result == 0)
391 no_zero++;
392 else
393 no_one++;
394 }
395 }
396
397 if ((no_zero == 20) && (no_one == 20)) {
398
399 writel(bk_sv[0], hdmi_base + S5P_HDCP_BKSV_0_0);
400 writel(bk_sv[1], hdmi_base + S5P_HDCP_BKSV_0_1);
401 writel(bk_sv[2], hdmi_base + S5P_HDCP_BKSV_0_2);
402 writel(bk_sv[3], hdmi_base + S5P_HDCP_BKSV_0_3);
403 writel(bk_sv[4], hdmi_base + S5P_HDCP_BKSV_1);
404
405 #ifdef S5P_HDCP_AUTH_DEBUG
406 for (i = 0; i < BKSV_SIZE; i++)
407 AUTHPRINTK("set reg : Bksv[%d]: 0x%x\n", i, bk_sv[i]);
408 #endif
409
410 HDCPPRINTK("Success: no_zero, and no_one is 20\n");
411
412 } else {
413
414 HDCPPRINTK("Failed: no_zero or no_one is NOT 20\n");
415
416 /* writel(HDCP_ENC_DISABLE, hdmi_base + S5P_ENC_EN); */
417
418 while (!read_again_bksv()) {
419
420 count++;
421
422 mdelay(20);
423
424 if (count == 140)
425 return false;
426 }
427 }
428
429 return true;
430 }
431
432 /*
433 * Compare the R value of Tx with that of Rx
434 */
435 static bool compare_r_val(void)
436 {
437 int ret = 0;
438 u8 ri[2] = {0, 0};
439 u8 rj[2] = {0, 0};
440 u16 i;
441
442 for (i = 0; i < R_VAL_RETRY_CNT; i++) {
443 /* Read R value from Tx */
444 ri[0] = readl(hdmi_base + S5P_HDCP_Ri_0);
445 ri[1] = readl(hdmi_base + S5P_HDCP_Ri_1);
446
447 /* Read R value from Rx */
448 ret = ddc_read(HDCP_Ri, rj, 2);
449 if (ret < 0) {
450 HDCPPRINTK("Can't read r data from i2c bus\n");
451 return false;
452 }
453
454 #ifdef S5P_HDCP_AUTH_DEBUG
455 AUTHPRINTK("retries :: %d\n", i);
456 printk("\t\t\t Rx(ddc) ->");
457 printk("rj[0]: 0x%02x, rj[1]: 0x%02x\n", rj[0], rj[1]);
458 printk(KERN_INFO "\t\t\t Tx(register) ->");
459 printk("ri[0]: 0x%02x, ri[1]: 0x%02x\n", ri[0], ri[1]);
460 #endif
461
462 /* Compare R value */
463 if ((ri[0] == rj[0]) && (ri[1] == rj[1]) && (ri[0] | ri[1])) {
464 writel(Ri_MATCH_RESULT__YES,
465 hdmi_base + S5P_HDCP_CHECK_RESULT);
466 HDCPPRINTK("R0, R0' is matched!!\n");
467 ret = true;
468 break;
469 } else {
470 writel(Ri_MATCH_RESULT__NO,
471 hdmi_base + S5P_HDCP_CHECK_RESULT);
472 HDCPPRINTK("R0, R0' is not matched!!\n");
473 ret = false;
474 }
475
476 }
477
478 return ret ? true : false;
479 }
480
481
482 /*
483 * Enable/Disable Software HPD control
484 */
485 void sw_hpd_enable(bool enable)
486 {
487 u8 reg;
488
489 reg = readb(hdmi_base + S5P_HPD);
490 reg &= ~HPD_SW_ENABLE;
491
492 if (enable)
493 writeb(reg | HPD_SW_ENABLE, hdmi_base + S5P_HPD);
494 else
495 writeb(reg, hdmi_base + S5P_HPD);
496 }
497
498 /*
499 * Set Software HPD level
500 *
501 * @param level [in] if 0 - low;othewise, high
502 */
503 void set_sw_hpd(bool level)
504 {
505 u8 reg;
506
507 reg = readb(hdmi_base + S5P_HPD);
508 reg &= ~HPD_ON;
509
510 if (level)
511 writeb(reg | HPD_ON, hdmi_base + S5P_HPD);
512 else
513 writeb(reg, hdmi_base + S5P_HPD);
514 }
515
516
517 /*
518 * Reset Authentication
519 */
520 void reset_authentication(void)
521 {
522 u8 reg;
523
524 hdcp_info.time_out = INFINITE;
525 hdcp_info.event = HDCP_EVENT_STOP;
526 hdcp_info.auth_status = NOT_AUTHENTICATED;
527
528 HDCPPRINTK("Now reset authentication\n");
529
530 /* set hdcp_int disable */
531 reg = readb(hdmi_base + S5P_STATUS_EN);
532 reg &= ~(WTFORACTIVERX_INT_OCCURRED | WATCHDOG_INT_OCCURRED |
533 EXCHANGEKSV_INT_OCCURRED | UPDATE_RI_INT_OCCURRED);
534 writeb(reg, hdmi_base + S5P_STATUS_EN);
535
536 /* clear all result */
537 writeb(CLEAR_ALL_RESULTS, hdmi_base + S5P_HDCP_CHECK_RESULT);
538
539 /* disable hdmi status enable reg. */
540 reg = readb(hdmi_base + S5P_STATUS_EN);
541 reg &= HDCP_STATUS_DIS_ALL;
542 writeb(reg, hdmi_base + S5P_STATUS_EN);
543
544 /* clear all status pending */
545 reg = readb(hdmi_base + S5P_STATUS);
546 reg |= HDCP_STATUS_EN_ALL;
547 writeb(reg, hdmi_base + S5P_STATUS);
548
549 /* Disable encryption */
550 writeb(HDCP_ENC_DIS, hdmi_base + S5P_ENC_EN);
551
552 /* Disable hdcp */
553 writeb(0x0, hdmi_base + S5P_HDCP_CTRL1);
554 writeb(0x0, hdmi_base + S5P_HDCP_CTRL2);
555
556 /*
557 * 1. Mask HPD plug and unplug interrupt
558 * disable HPD INT
559 */
560 s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_PLUG);
561 s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_UNPLUG);
562
563 /* 2. Enable software HPD */
564 sw_hpd_enable(true);
565
566 /* 3. Make software HPD logical 0 */
567 set_sw_hpd(false);
568
569 /* 4. Make software HPD logical 1 */
570 set_sw_hpd(true);
571
572 /* 5. Disable software HPD */
573 sw_hpd_enable(false);
574
575 /* 6. Unmask HPD plug and unplug interrupt */
576 s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_PLUG);
577 s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_UNPLUG);
578
579 /* set hdcp_int enable */
580 reg = readb(hdmi_base + S5P_STATUS_EN);
581 reg |= WTFORACTIVERX_INT_OCCURRED |
582 WATCHDOG_INT_OCCURRED |
583 EXCHANGEKSV_INT_OCCURRED |
584 UPDATE_RI_INT_OCCURRED;
585 writeb(reg, hdmi_base + S5P_STATUS_EN);
586
587 /* HDCP Enable */
588 writeb(CP_DESIRED_EN, hdmi_base + S5P_HDCP_CTRL1);
589
590 }
591
592 /*
593 * Set the timing parameter for load e-fuse key.
594 */
595
596 /* TODO: must use clk_get for pclk rate */
597 #define PCLK_D_RATE_FOR_HDCP 166000000
598
599 u32 efuse_ceil(u32 val, u32 time)
600 {
601 u32 res;
602
603 res = val / time;
604
605 if (val % time)
606 res += 1;
607
608 return res;
609 }
610
611 static void hdcp_efuse_timing(void)
612 {
613 u32 time, val;
614
615 /* TODO: must use clk_get for pclk rate */
616 time = 1000000000/PCLK_D_RATE_FOR_HDCP;
617
618 val = efuse_ceil(EFUSE_ADDR_WIDTH, time);
619 writeb(val, hdmi_base + S5P_EFUSE_ADDR_WIDTH);
620
621 val = efuse_ceil(EFUSE_SIGDEV_ASSERT, time);
622 writeb(val, hdmi_base + S5P_EFUSE_SIGDEV_ASSERT);
623
624 val = efuse_ceil(EFUSE_SIGDEV_DEASSERT, time);
625 writeb(val, hdmi_base + S5P_EFUSE_SIGDEV_DEASSERT);
626
627 val = efuse_ceil(EFUSE_PRCHG_ASSERT, time);
628 writeb(val, hdmi_base + S5P_EFUSE_PRCHG_ASSERT);
629
630 val = efuse_ceil(EFUSE_PRCHG_DEASSERT, time);
631 writeb(val, hdmi_base + S5P_EFUSE_PRCHG_DEASSERT);
632
633 val = efuse_ceil(EFUSE_FSET_ASSERT, time);
634 writeb(val, hdmi_base + S5P_EFUSE_FSET_ASSERT);
635
636 val = efuse_ceil(EFUSE_FSET_DEASSERT, time);
637 writeb(val, hdmi_base + S5P_EFUSE_FSET_DEASSERT);
638
639 val = efuse_ceil(EFUSE_SENSING, time);
640 writeb(val, hdmi_base + S5P_EFUSE_SENSING);
641
642 val = efuse_ceil(EFUSE_SCK_ASSERT, time);
643 writeb(val, hdmi_base + S5P_EFUSE_SCK_ASSERT);
644
645 val = efuse_ceil(EFUSE_SCK_DEASSERT, time);
646 writeb(val, hdmi_base + S5P_EFUSE_SCK_DEASSERT);
647
648 val = efuse_ceil(EFUSE_SDOUT_OFFSET, time);
649 writeb(val, hdmi_base + S5P_EFUSE_SDOUT_OFFSET);
650
651 val = efuse_ceil(EFUSE_READ_OFFSET, time);
652 writeb(val, hdmi_base + S5P_EFUSE_READ_OFFSET);
653
654 }
655
656 /*
657 * load hdcp key from e-fuse mem.
658 */
659 static int hdcp_loadkey(void)
660 {
661 u8 status;
662
663 hdcp_efuse_timing();
664
665 /* read HDCP key from E-Fuse */
666 writeb(EFUSE_CTRL_ACTIVATE, hdmi_base + S5P_EFUSE_CTRL);
667
668 do {
669 status = readb(hdmi_base + S5P_EFUSE_STATUS);
670 } while (!(status & EFUSE_ECC_DONE));
671
672 if (readb(hdmi_base + S5P_EFUSE_STATUS) & EFUSE_ECC_FAIL) {
673 HDCPPRINTK("Can't load key from fuse ctrl.\n");
674 return -EINVAL;
675 }
676
677 return 0;
678
679 }
680
681 /*
682 * Start encryption
683 */
684 static void start_encryption(void)
685 {
686 u32 hdcp_status;
687
688 /* Ri == Ri' |Ready the compared result of Ri */
689 writel(Ri_MATCH_RESULT__YES, hdmi_base + S5P_HDCP_CHECK_RESULT);
690
691 do {
692 hdcp_status = readl(hdmi_base + S5P_STATUS);
693 /* Wait for STATUS[7] to '1'*/
694 } while ((hdcp_status & AUTHENTICATED) != AUTHENTICATED);
695
696 /* Start encryption */
697 writel(HDCP_ENC_ENABLE, hdmi_base + S5P_ENC_EN);
698
699 }
700
701 /*
702 * Check whether Rx is repeater or not
703 */
704 static int check_repeater(void)
705 {
706 int ret = 0;
707 u8 i = 0;
708 u16 j = 0;
709
710 u8 bcaps[BCAPS_SIZE] = {0};
711 u8 status[BSTATUS_SIZE] = {0, 0};
712 u8 rx_v[SHA_1_HASH_SIZE] = {0};
713 u8 ksv_list[HDCP_MAX_DEVS*HDCP_KSV_SIZE] = {0};
714
715 u32 hdcp_ctrl = 0;
716 u32 dev_cnt;
717 u32 stat;
718
719 bool ksv_fifo_ready = false;
720
721 memset(rx_v, 0x0, SHA_1_HASH_SIZE);
722 memset(ksv_list, 0x0, HDCP_MAX_DEVS*HDCP_KSV_SIZE);
723
724 while (j <= 500) {
725 ret = ddc_read(HDCP_Bcaps,
726 bcaps, BCAPS_SIZE);
727
728 if (ret < 0) {
729 HDCPPRINTK("Can't read bcaps data from i2c bus\n");
730 return false;
731 }
732
733 if (bcaps[0] & KSV_FIFO_READY) {
734 HDCPPRINTK("ksv fifo is ready\n");
735 ksv_fifo_ready = true;
736 writel(bcaps[0], hdmi_base + S5P_HDCP_BCAPS);
737 break;
738 } else {
739 HDCPPRINTK("ksv fifo is not ready\n");
740 ksv_fifo_ready = false;
741 mdelay(10);
742 j++;
743 }
744
745 }
746
747 if (j == 500) {
748 HDCPPRINTK("ksv fifo check timeout occurred!!\n");
749 return false;
750 }
751
752 if (ksv_fifo_ready) {
753 hdcp_ctrl = readl(hdmi_base + S5P_HDCP_CTRL1);
754 hdcp_ctrl &= CLEAR_REPEATER_TIMEOUT;
755 writel(hdcp_ctrl, hdmi_base + S5P_HDCP_CTRL1);
756 } else
757 return false;
758
759 /*
760 * Check MAX_CASCADE_EXCEEDED
761 * or MAX_DEVS_EXCEEDED indicator
762 */
763 ret = ddc_read(HDCP_BStatus, status, BSTATUS_SIZE);
764
765 if (ret < 0) {
766 HDCPPRINTK("Can't read status data from i2c bus\n");
767 return false;
768 }
769
770 /* MAX_CASCADE_EXCEEDED || MAX_DEVS_EXCEEDED */
771 if (status[1] & MAX_CASCADE_EXCEEDED) {
772 HDCPPRINTK("MAX_CASCADE_EXCEEDED\n");
773 return MAX_CASCADE_EXCEEDED_ERROR;
774 } else if (status[0] & MAX_DEVS_EXCEEDED) {
775 HDCPPRINTK("MAX_CASCADE_EXCEEDED\n");
776 return MAX_DEVS_EXCEEDED_ERROR;
777 }
778
779 writel(status[0], hdmi_base + S5P_HDCP_BSTATUS_0);
780 writel(status[1], hdmi_base + S5P_HDCP_BSTATUS_1);
781
782 /* Read KSV list */
783 dev_cnt = (*status) & 0x7f;
784
785 HDCPPRINTK("status[0] :0x%08x, status[1] :0x%08x!!\n",
786 status[0], status[1]);
787
788 if (dev_cnt) {
789
790 u32 val = 0;
791
792 /* read ksv */
793 ret = ddc_read(HDCP_KSVFIFO, ksv_list,
794 dev_cnt * HDCP_KSV_SIZE);
795 if (ret < 0) {
796 HDCPPRINTK("Can't read ksv fifo!!\n");
797 return false;
798 }
799
800 /* write ksv */
801 for (i = 0; i < dev_cnt; i++) {
802
803 writel(ksv_list[(i*5) + 0],
804 hdmi_base + S5P_HDCP_RX_KSV_0_0);
805 writel(ksv_list[(i*5) + 1],
806 hdmi_base + S5P_HDCP_RX_KSV_0_1);
807 writel(ksv_list[(i*5) + 2],
808 hdmi_base + S5P_HDCP_RX_KSV_0_2);
809 writel(ksv_list[(i*5) + 3],
810 hdmi_base + S5P_HDCP_RX_KSV_0_3);
811 writel(ksv_list[(i*5) + 4],
812 hdmi_base + S5P_HDCP_RX_KSV_0_4);
813
814 if (i != (dev_cnt - 1)) { /* if it's not end */
815 /* it's not in manual */
816 writel(SET_HDCP_KSV_WRITE_DONE,
817 S5P_HDCP_RX_KSV_LIST_CTRL);
818
819 mdelay(20);
820
821 /* check ksv readed */
822 do {
823 if (!hdcp_info.hdcp_enable)
824 return false;
825
826 stat = readl(hdmi_base +
827 S5P_HDCP_RX_KSV_LIST_CTRL);
828
829 } while (!(stat & SET_HDCP_KSV_READ));
830
831
832 HDCPPRINTK("read complete\n");
833
834 }
835
836 HDCPPRINTK("HDCP_RX_KSV_1 = 0x%x\n\r",
837 readl(hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL));
838 HDCPPRINTK("i : %d, dev_cnt : %d, val = 0x%08x\n",
839 i, dev_cnt, val);
840 }
841
842 /* end of ksv */
843 val = readl(hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL);
844 val |= SET_HDCP_KSV_END|SET_HDCP_KSV_WRITE_DONE;
845 writel(val, hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL);
846
847 HDCPPRINTK("HDCP_RX_KSV_1 = 0x%x\n\r",
848 readl(hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL));
849 HDCPPRINTK("i : %d, dev_cnt : %d, val = 0x%08x\n",
850 i, dev_cnt, val);
851
852 } else {
853
854 /* mdelay(200); */
855
856 writel(SET_HDCP_KSV_LIST_EMPTY,
857 hdmi_base + S5P_HDCP_RX_KSV_LIST_CTRL);
858 }
859
860
861 /* Read SHA-1 from receiver */
862 ret = ddc_read(HDCP_SHA1, rx_v, SHA_1_HASH_SIZE);
863
864 if (ret < 0) {
865 HDCPPRINTK("Can't read sha_1_hash data from i2c bus\n");
866 return false;
867 }
868
869 for (i = 0; i < SHA_1_HASH_SIZE; i++)
870 HDCPPRINTK("SHA_1 rx :: %x\n", rx_v[i]);
871
872 /* write SHA-1 to register */
873 writel(rx_v[0], hdmi_base + S5P_HDCP_RX_SHA1_0_0);
874 writel(rx_v[1], hdmi_base + S5P_HDCP_RX_SHA1_0_1);
875 writel(rx_v[2], hdmi_base + S5P_HDCP_RX_SHA1_0_2);
876 writel(rx_v[3], hdmi_base + S5P_HDCP_RX_SHA1_0_3);
877 writel(rx_v[4], hdmi_base + S5P_HDCP_RX_SHA1_1_0);
878 writel(rx_v[5], hdmi_base + S5P_HDCP_RX_SHA1_1_1);
879 writel(rx_v[6], hdmi_base + S5P_HDCP_RX_SHA1_1_2);
880 writel(rx_v[7], hdmi_base + S5P_HDCP_RX_SHA1_1_3);
881 writel(rx_v[8], hdmi_base + S5P_HDCP_RX_SHA1_2_0);
882 writel(rx_v[9], hdmi_base + S5P_HDCP_RX_SHA1_2_1);
883 writel(rx_v[10], hdmi_base + S5P_HDCP_RX_SHA1_2_2);
884 writel(rx_v[11], hdmi_base + S5P_HDCP_RX_SHA1_2_3);
885 writel(rx_v[12], hdmi_base + S5P_HDCP_RX_SHA1_3_0);
886 writel(rx_v[13], hdmi_base + S5P_HDCP_RX_SHA1_3_1);
887 writel(rx_v[14], hdmi_base + S5P_HDCP_RX_SHA1_3_2);
888 writel(rx_v[15], hdmi_base + S5P_HDCP_RX_SHA1_3_3);
889 writel(rx_v[16], hdmi_base + S5P_HDCP_RX_SHA1_4_0);
890 writel(rx_v[17], hdmi_base + S5P_HDCP_RX_SHA1_4_1);
891 writel(rx_v[18], hdmi_base + S5P_HDCP_RX_SHA1_4_2);
892 writel(rx_v[19], hdmi_base + S5P_HDCP_RX_SHA1_4_3);
893
894 /* SHA write done, and wait for SHA computation being done */
895 mdelay(1);
896
897 /* check authentication success or not */
898 stat = readl(hdmi_base + S5P_HDCP_AUTH_STATUS);
899
900 HDCPPRINTK("auth status %d\n", stat);
901
902 if (stat & SET_HDCP_SHA_VALID_READY) {
903
904 HDCPPRINTK("SHA valid ready 0x%x \n\r", stat);
905
906 stat = readl(hdmi_base + S5P_HDCP_AUTH_STATUS);
907
908 if (stat & SET_HDCP_SHA_VALID) {
909
910 HDCPPRINTK("SHA valid 0x%x \n\r", stat);
911
912 ret = true;
913 } else {
914 HDCPPRINTK("SHA valid ready, but not valid 0x%x \n\r",
915 stat);
916 ret = false;
917 }
918
919 } else {
920
921 HDCPPRINTK("SHA not ready 0x%x \n\r", stat);
922 ret = false;
923 }
924
925
926 /* clear all validate bit */
927 writel(0x0, hdmi_base + S5P_HDCP_AUTH_STATUS);
928
929 return ret;
930
931 }
932
933 static bool try_read_receiver(void)
934 {
935 u8 i = 0;
936 bool ret = false;
937
938 for (i = 0; i < 40; i++) {
939
940 mdelay(250);
941
942 if (hdcp_info.auth_status != RECEIVER_READ_READY) {
943
944 HDCPPRINTK("hdcp stat. changed!!"
945 "failed attempt no = %d\n\r", i);
946
947 return false;
948 }
949
950 ret = read_bcaps();
951
952 if (ret) {
953
954 HDCPPRINTK("succeeded at attempt no= %d \n\r", i);
955
956 return true;
957
958 } else
959 HDCPPRINTK("can't read bcaps!!"
960 "failed attempt no=%d\n\r", i);
961 }
962
963 return false;
964 }
965
966
967 /*
968 * stop - stop functions are only called under running HDCP
969 */
970 bool tv_stop_hdcp(void)
971 {
972 u32 sfr_val = 0;
973
974 HDCPPRINTK("HDCP ftn. Stop!!\n");
975
976 s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_PLUG);
977 s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_UNPLUG);
978 s5p_hdmi_disable_interrupts(HDMI_IRQ_HDCP);
979
980 hdcp_protocol_status = 0;
981
982 hdcp_info.time_out = INFINITE;
983 hdcp_info.event = HDCP_EVENT_STOP;
984 hdcp_info.auth_status = NOT_AUTHENTICATED;
985 hdcp_info.hdcp_enable = false;
986
987 /* hdcp_info.client = NULL; */
988
989 /* 3. disable hdcp control reg. */
990 sfr_val = readl(hdmi_base + S5P_HDCP_CTRL1);
991 sfr_val &= (ENABLE_1_DOT_1_FEATURE_DIS
992 & CLEAR_REPEATER_TIMEOUT
993 & EN_PJ_DIS
994 & CP_DESIRED_DIS);
995 writel(sfr_val, hdmi_base + S5P_HDCP_CTRL1);
996
997 /* 1-3. disable hdmi hpd reg. */
998 writel(CABLE_UNPLUGGED, hdmi_base + S5P_HPD);
999
1000 /* 1-2. disable hdmi status enable reg. */
1001 sfr_val = readl(hdmi_base + S5P_STATUS_EN);
1002 sfr_val &= HDCP_STATUS_DIS_ALL;
1003 writel(sfr_val, hdmi_base + S5P_STATUS_EN);
1004
1005 /* 1-1. clear all status pending */
1006 sfr_val = readl(hdmi_base + S5P_STATUS);
1007 sfr_val |= HDCP_STATUS_EN_ALL;
1008 writel(sfr_val, hdmi_base + S5P_STATUS);
1009
1010 /* disable encryption */
1011 writel(HDCP_ENC_DISABLE, hdmi_base + S5P_ENC_EN);
1012
1013 /* clear result */
1014 writel(Ri_MATCH_RESULT__NO, hdmi_base + S5P_HDCP_CHECK_RESULT);
1015 writel(readl(hdmi_base + S5P_HDMI_CON_0) & HDMI_DIS,
1016 hdmi_base + S5P_HDMI_CON_0);
1017 writel(readl(hdmi_base + S5P_HDMI_CON_0) | HDMI_EN,
1018 hdmi_base + S5P_HDMI_CON_0);
1019 writel(CLEAR_ALL_RESULTS, hdmi_base + S5P_HDCP_CHECK_RESULT);
1020
1021 /* hdmi disable */
1022 /*
1023 sfr_val = readl(hdmi_base + S5P_HDMI_CON_0);
1024 sfr_val &= ~(PWDN_ENB_NORMAL | HDMI_EN | ASP_EN);
1025 writel( sfr_val, hdmi_base + S5P_HDMI_CON_0);
1026 */
1027 HDCPPRINTK("\tSTATUS \t0x%08x\n", readl(hdmi_base + S5P_STATUS));
1028 HDCPPRINTK("\tSTATUS_EN \t0x%08x\n",
1029 readl(hdmi_base + S5P_STATUS_EN));
1030 HDCPPRINTK("\tHPD \t0x%08x\n", readl(hdmi_base + S5P_HPD));
1031 HDCPPRINTK("\tHDCP_CTRL \t0x%08x\n",
1032 readl(hdmi_base + S5P_HDCP_CTRL1));
1033 HDCPPRINTK("\tMODE_SEL \t0x%08x\n",
1034 readl(hdmi_base + S5P_MODE_SEL));
1035 HDCPPRINTK("\tENC_EN \t0x%08x\n", readl(hdmi_base + S5P_ENC_EN));
1036 HDCPPRINTK("\tHDMI_CON_0 \t0x%08x\n",
1037 readl(hdmi_base + S5P_HDMI_CON_0));
1038
1039 return true;
1040 }
1041
1042 void tv_hdcp_reset(void)
1043 {
1044 tv_stop_hdcp();
1045
1046 hdcp_protocol_status = 2;
1047
1048 HDCPPRINTK("HDCP ftn. reset!!\n");
1049 }
1050
1051 /*
1052 * start - start functions are only called under stopping HDCP
1053 */
1054 bool tv_start_hdcp(void)
1055 {
1056 u32 sfr_val;
1057
1058 hdcp_info.event = HDCP_EVENT_STOP;
1059 hdcp_info.time_out = INFINITE;
1060 hdcp_info.auth_status = NOT_AUTHENTICATED;
1061
1062 HDCPPRINTK("HDCP ftn. Start!!\n");
1063
1064 /* from hpd for test */
1065 s5p_hdmi_hpd_gen();
1066
1067 s3c_gpio_cfgpin(S5PV210_GPH1(5), S5P_GPH1_5_HDMI_HPD);
1068 s3c_gpio_setpull(S5PV210_GPH1(5), S3C_GPIO_PULL_UP);
1069
1070 s5p_hdmi_enable_interrupts(HDMI_IRQ_HDCP);
1071
1072 s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_PLUG);
1073 s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_UNPLUG);
1074
1075 /* 2. Enable software HPD */
1076 sw_hpd_enable(true);
1077
1078 /* 3. Make software HPD logical 0 */
1079 set_sw_hpd(false);
1080
1081 /* 4. Make software HPD logical 1 */
1082 set_sw_hpd(true);
1083
1084 /* 5. Disable software HPD */
1085 sw_hpd_enable(false);
1086
1087 /* 6. Unmask HPD plug and unplug interrupt */
1088 s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_PLUG);
1089 s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_UNPLUG);
1090
1091
1092 hdcp_protocol_status = 1;
1093
1094 if (!read_bcaps()) {
1095 HDCPPRINTK("can't read ddc port!\n");
1096 reset_authentication();
1097 }
1098
1099 /* for av mute */
1100 writel(DO_NOT_TRANSMIT, hdmi_base + S5P_GCP_CON);
1101
1102 /*
1103 * 1-1. set hdmi status enable reg.
1104 * Update_Ri_int_en should be enabled after
1105 * s/w gets ExchangeKSV_int.
1106 */
1107 writel(HDCP_STATUS_EN_ALL, hdmi_base + S5P_STATUS_EN);
1108
1109 /* 1-2. set hdmi hpd reg. */
1110 writel(CABLE_PLUGGED, hdmi_base+S5P_HPD);
1111
1112 if (hdcp_loadkey() < 0)
1113 return false;
1114
1115 /*
1116 * 3. set hdcp control reg.
1117 * Disable advance cipher option, Enable CP(Content Protection),
1118 * Disable time-out (This bit is only available in a REPEATER)
1119 * Disable XOR shift,Disable Pj port update,Use external key
1120 */
1121 sfr_val = 0;
1122 sfr_val |= CP_DESIRED_EN;
1123 writel(sfr_val, hdmi_base + S5P_HDCP_CTRL1);
1124
1125 hdcp_info.hdcp_enable = true;
1126
1127 HDCPPRINTK("\tSTATUS \t0x%08x\n", readl(hdmi_base + S5P_STATUS));
1128 HDCPPRINTK("\tSTATUS_EN \t0x%08x\n",
1129 readl(hdmi_base + S5P_STATUS_EN));
1130 HDCPPRINTK("\tHPD \t0x%08x\n", readl(hdmi_base + S5P_HPD));
1131 HDCPPRINTK("\tHDCP_CTRL \t0x%08x\n",
1132 readl(hdmi_base + S5P_HDCP_CTRL1));
1133 HDCPPRINTK("\tMODE_SEL \t0x%08x\n",
1134 readl(hdmi_base + S5P_MODE_SEL));
1135 HDCPPRINTK("\tENC_EN \t0x%08x\n", readl(hdmi_base + S5P_ENC_EN));
1136 HDCPPRINTK("\tHDMI_CON_0 \t0x%08x\n",
1137 readl(hdmi_base + S5P_HDMI_CON_0));
1138
1139 return true;
1140 }
1141
1142 static void bksv_start_bh(void)
1143 {
1144 bool ret = false;
1145
1146 HDCPPRINTK("HDCP_EVENT_READ_BKSV_START bh\n");
1147
1148 hdcp_info.auth_status = RECEIVER_READ_READY;
1149
1150 ret = read_bcaps();
1151
1152 if (!ret) {
1153
1154 ret = try_read_receiver();
1155
1156 if (!ret) {
1157 HDCPPRINTK("Can't read bcaps!! retry failed!!\n"
1158 "\t\t\t\thdcp ftn. will be stopped\n");
1159
1160 tv_stop_hdcp();
1161 return;
1162 }
1163 }
1164
1165 hdcp_info.auth_status = BCAPS_READ_DONE;
1166
1167 ret = read_bksv();
1168
1169 if (!ret) {
1170 HDCPPRINTK("Can't read bksv!!"
1171 "hdcp ftn. will be reset\n");
1172
1173 tv_stop_hdcp();
1174 return;
1175 }
1176
1177 hdcp_info.auth_status = BKSV_READ_DONE;
1178
1179 HDCPPRINTK("authentication status : bksv is done (0x%08x)\n",
1180 hdcp_info.auth_status);
1181 }
1182
1183 static void second_auth_start_bh(void)
1184 {
1185 u8 count = 0;
1186 bool ret = false;
1187
1188 int ret_err;
1189
1190 u32 bcaps;
1191
1192 HDCPPRINTK("HDCP_EVENT_SECOND_AUTH_START bh\n");
1193
1194 ret = read_bcaps();
1195
1196 if (!ret) {
1197
1198 ret = try_read_receiver();
1199
1200 if (!ret) {
1201
1202 HDCPPRINTK("Can't read bcaps!! retry failed!!\n"
1203 "\t\t\t\thdcp ftn. will be stopped\n");
1204
1205 tv_stop_hdcp();
1206 return;
1207 }
1208
1209 }
1210
1211 bcaps = readl(hdmi_base + S5P_HDCP_BCAPS);
1212 bcaps &= (KSV_FIFO_READY);
1213
1214 if (!bcaps) {
1215
1216 HDCPPRINTK("ksv fifo is not ready\n");
1217
1218 do {
1219 count++;
1220
1221 ret = read_bcaps();
1222
1223 if (!ret) {
1224
1225 ret = try_read_receiver();
1226
1227 if (!ret)
1228 tv_stop_hdcp();
1229
1230 return;
1231
1232 }
1233
1234 bcaps = readl(hdmi_base + S5P_HDCP_BCAPS);
1235 bcaps &= (KSV_FIFO_READY);
1236
1237 if (bcaps) {
1238 HDCPPRINTK("bcaps retries : %d\n", count);
1239 break;
1240 }
1241
1242 mdelay(100);
1243
1244 if (!hdcp_info.hdcp_enable) {
1245
1246 tv_stop_hdcp();
1247
1248 return;
1249
1250 }
1251
1252 } while (count <= 50);
1253
1254 /* wait times exceeded 5 seconds */
1255 if (count > 50) {
1256
1257 hdcp_info.time_out = INFINITE;
1258
1259 /* time-out (This bit is only available in a REPEATER) */
1260 writel(readl(hdmi_base + S5P_HDCP_CTRL1) | 0x1 << 2,
1261 hdmi_base + S5P_HDCP_CTRL1);
1262
1263 reset_authentication();
1264
1265 return;
1266 }
1267 }
1268
1269 HDCPPRINTK("ksv fifo ready\n");
1270
1271 ret_err = check_repeater();
1272
1273 if (ret_err == true) {
1274 u32 flag;
1275
1276 hdcp_info.auth_status = SECOND_AUTHENTICATION_DONE;
1277 HDCPPRINTK("second authentication done!!\n");
1278
1279 flag = readb(hdmi_base + S5P_STATUS);
1280 HDCPPRINTK("hdcp state : %s authenticated!!\n",
1281 flag & AUTHENTICATED ? "" : "not not");
1282
1283 start_encryption();
1284 } else if (ret_err == false) {
1285 /* i2c error */
1286 HDCPPRINTK("repeater check error!!\n");
1287 reset_authentication();
1288 } else {
1289 if (ret_err == REPEATER_ILLEGAL_DEVICE_ERROR) {
1290 /*
1291 * No need to start the HDCP
1292 * in case of invalid KSV (revocation case)
1293 */
1294 HDCPPRINTK("illegal dev. error!!\n");
1295
1296 tv_stop_hdcp();
1297 } else {
1298 /*
1299 * MAX_CASCADE_EXCEEDED_ERROR
1300 * MAX_DEVS_EXCEEDED_ERROR
1301 */
1302 HDCPPRINTK("repeater check error(MAX_EXCEEDED)!!\n");
1303 reset_authentication();
1304 }
1305 }
1306 }
1307
1308 static bool write_aksv_start_bh(void)
1309 {
1310 bool ret = false;
1311
1312 HDCPPRINTK("HDCP_EVENT_WRITE_AKSV_START bh\n");
1313
1314 if (hdcp_info.auth_status != BKSV_READ_DONE) {
1315 HDCPPRINTK("bksv is not ready!!\n");
1316 return false;
1317 }
1318
1319 ret = write_ainfo();
1320 if (!ret)
1321 return false;
1322
1323 HDCPPRINTK("ainfo write done!!\n");
1324
1325 ret = write_an();
1326 if (!ret)
1327 return false;
1328
1329 hdcp_info.auth_status = AN_WRITE_DONE;
1330
1331 HDCPPRINTK("an write done!!\n");
1332
1333 ret = write_aksv();
1334 if (!ret)
1335 return false;
1336
1337 /*
1338 * Wait for 100ms. Transmitter must not read
1339 * Ro' value sooner than 100ms after writing
1340 * Aksv
1341 */
1342 mdelay(100);
1343
1344 hdcp_info.auth_status = AKSV_WRITE_DONE;
1345
1346 HDCPPRINTK("aksv write done!!\n");
1347
1348 return ret;
1349 }
1350
1351 static bool check_ri_start_bh(void)
1352 {
1353 bool ret = false;
1354
1355
1356 HDCPPRINTK("HDCP_EVENT_CHECK_RI_START bh\n");
1357
1358 if (hdcp_info.auth_status == AKSV_WRITE_DONE ||
1359 hdcp_info.auth_status == FIRST_AUTHENTICATION_DONE ||
1360 hdcp_info.auth_status == SECOND_AUTHENTICATION_DONE) {
1361
1362 ret = compare_r_val();
1363
1364 if (ret) {
1365
1366 if (hdcp_info.auth_status == AKSV_WRITE_DONE) {
1367 /*
1368 * Check whether HDMI receiver is
1369 * repeater or not
1370 */
1371 if (hdcp_info.is_repeater)
1372 hdcp_info.auth_status
1373 = SECOND_AUTHENTICATION_RDY;
1374 else {
1375 hdcp_info.auth_status
1376 = FIRST_AUTHENTICATION_DONE;
1377 start_encryption();
1378 }
1379 }
1380
1381 } else {
1382
1383 HDCPPRINTK("authentication reset\n");
1384 reset_authentication();
1385
1386 }
1387
1388 HDCPPRINTK("auth_status = 0x%08x\n",
1389 hdcp_info.auth_status);
1390
1391
1392 return true;
1393 }
1394
1395 HDCPPRINTK("aksv_write or first/second"
1396 " authentication is not done\n");
1397
1398 return false;
1399 }
1400
1401 /*
1402 * bottom half for hdmi interrupt
1403 *
1404 */
1405 static void hdcp_work(void *arg)
1406 {
1407 /* HDCPPRINTK("event : 0x%08x \n\r", hdcp_info.event); */
1408
1409 /*
1410 * I2C int. was occurred
1411 * for reading Bksv and Bcaps
1412 */
1413
1414 if (hdcp_info.event & (1 << HDCP_EVENT_READ_BKSV_START)) {
1415
1416 bksv_start_bh();
1417
1418 /* clear event */
1419 /* spin_lock_bh(&hdcp_info.lock); */
1420 hdcp_info.event &= ~(1 << HDCP_EVENT_READ_BKSV_START);
1421 /* spin_unlock_bh(&hdcp_info.lock); */
1422 }
1423
1424 /*
1425 * Watchdog timer int. was occurred
1426 * for checking repeater
1427 */
1428 if (hdcp_info.event & (1 << HDCP_EVENT_SECOND_AUTH_START)) {
1429
1430 second_auth_start_bh();
1431
1432 /* clear event */
1433 /* spin_lock_bh(&hdcp_info.lock); */
1434 hdcp_info.event &= ~(1 << HDCP_EVENT_SECOND_AUTH_START);
1435 /* spin_unlock_bh(&hdcp_info.lock); */
1436 }
1437
1438 /*
1439 * An_Write int. was occurred
1440 * for writing Ainfo, An and Aksv
1441 */
1442 if (hdcp_info.event & (1 << HDCP_EVENT_WRITE_AKSV_START)) {
1443
1444 write_aksv_start_bh();
1445
1446 /* clear event */
1447 /* spin_lock_bh(&hdcp_info.lock); */
1448 hdcp_info.event &= ~(1 << HDCP_EVENT_WRITE_AKSV_START);
1449 /* spin_unlock_bh(&hdcp_info.lock); */
1450 }
1451
1452 /*
1453 * Ri int. was occurred
1454 * for comparing Ri and Ri'(from HDMI sink)
1455 */
1456 if (hdcp_info.event & (1 << HDCP_EVENT_CHECK_RI_START)) {
1457
1458
1459 check_ri_start_bh();
1460
1461 /* clear event */
1462 /* spin_lock_bh(&hdcp_info.lock); */
1463 hdcp_info.event &= ~(1 << HDCP_EVENT_CHECK_RI_START);
1464 /* spin_unlock_bh(&hdcp_info.lock); */
1465 }
1466
1467 }
1468
1469 irqreturn_t tv_hdcp_irq_handler(int irq, void *dev_id)
1470 {
1471 u32 event = 0;
1472 u8 flag;
1473
1474 event = 0;
1475 /* check HDCP Status */
1476 flag = readb(hdmi_base + S5P_STATUS);
1477
1478 HDCPPRINTK("irq_status : 0x%08x\n", readb(hdmi_base + S5P_STATUS));
1479
1480 HDCPPRINTK("hdcp state : %s authenticated!!\n",
1481 flag & AUTHENTICATED ? "" : "not");
1482
1483 spin_lock_irq(&hdcp_info.lock);
1484
1485 /*
1486 * processing interrupt
1487 * interrupt processing seq. is firstly set event for workqueue,
1488 * and interrupt pending clear. 'flag|' was used for preventing
1489 * to clear AUTHEN_ACK.- it caused many problem. be careful.
1490 */
1491 /* I2C INT */
1492 if (flag & WTFORACTIVERX_INT_OCCURRED) {
1493 event |= (1 << HDCP_EVENT_READ_BKSV_START);
1494 writeb(flag | WTFORACTIVERX_INT_OCCURRED,
1495 hdmi_base + S5P_STATUS);
1496 writeb(0x0, hdmi_base + S5P_HDCP_I2C_INT);
1497 }
1498
1499 /* AN INT */
1500 if (flag & EXCHANGEKSV_INT_OCCURRED) {
1501 event |= (1 << HDCP_EVENT_WRITE_AKSV_START);
1502 writeb(flag | EXCHANGEKSV_INT_OCCURRED,
1503 hdmi_base + S5P_STATUS);
1504 writeb(0x0, hdmi_base + S5P_HDCP_AN_INT);
1505 }
1506
1507 /* RI INT */
1508 if (flag & UPDATE_RI_INT_OCCURRED) {
1509 event |= (1 << HDCP_EVENT_CHECK_RI_START);
1510 writeb(flag | UPDATE_RI_INT_OCCURRED,
1511 hdmi_base + S5P_STATUS);
1512 writeb(0x0, hdmi_base + S5P_HDCP_RI_INT);
1513 }
1514
1515 /* WATCHDOG INT */
1516 if (flag & WATCHDOG_INT_OCCURRED) {
1517 event |= (1 << HDCP_EVENT_SECOND_AUTH_START);
1518 writeb(flag | WATCHDOG_INT_OCCURRED,
1519 hdmi_base + S5P_STATUS);
1520 writeb(0x0, hdmi_base + S5P_HDCP_WDT_INT);
1521 }
1522
1523 if (!event) {
1524 HDCPPRINTK("unknown irq.\n");
1525 return IRQ_HANDLED;
1526 }
1527
1528 hdcp_info.event |= event;
1529
1530 schedule_work(&hdcp_info.work);
1531
1532 spin_unlock_irq(&hdcp_info.lock);
1533
1534 return IRQ_HANDLED;
1535 }
1536
1537 bool tv_set_hpd_detection(bool detection, bool hdcp_enabled,
1538 struct i2c_client *client)
1539 {
1540 u32 hpd_reg_val = 0;
1541
1542 if (detection)
1543 hpd_reg_val = CABLE_PLUGGED;
1544 else
1545 hpd_reg_val = CABLE_UNPLUGGED;
1546
1547 writel(hpd_reg_val, hdmi_base + S5P_HPD);
1548
1549 HDCPPRINTK("HPD status :: 0x%08x\n\r",
1550 readl(hdmi_base + S5P_HPD));
1551
1552 return true;
1553 }
1554
1555 int tv_hdcp_init(void)
1556 {
1557 /* for bh */
1558 INIT_WORK(&hdcp_info.work, (work_func_t)hdcp_work);
1559
1560 init_waitqueue_head(&hdcp_info.waitq);
1561
1562 /* for dev_dbg err. */
1563 spin_lock_init(&hdcp_info.lock);
1564
1565 s5p_hdmi_register_isr((hdmi_isr)tv_hdcp_irq_handler,
1566 (u8)HDMI_IRQ_HDCP);
1567
1568 return 0;
1569 }
OLDNEW
« no previous file with comments | « drivers/media/video/samsung/tv20/ddc.c ('k') | drivers/media/video/samsung/tv20/hdmi_param.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698