0b067c0114c3c0ac665f2a5a05d769e5138e9143
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / hdmi / rockchip-hdmiv1 / rockchip_hdmiv1_hdcp.c
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/errno.h>
4 #include <linux/string.h>
5 #include <linux/miscdevice.h>
6 #include <linux/workqueue.h>
7 #include <linux/firmware.h>
8 #include <linux/timer.h>
9 #include <linux/jiffies.h>
10 #include "rockchip_hdmiv1.h"
11 #include "rockchip_hdmiv1_hdcp.h"
12 #include "rockchip_hdmiv1_hw.h"
13
14 static struct hdcp *hdcp;
15
16 static void hdcp_work_queue(struct work_struct *work);
17
18 #define AUTH_TIMEOUT (2*HZ)
19 static struct timer_list auth_timer;
20 static int timer_state;
21
22 static int is_1b_03_test(struct hdmi_dev *hdmi_dev)
23 {
24         int reg_value;
25         int reg_val_1;
26
27         hdmi_readl(hdmi_dev, 0x58, &reg_value);
28         hdmi_readl(hdmi_dev, 0xc3, &reg_val_1);
29
30         if (reg_value != 0) {
31                 if ((reg_val_1 & 0x40) == 0)
32                         return 1;
33         }
34         return 0;
35 }
36
37 static void rockchip_hdmiv1_set_colorbar(struct hdmi_dev *hdmi_dev,
38                                          int enable)
39 {
40         static int display_mask;
41         int reg_value;
42         int tmds_clk;
43
44         tmds_clk = hdmi_dev->tmdsclk;
45         if (enable) {
46                 if (!display_mask) {
47                         if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) {
48                                 hdmi_readl(hdmi_dev, SYS_CTRL, &reg_value);
49                                 hdmi_msk_reg(hdmi_dev, SYS_CTRL,
50                                              m_REG_CLK_SOURCE,
51                                              v_REG_CLK_SOURCE_SYS);
52                                 hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x00);
53                                 hdmi_writel(hdmi_dev, SYS_CTRL, reg_value);
54                         } else {
55                                 hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x00);
56                         }
57                         display_mask = 1;
58                 }
59         } else {
60                 if (display_mask) {
61                         if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) {
62                                 hdmi_readl(hdmi_dev, SYS_CTRL, &reg_value);
63                                 hdmi_msk_reg(hdmi_dev, SYS_CTRL,
64                                              m_REG_CLK_SOURCE,
65                                              v_REG_CLK_SOURCE_SYS);
66                                 hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x10);
67                                 hdmi_writel(hdmi_dev, SYS_CTRL, reg_value);
68                         } else {
69                                 hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x10);
70                         }
71                         display_mask = 0;
72                 }
73         }
74 }
75
76 static void rockchip_hdmiv1_hdcp_disable(struct hdmi_dev *hdmi_dev)
77 {
78         int reg_value;
79         int tmds_clk;
80
81         tmds_clk = hdmi_dev->tmdsclk;
82         if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) {
83                 hdmi_readl(hdmi_dev, SYS_CTRL, &reg_value);
84                 hdmi_msk_reg(hdmi_dev, SYS_CTRL,
85                              m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
86         }
87
88         /* Diable HDCP Interrupt*/
89         hdmi_writel(hdmi_dev, HDCP_INT_MASK1, 0x00);
90         /* Stop and Reset HDCP*/
91         hdmi_msk_reg(hdmi_dev, HDCP_CTRL1,
92                      m_AUTH_START | m_AUTH_STOP | m_HDCP_RESET,
93                      v_AUTH_START(0) | v_AUTH_STOP(1) | v_HDCP_RESET(1));
94
95         if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2))
96                 hdmi_writel(hdmi_dev, SYS_CTRL, reg_value);
97 }
98
99 static int rockchip_hdmiv1_hdcp_key_check(struct hdcp_keys *key)
100 {
101         int i = 0;
102
103         DBG("HDCP: check hdcp key\n");
104         /*check 40 private key */
105         for (i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++) {
106                 if (key->devicekey[i] != 0x00)
107                         return HDCP_KEY_VALID;
108         }
109         /*check aksv*/
110         for (i = 0; i < 5; i++) {
111                 if (key->ksv[i] != 0x00)
112                         return HDCP_KEY_VALID;
113         }
114
115         return HDCP_KEY_INVALID;
116 }
117
118 static int rockchip_hdmiv1_hdcp_load_key2mem(void)
119 {
120         int i;
121         struct hdmi_dev *hdmi_dev;
122         struct hdcp_keys *key;
123
124         if (!hdcp)
125                 return -1;
126         hdmi_dev = hdcp->hdmi_dev;
127         key = hdcp->keys;
128         DBG("HDCP: rockchip_hdmiv1_hdcp_load_key2mem start\n");
129         /* Write 40 private key*/
130         for (i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++)
131                 hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->devicekey[i]);
132         /* Write 1st aksv*/
133         for (i = 0; i < 5; i++)
134                 hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->ksv[i]);
135         /* Write 2nd aksv*/
136         for (i = 0; i < 5; i++)
137                 hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->ksv[i]);
138         DBG("HDCP: rockchip_hdmiv1_hdcp_load_key2mem end\n");
139         return HDCP_OK;
140 }
141
142 static int rockchip_hdmiv1_hdcp_start_authentication(struct hdmi_dev *hdmi_dev)
143 {
144         int temp;
145         int retry = 0;
146         int tmds_clk;
147
148         tmds_clk = hdmi_dev->tmdsclk;
149         if (hdcp->keys == NULL) {
150                 HDCP_WARN("HDCP: key is not loaded\n");
151                 return HDCP_KEY_ERR;
152         }
153         if (rockchip_hdmiv1_hdcp_key_check(hdcp->keys) == HDCP_KEY_INVALID) {
154                 HDCP_WARN("loaded HDCP key is incorrect\n");
155                 return HDCP_KEY_ERR;
156         }
157         if (tmds_clk > (HDMI_SYS_FREG_CLK << 2)) {
158                 /*Select TMDS CLK to configure regs*/
159                 hdmi_msk_reg(hdmi_dev, SYS_CTRL,
160                              m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_TMDS);
161         } else {
162                 hdmi_msk_reg(hdmi_dev, SYS_CTRL,
163                              m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
164         }
165         hdmi_writel(hdmi_dev, HDCP_TIMER_100MS, 0x28);
166         hdmi_readl(hdmi_dev, HDCP_KEY_STATUS, &temp);
167         while ((temp & m_KEY_READY) == 0) {
168                 if (retry > 1000) {
169                         HDCP_WARN("HDCP: loaded key error\n");
170                         return HDCP_KEY_ERR;
171                 }
172                 rockchip_hdmiv1_hdcp_load_key2mem();
173                 usleep_range(900, 1000);
174                 hdmi_readl(hdmi_dev, HDCP_KEY_STATUS, &temp);
175                 retry++;
176         }
177         /*Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b)*/
178         retry = hdmi_dev->hclk_rate/(HDCP_DDC_CLK << 2);
179         hdmi_writel(hdmi_dev, DDC_CLK_L, retry & 0xFF);
180         hdmi_writel(hdmi_dev, DDC_CLK_H, (retry >> 8) & 0xFF);
181         hdmi_writel(hdmi_dev, HDCP_CTRL2, 0x67);
182         /*Enable interrupt*/
183         hdmi_writel(hdmi_dev, HDCP_INT_MASK1,
184                     m_INT_HDCP_ERR | m_INT_BKSV_READY | m_INT_BKSV_UPDATE |
185                     m_INT_AUTH_SUCCESS | m_INT_AUTH_READY);
186         hdmi_writel(hdmi_dev, HDCP_INT_MASK2, 0x00);
187         /*Start authentication*/
188         hdmi_msk_reg(hdmi_dev, HDCP_CTRL1,
189                      m_AUTH_START | m_ENCRYPT_ENABLE | m_ADVANED_ENABLE |
190                      m_AUTH_STOP | m_HDCP_RESET,
191                      v_AUTH_START(1) | v_ENCRYPT_ENABLE(1) |
192                      v_ADVANED_ENABLE(0) | v_AUTH_STOP(0) | v_HDCP_RESET(0));
193
194         if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) {
195                 hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE,
196                              v_REG_CLK_SOURCE_TMDS);
197         }
198         return HDCP_OK;
199 }
200
201 static int rockchip_hdmiv1_hdcp_stop_authentication(struct hdmi_dev *hdmi_dev)
202 {
203         hdmi_msk_reg(hdmi_dev, SYS_CTRL,
204                      m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
205         hdmi_writel(hdmi_dev, DDC_CLK_L, 0x1c);
206         hdmi_writel(hdmi_dev, DDC_CLK_H, 0x00);
207         hdmi_writel(hdmi_dev, HDCP_CTRL2, 0x08);
208         hdmi_writel(hdmi_dev, HDCP_INT_MASK2, 0x06);
209         hdmi_writel(hdmi_dev, HDCP_CTRL1, 0x02);
210         return 0;
211         /*hdmi_writel(HDCP_CTRL1, 0x0a);*/
212 }
213
214 static int rockchip_hdmiv1_hdcp_error(int value)
215 {
216         if (value & 0x80)
217                 HDCP_WARN("Timed out waiting for downstream repeater\n");
218         else if (value & 0x40)
219                 HDCP_WARN("Too many devices connected to repeater tree\n");
220         else if (value & 0x20)
221                 HDCP_WARN("SHA-1 hash check of BKSV list failed\n");
222         else if (value & 0x10)
223                 HDCP_WARN("SHA-1 hash check of BKSV list failed\n");
224         else if (value & 0x08)
225                 HDCP_WARN("DDC channels no acknowledge\n");
226         else if (value & 0x04)
227                 HDCP_WARN("Pj mismatch\n");
228         else if (value & 0x02)
229                 HDCP_WARN("Ri mismatch\n");
230         else if (value & 0x01)
231                 HDCP_WARN("Bksv is wrong\n");
232         else
233                 return 0;
234         return 1;
235 }
236
237 static void rockchip_hdmiv1_hdcp_interrupt(struct hdmi_dev *hdmi_dev,
238                                            char *status1, char *status2)
239 {
240         int interrupt1 = 0;
241         int interrupt2 = 0;
242         int temp = 0;
243         int tmds_clk;
244
245         tmds_clk = hdmi_dev->tmdsclk;
246         hdmi_readl(hdmi_dev, HDCP_INT_STATUS1, &interrupt1);
247         hdmi_readl(hdmi_dev, HDCP_INT_STATUS2, &interrupt2);
248
249         if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2))
250                 hdmi_msk_reg(hdmi_dev, SYS_CTRL,
251                              m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
252
253         if (interrupt1) {
254                 hdmi_writel(hdmi_dev, HDCP_INT_STATUS1, interrupt1);
255                 if (interrupt1 & m_INT_HDCP_ERR) {
256                         hdmi_readl(hdmi_dev, HDCP_ERROR, &temp);
257                         HDCP_WARN("HDCP: Error reg 0x65 = 0x%02x\n", temp);
258                         rockchip_hdmiv1_hdcp_error(temp);
259                         hdmi_writel(hdmi_dev, HDCP_ERROR, temp);
260                 }
261         }
262         if (interrupt2)
263                 hdmi_writel(hdmi_dev, HDCP_INT_STATUS2, interrupt2);
264
265         *status1 = interrupt1;
266         *status2 = interrupt2;
267
268         if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2))
269                 hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE,
270                              v_REG_CLK_SOURCE_TMDS);
271 /*
272         hdmi_readl(HDCP_ERROR, &temp);
273         DBG("HDCP: Error reg 0x65 = 0x%02x\n", temp);
274 */
275 }
276
277 /*-----------------------------------------------------------------------------
278  * Function: hdcp_submit_work
279  *-----------------------------------------------------------------------------
280  */
281 static struct delayed_work *hdcp_submit_work(int event, int delay)
282 {
283         struct hdcp_delayed_work *work;
284
285         DBG("%s event %04x delay %d\n", __func__, event, delay);
286         work = kmalloc(sizeof(*work), GFP_ATOMIC);
287
288         if (work) {
289                 INIT_DELAYED_WORK(&work->work, hdcp_work_queue);
290                 work->event = event;
291                 queue_delayed_work(hdcp->workqueue,
292                                    &work->work,
293                                    msecs_to_jiffies(delay));
294         } else {
295                 HDCP_WARN("HDCP:Cannot allocate memory to create work\n");
296                 return 0;
297         }
298
299         return &work->work;
300 }
301
302 /*-----------------------------------------------------------------------------
303  * Function: hdcp_cancel_work
304  *-----------------------------------------------------------------------------
305  */
306 static void hdcp_cancel_work(struct delayed_work **work)
307 {
308         int ret = 0;
309
310         if (*work) {
311                 ret = cancel_delayed_work(*work);
312                 if (ret != 1) {
313                         ret = cancel_work_sync(&((*work)->work));
314                         HDCP_WARN("Canceling sync work failed %d\n", ret);
315                 }
316                 kfree(*work);
317                 *work = 0;
318         }
319 }
320
321 /*-----------------------------------------------------------------------------
322  * Function: auth_timer_func
323  *-----------------------------------------------------------------------------
324  */
325 static void auth_timer_func(unsigned long data)
326 {
327         HDCP_WARN("hdcp auth 2 second timeout\n");
328         if (hdcp->auth_state == 0) {
329                 mod_timer(&auth_timer, jiffies + AUTH_TIMEOUT);
330                 if ((hdcp->hdcp_state != HDCP_DISABLED) &&
331                     (hdcp->hdcp_state != HDCP_ENABLE_PENDING)) {
332                         if (is_1b_03_test(hdcp->hdmi_dev))
333                                 return;
334                         hdcp_submit_work(HDCP_FAIL_EVENT, 0);
335                 }
336         }
337 }
338
339 /*-----------------------------------------------------------------------------
340  * Function: hdcp_wq_authentication_failure
341  *-----------------------------------------------------------------------------
342  */
343 static void hdcp_wq_authentication_failure(void)
344 {
345         if (hdcp->hdmi_state == HDMI_STOPPED)
346                 return;
347
348         rockchip_hdmiv1_hdcp_disable(hdcp->hdmi_dev);
349 /*
350         rockchip_hdmiv1_hdmi_control_output(false);
351  */
352         rockchip_hdmiv1_set_colorbar(hdcp->hdmi_dev, 1);
353         hdcp_cancel_work(&hdcp->pending_wq_event);
354         if (hdcp->retry_cnt && (hdcp->hdmi_state != HDMI_STOPPED)) {
355                 if (hdcp->retry_cnt <= HDCP_INFINITE_REAUTH) {
356                         hdcp->retry_cnt--;
357                         HDCP_WARN("authentication failed attempts=%d\n",
358                                   hdcp->retry_cnt);
359                 } else {
360                         HDCP_WARN("authentication failed retrying\n");
361                 }
362                 hdcp->hdcp_state = HDCP_AUTHENTICATION_START;
363
364                 if (hdcp->auth_state == 1 && timer_state == 0) {
365                         DBG("add auth timer\n");
366                         hdcp->auth_state = 0;
367                         hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
368                         auth_timer.expires = jiffies + AUTH_TIMEOUT;
369                         add_timer(&auth_timer);
370                         timer_state = 1;
371                 }
372
373                 hdcp->pending_wq_event = hdcp_submit_work(HDCP_AUTH_REATT_EVENT,
374                                                          HDCP_REAUTH_DELAY);
375         } else {
376                 HDCP_WARN("authentication failed HDCP disabled\n");
377                 hdcp->hdcp_state = HDCP_ENABLE_PENDING;
378
379                 if (timer_state == 1) {
380                         DBG("delete auth timer\n");
381                         del_timer_sync(&auth_timer);
382                         timer_state = 0;
383                 }
384         }
385 }
386
387 /*-----------------------------------------------------------------------------
388  * Function: hdcp_wq_start_authentication
389  *-----------------------------------------------------------------------------
390  */
391 static void hdcp_wq_start_authentication(void)
392 {
393         int status = HDCP_OK;
394
395         hdcp->hdcp_state = HDCP_AUTHENTICATION_START;
396         DBG("HDCP: authentication start\n");
397         status = rockchip_hdmiv1_hdcp_start_authentication(hdcp->hdmi_dev);
398         if (status != HDCP_OK) {
399                 DBG("HDCP: authentication failed\n");
400                 hdcp_wq_authentication_failure();
401         } else {
402                 /*hdcp->hdcp_state = HDCP_WAIT_KSV_LIST;*/
403                 hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK;
404         }
405 }
406 #if 0
407 /*-----------------------------------------------------------------------------
408  * Function: hdcp_wq_check_bksv
409  *-----------------------------------------------------------------------------
410  */
411 static void hdcp_wq_check_bksv(void)
412 {
413         int status = HDCP_OK;
414
415         DBG("Check BKSV start");
416         status = rockchip_hdmiv1_hdcp_check_bksv();
417         if (status != HDCP_OK) {
418                 HDCP_WARN("HDCP: Check BKSV failed");
419                 hdcp->retry_cnt = 0;
420                 hdcp_wq_authentication_failure();
421         } else {
422                 DBG("HDCP: Check BKSV successful");
423                 hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK;
424                 /* Restore retry counter */
425                 if (hdcp->retry_times == 0)
426                         hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
427                 else
428                         hdcp->retry_cnt = hdcp->retry_times;
429         }
430 }
431 #endif
432 /*-----------------------------------------------------------------------------
433  * Function: hdcp_wq_authentication_sucess
434  *-----------------------------------------------------------------------------
435  */
436 static void hdcp_wq_authentication_sucess(void)
437 {
438         hdcp->auth_state = 1;
439         if (timer_state == 1) {
440                 DBG("delete auth timer\n");
441                 timer_state = 0;
442                 del_timer_sync(&auth_timer);
443         }
444
445         rockchip_hdmiv1_set_colorbar(hdcp->hdmi_dev, 0);
446         HDCP_WARN("HDCP: authentication pass\n");
447 }
448
449 /*-----------------------------------------------------------------------------
450  * Function: hdcp_wq_disable
451  *-----------------------------------------------------------------------------
452  */
453 static void hdcp_wq_disable(int event)
454 {
455         HDCP_WARN("HDCP: disabled\n");
456
457         hdcp_cancel_work(&hdcp->pending_wq_event);
458         rockchip_hdmiv1_hdcp_disable(hdcp->hdmi_dev);
459         if (event == HDCP_DISABLE_CTL) {
460                 hdcp->hdcp_state = HDCP_DISABLED;
461                 if (hdcp->hdmi_state == HDMI_STARTED)
462                         rockchip_hdmiv1_set_colorbar(hdcp->hdmi_dev, 0);
463         } else if (event == HDCP_STOP_FRAME_EVENT) {
464                 hdcp->hdcp_state = HDCP_ENABLE_PENDING;
465         }
466 }
467
468 /*-----------------------------------------------------------------------------
469  * Function: hdcp_work_queue
470  *-----------------------------------------------------------------------------
471  */
472 static void hdcp_work_queue(struct work_struct *work)
473 {
474         struct hdcp_delayed_work *hdcp_w =
475                 container_of(work, struct hdcp_delayed_work, work.work);
476         int event = hdcp_w->event;
477
478         mutex_lock(&hdcp->lock);
479         DBG("hdcp_work_queue() - START - %u hdmi=%d hdcp=%d evt= %x %d\n",
480             jiffies_to_msecs(jiffies),
481             hdcp->hdmi_state,
482             hdcp->hdcp_state,
483             (event & 0xFF00) >> 8,
484             event & 0xFF);
485
486         if (event == HDCP_STOP_FRAME_EVENT)
487                 hdcp->hdmi_state = HDMI_STOPPED;
488         if (event == HDCP_DISABLE_CTL || event == HDCP_STOP_FRAME_EVENT)
489                 hdcp_wq_disable(event);
490         if (event & HDCP_WORKQUEUE_SRC)
491                 hdcp->pending_wq_event = 0;
492         /* First handle HDMI state */
493         if (event == HDCP_START_FRAME_EVENT) {
494                 hdcp->pending_start = 0;
495                 hdcp->hdmi_state = HDMI_STARTED;
496         }
497
498         /**********************/
499         /* HDCP state machine */
500         /**********************/
501         switch (hdcp->hdcp_state) {
502         case HDCP_DISABLED:
503                 /* HDCP enable control or re-authentication event */
504                 if (event == HDCP_ENABLE_CTL) {
505                         /*if (hdcp->retry_times == 0)
506                                 hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
507                         else
508                                 hdcp->retry_cnt = hdcp->retry_times;*/
509                         hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
510                         if (hdcp->hdmi_state == HDMI_STARTED)
511                                 hdcp_wq_start_authentication();
512                         else
513                                 hdcp->hdcp_state = HDCP_ENABLE_PENDING;
514                 }
515                 break;
516         case HDCP_ENABLE_PENDING:
517                 /* HDMI start frame event */
518                 if (event == HDCP_START_FRAME_EVENT)
519                         hdcp_wq_start_authentication();
520                 break;
521         case HDCP_AUTHENTICATION_START:
522                 /* Re-authentication */
523                 if (event == HDCP_AUTH_REATT_EVENT)
524                         hdcp_wq_start_authentication();
525                 break;
526 #if 0
527         case HDCP_WAIT_KSV_LIST:
528                 /* KSV failure */
529                 if (event == HDCP_FAIL_EVENT) {
530                         HDCP_WARN("HDCP: KSV switch failure\n");
531                         hdcp_wq_authentication_failure();
532                 }
533                 /* KSV list ready event */
534                 else if (event == HDCP_KSV_LIST_RDY_EVENT)
535                         hdcp_wq_check_bksv();
536                 break;
537 #endif
538         case HDCP_LINK_INTEGRITY_CHECK:
539                 /* authentication failure */
540                 if (event == HDCP_FAIL_EVENT) {
541                         HDCP_WARN("HDCP: Ri check failure\n");
542                         hdcp_wq_authentication_failure();
543                 } else if (event == HDCP_AUTH_PASS_EVENT) {
544                         hdcp_wq_authentication_sucess();
545                 }
546                 break;
547         default:
548                 HDCP_WARN("HDCP: error - unknow HDCP state\n");
549                 break;
550         }
551         kfree(hdcp_w);
552         if (event == HDCP_STOP_FRAME_EVENT)
553                 complete(&hdcp->complete);
554         mutex_unlock(&hdcp->lock);
555 }
556
557 /*-----------------------------------------------------------------------------
558  * Function: hdcp_start_frame_cb
559  *-----------------------------------------------------------------------------
560  */
561 static void hdcp_start_frame_cb(struct hdmi *hdmi)
562 {
563         DBG("hdcp_start_frame_cb()\n");
564
565         /* Cancel any pending work */
566         if (hdcp->pending_start)
567                 hdcp_cancel_work(&hdcp->pending_start);
568         if (hdcp->pending_wq_event)
569                 hdcp_cancel_work(&hdcp->pending_wq_event);
570
571         if (timer_state == 0) {
572                 DBG("add auth timer\n");
573                 auth_timer.expires = jiffies + AUTH_TIMEOUT;
574                 add_timer(&auth_timer);
575                 timer_state = 1;
576         }
577
578         hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
579         hdcp->pending_start = hdcp_submit_work(HDCP_START_FRAME_EVENT,
580                                                HDCP_ENABLE_DELAY);
581 }
582
583 /*-----------------------------------------------------------------------------
584  * Function: hdcp_irq_cb
585  *-----------------------------------------------------------------------------
586  */
587 static void hdcp_irq_cb(int status)
588 {
589         char interrupt1;
590         char interrupt2;
591
592         rockchip_hdmiv1_hdcp_interrupt(hdcp->hdmi_dev,
593                                        &interrupt1,
594                                        &interrupt2);
595         DBG("%s 0x%02x 0x%02x\n", __func__, interrupt1, interrupt2);
596         if (interrupt1 & m_INT_HDCP_ERR) {
597                 if ((hdcp->hdcp_state != HDCP_DISABLED) &&
598                     (hdcp->hdcp_state != HDCP_ENABLE_PENDING))
599                         hdcp_submit_work(HDCP_FAIL_EVENT, 0);
600         }
601 /*
602         else if (interrupt1 & (m_INT_BKSV_READY | m_INT_BKSV_UPDATE))
603                 hdcp_submit_work(HDCP_KSV_LIST_RDY_EVENT, 0);
604  */
605         else if (interrupt1 & m_INT_AUTH_SUCCESS)
606                 hdcp_submit_work(HDCP_AUTH_PASS_EVENT, 0);
607 }
608
609 /*-----------------------------------------------------------------------------
610  * Function: hdcp_power_on_cb
611  *-----------------------------------------------------------------------------
612  */
613 static int hdcp_power_on_cb(void)
614 {
615         DBG("%s", __func__);
616         return rockchip_hdmiv1_hdcp_load_key2mem();
617 }
618
619 /*-----------------------------------------------------------------------------
620  * Function: hdcp_power_off_cb
621  *-----------------------------------------------------------------------------
622  */
623 static void hdcp_power_off_cb(struct hdmi *hdmi)
624 {
625         unsigned int time;
626
627         DBG("%s\n", __func__);
628         if (timer_state == 1) {
629                 DBG("delete auth timer\n");
630                 timer_state = 0;
631                 del_timer_sync(&auth_timer);
632         }
633         hdcp->auth_state = 0;
634
635         if (!hdcp->enable)
636                 return;
637         rockchip_hdmiv1_hdcp_stop_authentication(hdcp->hdmi_dev);
638         hdcp_cancel_work(&hdcp->pending_start);
639         hdcp_cancel_work(&hdcp->pending_wq_event);
640         init_completion(&hdcp->complete);
641         /* Post event to workqueue */
642         time = msecs_to_jiffies(5000);
643         if (hdcp_submit_work(HDCP_STOP_FRAME_EVENT, 0))
644                 wait_for_completion_interruptible_timeout(&hdcp->complete,
645                                                           time);
646 }
647
648 /*
649  * Load HDCP key to external HDCP memory
650  */
651 static void hdcp_load_keys_cb(const struct firmware *fw, void *context)
652 {
653         if (!fw) {
654                 pr_err("HDCP: failed to load keys\n");
655                 return;
656         }
657         if (fw->size < HDCP_KEY_SIZE) {
658                 pr_err("HDCP: firmware wrong size %d\n", (int)fw->size);
659                 return;
660         }
661         hdcp->keys =  kmalloc(HDCP_KEY_SIZE, GFP_KERNEL);
662         if (hdcp->keys == NULL) {
663                 pr_err("HDCP: can't allocated space for keys\n");
664                 return;
665         }
666         memcpy(hdcp->keys, fw->data, HDCP_KEY_SIZE);
667         HDCP_WARN("HDCP: load hdcp key success\n");
668
669         if (fw->size > HDCP_KEY_SIZE) {
670                 DBG("%s invalid key size %d\n", __func__,
671                     (int)fw->size - HDCP_KEY_SIZE);
672                 if ((fw->size - HDCP_KEY_SIZE) % 5) {
673                         pr_err("HDCP: failed to load invalid keys\n");
674                         return;
675                 }
676                 hdcp->invalidkeys =
677                         kmalloc(fw->size - HDCP_KEY_SIZE, GFP_KERNEL);
678                 if (hdcp->invalidkeys == NULL) {
679                         pr_err("HDCP: can't allocated space for invalid keys\n");
680                         return;
681                 }
682                 memcpy(hdcp->invalidkeys, fw->data +
683                        HDCP_KEY_SIZE, fw->size - HDCP_KEY_SIZE);
684                 hdcp->invalidkey = (fw->size - HDCP_KEY_SIZE)/5;
685                 HDCP_WARN("HDCP: loaded hdcp invalid key success\n");
686         }
687 }
688
689 static ssize_t hdcp_enable_read(struct device *device,
690                                 struct device_attribute *attr,
691                                 char *buf)
692 {
693         int enable = 0;
694
695         if (hdcp)
696                 enable = hdcp->enable;
697         return snprintf(buf, PAGE_SIZE, "%d\n", enable);
698 }
699
700 static ssize_t hdcp_enable_write(struct device *device,
701                                  struct device_attribute *attr,
702                                  const char *buf, size_t count)
703 {
704         int enable;
705
706         if (hdcp == NULL)
707                 return -EINVAL;
708         if (kstrtoint(buf, 0, &enable))
709                 return -EINVAL;
710         if (hdcp->enable != enable) {
711                 /* Post event to workqueue */
712                 if (enable) {
713                         if (hdcp_submit_work(HDCP_ENABLE_CTL, 0) == 0)
714                                 return -EFAULT;
715                 } else {
716                         hdcp_cancel_work(&hdcp->pending_start);
717                         hdcp_cancel_work(&hdcp->pending_wq_event);
718
719                         /* Post event to workqueue */
720                         if (hdcp_submit_work(HDCP_DISABLE_CTL, 0) == 0)
721                                 return -EFAULT;
722                 }
723                 hdcp->enable = enable;
724         }
725         return count;
726 }
727
728 static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR,
729                          hdcp_enable_read, hdcp_enable_write);
730
731 static ssize_t hdcp_trytimes_read(struct device *device,
732                                   struct device_attribute *attr,
733                                   char *buf)
734 {
735         int trytimes = 0;
736
737         if (hdcp)
738                 trytimes = hdcp->retry_times;
739         return snprintf(buf, PAGE_SIZE, "%d\n", trytimes);
740 }
741
742 static ssize_t hdcp_trytimes_wrtie(struct device *device,
743                                    struct device_attribute *attr,
744                                    const char *buf, size_t count)
745 {
746         int trytimes;
747
748         if (hdcp == NULL)
749                 return -EINVAL;
750         if (kstrtoint(buf, 0, &trytimes))
751                 return -EINVAL;
752         if (hdcp->retry_times != trytimes)
753                 hdcp->retry_times = trytimes;
754         return count;
755 }
756
757
758 static DEVICE_ATTR(trytimes, S_IRUGO|S_IWUSR,
759                          hdcp_trytimes_read, hdcp_trytimes_wrtie);
760 static struct miscdevice mdev;
761
762 int rockchip_hdmiv1_hdcp_init(struct hdmi *hdmi)
763 {
764         int ret;
765
766         DBG("[%s]\n", __func__);
767         if (hdcp)
768                 return 0;
769
770         hdcp = kmalloc(sizeof(*hdcp), GFP_KERNEL);
771         if (!hdcp) {
772                 HDCP_WARN(">>HDCP: kmalloc fail!\n");
773                 ret = -ENOMEM;
774                 goto error0;
775         }
776         memset(hdcp, 0, sizeof(struct hdcp));
777         mutex_init(&hdcp->lock);
778         mdev.minor = MISC_DYNAMIC_MINOR;
779         mdev.name = "hdcp";
780         mdev.mode = 0666;
781         if (misc_register(&mdev)) {
782                 HDCP_WARN("HDCP: Could not add character driver\n");
783                 ret = HDMI_ERROR_FALSE;
784                 goto error1;
785         }
786         ret = device_create_file(mdev.this_device, &dev_attr_enable);
787         if (ret) {
788                 HDCP_WARN("HDCP: Could not add sys file enable\n");
789                 ret = -EINVAL;
790                 goto error2;
791         }
792         ret = device_create_file(mdev.this_device, &dev_attr_trytimes);
793         if (ret) {
794                 HDCP_WARN("HDCP: Could not add sys file trytimes\n");
795                 ret = -EINVAL;
796                         goto error3;
797         }
798         hdcp->workqueue = create_singlethread_workqueue("hdcp");
799         if (hdcp->workqueue == NULL) {
800                 HDCP_WARN("HDCP,: create workqueue failed.\n");
801                 goto error4;
802         }
803         ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
804                                       "hdcp", mdev.this_device,
805                                       GFP_KERNEL, hdcp,
806                                       hdcp_load_keys_cb);
807         if (ret < 0) {
808                 HDCP_WARN("HDCP: request_firmware_nowait failed: %d\n", ret);
809                 goto error5;
810         }
811         hdcp->hdmi_dev = hdmi->property->priv;
812         hdmi->ops->hdcp_cb = hdcp_start_frame_cb;
813         hdmi->ops->hdcp_irq_cb = hdcp_irq_cb;
814         hdmi->ops->hdcp_power_on_cb = hdcp_power_on_cb;
815         hdmi->ops->hdcp_power_off_cb = hdcp_power_off_cb;
816
817         init_timer(&auth_timer);
818         auth_timer.data = 0;
819         auth_timer.function = auth_timer_func;
820         DBG("%s success\n", __func__);
821         return 0;
822 error5:
823         destroy_workqueue(hdcp->workqueue);
824 error4:
825         device_remove_file(mdev.this_device, &dev_attr_trytimes);
826 error3:
827         device_remove_file(mdev.this_device, &dev_attr_enable);
828 error2:
829         misc_deregister(&mdev);
830 error1:
831         kfree(hdcp->keys);
832         kfree(hdcp->invalidkeys);
833         kfree(hdcp);
834 error0:
835         return ret;
836 }
837