blob: 98f4c658d3049dc421ee4f6190d9b2242eeea9d7 [file] [log] [blame]
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301/* Copyright (c) 2015-2016, 2018, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#define pr_fmt(fmt) "%s: " fmt, __func__
14
15#include <linux/delay.h>
16#include <linux/io.h>
17#include <linux/slab.h>
18#include <linux/stat.h>
19#include <linux/types.h>
20#include <linux/kthread.h>
21
22#include <linux/hdcp_qseecom.h>
23#include "mdss_hdmi_hdcp.h"
24#include "video/msm_hdmi_hdcp_mgr.h"
25#include "mdss_hdmi_util.h"
26
27/*
28 * Defined addresses and offsets of standard HDCP 2.2 sink registers
29 * for DDC, as defined in HDCP 2.2 spec section 2.14 table 2.7
30 */
31#define HDCP_SINK_DDC_SLAVE_ADDR 0x74 /* Sink DDC slave address */
32#define HDCP_SINK_DDC_HDCP2_VERSION 0x50 /* Does sink support HDCP2.2 */
33#define HDCP_SINK_DDC_HDCP2_WRITE_MESSAGE 0x60 /* HDCP Tx writes here */
34#define HDCP_SINK_DDC_HDCP2_RXSTATUS 0x70 /* RxStatus, 2 bytes */
35#define HDCP_SINK_DDC_HDCP2_READ_MESSAGE 0x80 /* HDCP Tx reads here */
36
37#define HDCP2P2_DEFAULT_TIMEOUT 500
38
39/*
40 * HDCP 2.2 encryption requires the data encryption block that is present in
41 * HDMI controller version 4.0.0 and above
42 */
43#define MIN_HDMI_TX_MAJOR_VERSION 4
44
45enum hdmi_hdcp2p2_sink_status {
46 SINK_DISCONNECTED,
47 SINK_CONNECTED
48};
49
50enum hdmi_auth_status {
51 HDMI_HDCP_AUTH_STATUS_FAILURE,
52 HDMI_HDCP_AUTH_STATUS_SUCCESS
53};
54
55struct hdmi_hdcp2p2_ctrl {
56 atomic_t auth_state;
57 bool tethered;
58 enum hdmi_hdcp2p2_sink_status sink_status; /* Is sink connected */
59 struct hdmi_hdcp_init_data init_data; /* Feature data from HDMI drv */
60 struct mutex mutex; /* mutex to protect access to ctrl */
61 struct mutex msg_lock; /* mutex to protect access to msg buffer */
62 struct mutex wakeup_mutex; /* mutex to protect access to wakeup call*/
63 struct hdmi_hdcp_ops *ops;
64 void *lib_ctx; /* Handle to HDCP 2.2 Trustzone library */
65 struct hdcp_txmtr_ops *lib; /* Ops for driver to call into TZ */
66
Sachin Bhayare3d3767e2018-01-02 21:10:57 +053067 enum hdcp_wakeup_cmd wakeup_cmd;
Sachin Bhayareeeb88892018-01-02 16:36:01 +053068 enum hdmi_auth_status auth_status;
69 char *send_msg_buf;
70 uint32_t send_msg_len;
71 uint32_t timeout;
72 uint32_t timeout_left;
73
74 struct task_struct *thread;
75 struct kthread_worker worker;
76 struct kthread_work status;
77 struct kthread_work auth;
78 struct kthread_work send_msg;
79 struct kthread_work recv_msg;
80 struct kthread_work link;
81 struct kthread_work poll;
82};
83
84static int hdmi_hdcp2p2_auth(struct hdmi_hdcp2p2_ctrl *ctrl);
85static void hdmi_hdcp2p2_send_msg(struct hdmi_hdcp2p2_ctrl *ctrl);
86static void hdmi_hdcp2p2_recv_msg(struct hdmi_hdcp2p2_ctrl *ctrl);
87static void hdmi_hdcp2p2_auth_status(struct hdmi_hdcp2p2_ctrl *ctrl);
88static int hdmi_hdcp2p2_link_check(struct hdmi_hdcp2p2_ctrl *ctrl);
89
90static inline bool hdmi_hdcp2p2_is_valid_state(struct hdmi_hdcp2p2_ctrl *ctrl)
91{
Sachin Bhayare3d3767e2018-01-02 21:10:57 +053092 if (ctrl->wakeup_cmd == HDCP_WKUP_CMD_AUTHENTICATE)
Sachin Bhayareeeb88892018-01-02 16:36:01 +053093 return true;
94
95 if (atomic_read(&ctrl->auth_state) != HDCP_STATE_INACTIVE)
96 return true;
97
98 return false;
99}
100
101static int hdmi_hdcp2p2_copy_buf(struct hdmi_hdcp2p2_ctrl *ctrl,
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530102 struct hdcp_wakeup_data *data)
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530103{
104 mutex_lock(&ctrl->msg_lock);
105
106 if (!data->send_msg_len) {
107 mutex_unlock(&ctrl->msg_lock);
108 return 0;
109 }
110
111 ctrl->send_msg_len = data->send_msg_len;
112
113 kzfree(ctrl->send_msg_buf);
114
115 ctrl->send_msg_buf = kzalloc(data->send_msg_len, GFP_KERNEL);
116
117 if (!ctrl->send_msg_buf) {
118 mutex_unlock(&ctrl->msg_lock);
119 return -ENOMEM;
120 }
121
122 memcpy(ctrl->send_msg_buf, data->send_msg_buf, ctrl->send_msg_len);
123
124 mutex_unlock(&ctrl->msg_lock);
125
126 return 0;
127}
128
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530129static int hdmi_hdcp2p2_wakeup(struct hdcp_wakeup_data *data)
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530130{
131 struct hdmi_hdcp2p2_ctrl *ctrl;
132
133 if (!data) {
134 pr_err("invalid input\n");
135 return -EINVAL;
136 }
137
138 ctrl = data->context;
139 if (!ctrl) {
140 pr_err("invalid ctrl\n");
141 return -EINVAL;
142 }
143
144 mutex_lock(&ctrl->wakeup_mutex);
145
146 pr_debug("cmd: %s, timeout %dms, tethered %d\n",
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530147 hdcp_cmd_to_str(data->cmd),
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530148 data->timeout, ctrl->tethered);
149
150 ctrl->wakeup_cmd = data->cmd;
151
152 if (data->timeout)
153 ctrl->timeout = data->timeout * 2;
154 else
155 ctrl->timeout = HDCP2P2_DEFAULT_TIMEOUT;
156
157 if (!hdmi_hdcp2p2_is_valid_state(ctrl)) {
158 pr_err("invalid state\n");
159 goto exit;
160 }
161
162 if (hdmi_hdcp2p2_copy_buf(ctrl, data))
163 goto exit;
164
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530165 if (ctrl->wakeup_cmd == HDCP_WKUP_CMD_STATUS_SUCCESS)
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530166 ctrl->auth_status = HDMI_HDCP_AUTH_STATUS_SUCCESS;
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530167 else if (ctrl->wakeup_cmd == HDCP_WKUP_CMD_STATUS_FAILED)
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530168 ctrl->auth_status = HDMI_HDCP_AUTH_STATUS_FAILURE;
169
170 if (ctrl->tethered)
171 goto exit;
172
173 switch (ctrl->wakeup_cmd) {
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530174 case HDCP_WKUP_CMD_SEND_MESSAGE:
175 kthread_queue_work(&ctrl->worker, &ctrl->send_msg);
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530176 break;
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530177 case HDCP_WKUP_CMD_RECV_MESSAGE:
178 kthread_queue_work(&ctrl->worker, &ctrl->recv_msg);
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530179 break;
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530180 case HDCP_WKUP_CMD_STATUS_SUCCESS:
181 case HDCP_WKUP_CMD_STATUS_FAILED:
182 kthread_queue_work(&ctrl->worker, &ctrl->status);
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530183 break;
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530184 case HDCP_WKUP_CMD_LINK_POLL:
185 kthread_queue_work(&ctrl->worker, &ctrl->poll);
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530186 break;
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530187 case HDCP_WKUP_CMD_AUTHENTICATE:
188 kthread_queue_work(&ctrl->worker, &ctrl->auth);
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530189 break;
190 default:
191 pr_err("invalid wakeup command %d\n", ctrl->wakeup_cmd);
192 }
193exit:
194 mutex_unlock(&ctrl->wakeup_mutex);
195 return 0;
196}
197
198static inline int hdmi_hdcp2p2_wakeup_lib(struct hdmi_hdcp2p2_ctrl *ctrl,
199 struct hdcp_lib_wakeup_data *data)
200{
201 int rc = 0;
202
203 if (ctrl && ctrl->lib && ctrl->lib->wakeup &&
204 data && (data->cmd != HDCP_LIB_WKUP_CMD_INVALID)) {
205 rc = ctrl->lib->wakeup(data);
206 if (rc)
207 pr_err("error sending %s to lib\n",
208 hdcp_lib_cmd_to_str(data->cmd));
209 }
210
211 return rc;
212}
213
214static void hdmi_hdcp2p2_run(struct hdmi_hdcp2p2_ctrl *ctrl)
215{
216 if (!ctrl) {
217 pr_err("invalid input\n");
218 return;
219 }
220
221 while (1) {
222 switch (ctrl->wakeup_cmd) {
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530223 case HDCP_WKUP_CMD_SEND_MESSAGE:
224 ctrl->wakeup_cmd = HDCP_WKUP_CMD_INVALID;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530225 hdmi_hdcp2p2_send_msg(ctrl);
226 break;
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530227 case HDCP_WKUP_CMD_RECV_MESSAGE:
228 ctrl->wakeup_cmd = HDCP_WKUP_CMD_INVALID;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530229 hdmi_hdcp2p2_recv_msg(ctrl);
230 break;
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530231 case HDCP_WKUP_CMD_STATUS_SUCCESS:
232 case HDCP_WKUP_CMD_STATUS_FAILED:
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530233 hdmi_hdcp2p2_auth_status(ctrl);
234 goto exit;
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530235 case HDCP_WKUP_CMD_LINK_POLL:
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530236 hdmi_hdcp2p2_link_check(ctrl);
237 goto exit;
238 default:
239 goto exit;
240 }
241 }
242exit:
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530243 ctrl->wakeup_cmd = HDCP_WKUP_CMD_INVALID;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530244}
245
246int hdmi_hdcp2p2_authenticate_tethered(struct hdmi_hdcp2p2_ctrl *ctrl)
247{
248 int rc = 0;
249
250 if (!ctrl) {
251 pr_err("invalid input\n");
252 rc = -EINVAL;
253 goto exit;
254 }
255
256 rc = hdmi_hdcp2p2_auth(ctrl);
257 if (rc) {
258 pr_err("auth failed %d\n", rc);
259 goto exit;
260 }
261
262 hdmi_hdcp2p2_run(ctrl);
263exit:
264 return rc;
265}
266
267static void hdmi_hdcp2p2_reset(struct hdmi_hdcp2p2_ctrl *ctrl)
268{
269 if (!ctrl) {
270 pr_err("invalid input\n");
271 return;
272 }
273
274 ctrl->sink_status = SINK_DISCONNECTED;
275 atomic_set(&ctrl->auth_state, HDCP_STATE_INACTIVE);
276}
277
278static void hdmi_hdcp2p2_off(void *input)
279{
280 struct hdmi_hdcp2p2_ctrl *ctrl = (struct hdmi_hdcp2p2_ctrl *)input;
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530281 struct hdcp_wakeup_data cdata = {HDCP_WKUP_CMD_AUTHENTICATE};
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530282
283 if (!ctrl) {
284 pr_err("invalid input\n");
285 return;
286 }
287
288 hdmi_hdcp2p2_reset(ctrl);
289
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530290 kthread_flush_worker(&ctrl->worker);
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530291
292 hdmi_hdcp2p2_ddc_disable(ctrl->init_data.ddc_ctrl);
293
294 if (ctrl->tethered) {
295 hdmi_hdcp2p2_auth(ctrl);
296 } else {
297 cdata.context = input;
298 hdmi_hdcp2p2_wakeup(&cdata);
299 }
300}
301
302static int hdmi_hdcp2p2_authenticate(void *input)
303{
304 struct hdmi_hdcp2p2_ctrl *ctrl = input;
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530305 struct hdcp_wakeup_data cdata = {HDCP_WKUP_CMD_AUTHENTICATE};
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530306 u32 regval;
307 int rc = 0;
308
309 /* Enable authentication success interrupt */
310 regval = DSS_REG_R(ctrl->init_data.core_io, HDMI_HDCP_INT_CTRL2);
311 regval |= BIT(1) | BIT(2);
312
313 DSS_REG_W(ctrl->init_data.core_io, HDMI_HDCP_INT_CTRL2, regval);
314
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530315 kthread_flush_worker(&ctrl->worker);
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530316
317 ctrl->sink_status = SINK_CONNECTED;
318 atomic_set(&ctrl->auth_state, HDCP_STATE_AUTHENTICATING);
319
320 /* make sure ddc is idle before starting hdcp 2.2 authentication */
321 hdmi_scrambler_ddc_disable(ctrl->init_data.ddc_ctrl);
322 hdmi_hdcp2p2_ddc_disable(ctrl->init_data.ddc_ctrl);
323
324 if (ctrl->tethered) {
325 hdmi_hdcp2p2_authenticate_tethered(ctrl);
326 } else {
327 cdata.context = input;
328 hdmi_hdcp2p2_wakeup(&cdata);
329 }
330
331 return rc;
332}
333
334static int hdmi_hdcp2p2_reauthenticate(void *input)
335{
336 struct hdmi_hdcp2p2_ctrl *ctrl = (struct hdmi_hdcp2p2_ctrl *)input;
337
338 if (!ctrl) {
339 pr_err("invalid input\n");
340 return -EINVAL;
341 }
342
343 hdmi_hdcp2p2_reset((struct hdmi_hdcp2p2_ctrl *)input);
344
345 return hdmi_hdcp2p2_authenticate(input);
346}
347
348static ssize_t hdmi_hdcp2p2_sysfs_rda_tethered(struct device *dev,
349 struct device_attribute *attr, char *buf)
350{
351 ssize_t ret;
352 struct hdmi_hdcp2p2_ctrl *ctrl =
353 hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_HDCP2P2);
354
355 if (!ctrl) {
356 pr_err("invalid input\n");
357 return -EINVAL;
358 }
359
360 mutex_lock(&ctrl->mutex);
361 ret = snprintf(buf, PAGE_SIZE, "%d\n", ctrl->tethered);
362 mutex_unlock(&ctrl->mutex);
363
364 return ret;
365}
366
367static ssize_t hdmi_hdcp2p2_sysfs_wta_tethered(struct device *dev,
368 struct device_attribute *attr, const char *buf, size_t count)
369{
370 struct hdmi_hdcp2p2_ctrl *ctrl =
371 hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_HDCP2P2);
372 int rc, tethered;
373
374 if (!ctrl) {
375 pr_err("invalid input\n");
376 return -EINVAL;
377 }
378
379 mutex_lock(&ctrl->mutex);
380 rc = kstrtoint(buf, 10, &tethered);
381 if (rc) {
382 pr_err("kstrtoint failed. rc=%d\n", rc);
383 goto exit;
384 }
385
386 ctrl->tethered = !!tethered;
387
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530388 //if (ctrl->lib && ctrl->lib->update_exec_type && ctrl->lib_ctx)
389 // ctrl->lib->update_exec_type(ctrl->lib_ctx, ctrl->tethered);
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530390exit:
391 mutex_unlock(&ctrl->mutex);
392
393 return count;
394}
395
396static ssize_t hdmi_hdcp2p2_sysfs_wta_min_level_change(struct device *dev,
397 struct device_attribute *attr, const char *buf, size_t count)
398{
399 struct hdmi_hdcp2p2_ctrl *ctrl =
400 hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_HDCP2P2);
401 struct hdcp_lib_wakeup_data cdata = {
402 HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE};
403 bool enc_notify = true;
404 enum hdmi_hdcp_state enc_lvl;
405 int min_enc_lvl;
406 int rc;
407
408 if (!ctrl) {
409 pr_err("invalid input\n");
410 rc = -EINVAL;
411 goto exit;
412 }
413
414 rc = kstrtoint(buf, 10, &min_enc_lvl);
415 if (rc) {
416 DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc);
417 goto exit;
418 }
419
420 switch (min_enc_lvl) {
421 case 0:
422 enc_lvl = HDCP_STATE_AUTH_ENC_NONE;
423 break;
424 case 1:
425 enc_lvl = HDCP_STATE_AUTH_ENC_1X;
426 break;
427 case 2:
428 enc_lvl = HDCP_STATE_AUTH_ENC_2P2;
429 break;
430 default:
431 enc_notify = false;
432 }
433
434 pr_debug("enc level changed %d\n", min_enc_lvl);
435
436 cdata.context = ctrl->lib_ctx;
437 hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata);
438
439 if (ctrl->tethered)
440 hdmi_hdcp2p2_run(ctrl);
441
442 if (enc_notify && ctrl->init_data.notify_status)
443 ctrl->init_data.notify_status(ctrl->init_data.cb_data, enc_lvl);
444
445 rc = count;
446exit:
447 return rc;
448}
449
450static void hdmi_hdcp2p2_auth_failed(struct hdmi_hdcp2p2_ctrl *ctrl)
451{
452 if (!ctrl) {
453 pr_err("invalid input\n");
454 return;
455 }
456
457 atomic_set(&ctrl->auth_state, HDCP_STATE_AUTH_FAIL);
458
459 hdmi_hdcp2p2_ddc_disable(ctrl->init_data.ddc_ctrl);
460
461 /* notify hdmi tx about HDCP failure */
462 ctrl->init_data.notify_status(ctrl->init_data.cb_data,
463 HDCP_STATE_AUTH_FAIL);
464}
465
466static int hdmi_hdcp2p2_ddc_read_message(struct hdmi_hdcp2p2_ctrl *ctrl,
467 u8 *buf, int size, u32 timeout)
468{
469 struct hdmi_tx_ddc_data ddc_data;
470 int rc;
471
472 if (atomic_read(&ctrl->auth_state) == HDCP_STATE_INACTIVE) {
473 pr_err("hdcp is off\n");
474 return -EINVAL;
475 }
476
477 memset(&ddc_data, 0, sizeof(ddc_data));
478 ddc_data.dev_addr = HDCP_SINK_DDC_SLAVE_ADDR;
479 ddc_data.offset = HDCP_SINK_DDC_HDCP2_READ_MESSAGE;
480 ddc_data.data_buf = buf;
481 ddc_data.data_len = size;
482 ddc_data.request_len = size;
483 ddc_data.retry = 0;
484 ddc_data.hard_timeout = timeout;
485 ddc_data.what = "HDCP2ReadMessage";
486
487 ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;
488
489 pr_debug("read msg timeout %dms\n", timeout);
490
491 rc = hdmi_ddc_read(ctrl->init_data.ddc_ctrl);
492 if (rc)
493 pr_err("Cannot read HDCP message register\n");
494
495 ctrl->timeout_left = ctrl->init_data.ddc_ctrl->ddc_data.timeout_left;
496
497 return rc;
498}
499
500int hdmi_hdcp2p2_ddc_write_message(struct hdmi_hdcp2p2_ctrl *ctrl,
501 u8 *buf, size_t size)
502{
503 struct hdmi_tx_ddc_data ddc_data;
504 int rc;
505
506 memset(&ddc_data, 0, sizeof(ddc_data));
507 ddc_data.dev_addr = HDCP_SINK_DDC_SLAVE_ADDR;
508 ddc_data.offset = HDCP_SINK_DDC_HDCP2_WRITE_MESSAGE;
509 ddc_data.data_buf = buf;
510 ddc_data.data_len = size;
511 ddc_data.hard_timeout = ctrl->timeout;
512 ddc_data.what = "HDCP2WriteMessage";
513
514 ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;
515
516 rc = hdmi_ddc_write(ctrl->init_data.ddc_ctrl);
517 if (rc)
518 pr_err("Cannot write HDCP message register\n");
519
520 ctrl->timeout_left = ctrl->init_data.ddc_ctrl->ddc_data.timeout_left;
521
522 return rc;
523}
524
525static int hdmi_hdcp2p2_read_version(struct hdmi_hdcp2p2_ctrl *ctrl,
526 u8 *hdcp2version)
527{
528 struct hdmi_tx_ddc_data ddc_data;
529 int rc;
530
531 memset(&ddc_data, 0, sizeof(ddc_data));
532 ddc_data.dev_addr = HDCP_SINK_DDC_SLAVE_ADDR;
533 ddc_data.offset = HDCP_SINK_DDC_HDCP2_VERSION;
534 ddc_data.data_buf = hdcp2version;
535 ddc_data.data_len = 1;
536 ddc_data.request_len = 1;
537 ddc_data.retry = 1;
538 ddc_data.what = "HDCP2Version";
539
540 ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;
541
542 rc = hdmi_ddc_read(ctrl->init_data.ddc_ctrl);
543 if (rc) {
544 pr_err("Cannot read HDCP2Version register");
545 return rc;
546 }
547
548 pr_debug("Read HDCP2Version as %u\n", *hdcp2version);
549 return rc;
550}
551
552static DEVICE_ATTR(min_level_change, 0200, NULL,
553 hdmi_hdcp2p2_sysfs_wta_min_level_change);
554static DEVICE_ATTR(tethered, 0644, hdmi_hdcp2p2_sysfs_rda_tethered,
555 hdmi_hdcp2p2_sysfs_wta_tethered);
556
557static struct attribute *hdmi_hdcp2p2_fs_attrs[] = {
558 &dev_attr_min_level_change.attr,
559 &dev_attr_tethered.attr,
560 NULL,
561};
562
563static struct attribute_group hdmi_hdcp2p2_fs_attr_group = {
564 .name = "hdcp2p2",
565 .attrs = hdmi_hdcp2p2_fs_attrs,
566};
567
568static bool hdmi_hdcp2p2_feature_supported(void *input)
569{
570 struct hdmi_hdcp2p2_ctrl *ctrl = input;
571 struct hdcp_txmtr_ops *lib = NULL;
572 bool supported = false;
573
574 if (!ctrl) {
575 pr_err("invalid input\n");
576 goto end;
577 }
578
579 lib = ctrl->lib;
580 if (!lib) {
581 pr_err("invalid lib ops data\n");
582 goto end;
583 }
584
585 if (lib->feature_supported)
586 supported = lib->feature_supported(
587 ctrl->lib_ctx);
588end:
589 return supported;
590}
591
592static void hdmi_hdcp2p2_send_msg(struct hdmi_hdcp2p2_ctrl *ctrl)
593{
594 int rc = 0;
595 struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_INVALID};
596 uint32_t msglen;
597 char *msg = NULL;
598
599 if (!ctrl) {
600 pr_err("invalid input\n");
601 rc = -EINVAL;
602 goto exit;
603 }
604
605 cdata.context = ctrl->lib_ctx;
606
607 if (atomic_read(&ctrl->auth_state) == HDCP_STATE_INACTIVE) {
608 pr_err("hdcp is off\n");
609 goto exit;
610 }
611
612 mutex_lock(&ctrl->msg_lock);
613 msglen = ctrl->send_msg_len;
614
615 if (!msglen) {
616 mutex_unlock(&ctrl->msg_lock);
617 rc = -EINVAL;
618 goto exit;
619 }
620
621 msg = kzalloc(msglen, GFP_KERNEL);
622 if (!msg) {
623 mutex_unlock(&ctrl->msg_lock);
624 rc = -ENOMEM;
625 goto exit;
626 }
627
628 memcpy(msg, ctrl->send_msg_buf, msglen);
629 mutex_unlock(&ctrl->msg_lock);
630
631 /* Forward the message to the sink */
632 rc = hdmi_hdcp2p2_ddc_write_message(ctrl, msg, (size_t)msglen);
633 if (rc) {
634 pr_err("Error sending msg to sink %d\n", rc);
635 cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_SEND_FAILED;
636 } else {
637 cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_SEND_SUCCESS;
638 cdata.timeout = ctrl->timeout_left;
639 }
640exit:
641 kfree(msg);
642
643 hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata);
644}
645
646static void hdmi_hdcp2p2_send_msg_work(struct kthread_work *work)
647{
648 struct hdmi_hdcp2p2_ctrl *ctrl = container_of(work,
649 struct hdmi_hdcp2p2_ctrl, send_msg);
650
651 hdmi_hdcp2p2_send_msg(ctrl);
652}
653
654static void hdmi_hdcp2p2_link_cb(void *data)
655{
656 struct hdmi_hdcp2p2_ctrl *ctrl = data;
657
658 if (!ctrl) {
659 pr_debug("invalid input\n");
660 return;
661 }
662
663 if (atomic_read(&ctrl->auth_state) != HDCP_STATE_INACTIVE)
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530664 kthread_queue_work(&ctrl->worker, &ctrl->link);
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530665}
666
667static void hdmi_hdcp2p2_recv_msg(struct hdmi_hdcp2p2_ctrl *ctrl)
668{
Krishna Manikandan8120dfc2016-11-28 17:52:45 +0530669 int timeout_hsync = 0, rc = 0;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530670 char *recvd_msg_buf = NULL;
671 struct hdmi_tx_hdcp2p2_ddc_data *ddc_data;
672 struct hdmi_tx_ddc_ctrl *ddc_ctrl;
673 struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_INVALID};
674
675 if (!ctrl) {
676 pr_err("invalid input\n");
677 rc = -EINVAL;
678 goto exit;
679 }
680
681 cdata.context = ctrl->lib_ctx;
682
683 ddc_ctrl = ctrl->init_data.ddc_ctrl;
684 if (!ddc_ctrl) {
685 pr_err("invalid ddc ctrl\n");
686 rc = -EINVAL;
687 goto exit;
688 }
689
690 if (atomic_read(&ctrl->auth_state) == HDCP_STATE_INACTIVE) {
691 pr_err("hdcp is off\n");
692 goto exit;
693 }
694 hdmi_ddc_config(ddc_ctrl);
695
696 ddc_data = &ddc_ctrl->hdcp2p2_ddc_data;
697
698 memset(ddc_data, 0, sizeof(*ddc_data));
699
700 timeout_hsync = hdmi_utils_get_timeout_in_hysnc(
701 ctrl->init_data.timing, ctrl->timeout);
702
703 if (timeout_hsync <= 0) {
704 pr_err("err in timeout hsync calc\n");
705 timeout_hsync = HDMI_DEFAULT_TIMEOUT_HSYNC;
706 }
707
708 pr_debug("timeout for rxstatus %dms, %d hsync\n",
709 ctrl->timeout, timeout_hsync);
710
711 ddc_data->intr_mask = RXSTATUS_MESSAGE_SIZE | RXSTATUS_REAUTH_REQ;
712 ddc_data->timeout_ms = ctrl->timeout;
713 ddc_data->timeout_hsync = timeout_hsync;
714 ddc_data->periodic_timer_hsync = timeout_hsync / 20;
715 ddc_data->read_method = HDCP2P2_RXSTATUS_HW_DDC_SW_TRIGGER;
716 ddc_data->wait = true;
717
718 rc = hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl);
719 if (rc) {
720 pr_err("error reading rxstatus %d\n", rc);
721 goto exit;
722 }
723
724 if (ddc_data->reauth_req) {
725 ddc_data->reauth_req = false;
726
727 pr_debug("reauth triggered by sink\n");
728 rc = -EINVAL;
729 goto exit;
730 }
731
732 ctrl->timeout_left = ddc_data->timeout_left;
733
734 pr_debug("timeout left after rxstatus %dms, msg size %d\n",
735 ctrl->timeout_left, ddc_data->message_size);
736
737 if (!ddc_data->message_size) {
738 pr_err("recvd invalid message size\n");
739 rc = -EINVAL;
740 goto exit;
741 }
742
743 recvd_msg_buf = kzalloc(ddc_data->message_size, GFP_KERNEL);
744 if (!recvd_msg_buf) {
745 rc = -ENOMEM;
746 goto exit;
747 }
748
749 rc = hdmi_hdcp2p2_ddc_read_message(ctrl, recvd_msg_buf,
750 ddc_data->message_size, ctrl->timeout_left);
751 if (rc) {
752 pr_err("error reading message %d\n", rc);
753 goto exit;
754 }
755
756 cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_RECV_SUCCESS;
757 cdata.recvd_msg_buf = recvd_msg_buf;
758 cdata.recvd_msg_len = ddc_data->message_size;
759 cdata.timeout = ctrl->timeout_left;
760exit:
761 if (rc == -ETIMEDOUT)
762 cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT;
763 else if (rc)
764 cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_RECV_FAILED;
765
766 hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata);
767 kfree(recvd_msg_buf);
768}
769
770static void hdmi_hdcp2p2_recv_msg_work(struct kthread_work *work)
771{
772 struct hdmi_hdcp2p2_ctrl *ctrl = container_of(work,
773 struct hdmi_hdcp2p2_ctrl, recv_msg);
774
775 hdmi_hdcp2p2_recv_msg(ctrl);
776}
777
778static int hdmi_hdcp2p2_link_check(struct hdmi_hdcp2p2_ctrl *ctrl)
779{
780 struct hdmi_tx_ddc_ctrl *ddc_ctrl;
781 struct hdmi_tx_hdcp2p2_ddc_data *ddc_data;
782 int timeout_hsync;
783
784 ddc_ctrl = ctrl->init_data.ddc_ctrl;
785 if (!ddc_ctrl)
786 return -EINVAL;
787
788 hdmi_ddc_config(ddc_ctrl);
789
790 ddc_data = &ddc_ctrl->hdcp2p2_ddc_data;
791
792 memset(ddc_data, 0, sizeof(*ddc_data));
793
794 timeout_hsync = hdmi_utils_get_timeout_in_hysnc(
795 ctrl->init_data.timing, jiffies_to_msecs(HZ / 2));
796
797 if (timeout_hsync <= 0) {
798 pr_err("err in timeout hsync calc\n");
799 timeout_hsync = HDMI_DEFAULT_TIMEOUT_HSYNC;
800 }
801 pr_debug("timeout for rxstatus %d hsyncs\n", timeout_hsync);
802
803 ddc_data->intr_mask = RXSTATUS_READY | RXSTATUS_MESSAGE_SIZE |
804 RXSTATUS_REAUTH_REQ;
805 ddc_data->timeout_hsync = timeout_hsync;
806 ddc_data->periodic_timer_hsync = timeout_hsync;
807 ddc_data->read_method = HDCP2P2_RXSTATUS_HW_DDC_SW_TRIGGER;
808 ddc_data->link_cb = hdmi_hdcp2p2_link_cb;
809 ddc_data->link_data = ctrl;
810
811 return hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl);
812}
813
814static void hdmi_hdcp2p2_poll_work(struct kthread_work *work)
815{
816 struct hdmi_hdcp2p2_ctrl *ctrl = container_of(work,
817 struct hdmi_hdcp2p2_ctrl, poll);
818
819 hdmi_hdcp2p2_link_check(ctrl);
820}
821
822static void hdmi_hdcp2p2_auth_status(struct hdmi_hdcp2p2_ctrl *ctrl)
823{
824 if (!ctrl) {
825 pr_err("invalid input\n");
826 return;
827 }
828
829 if (atomic_read(&ctrl->auth_state) == HDCP_STATE_INACTIVE) {
830 pr_err("hdcp is off\n");
831 return;
832 }
833
834 if (ctrl->auth_status == HDMI_HDCP_AUTH_STATUS_SUCCESS) {
835 ctrl->init_data.notify_status(ctrl->init_data.cb_data,
836 HDCP_STATE_AUTHENTICATED);
837
838 atomic_set(&ctrl->auth_state, HDCP_STATE_AUTHENTICATED);
839
840 if (ctrl->tethered)
841 hdmi_hdcp2p2_link_check(ctrl);
842 } else {
843 hdmi_hdcp2p2_auth_failed(ctrl);
844 }
845}
846
847static void hdmi_hdcp2p2_auth_status_work(struct kthread_work *work)
848{
849 struct hdmi_hdcp2p2_ctrl *ctrl = container_of(work,
850 struct hdmi_hdcp2p2_ctrl, status);
851
852 hdmi_hdcp2p2_auth_status(ctrl);
853}
854
855static void hdmi_hdcp2p2_link_work(struct kthread_work *work)
856{
857 int rc = 0;
858 struct hdmi_hdcp2p2_ctrl *ctrl = container_of(work,
859 struct hdmi_hdcp2p2_ctrl, link);
860 struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_INVALID};
861 char *recvd_msg_buf = NULL;
862 struct hdmi_tx_hdcp2p2_ddc_data *ddc_data;
863 struct hdmi_tx_ddc_ctrl *ddc_ctrl;
864
865 if (!ctrl) {
866 pr_err("invalid input\n");
867 return;
868 }
869
870 cdata.context = ctrl->lib_ctx;
871
872 ddc_ctrl = ctrl->init_data.ddc_ctrl;
873 if (!ddc_ctrl) {
874 rc = -EINVAL;
875 cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
876 goto exit;
877 }
878
879 ddc_data = &ddc_ctrl->hdcp2p2_ddc_data;
880
881 if (ddc_data->reauth_req) {
882 pr_debug("reauth triggered by sink\n");
883
884 ddc_data->reauth_req = false;
885 rc = -ENOLINK;
886 cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
887 goto exit;
888 }
889
890 if (ddc_data->ready && ddc_data->message_size) {
891 pr_debug("topology changed. rxstatus msg size %d\n",
892 ddc_data->message_size);
893
894 ddc_data->ready = false;
895
896 recvd_msg_buf = kzalloc(ddc_data->message_size, GFP_KERNEL);
897 if (!recvd_msg_buf) {
898 cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
899 goto exit;
900 }
901
902 rc = hdmi_hdcp2p2_ddc_read_message(ctrl, recvd_msg_buf,
903 ddc_data->message_size, HDCP2P2_DEFAULT_TIMEOUT);
904 if (rc) {
905 cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
906 pr_err("error reading message %d\n", rc);
907 } else {
908 cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_RECV_SUCCESS;
909 cdata.recvd_msg_buf = recvd_msg_buf;
910 cdata.recvd_msg_len = ddc_data->message_size;
911 }
912
913 ddc_data->message_size = 0;
914 }
915exit:
916 hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata);
917 kfree(recvd_msg_buf);
918
919 if (ctrl->tethered)
920 hdmi_hdcp2p2_run(ctrl);
921
922 if (rc) {
923 hdmi_hdcp2p2_auth_failed(ctrl);
924 return;
925 }
926}
927
928static int hdmi_hdcp2p2_auth(struct hdmi_hdcp2p2_ctrl *ctrl)
929{
930 struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_INVALID};
931 int rc = 0;
932
933 if (!ctrl) {
934 pr_err("invalid input\n");
935 return -EINVAL;
936 }
937
938 cdata.context = ctrl->lib_ctx;
939
940 if (atomic_read(&ctrl->auth_state) == HDCP_STATE_AUTHENTICATING)
941 cdata.cmd = HDCP_LIB_WKUP_CMD_START;
942 else
943 cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
944
945 rc = hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata);
946 if (rc)
947 hdmi_hdcp2p2_auth_failed(ctrl);
948
949 return rc;
950}
951
952static void hdmi_hdcp2p2_auth_work(struct kthread_work *work)
953{
954 struct hdmi_hdcp2p2_ctrl *ctrl = container_of(work,
955 struct hdmi_hdcp2p2_ctrl, auth);
956
957 hdmi_hdcp2p2_auth(ctrl);
958}
959
960void hdmi_hdcp2p2_deinit(void *input)
961{
962 struct hdmi_hdcp2p2_ctrl *ctrl = (struct hdmi_hdcp2p2_ctrl *)input;
963 struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_INVALID};
964
965 if (!ctrl) {
966 pr_err("invalid input\n");
967 return;
968 }
969
970 cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
971 cdata.context = ctrl->lib_ctx;
972 hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata);
973
974 kthread_stop(ctrl->thread);
975
976 sysfs_remove_group(ctrl->init_data.sysfs_kobj,
977 &hdmi_hdcp2p2_fs_attr_group);
978
979 mutex_destroy(&ctrl->mutex);
980 mutex_destroy(&ctrl->msg_lock);
981 mutex_destroy(&ctrl->wakeup_mutex);
982 kfree(ctrl);
983}
984
985void *hdmi_hdcp2p2_init(struct hdmi_hdcp_init_data *init_data)
986{
987 int rc;
988 struct hdmi_hdcp2p2_ctrl *ctrl;
989 static struct hdmi_hdcp_ops ops = {
990 .hdmi_hdcp_reauthenticate = hdmi_hdcp2p2_reauthenticate,
991 .hdmi_hdcp_authenticate = hdmi_hdcp2p2_authenticate,
992 .feature_supported = hdmi_hdcp2p2_feature_supported,
993 .hdmi_hdcp_off = hdmi_hdcp2p2_off
994 };
995
996 static struct hdcp_client_ops client_ops = {
997 .wakeup = hdmi_hdcp2p2_wakeup,
998 };
999
1000 static struct hdcp_txmtr_ops txmtr_ops;
1001 struct hdcp_register_data register_data;
1002
1003 pr_debug("HDCP2P2 feature initialization\n");
1004
1005 if (!init_data || !init_data->core_io || !init_data->mutex ||
1006 !init_data->ddc_ctrl || !init_data->notify_status ||
1007 !init_data->workq || !init_data->cb_data) {
1008 pr_err("invalid input\n");
1009 return ERR_PTR(-EINVAL);
1010 }
1011
1012 if (init_data->hdmi_tx_ver < MIN_HDMI_TX_MAJOR_VERSION) {
1013 pr_err("HDMI Tx does not support HDCP 2.2\n");
1014 return ERR_PTR(-ENODEV);
1015 }
1016
1017 ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
1018 if (!ctrl)
1019 return ERR_PTR(-ENOMEM);
1020
1021 ctrl->init_data = *init_data;
1022 ctrl->lib = &txmtr_ops;
1023 ctrl->tethered = init_data->tethered;
1024
1025 rc = sysfs_create_group(init_data->sysfs_kobj,
1026 &hdmi_hdcp2p2_fs_attr_group);
1027 if (rc) {
1028 pr_err("hdcp2p2 sysfs group creation failed\n");
1029 goto error;
1030 }
1031
1032 ctrl->sink_status = SINK_DISCONNECTED;
1033
1034 atomic_set(&ctrl->auth_state, HDCP_STATE_INACTIVE);
1035
1036 ctrl->ops = &ops;
1037 mutex_init(&ctrl->mutex);
1038 mutex_init(&ctrl->msg_lock);
1039 mutex_init(&ctrl->wakeup_mutex);
1040
1041 register_data.hdcp_ctx = &ctrl->lib_ctx;
1042 register_data.client_ops = &client_ops;
1043 register_data.txmtr_ops = &txmtr_ops;
1044 register_data.client_ctx = ctrl;
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05301045 //register_data.tethered = ctrl->tethered;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301046
1047 rc = hdcp_library_register(&register_data);
1048 if (rc) {
1049 pr_err("Unable to register with HDCP 2.2 library\n");
1050 goto error;
1051 }
1052
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05301053 kthread_init_worker(&ctrl->worker);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301054
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05301055 kthread_init_work(&ctrl->auth, hdmi_hdcp2p2_auth_work);
1056 kthread_init_work(&ctrl->send_msg, hdmi_hdcp2p2_send_msg_work);
1057 kthread_init_work(&ctrl->recv_msg, hdmi_hdcp2p2_recv_msg_work);
1058 kthread_init_work(&ctrl->status, hdmi_hdcp2p2_auth_status_work);
1059 kthread_init_work(&ctrl->link, hdmi_hdcp2p2_link_work);
1060 kthread_init_work(&ctrl->poll, hdmi_hdcp2p2_poll_work);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301061
1062 ctrl->thread = kthread_run(kthread_worker_fn,
1063 &ctrl->worker, "hdmi_hdcp2p2");
1064
1065 if (IS_ERR(ctrl->thread)) {
1066 pr_err("unable to start hdcp2p2 thread\n");
1067 rc = PTR_ERR(ctrl->thread);
1068 ctrl->thread = NULL;
1069 goto error;
1070 }
1071
1072 return ctrl;
1073error:
1074 kfree(ctrl);
1075 return ERR_PTR(rc);
1076}
1077
1078static bool hdmi_hdcp2p2_supported(struct hdmi_hdcp2p2_ctrl *ctrl)
1079{
Krishna Manikandan8120dfc2016-11-28 17:52:45 +05301080 u8 hdcp2version = 0;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301081
1082 int rc = hdmi_hdcp2p2_read_version(ctrl, &hdcp2version);
1083
1084 if (rc)
1085 goto error;
1086
1087 if (hdcp2version & BIT(2)) {
1088 pr_debug("Sink is HDCP 2.2 capable\n");
1089 return true;
1090 }
1091
1092error:
1093 pr_debug("Sink is not HDCP 2.2 capable\n");
1094 return false;
1095}
1096
1097struct hdmi_hdcp_ops *hdmi_hdcp2p2_start(void *input)
1098{
1099 struct hdmi_hdcp2p2_ctrl *ctrl = input;
1100
1101 pr_debug("Checking sink capability\n");
1102 if (hdmi_hdcp2p2_supported(ctrl))
1103 return ctrl->ops;
1104 else
1105 return NULL;
1106
1107}
1108