2 * Copyright 2019 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
26 #include <linux/slab.h>
28 #include "dm_services.h"
29 #include "dm_helpers.h"
30 #include "include/hdcp_types.h"
31 #include "include/i2caux_interface.h"
32 #include "include/signal_types.h"
33 #include "core_types.h"
34 #include "dc_link_ddc.h"
35 #include "link_hwss.h"
39 #define HDCP14_KSV_SIZE 5
40 #define HDCP14_MAX_KSV_FIFO_SIZE 127*HDCP14_KSV_SIZE
42 static const bool hdcp_cmd_is_read
[] = {
43 [HDCP_MESSAGE_ID_READ_BKSV
] = true,
44 [HDCP_MESSAGE_ID_READ_RI_R0
] = true,
45 [HDCP_MESSAGE_ID_READ_PJ
] = true,
46 [HDCP_MESSAGE_ID_WRITE_AKSV
] = false,
47 [HDCP_MESSAGE_ID_WRITE_AINFO
] = false,
48 [HDCP_MESSAGE_ID_WRITE_AN
] = false,
49 [HDCP_MESSAGE_ID_READ_VH_X
] = true,
50 [HDCP_MESSAGE_ID_READ_VH_0
] = true,
51 [HDCP_MESSAGE_ID_READ_VH_1
] = true,
52 [HDCP_MESSAGE_ID_READ_VH_2
] = true,
53 [HDCP_MESSAGE_ID_READ_VH_3
] = true,
54 [HDCP_MESSAGE_ID_READ_VH_4
] = true,
55 [HDCP_MESSAGE_ID_READ_BCAPS
] = true,
56 [HDCP_MESSAGE_ID_READ_BSTATUS
] = true,
57 [HDCP_MESSAGE_ID_READ_KSV_FIFO
] = true,
58 [HDCP_MESSAGE_ID_READ_BINFO
] = true,
59 [HDCP_MESSAGE_ID_HDCP2VERSION
] = true,
60 [HDCP_MESSAGE_ID_RX_CAPS
] = true,
61 [HDCP_MESSAGE_ID_WRITE_AKE_INIT
] = false,
62 [HDCP_MESSAGE_ID_READ_AKE_SEND_CERT
] = true,
63 [HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM
] = false,
64 [HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM
] = false,
65 [HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME
] = true,
66 [HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO
] = true,
67 [HDCP_MESSAGE_ID_WRITE_LC_INIT
] = false,
68 [HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME
] = true,
69 [HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS
] = false,
70 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST
] = true,
71 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK
] = false,
72 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE
] = false,
73 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY
] = true,
74 [HDCP_MESSAGE_ID_READ_RXSTATUS
] = true,
75 [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE
] = false
78 static const uint8_t hdcp_i2c_offsets
[] = {
79 [HDCP_MESSAGE_ID_READ_BKSV
] = 0x0,
80 [HDCP_MESSAGE_ID_READ_RI_R0
] = 0x8,
81 [HDCP_MESSAGE_ID_READ_PJ
] = 0xA,
82 [HDCP_MESSAGE_ID_WRITE_AKSV
] = 0x10,
83 [HDCP_MESSAGE_ID_WRITE_AINFO
] = 0x15,
84 [HDCP_MESSAGE_ID_WRITE_AN
] = 0x18,
85 [HDCP_MESSAGE_ID_READ_VH_X
] = 0x20,
86 [HDCP_MESSAGE_ID_READ_VH_0
] = 0x20,
87 [HDCP_MESSAGE_ID_READ_VH_1
] = 0x24,
88 [HDCP_MESSAGE_ID_READ_VH_2
] = 0x28,
89 [HDCP_MESSAGE_ID_READ_VH_3
] = 0x2C,
90 [HDCP_MESSAGE_ID_READ_VH_4
] = 0x30,
91 [HDCP_MESSAGE_ID_READ_BCAPS
] = 0x40,
92 [HDCP_MESSAGE_ID_READ_BSTATUS
] = 0x41,
93 [HDCP_MESSAGE_ID_READ_KSV_FIFO
] = 0x43,
94 [HDCP_MESSAGE_ID_READ_BINFO
] = 0xFF,
95 [HDCP_MESSAGE_ID_HDCP2VERSION
] = 0x50,
96 [HDCP_MESSAGE_ID_WRITE_AKE_INIT
] = 0x60,
97 [HDCP_MESSAGE_ID_READ_AKE_SEND_CERT
] = 0x80,
98 [HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM
] = 0x60,
99 [HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM
] = 0x60,
100 [HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME
] = 0x80,
101 [HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO
] = 0x80,
102 [HDCP_MESSAGE_ID_WRITE_LC_INIT
] = 0x60,
103 [HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME
] = 0x80,
104 [HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS
] = 0x60,
105 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST
] = 0x80,
106 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK
] = 0x60,
107 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE
] = 0x60,
108 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY
] = 0x80,
109 [HDCP_MESSAGE_ID_READ_RXSTATUS
] = 0x70
112 struct protection_properties
{
114 bool (*process_transaction
)(
115 struct dc_link
*link
,
116 struct hdcp_protection_message
*message_info
);
119 static const struct protection_properties non_supported_protection
= {
123 static bool hdmi_14_process_transaction(
124 struct dc_link
*link
,
125 struct hdcp_protection_message
*message_info
)
127 uint8_t *buff
= NULL
;
129 const uint8_t hdcp_i2c_addr_link_primary
= 0x3a; /* 0x74 >> 1*/
130 const uint8_t hdcp_i2c_addr_link_secondary
= 0x3b; /* 0x76 >> 1*/
131 struct i2c_command i2c_command
;
132 uint8_t offset
= hdcp_i2c_offsets
[message_info
->msg_id
];
133 struct i2c_payload i2c_payloads
[] = {
134 { true, 0, 1, &offset
},
135 /* actual hdcp payload, will be filled later, zeroed for now*/
139 switch (message_info
->link
) {
140 case HDCP_LINK_SECONDARY
:
141 i2c_payloads
[0].address
= hdcp_i2c_addr_link_secondary
;
142 i2c_payloads
[1].address
= hdcp_i2c_addr_link_secondary
;
144 case HDCP_LINK_PRIMARY
:
146 i2c_payloads
[0].address
= hdcp_i2c_addr_link_primary
;
147 i2c_payloads
[1].address
= hdcp_i2c_addr_link_primary
;
151 if (hdcp_cmd_is_read
[message_info
->msg_id
]) {
152 i2c_payloads
[1].write
= false;
153 i2c_command
.number_of_payloads
= ARRAY_SIZE(i2c_payloads
);
154 i2c_payloads
[1].length
= message_info
->length
;
155 i2c_payloads
[1].data
= message_info
->data
;
157 i2c_command
.number_of_payloads
= 1;
158 buff
= kzalloc(message_info
->length
+ 1, GFP_KERNEL
);
164 memmove(&buff
[1], message_info
->data
, message_info
->length
);
165 i2c_payloads
[0].length
= message_info
->length
+ 1;
166 i2c_payloads
[0].data
= buff
;
169 i2c_command
.payloads
= i2c_payloads
;
170 i2c_command
.engine
= I2C_COMMAND_ENGINE_HW
;//only HW
171 i2c_command
.speed
= link
->ddc
->ctx
->dc
->caps
.i2c_speed_in_khz
;
173 result
= dm_helpers_submit_i2c(
182 static const struct protection_properties hdmi_14_protection
= {
184 .process_transaction
= hdmi_14_process_transaction
187 static const uint32_t hdcp_dpcd_addrs
[] = {
188 [HDCP_MESSAGE_ID_READ_BKSV
] = 0x68000,
189 [HDCP_MESSAGE_ID_READ_RI_R0
] = 0x68005,
190 [HDCP_MESSAGE_ID_READ_PJ
] = 0xFFFFFFFF,
191 [HDCP_MESSAGE_ID_WRITE_AKSV
] = 0x68007,
192 [HDCP_MESSAGE_ID_WRITE_AINFO
] = 0x6803B,
193 [HDCP_MESSAGE_ID_WRITE_AN
] = 0x6800c,
194 [HDCP_MESSAGE_ID_READ_VH_X
] = 0x68014,
195 [HDCP_MESSAGE_ID_READ_VH_0
] = 0x68014,
196 [HDCP_MESSAGE_ID_READ_VH_1
] = 0x68018,
197 [HDCP_MESSAGE_ID_READ_VH_2
] = 0x6801c,
198 [HDCP_MESSAGE_ID_READ_VH_3
] = 0x68020,
199 [HDCP_MESSAGE_ID_READ_VH_4
] = 0x68024,
200 [HDCP_MESSAGE_ID_READ_BCAPS
] = 0x68028,
201 [HDCP_MESSAGE_ID_READ_BSTATUS
] = 0x68029,
202 [HDCP_MESSAGE_ID_READ_KSV_FIFO
] = 0x6802c,
203 [HDCP_MESSAGE_ID_READ_BINFO
] = 0x6802a,
204 [HDCP_MESSAGE_ID_RX_CAPS
] = 0x6921d,
205 [HDCP_MESSAGE_ID_WRITE_AKE_INIT
] = 0x69000,
206 [HDCP_MESSAGE_ID_READ_AKE_SEND_CERT
] = 0x6900b,
207 [HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM
] = 0x69220,
208 [HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM
] = 0x692a0,
209 [HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME
] = 0x692c0,
210 [HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO
] = 0x692e0,
211 [HDCP_MESSAGE_ID_WRITE_LC_INIT
] = 0x692f0,
212 [HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME
] = 0x692f8,
213 [HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS
] = 0x69318,
214 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST
] = 0x69330,
215 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK
] = 0x693e0,
216 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE
] = 0x693f0,
217 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY
] = 0x69473,
218 [HDCP_MESSAGE_ID_READ_RXSTATUS
] = 0x69493,
219 [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE
] = 0x69494
222 static bool dpcd_access_helper(
223 struct dc_link
*link
,
229 enum dc_status status
;
230 uint32_t cur_length
= 0;
232 uint32_t ksv_read_size
= 0x6803b - 0x6802c;
234 /* Read KSV, need repeatedly handle */
235 if (dpcd_addr
== 0x6802c) {
236 if (length
% HDCP14_KSV_SIZE
) {
237 DC_LOG_ERROR("%s: KsvFifo Size(%d) is not a multiple of HDCP14_KSV_SIZE(%d)\n",
242 if (length
> HDCP14_MAX_KSV_FIFO_SIZE
) {
243 DC_LOG_ERROR("%s: KsvFifo Size(%d) is greater than HDCP14_MAX_KSV_FIFO_SIZE(%d)\n",
246 HDCP14_MAX_KSV_FIFO_SIZE
);
249 DC_LOG_ERROR("%s: Reading %d Ksv(s) from KsvFifo\n",
251 length
/ HDCP14_KSV_SIZE
);
254 if (length
> ksv_read_size
) {
255 status
= core_link_read_dpcd(
261 data
+= ksv_read_size
;
262 length
-= ksv_read_size
;
264 status
= core_link_read_dpcd(
279 if (length
> DEFAULT_AUX_MAX_DATA_SIZE
)
280 cur_length
= DEFAULT_AUX_MAX_DATA_SIZE
;
285 status
= core_link_read_dpcd(
291 status
= core_link_write_dpcd(
301 length
-= cur_length
;
302 offset
+= cur_length
;
308 static bool dp_11_process_transaction(
309 struct dc_link
*link
,
310 struct hdcp_protection_message
*message_info
)
312 return dpcd_access_helper(
314 message_info
->length
,
316 hdcp_dpcd_addrs
[message_info
->msg_id
],
317 hdcp_cmd_is_read
[message_info
->msg_id
]);
320 static const struct protection_properties dp_11_protection
= {
322 .process_transaction
= dp_11_process_transaction
325 static const struct protection_properties
*get_protection_properties_by_signal(
326 struct dc_link
*link
,
328 enum hdcp_version version
)
331 case HDCP_VERSION_14
:
333 case SIGNAL_TYPE_DVI_SINGLE_LINK
:
334 case SIGNAL_TYPE_DVI_DUAL_LINK
:
335 case SIGNAL_TYPE_HDMI_TYPE_A
:
336 return &hdmi_14_protection
;
337 case SIGNAL_TYPE_DISPLAY_PORT
:
339 (link
->dpcd_caps
.dongle_type
== DISPLAY_DONGLE_DP_VGA_CONVERTER
||
340 link
->dpcd_caps
.dongle_caps
.dongle_type
== DISPLAY_DONGLE_DP_VGA_CONVERTER
)) {
341 return &non_supported_protection
;
343 return &dp_11_protection
;
344 case SIGNAL_TYPE_DISPLAY_PORT_MST
:
345 case SIGNAL_TYPE_EDP
:
346 return &dp_11_protection
;
348 return &non_supported_protection
;
351 case HDCP_VERSION_22
:
353 case SIGNAL_TYPE_DVI_SINGLE_LINK
:
354 case SIGNAL_TYPE_DVI_DUAL_LINK
:
355 case SIGNAL_TYPE_HDMI_TYPE_A
:
356 return &hdmi_14_protection
; //todo version2.2
357 case SIGNAL_TYPE_DISPLAY_PORT
:
358 case SIGNAL_TYPE_DISPLAY_PORT_MST
:
359 case SIGNAL_TYPE_EDP
:
360 return &dp_11_protection
; //todo version2.2
362 return &non_supported_protection
;
366 return &non_supported_protection
;
370 enum hdcp_message_status
dc_process_hdcp_msg(
371 enum signal_type signal
,
372 struct dc_link
*link
,
373 struct hdcp_protection_message
*message_info
)
375 enum hdcp_message_status status
= HDCP_MESSAGE_FAILURE
;
378 const struct protection_properties
*protection_props
;
381 return HDCP_MESSAGE_UNSUPPORTED
;
383 if (message_info
->msg_id
< HDCP_MESSAGE_ID_READ_BKSV
||
384 message_info
->msg_id
>= HDCP_MESSAGE_ID_MAX
)
385 return HDCP_MESSAGE_UNSUPPORTED
;
388 get_protection_properties_by_signal(
391 message_info
->version
);
393 if (!protection_props
->supported
)
394 return HDCP_MESSAGE_UNSUPPORTED
;
396 if (protection_props
->process_transaction(
399 status
= HDCP_MESSAGE_SUCCESS
;
401 for (i
= 0; i
< message_info
->max_retries
; i
++) {
402 if (protection_props
->process_transaction(
405 status
= HDCP_MESSAGE_SUCCESS
;