Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Add execution and transition states for HDCP2.2

The module works like a state machine

+-------------+
------> | Execution.c | ------
| +-------------+ |
| V
+----+ +--------+ +--------------+
| DM | -----> | Hdcp.c | <------------ | Transition.c |
+----+ <----- +--------+ +--------------+

This patch adds the execution and transition files for 2.2

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Bhawanpreet Lakha and committed by
Alex Deucher
51466b3f eff682f8

+1764 -9
+2 -1
drivers/gpu/drm/amd/display/modules/hdcp/Makefile
··· 24 24 # 25 25 26 26 HDCP = hdcp_ddc.o hdcp_log.o hdcp_psp.o hdcp.o \ 27 - hdcp1_execution.o hdcp1_transition.o 27 + hdcp1_execution.o hdcp1_transition.o \ 28 + hdcp2_execution.o hdcp2_transition.o 28 29 29 30 AMD_DAL_HDCP = $(addprefix $(AMDDALPATH)/modules/hdcp/,$(HDCP)) 30 31 #$(info ************ DAL-HDCP_MAKEFILE ************)
+78 -8
drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
··· 37 37 HDCP_ERROR_TRACE(hdcp, status); 38 38 } 39 39 40 - hdcp->connection.hdcp1_retry_count++; 40 + if (is_hdcp1(hdcp)) { 41 + hdcp->connection.hdcp1_retry_count++; 42 + } else if (is_hdcp2(hdcp)) { 43 + hdcp->connection.hdcp2_retry_count++; 44 + } 41 45 } 42 46 43 47 static uint8_t is_cp_desired_hdcp1(struct mod_hdcp *hdcp) 44 48 { 45 - int i, display_enabled = 0; 49 + int i, is_auth_needed = 0; 46 50 47 - /* if all displays on the link are disabled, hdcp is not desired */ 51 + /* if all displays on the link don't need authentication, 52 + * hdcp is not desired 53 + */ 48 54 for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) { 49 55 if (hdcp->connection.displays[i].state != MOD_HDCP_DISPLAY_INACTIVE && 50 56 !hdcp->connection.displays[i].adjust.disable) { 51 - display_enabled = 1; 57 + is_auth_needed = 1; 52 58 break; 53 59 } 54 60 } 55 61 56 62 return (hdcp->connection.hdcp1_retry_count < MAX_NUM_OF_ATTEMPTS) && 57 - display_enabled && !hdcp->connection.link.adjust.hdcp1.disable; 63 + is_auth_needed && 64 + !hdcp->connection.link.adjust.hdcp1.disable; 65 + } 66 + 67 + static uint8_t is_cp_desired_hdcp2(struct mod_hdcp *hdcp) 68 + { 69 + int i, is_auth_needed = 0; 70 + 71 + /* if all displays on the link don't need authentication, 72 + * hdcp is not desired 73 + */ 74 + for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) { 75 + if (hdcp->connection.displays[i].state != MOD_HDCP_DISPLAY_INACTIVE && 76 + !hdcp->connection.displays[i].adjust.disable) { 77 + is_auth_needed = 1; 78 + break; 79 + } 80 + } 81 + 82 + return (hdcp->connection.hdcp2_retry_count < MAX_NUM_OF_ATTEMPTS) && 83 + is_auth_needed && 84 + !hdcp->connection.link.adjust.hdcp2.disable && 85 + !hdcp->connection.is_hdcp2_revoked; 58 86 } 59 87 60 88 static enum mod_hdcp_status execution(struct mod_hdcp *hdcp, ··· 110 82 } else if (is_in_hdcp1_dp_states(hdcp)) { 111 83 status = mod_hdcp_hdcp1_dp_execution(hdcp, 112 84 event_ctx, &input->hdcp1); 85 + } else if (is_in_hdcp2_states(hdcp)) { 86 + status = mod_hdcp_hdcp2_execution(hdcp, event_ctx, &input->hdcp2); 87 + } else if (is_in_hdcp2_dp_states(hdcp)) { 88 + status = mod_hdcp_hdcp2_dp_execution(hdcp, 89 + event_ctx, &input->hdcp2); 113 90 } 114 91 out: 115 92 return status; ··· 132 99 133 100 if (is_in_initialized_state(hdcp)) { 134 101 if (is_dp_hdcp(hdcp)) 135 - if (is_cp_desired_hdcp1(hdcp)) { 102 + if (is_cp_desired_hdcp2(hdcp)) { 103 + callback_in_ms(0, output); 104 + set_state_id(hdcp, output, D2_A0_DETERMINE_RX_HDCP_CAPABLE); 105 + } else if (is_cp_desired_hdcp1(hdcp)) { 136 106 callback_in_ms(0, output); 137 107 set_state_id(hdcp, output, D1_A0_DETERMINE_RX_HDCP_CAPABLE); 138 108 } else { ··· 143 107 set_state_id(hdcp, output, HDCP_CP_NOT_DESIRED); 144 108 } 145 109 else if (is_hdmi_dvi_sl_hdcp(hdcp)) 146 - if (is_cp_desired_hdcp1(hdcp)) { 110 + if (is_cp_desired_hdcp2(hdcp)) { 111 + callback_in_ms(0, output); 112 + set_state_id(hdcp, output, H2_A0_KNOWN_HDCP2_CAPABLE_RX); 113 + } else if (is_cp_desired_hdcp1(hdcp)) { 147 114 callback_in_ms(0, output); 148 115 set_state_id(hdcp, output, H1_A0_WAIT_FOR_ACTIVE_RX); 149 116 } else { ··· 165 126 } else if (is_in_hdcp1_dp_states(hdcp)) { 166 127 status = mod_hdcp_hdcp1_dp_transition(hdcp, 167 128 event_ctx, &input->hdcp1, output); 129 + } else if (is_in_hdcp2_states(hdcp)) { 130 + status = mod_hdcp_hdcp2_transition(hdcp, 131 + event_ctx, &input->hdcp2, output); 132 + } else if (is_in_hdcp2_dp_states(hdcp)) { 133 + status = mod_hdcp_hdcp2_dp_transition(hdcp, 134 + event_ctx, &input->hdcp2, output); 168 135 } else { 169 136 status = MOD_HDCP_STATUS_INVALID_STATE; 170 137 } ··· 184 139 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 185 140 186 141 if (is_hdcp1(hdcp)) { 187 - if (hdcp->auth.trans_input.hdcp1.create_session != UNKNOWN) 142 + if (hdcp->auth.trans_input.hdcp1.create_session != UNKNOWN) { 143 + /* TODO - update psp to unify create session failure 144 + * recovery between hdcp1 and 2. 145 + */ 188 146 mod_hdcp_hdcp1_destroy_session(hdcp); 189 147 148 + } 190 149 if (hdcp->auth.trans_input.hdcp1.add_topology == PASS) { 150 + status = mod_hdcp_remove_display_topology(hdcp); 151 + if (status != MOD_HDCP_STATUS_SUCCESS) { 152 + output->callback_needed = 0; 153 + output->watchdog_timer_needed = 0; 154 + goto out; 155 + } 156 + } 157 + HDCP_TOP_RESET_AUTH_TRACE(hdcp); 158 + memset(&hdcp->auth, 0, sizeof(struct mod_hdcp_authentication)); 159 + memset(&hdcp->state, 0, sizeof(struct mod_hdcp_state)); 160 + set_state_id(hdcp, output, HDCP_INITIALIZED); 161 + } else if (is_hdcp2(hdcp)) { 162 + if (hdcp->auth.trans_input.hdcp2.create_session == PASS) { 163 + status = mod_hdcp_hdcp2_destroy_session(hdcp); 164 + if (status != MOD_HDCP_STATUS_SUCCESS) { 165 + output->callback_needed = 0; 166 + output->watchdog_timer_needed = 0; 167 + goto out; 168 + } 169 + } 170 + if (hdcp->auth.trans_input.hdcp2.add_topology == PASS) { 191 171 status = mod_hdcp_remove_display_topology(hdcp); 192 172 if (status != MOD_HDCP_STATUS_SUCCESS) { 193 173 output->callback_needed = 0;
+127
drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h
··· 44 44 #define BINFO_MAX_DEVS_EXCEEDED_MASK_DP 0x0080 45 45 #define BINFO_MAX_CASCADE_EXCEEDED_MASK_DP 0x0800 46 46 47 + #define VERSION_HDCP2_MASK 0x04 47 48 #define RXSTATUS_MSG_SIZE_MASK 0x03FF 48 49 #define RXSTATUS_READY_MASK 0x0400 49 50 #define RXSTATUS_REAUTH_REQUEST_MASK 0x0800 50 51 #define RXIDLIST_DEVICE_COUNT_LOWER_MASK 0xf0 51 52 #define RXIDLIST_DEVICE_COUNT_UPPER_MASK 0x01 53 + #define RXCAPS_BYTE2_HDCP2_VERSION_DP 0x02 52 54 #define RXCAPS_BYTE0_HDCP_CAPABLE_MASK_DP 0x02 53 55 #define RXSTATUS_READY_MASK_DP 0x0001 54 56 #define RXSTATUS_H_P_AVAILABLE_MASK_DP 0x0002 ··· 94 92 uint8_t stream_encryption_dp; 95 93 }; 96 94 95 + struct mod_hdcp_transition_input_hdcp2 { 96 + uint8_t hdcp2version_read; 97 + uint8_t hdcp2_capable_check; 98 + uint8_t add_topology; 99 + uint8_t create_session; 100 + uint8_t ake_init_prepare; 101 + uint8_t ake_init_write; 102 + uint8_t rxstatus_read; 103 + uint8_t ake_cert_available; 104 + uint8_t ake_cert_read; 105 + uint8_t ake_cert_validation; 106 + uint8_t stored_km_write; 107 + uint8_t no_stored_km_write; 108 + uint8_t h_prime_available; 109 + uint8_t h_prime_read; 110 + uint8_t pairing_available; 111 + uint8_t pairing_info_read; 112 + uint8_t h_prime_validation; 113 + uint8_t lc_init_prepare; 114 + uint8_t lc_init_write; 115 + uint8_t l_prime_available_poll; 116 + uint8_t l_prime_read; 117 + uint8_t l_prime_validation; 118 + uint8_t eks_prepare; 119 + uint8_t eks_write; 120 + uint8_t enable_encryption; 121 + uint8_t reauth_request_check; 122 + uint8_t rx_id_list_read; 123 + uint8_t device_count_check; 124 + uint8_t rx_id_list_validation; 125 + uint8_t repeater_auth_ack_write; 126 + uint8_t prepare_stream_manage; 127 + uint8_t stream_manage_write; 128 + uint8_t stream_ready_available; 129 + uint8_t stream_ready_read; 130 + uint8_t stream_ready_validation; 131 + 132 + uint8_t rx_caps_read_dp; 133 + uint8_t content_stream_type_write; 134 + uint8_t link_integrity_check_dp; 135 + uint8_t stream_encryption_dp; 136 + }; 137 + 97 138 union mod_hdcp_transition_input { 98 139 struct mod_hdcp_transition_input_hdcp1 hdcp1; 140 + struct mod_hdcp_transition_input_hdcp2 hdcp2; 99 141 }; 100 142 101 143 struct mod_hdcp_message_hdcp1 { ··· 196 150 struct mod_hdcp_display displays[MAX_NUM_OF_DISPLAYS]; 197 151 uint8_t is_repeater; 198 152 uint8_t is_km_stored; 153 + uint8_t is_hdcp2_revoked; 199 154 struct mod_hdcp_trace trace; 200 155 uint8_t hdcp1_retry_count; 156 + uint8_t hdcp2_retry_count; 201 157 }; 202 158 203 159 /* contains values per authentication cycle */ ··· 267 219 HDCP1_DP_STATE_END = D1_A7_READ_KSV_LIST, 268 220 }; 269 221 222 + enum mod_hdcp_hdcp2_state_id { 223 + HDCP2_STATE_START = HDCP1_DP_STATE_END, 224 + H2_A0_KNOWN_HDCP2_CAPABLE_RX, 225 + H2_A1_SEND_AKE_INIT, 226 + H2_A1_VALIDATE_AKE_CERT, 227 + H2_A1_SEND_NO_STORED_KM, 228 + H2_A1_READ_H_PRIME, 229 + H2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME, 230 + H2_A1_SEND_STORED_KM, 231 + H2_A1_VALIDATE_H_PRIME, 232 + H2_A2_LOCALITY_CHECK, 233 + H2_A3_EXCHANGE_KS_AND_TEST_FOR_REPEATER, 234 + H2_ENABLE_ENCRYPTION, 235 + H2_A5_AUTHENTICATED, 236 + H2_A6_WAIT_FOR_RX_ID_LIST, 237 + H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK, 238 + H2_A9_SEND_STREAM_MANAGEMENT, 239 + H2_A9_VALIDATE_STREAM_READY, 240 + HDCP2_STATE_END = H2_A9_VALIDATE_STREAM_READY, 241 + }; 242 + 243 + enum mod_hdcp_hdcp2_dp_state_id { 244 + HDCP2_DP_STATE_START = HDCP2_STATE_END, 245 + D2_A0_DETERMINE_RX_HDCP_CAPABLE, 246 + D2_A1_SEND_AKE_INIT, 247 + D2_A1_VALIDATE_AKE_CERT, 248 + D2_A1_SEND_NO_STORED_KM, 249 + D2_A1_READ_H_PRIME, 250 + D2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME, 251 + D2_A1_SEND_STORED_KM, 252 + D2_A1_VALIDATE_H_PRIME, 253 + D2_A2_LOCALITY_CHECK, 254 + D2_A34_EXCHANGE_KS_AND_TEST_FOR_REPEATER, 255 + D2_SEND_CONTENT_STREAM_TYPE, 256 + D2_ENABLE_ENCRYPTION, 257 + D2_A5_AUTHENTICATED, 258 + D2_A6_WAIT_FOR_RX_ID_LIST, 259 + D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK, 260 + D2_A9_SEND_STREAM_MANAGEMENT, 261 + D2_A9_VALIDATE_STREAM_READY, 262 + HDCP2_DP_STATE_END = D2_A9_VALIDATE_STREAM_READY, 263 + HDCP_STATE_END = HDCP2_DP_STATE_END, 264 + }; 265 + 270 266 /* hdcp1 executions and transitions */ 271 267 typedef enum mod_hdcp_status (*mod_hdcp_action)(struct mod_hdcp *hdcp); 272 268 uint8_t mod_hdcp_execute_and_set( ··· 329 237 enum mod_hdcp_status mod_hdcp_hdcp1_dp_transition(struct mod_hdcp *hdcp, 330 238 struct mod_hdcp_event_context *event_ctx, 331 239 struct mod_hdcp_transition_input_hdcp1 *input, 240 + struct mod_hdcp_output *output); 241 + 242 + /* hdcp2 executions and transitions */ 243 + enum mod_hdcp_status mod_hdcp_hdcp2_execution(struct mod_hdcp *hdcp, 244 + struct mod_hdcp_event_context *event_ctx, 245 + struct mod_hdcp_transition_input_hdcp2 *input); 246 + enum mod_hdcp_status mod_hdcp_hdcp2_dp_execution(struct mod_hdcp *hdcp, 247 + struct mod_hdcp_event_context *event_ctx, 248 + struct mod_hdcp_transition_input_hdcp2 *input); 249 + enum mod_hdcp_status mod_hdcp_hdcp2_transition(struct mod_hdcp *hdcp, 250 + struct mod_hdcp_event_context *event_ctx, 251 + struct mod_hdcp_transition_input_hdcp2 *input, 252 + struct mod_hdcp_output *output); 253 + enum mod_hdcp_status mod_hdcp_hdcp2_dp_transition(struct mod_hdcp *hdcp, 254 + struct mod_hdcp_event_context *event_ctx, 255 + struct mod_hdcp_transition_input_hdcp2 *input, 332 256 struct mod_hdcp_output *output); 333 257 334 258 /* log functions */ ··· 397 289 enum mod_hdcp_status mod_hdcp_write_aksv(struct mod_hdcp *hdcp); 398 290 enum mod_hdcp_status mod_hdcp_write_ainfo(struct mod_hdcp *hdcp); 399 291 enum mod_hdcp_status mod_hdcp_write_an(struct mod_hdcp *hdcp); 292 + enum mod_hdcp_status mod_hdcp_read_hdcp2version(struct mod_hdcp *hdcp); 400 293 enum mod_hdcp_status mod_hdcp_read_rxcaps(struct mod_hdcp *hdcp); 401 294 enum mod_hdcp_status mod_hdcp_read_rxstatus(struct mod_hdcp *hdcp); 402 295 enum mod_hdcp_status mod_hdcp_read_ake_cert(struct mod_hdcp *hdcp); ··· 461 352 current_state(hdcp) <= HDCP1_DP_STATE_END); 462 353 } 463 354 355 + static inline uint8_t is_in_hdcp2_states(struct mod_hdcp *hdcp) 356 + { 357 + return (current_state(hdcp) > HDCP2_STATE_START && 358 + current_state(hdcp) <= HDCP2_STATE_END); 359 + } 360 + 361 + static inline uint8_t is_in_hdcp2_dp_states(struct mod_hdcp *hdcp) 362 + { 363 + return (current_state(hdcp) > HDCP2_DP_STATE_START && 364 + current_state(hdcp) <= HDCP2_DP_STATE_END); 365 + } 366 + 464 367 static inline uint8_t is_hdcp1(struct mod_hdcp *hdcp) 465 368 { 466 369 return (is_in_hdcp1_states(hdcp) || is_in_hdcp1_dp_states(hdcp)); 370 + } 371 + 372 + static inline uint8_t is_hdcp2(struct mod_hdcp *hdcp) 373 + { 374 + return (is_in_hdcp2_states(hdcp) || is_in_hdcp2_dp_states(hdcp)); 467 375 } 468 376 469 377 static inline uint8_t is_in_cp_not_desired_state(struct mod_hdcp *hdcp) ··· 607 481 static inline void reset_retry_counts(struct mod_hdcp *hdcp) 608 482 { 609 483 hdcp->connection.hdcp1_retry_count = 0; 484 + hdcp->connection.hdcp2_retry_count = 0; 610 485 } 611 486 612 487 #endif /* HDCP_H_ */
+881
drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c
··· 1 + /* 2 + * Copyright 2018 Advanced Micro Devices, Inc. 3 + * 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: 10 + * 11 + * The above copyright notice and this permission notice shall be included in 12 + * all copies or substantial portions of the Software. 13 + * 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. 21 + * 22 + * Authors: AMD 23 + * 24 + */ 25 + 26 + #include "hdcp.h" 27 + 28 + static inline enum mod_hdcp_status check_receiver_id_list_ready(struct mod_hdcp *hdcp) 29 + { 30 + uint8_t is_ready = 0; 31 + 32 + if (is_dp_hdcp(hdcp)) 33 + is_ready = (hdcp->auth.msg.hdcp2.rxstatus & RXSTATUS_READY_MASK_DP) ? 1 : 0; 34 + else 35 + is_ready = ((hdcp->auth.msg.hdcp2.rxstatus & RXSTATUS_READY_MASK) && 36 + (hdcp->auth.msg.hdcp2.rxstatus & RXSTATUS_MSG_SIZE_MASK)) ? 1 : 0; 37 + return is_ready ? MOD_HDCP_STATUS_SUCCESS : 38 + MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY; 39 + } 40 + 41 + static inline enum mod_hdcp_status check_hdcp2_capable(struct mod_hdcp *hdcp) 42 + { 43 + enum mod_hdcp_status status; 44 + 45 + if (is_dp_hdcp(hdcp)) 46 + status = ((hdcp->auth.msg.hdcp2.rxcaps_dp[2] & 47 + RXCAPS_BYTE0_HDCP_CAPABLE_MASK_DP) && 48 + (hdcp->auth.msg.hdcp2.rxcaps_dp[0] == 49 + RXCAPS_BYTE2_HDCP2_VERSION_DP)) ? 50 + MOD_HDCP_STATUS_SUCCESS : 51 + MOD_HDCP_STATUS_HDCP2_NOT_CAPABLE; 52 + else 53 + status = (hdcp->auth.msg.hdcp2.hdcp2version_hdmi & VERSION_HDCP2_MASK) ? 54 + MOD_HDCP_STATUS_SUCCESS : 55 + MOD_HDCP_STATUS_HDCP2_NOT_CAPABLE; 56 + return status; 57 + } 58 + 59 + static inline enum mod_hdcp_status check_reauthentication_request( 60 + struct mod_hdcp *hdcp) 61 + { 62 + uint8_t ret = 0; 63 + 64 + if (is_dp_hdcp(hdcp)) 65 + ret = (hdcp->auth.msg.hdcp2.rxstatus & 66 + RXSTATUS_REAUTH_REQUEST_MASK_DP) ? 67 + MOD_HDCP_STATUS_HDCP2_REAUTH_REQUEST : 68 + MOD_HDCP_STATUS_SUCCESS; 69 + else 70 + ret = (hdcp->auth.msg.hdcp2.rxstatus & RXSTATUS_REAUTH_REQUEST_MASK) ? 71 + MOD_HDCP_STATUS_HDCP2_REAUTH_REQUEST : 72 + MOD_HDCP_STATUS_SUCCESS; 73 + return ret; 74 + } 75 + 76 + static inline enum mod_hdcp_status check_link_integrity_failure_dp( 77 + struct mod_hdcp *hdcp) 78 + { 79 + return (hdcp->auth.msg.hdcp2.rxstatus & 80 + RXSTATUS_LINK_INTEGRITY_FAILURE_MASK_DP) ? 81 + MOD_HDCP_STATUS_HDCP2_REAUTH_LINK_INTEGRITY_FAILURE : 82 + MOD_HDCP_STATUS_SUCCESS; 83 + } 84 + 85 + static enum mod_hdcp_status check_ake_cert_available(struct mod_hdcp *hdcp) 86 + { 87 + enum mod_hdcp_status status; 88 + uint16_t size; 89 + 90 + if (is_dp_hdcp(hdcp)) { 91 + status = MOD_HDCP_STATUS_SUCCESS; 92 + } else { 93 + status = mod_hdcp_read_rxstatus(hdcp); 94 + if (status == MOD_HDCP_STATUS_SUCCESS) { 95 + size = hdcp->auth.msg.hdcp2.rxstatus & RXSTATUS_MSG_SIZE_MASK; 96 + status = (size == sizeof(hdcp->auth.msg.hdcp2.ake_cert)) ? 97 + MOD_HDCP_STATUS_SUCCESS : 98 + MOD_HDCP_STATUS_HDCP2_AKE_CERT_PENDING; 99 + } 100 + } 101 + return status; 102 + } 103 + 104 + static enum mod_hdcp_status check_h_prime_available(struct mod_hdcp *hdcp) 105 + { 106 + enum mod_hdcp_status status; 107 + uint8_t size; 108 + 109 + status = mod_hdcp_read_rxstatus(hdcp); 110 + if (status != MOD_HDCP_STATUS_SUCCESS) 111 + goto out; 112 + 113 + if (is_dp_hdcp(hdcp)) { 114 + status = (hdcp->auth.msg.hdcp2.rxstatus & RXSTATUS_H_P_AVAILABLE_MASK_DP) ? 115 + MOD_HDCP_STATUS_SUCCESS : 116 + MOD_HDCP_STATUS_HDCP2_H_PRIME_PENDING; 117 + } else { 118 + size = hdcp->auth.msg.hdcp2.rxstatus & RXSTATUS_MSG_SIZE_MASK; 119 + status = (size == sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)) ? 120 + MOD_HDCP_STATUS_SUCCESS : 121 + MOD_HDCP_STATUS_HDCP2_H_PRIME_PENDING; 122 + } 123 + out: 124 + return status; 125 + } 126 + 127 + static enum mod_hdcp_status check_pairing_info_available(struct mod_hdcp *hdcp) 128 + { 129 + enum mod_hdcp_status status; 130 + uint8_t size; 131 + 132 + status = mod_hdcp_read_rxstatus(hdcp); 133 + if (status != MOD_HDCP_STATUS_SUCCESS) 134 + goto out; 135 + 136 + if (is_dp_hdcp(hdcp)) { 137 + status = (hdcp->auth.msg.hdcp2.rxstatus & RXSTATUS_PAIRING_AVAILABLE_MASK_DP) ? 138 + MOD_HDCP_STATUS_SUCCESS : 139 + MOD_HDCP_STATUS_HDCP2_PAIRING_INFO_PENDING; 140 + } else { 141 + size = hdcp->auth.msg.hdcp2.rxstatus & RXSTATUS_MSG_SIZE_MASK; 142 + status = (size == sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)) ? 143 + MOD_HDCP_STATUS_SUCCESS : 144 + MOD_HDCP_STATUS_HDCP2_PAIRING_INFO_PENDING; 145 + } 146 + out: 147 + return status; 148 + } 149 + 150 + static enum mod_hdcp_status poll_l_prime_available(struct mod_hdcp *hdcp) 151 + { 152 + enum mod_hdcp_status status; 153 + uint8_t size; 154 + uint16_t max_wait = 20000; // units of us 155 + uint16_t num_polls = 5; 156 + uint16_t wait_time = max_wait / num_polls; 157 + 158 + if (is_dp_hdcp(hdcp)) 159 + status = MOD_HDCP_STATUS_INVALID_OPERATION; 160 + else 161 + for (; num_polls; num_polls--) { 162 + udelay(wait_time); 163 + 164 + status = mod_hdcp_read_rxstatus(hdcp); 165 + if (status != MOD_HDCP_STATUS_SUCCESS) 166 + break; 167 + 168 + size = hdcp->auth.msg.hdcp2.rxstatus & RXSTATUS_MSG_SIZE_MASK; 169 + status = (size == sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)) ? 170 + MOD_HDCP_STATUS_SUCCESS : 171 + MOD_HDCP_STATUS_HDCP2_L_PRIME_PENDING; 172 + if (status == MOD_HDCP_STATUS_SUCCESS) 173 + break; 174 + } 175 + return status; 176 + } 177 + 178 + static enum mod_hdcp_status check_stream_ready_available(struct mod_hdcp *hdcp) 179 + { 180 + enum mod_hdcp_status status; 181 + uint8_t size; 182 + 183 + if (is_dp_hdcp(hdcp)) { 184 + status = MOD_HDCP_STATUS_INVALID_OPERATION; 185 + } else { 186 + status = mod_hdcp_read_rxstatus(hdcp); 187 + if (status != MOD_HDCP_STATUS_SUCCESS) 188 + goto out; 189 + size = hdcp->auth.msg.hdcp2.rxstatus & RXSTATUS_MSG_SIZE_MASK; 190 + status = (size == sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)) ? 191 + MOD_HDCP_STATUS_SUCCESS : 192 + MOD_HDCP_STATUS_HDCP2_STREAM_READY_PENDING; 193 + } 194 + out: 195 + return status; 196 + } 197 + 198 + static inline uint8_t get_device_count(struct mod_hdcp *hdcp) 199 + { 200 + return ((hdcp->auth.msg.hdcp2.rx_id_list[2] & RXIDLIST_DEVICE_COUNT_LOWER_MASK) >> 4) + 201 + ((hdcp->auth.msg.hdcp2.rx_id_list[1] & RXIDLIST_DEVICE_COUNT_UPPER_MASK) << 4); 202 + } 203 + 204 + static enum mod_hdcp_status check_device_count(struct mod_hdcp *hdcp) 205 + { 206 + /* device count must be greater than or equal to tracked hdcp displays */ 207 + return (get_device_count(hdcp) < get_added_display_count(hdcp)) ? 208 + MOD_HDCP_STATUS_HDCP2_DEVICE_COUNT_MISMATCH_FAILURE : 209 + MOD_HDCP_STATUS_SUCCESS; 210 + } 211 + 212 + static uint8_t process_rxstatus(struct mod_hdcp *hdcp, 213 + struct mod_hdcp_event_context *event_ctx, 214 + struct mod_hdcp_transition_input_hdcp2 *input, 215 + enum mod_hdcp_status *status) 216 + { 217 + if (!mod_hdcp_execute_and_set(mod_hdcp_read_rxstatus, 218 + &input->rxstatus_read, status, 219 + hdcp, "rxstatus_read")) 220 + goto out; 221 + if (!mod_hdcp_execute_and_set(check_reauthentication_request, 222 + &input->reauth_request_check, status, 223 + hdcp, "reauth_request_check")) 224 + goto out; 225 + if (is_dp_hdcp(hdcp)) { 226 + if (!mod_hdcp_execute_and_set(check_link_integrity_failure_dp, 227 + &input->link_integrity_check_dp, status, 228 + hdcp, "link_integrity_check_dp")) 229 + goto out; 230 + } 231 + if (hdcp->connection.is_repeater) 232 + if (check_receiver_id_list_ready(hdcp) == 233 + MOD_HDCP_STATUS_SUCCESS) { 234 + HDCP_INPUT_PASS_TRACE(hdcp, "rx_id_list_ready"); 235 + event_ctx->rx_id_list_ready = 1; 236 + if (is_dp_hdcp(hdcp)) 237 + hdcp->auth.msg.hdcp2.rx_id_list_size = 238 + sizeof(hdcp->auth.msg.hdcp2.rx_id_list); 239 + else 240 + hdcp->auth.msg.hdcp2.rx_id_list_size = 241 + hdcp->auth.msg.hdcp2.rxstatus & 0x3FF; 242 + } 243 + out: 244 + return (*status == MOD_HDCP_STATUS_SUCCESS); 245 + } 246 + 247 + static enum mod_hdcp_status known_hdcp2_capable_rx(struct mod_hdcp *hdcp, 248 + struct mod_hdcp_event_context *event_ctx, 249 + struct mod_hdcp_transition_input_hdcp2 *input) 250 + { 251 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 252 + 253 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) { 254 + event_ctx->unexpected_event = 1; 255 + goto out; 256 + } 257 + if (!mod_hdcp_execute_and_set(mod_hdcp_read_hdcp2version, 258 + &input->hdcp2version_read, &status, 259 + hdcp, "hdcp2version_read")) 260 + goto out; 261 + if (!mod_hdcp_execute_and_set(check_hdcp2_capable, 262 + &input->hdcp2_capable_check, &status, 263 + hdcp, "hdcp2_capable")) 264 + goto out; 265 + out: 266 + return status; 267 + } 268 + 269 + static enum mod_hdcp_status send_ake_init(struct mod_hdcp *hdcp, 270 + struct mod_hdcp_event_context *event_ctx, 271 + struct mod_hdcp_transition_input_hdcp2 *input) 272 + { 273 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 274 + 275 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) { 276 + event_ctx->unexpected_event = 1; 277 + goto out; 278 + } 279 + if (!mod_hdcp_execute_and_set(mod_hdcp_add_display_topology, 280 + &input->add_topology, &status, 281 + hdcp, "add_topology")) 282 + goto out; 283 + if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_create_session, 284 + &input->create_session, &status, 285 + hdcp, "create_session")) 286 + goto out; 287 + if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_ake_init, 288 + &input->ake_init_prepare, &status, 289 + hdcp, "ake_init_prepare")) 290 + goto out; 291 + if (!mod_hdcp_execute_and_set(mod_hdcp_write_ake_init, 292 + &input->ake_init_write, &status, 293 + hdcp, "ake_init_write")) 294 + goto out; 295 + out: 296 + return status; 297 + } 298 + 299 + static enum mod_hdcp_status validate_ake_cert(struct mod_hdcp *hdcp, 300 + struct mod_hdcp_event_context *event_ctx, 301 + struct mod_hdcp_transition_input_hdcp2 *input) 302 + { 303 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 304 + 305 + 306 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK && 307 + event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) { 308 + event_ctx->unexpected_event = 1; 309 + goto out; 310 + } 311 + 312 + if (is_hdmi_dvi_sl_hdcp(hdcp)) 313 + if (!mod_hdcp_execute_and_set(check_ake_cert_available, 314 + &input->ake_cert_available, &status, 315 + hdcp, "ake_cert_available")) 316 + goto out; 317 + if (!mod_hdcp_execute_and_set(mod_hdcp_read_ake_cert, 318 + &input->ake_cert_read, &status, 319 + hdcp, "ake_cert_read")) 320 + goto out; 321 + if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_ake_cert, 322 + &input->ake_cert_validation, &status, 323 + hdcp, "ake_cert_validation")) 324 + goto out; 325 + out: 326 + return status; 327 + } 328 + 329 + static enum mod_hdcp_status send_no_stored_km(struct mod_hdcp *hdcp, 330 + struct mod_hdcp_event_context *event_ctx, 331 + struct mod_hdcp_transition_input_hdcp2 *input) 332 + { 333 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 334 + 335 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) { 336 + event_ctx->unexpected_event = 1; 337 + goto out; 338 + } 339 + 340 + if (!mod_hdcp_execute_and_set(mod_hdcp_write_no_stored_km, 341 + &input->no_stored_km_write, &status, 342 + hdcp, "no_stored_km_write")) 343 + goto out; 344 + out: 345 + return status; 346 + } 347 + 348 + static enum mod_hdcp_status read_h_prime(struct mod_hdcp *hdcp, 349 + struct mod_hdcp_event_context *event_ctx, 350 + struct mod_hdcp_transition_input_hdcp2 *input) 351 + { 352 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 353 + 354 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK && 355 + event_ctx->event != MOD_HDCP_EVENT_CPIRQ && 356 + event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) { 357 + event_ctx->unexpected_event = 1; 358 + goto out; 359 + } 360 + 361 + if (!mod_hdcp_execute_and_set(check_h_prime_available, 362 + &input->h_prime_available, &status, 363 + hdcp, "h_prime_available")) 364 + goto out; 365 + 366 + if (!mod_hdcp_execute_and_set(mod_hdcp_read_h_prime, 367 + &input->h_prime_read, &status, 368 + hdcp, "h_prime_read")) 369 + goto out; 370 + out: 371 + return status; 372 + } 373 + 374 + static enum mod_hdcp_status read_pairing_info_and_validate_h_prime( 375 + struct mod_hdcp *hdcp, 376 + struct mod_hdcp_event_context *event_ctx, 377 + struct mod_hdcp_transition_input_hdcp2 *input) 378 + { 379 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 380 + 381 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK && 382 + event_ctx->event != MOD_HDCP_EVENT_CPIRQ && 383 + event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) { 384 + event_ctx->unexpected_event = 1; 385 + goto out; 386 + } 387 + 388 + if (!mod_hdcp_execute_and_set(check_pairing_info_available, 389 + &input->pairing_available, &status, 390 + hdcp, "pairing_available")) 391 + goto out; 392 + if (!mod_hdcp_execute_and_set(mod_hdcp_read_pairing_info, 393 + &input->pairing_info_read, &status, 394 + hdcp, "pairing_info_read")) 395 + goto out; 396 + if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_h_prime, 397 + &input->h_prime_validation, &status, 398 + hdcp, "h_prime_validation")) 399 + goto out; 400 + out: 401 + return status; 402 + } 403 + 404 + static enum mod_hdcp_status send_stored_km(struct mod_hdcp *hdcp, 405 + struct mod_hdcp_event_context *event_ctx, 406 + struct mod_hdcp_transition_input_hdcp2 *input) 407 + { 408 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 409 + 410 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) { 411 + event_ctx->unexpected_event = 1; 412 + goto out; 413 + } 414 + 415 + if (!mod_hdcp_execute_and_set(mod_hdcp_write_stored_km, 416 + &input->stored_km_write, &status, 417 + hdcp, "stored_km_write")) 418 + goto out; 419 + out: 420 + return status; 421 + } 422 + 423 + static enum mod_hdcp_status validate_h_prime(struct mod_hdcp *hdcp, 424 + struct mod_hdcp_event_context *event_ctx, 425 + struct mod_hdcp_transition_input_hdcp2 *input) 426 + { 427 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 428 + 429 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK && 430 + event_ctx->event != MOD_HDCP_EVENT_CPIRQ && 431 + event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) { 432 + event_ctx->unexpected_event = 1; 433 + goto out; 434 + } 435 + 436 + if (!mod_hdcp_execute_and_set(check_h_prime_available, 437 + &input->h_prime_available, &status, 438 + hdcp, "h_prime_available")) 439 + goto out; 440 + if (!mod_hdcp_execute_and_set(mod_hdcp_read_h_prime, 441 + &input->h_prime_read, &status, 442 + hdcp, "h_prime_read")) 443 + goto out; 444 + if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_h_prime, 445 + &input->h_prime_validation, &status, 446 + hdcp, "h_prime_validation")) 447 + goto out; 448 + out: 449 + return status; 450 + } 451 + 452 + static enum mod_hdcp_status locality_check(struct mod_hdcp *hdcp, 453 + struct mod_hdcp_event_context *event_ctx, 454 + struct mod_hdcp_transition_input_hdcp2 *input) 455 + { 456 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 457 + 458 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) { 459 + event_ctx->unexpected_event = 1; 460 + goto out; 461 + } 462 + 463 + if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_lc_init, 464 + &input->lc_init_prepare, &status, 465 + hdcp, "lc_init_prepare")) 466 + goto out; 467 + if (!mod_hdcp_execute_and_set(mod_hdcp_write_lc_init, 468 + &input->lc_init_write, &status, 469 + hdcp, "lc_init_write")) 470 + goto out; 471 + if (is_dp_hdcp(hdcp)) 472 + udelay(16000); 473 + else 474 + if (!mod_hdcp_execute_and_set(poll_l_prime_available, 475 + &input->l_prime_available_poll, &status, 476 + hdcp, "l_prime_available_poll")) 477 + goto out; 478 + if (!mod_hdcp_execute_and_set(mod_hdcp_read_l_prime, 479 + &input->l_prime_read, &status, 480 + hdcp, "l_prime_read")) 481 + goto out; 482 + if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_l_prime, 483 + &input->l_prime_validation, &status, 484 + hdcp, "l_prime_validation")) 485 + goto out; 486 + out: 487 + return status; 488 + } 489 + 490 + static enum mod_hdcp_status exchange_ks_and_test_for_repeater(struct mod_hdcp *hdcp, 491 + struct mod_hdcp_event_context *event_ctx, 492 + struct mod_hdcp_transition_input_hdcp2 *input) 493 + { 494 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 495 + 496 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) { 497 + event_ctx->unexpected_event = 1; 498 + goto out; 499 + } 500 + 501 + if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_eks, 502 + &input->eks_prepare, &status, 503 + hdcp, "eks_prepare")) 504 + goto out; 505 + if (!mod_hdcp_execute_and_set(mod_hdcp_write_eks, 506 + &input->eks_write, &status, 507 + hdcp, "eks_write")) 508 + goto out; 509 + out: 510 + return status; 511 + } 512 + 513 + static enum mod_hdcp_status enable_encryption(struct mod_hdcp *hdcp, 514 + struct mod_hdcp_event_context *event_ctx, 515 + struct mod_hdcp_transition_input_hdcp2 *input) 516 + { 517 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 518 + 519 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK && 520 + event_ctx->event != MOD_HDCP_EVENT_CPIRQ) { 521 + event_ctx->unexpected_event = 1; 522 + goto out; 523 + } 524 + if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) { 525 + process_rxstatus(hdcp, event_ctx, input, &status); 526 + goto out; 527 + } 528 + 529 + if (is_hdmi_dvi_sl_hdcp(hdcp)) { 530 + if (!process_rxstatus(hdcp, event_ctx, input, &status)) 531 + goto out; 532 + if (event_ctx->rx_id_list_ready) 533 + goto out; 534 + } 535 + if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_enable_encryption, 536 + &input->enable_encryption, &status, 537 + hdcp, "enable_encryption")) 538 + goto out; 539 + if (is_dp_mst_hdcp(hdcp)) { 540 + if (!mod_hdcp_execute_and_set( 541 + mod_hdcp_hdcp2_enable_dp_stream_encryption, 542 + &input->stream_encryption_dp, &status, 543 + hdcp, "stream_encryption_dp")) 544 + goto out; 545 + } 546 + out: 547 + return status; 548 + } 549 + 550 + static enum mod_hdcp_status authenticated(struct mod_hdcp *hdcp, 551 + struct mod_hdcp_event_context *event_ctx, 552 + struct mod_hdcp_transition_input_hdcp2 *input) 553 + { 554 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 555 + 556 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK && 557 + event_ctx->event != MOD_HDCP_EVENT_CPIRQ) { 558 + event_ctx->unexpected_event = 1; 559 + goto out; 560 + } 561 + 562 + if (!process_rxstatus(hdcp, event_ctx, input, &status)) 563 + goto out; 564 + if (event_ctx->rx_id_list_ready) 565 + goto out; 566 + out: 567 + return status; 568 + } 569 + 570 + static enum mod_hdcp_status wait_for_rx_id_list(struct mod_hdcp *hdcp, 571 + struct mod_hdcp_event_context *event_ctx, 572 + struct mod_hdcp_transition_input_hdcp2 *input) 573 + { 574 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 575 + 576 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK && 577 + event_ctx->event != MOD_HDCP_EVENT_CPIRQ && 578 + event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) { 579 + event_ctx->unexpected_event = 1; 580 + goto out; 581 + } 582 + 583 + if (!process_rxstatus(hdcp, event_ctx, input, &status)) 584 + goto out; 585 + if (!event_ctx->rx_id_list_ready) { 586 + status = MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY; 587 + goto out; 588 + } 589 + out: 590 + return status; 591 + } 592 + 593 + static enum mod_hdcp_status verify_rx_id_list_and_send_ack(struct mod_hdcp *hdcp, 594 + struct mod_hdcp_event_context *event_ctx, 595 + struct mod_hdcp_transition_input_hdcp2 *input) 596 + { 597 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 598 + 599 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK && 600 + event_ctx->event != MOD_HDCP_EVENT_CPIRQ) { 601 + event_ctx->unexpected_event = 1; 602 + goto out; 603 + } 604 + if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) { 605 + process_rxstatus(hdcp, event_ctx, input, &status); 606 + goto out; 607 + } 608 + 609 + if (!mod_hdcp_execute_and_set(mod_hdcp_read_rx_id_list, 610 + &input->rx_id_list_read, 611 + &status, hdcp, "receiver_id_list_read")) 612 + goto out; 613 + if (!mod_hdcp_execute_and_set(check_device_count, 614 + &input->device_count_check, 615 + &status, hdcp, "device_count_check")) 616 + goto out; 617 + if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_rx_id_list, 618 + &input->rx_id_list_validation, 619 + &status, hdcp, "rx_id_list_validation")) 620 + goto out; 621 + if (!mod_hdcp_execute_and_set(mod_hdcp_write_repeater_auth_ack, 622 + &input->repeater_auth_ack_write, 623 + &status, hdcp, "repeater_auth_ack_write")) 624 + goto out; 625 + out: 626 + return status; 627 + } 628 + 629 + static enum mod_hdcp_status send_stream_management(struct mod_hdcp *hdcp, 630 + struct mod_hdcp_event_context *event_ctx, 631 + struct mod_hdcp_transition_input_hdcp2 *input) 632 + { 633 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 634 + 635 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK && 636 + event_ctx->event != MOD_HDCP_EVENT_CPIRQ) { 637 + event_ctx->unexpected_event = 1; 638 + goto out; 639 + } 640 + if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) { 641 + process_rxstatus(hdcp, event_ctx, input, &status); 642 + goto out; 643 + } 644 + 645 + if (is_hdmi_dvi_sl_hdcp(hdcp)) { 646 + if (!process_rxstatus(hdcp, event_ctx, input, &status)) 647 + goto out; 648 + if (event_ctx->rx_id_list_ready) 649 + goto out; 650 + } 651 + if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_stream_management, 652 + &input->prepare_stream_manage, 653 + &status, hdcp, "prepare_stream_manage")) 654 + goto out; 655 + 656 + if (!mod_hdcp_execute_and_set(mod_hdcp_write_stream_manage, 657 + &input->stream_manage_write, 658 + &status, hdcp, "stream_manage_write")) 659 + goto out; 660 + out: 661 + return status; 662 + } 663 + 664 + static enum mod_hdcp_status validate_stream_ready(struct mod_hdcp *hdcp, 665 + struct mod_hdcp_event_context *event_ctx, 666 + struct mod_hdcp_transition_input_hdcp2 *input) 667 + { 668 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 669 + 670 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK && 671 + event_ctx->event != MOD_HDCP_EVENT_CPIRQ && 672 + event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) { 673 + event_ctx->unexpected_event = 1; 674 + goto out; 675 + } 676 + if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) { 677 + process_rxstatus(hdcp, event_ctx, input, &status); 678 + goto out; 679 + } 680 + 681 + if (is_hdmi_dvi_sl_hdcp(hdcp)) { 682 + if (!process_rxstatus(hdcp, event_ctx, input, &status)) 683 + goto out; 684 + if (event_ctx->rx_id_list_ready) { 685 + goto out; 686 + } 687 + } 688 + if (is_hdmi_dvi_sl_hdcp(hdcp)) 689 + if (!mod_hdcp_execute_and_set(check_stream_ready_available, 690 + &input->stream_ready_available, 691 + &status, hdcp, "stream_ready_available")) 692 + goto out; 693 + if (!mod_hdcp_execute_and_set(mod_hdcp_read_stream_ready, 694 + &input->stream_ready_read, 695 + &status, hdcp, "stream_ready_read")) 696 + goto out; 697 + if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_stream_ready, 698 + &input->stream_ready_validation, 699 + &status, hdcp, "stream_ready_validation")) 700 + goto out; 701 + 702 + out: 703 + return status; 704 + } 705 + 706 + static enum mod_hdcp_status determine_rx_hdcp_capable_dp(struct mod_hdcp *hdcp, 707 + struct mod_hdcp_event_context *event_ctx, 708 + struct mod_hdcp_transition_input_hdcp2 *input) 709 + { 710 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 711 + 712 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) { 713 + event_ctx->unexpected_event = 1; 714 + goto out; 715 + } 716 + 717 + if (!mod_hdcp_execute_and_set(mod_hdcp_read_rxcaps, 718 + &input->rx_caps_read_dp, 719 + &status, hdcp, "rx_caps_read_dp")) 720 + goto out; 721 + if (!mod_hdcp_execute_and_set(check_hdcp2_capable, 722 + &input->hdcp2_capable_check, &status, 723 + hdcp, "hdcp2_capable_check")) 724 + goto out; 725 + out: 726 + return status; 727 + } 728 + 729 + static enum mod_hdcp_status send_content_stream_type_dp(struct mod_hdcp *hdcp, 730 + struct mod_hdcp_event_context *event_ctx, 731 + struct mod_hdcp_transition_input_hdcp2 *input) 732 + { 733 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 734 + 735 + if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK && 736 + event_ctx->event != MOD_HDCP_EVENT_CPIRQ) { 737 + event_ctx->unexpected_event = 1; 738 + goto out; 739 + } 740 + 741 + if (!process_rxstatus(hdcp, event_ctx, input, &status)) 742 + goto out; 743 + if (!mod_hdcp_execute_and_set(mod_hdcp_write_content_type, 744 + &input->content_stream_type_write, &status, 745 + hdcp, "content_stream_type_write")) 746 + goto out; 747 + out: 748 + return status; 749 + } 750 + 751 + enum mod_hdcp_status mod_hdcp_hdcp2_execution(struct mod_hdcp *hdcp, 752 + struct mod_hdcp_event_context *event_ctx, 753 + struct mod_hdcp_transition_input_hdcp2 *input) 754 + { 755 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 756 + 757 + switch (current_state(hdcp)) { 758 + case H2_A0_KNOWN_HDCP2_CAPABLE_RX: 759 + status = known_hdcp2_capable_rx(hdcp, event_ctx, input); 760 + break; 761 + case H2_A1_SEND_AKE_INIT: 762 + status = send_ake_init(hdcp, event_ctx, input); 763 + break; 764 + case H2_A1_VALIDATE_AKE_CERT: 765 + status = validate_ake_cert(hdcp, event_ctx, input); 766 + break; 767 + case H2_A1_SEND_NO_STORED_KM: 768 + status = send_no_stored_km(hdcp, event_ctx, input); 769 + break; 770 + case H2_A1_READ_H_PRIME: 771 + status = read_h_prime(hdcp, event_ctx, input); 772 + break; 773 + case H2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME: 774 + status = read_pairing_info_and_validate_h_prime(hdcp, 775 + event_ctx, input); 776 + break; 777 + case H2_A1_SEND_STORED_KM: 778 + status = send_stored_km(hdcp, event_ctx, input); 779 + break; 780 + case H2_A1_VALIDATE_H_PRIME: 781 + status = validate_h_prime(hdcp, event_ctx, input); 782 + break; 783 + case H2_A2_LOCALITY_CHECK: 784 + status = locality_check(hdcp, event_ctx, input); 785 + break; 786 + case H2_A3_EXCHANGE_KS_AND_TEST_FOR_REPEATER: 787 + status = exchange_ks_and_test_for_repeater(hdcp, event_ctx, input); 788 + break; 789 + case H2_ENABLE_ENCRYPTION: 790 + status = enable_encryption(hdcp, event_ctx, input); 791 + break; 792 + case H2_A5_AUTHENTICATED: 793 + status = authenticated(hdcp, event_ctx, input); 794 + break; 795 + case H2_A6_WAIT_FOR_RX_ID_LIST: 796 + status = wait_for_rx_id_list(hdcp, event_ctx, input); 797 + break; 798 + case H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK: 799 + status = verify_rx_id_list_and_send_ack(hdcp, event_ctx, input); 800 + break; 801 + case H2_A9_SEND_STREAM_MANAGEMENT: 802 + status = send_stream_management(hdcp, event_ctx, input); 803 + break; 804 + case H2_A9_VALIDATE_STREAM_READY: 805 + status = validate_stream_ready(hdcp, event_ctx, input); 806 + break; 807 + default: 808 + status = MOD_HDCP_STATUS_INVALID_STATE; 809 + break; 810 + } 811 + 812 + return status; 813 + } 814 + 815 + enum mod_hdcp_status mod_hdcp_hdcp2_dp_execution(struct mod_hdcp *hdcp, 816 + struct mod_hdcp_event_context *event_ctx, 817 + struct mod_hdcp_transition_input_hdcp2 *input) 818 + { 819 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 820 + 821 + switch (current_state(hdcp)) { 822 + case D2_A0_DETERMINE_RX_HDCP_CAPABLE: 823 + status = determine_rx_hdcp_capable_dp(hdcp, event_ctx, input); 824 + break; 825 + case D2_A1_SEND_AKE_INIT: 826 + status = send_ake_init(hdcp, event_ctx, input); 827 + break; 828 + case D2_A1_VALIDATE_AKE_CERT: 829 + status = validate_ake_cert(hdcp, event_ctx, input); 830 + break; 831 + case D2_A1_SEND_NO_STORED_KM: 832 + status = send_no_stored_km(hdcp, event_ctx, input); 833 + break; 834 + case D2_A1_READ_H_PRIME: 835 + status = read_h_prime(hdcp, event_ctx, input); 836 + break; 837 + case D2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME: 838 + status = read_pairing_info_and_validate_h_prime(hdcp, 839 + event_ctx, input); 840 + break; 841 + case D2_A1_SEND_STORED_KM: 842 + status = send_stored_km(hdcp, event_ctx, input); 843 + break; 844 + case D2_A1_VALIDATE_H_PRIME: 845 + status = validate_h_prime(hdcp, event_ctx, input); 846 + break; 847 + case D2_A2_LOCALITY_CHECK: 848 + status = locality_check(hdcp, event_ctx, input); 849 + break; 850 + case D2_A34_EXCHANGE_KS_AND_TEST_FOR_REPEATER: 851 + status = exchange_ks_and_test_for_repeater(hdcp, 852 + event_ctx, input); 853 + break; 854 + case D2_SEND_CONTENT_STREAM_TYPE: 855 + status = send_content_stream_type_dp(hdcp, event_ctx, input); 856 + break; 857 + case D2_ENABLE_ENCRYPTION: 858 + status = enable_encryption(hdcp, event_ctx, input); 859 + break; 860 + case D2_A5_AUTHENTICATED: 861 + status = authenticated(hdcp, event_ctx, input); 862 + break; 863 + case D2_A6_WAIT_FOR_RX_ID_LIST: 864 + status = wait_for_rx_id_list(hdcp, event_ctx, input); 865 + break; 866 + case D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK: 867 + status = verify_rx_id_list_and_send_ack(hdcp, event_ctx, input); 868 + break; 869 + case D2_A9_SEND_STREAM_MANAGEMENT: 870 + status = send_stream_management(hdcp, event_ctx, input); 871 + break; 872 + case D2_A9_VALIDATE_STREAM_READY: 873 + status = validate_stream_ready(hdcp, event_ctx, input); 874 + break; 875 + default: 876 + status = MOD_HDCP_STATUS_INVALID_STATE; 877 + break; 878 + } 879 + 880 + return status; 881 + }
+674
drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c
··· 1 + /* 2 + * Copyright 2018 Advanced Micro Devices, Inc. 3 + * 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: 10 + * 11 + * The above copyright notice and this permission notice shall be included in 12 + * all copies or substantial portions of the Software. 13 + * 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. 21 + * 22 + * Authors: AMD 23 + * 24 + */ 25 + 26 + #include "hdcp.h" 27 + 28 + enum mod_hdcp_status mod_hdcp_hdcp2_transition(struct mod_hdcp *hdcp, 29 + struct mod_hdcp_event_context *event_ctx, 30 + struct mod_hdcp_transition_input_hdcp2 *input, 31 + struct mod_hdcp_output *output) 32 + { 33 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 34 + struct mod_hdcp_connection *conn = &hdcp->connection; 35 + struct mod_hdcp_link_adjustment *adjust = &hdcp->connection.link.adjust; 36 + 37 + switch (current_state(hdcp)) { 38 + case H2_A0_KNOWN_HDCP2_CAPABLE_RX: 39 + if (input->hdcp2version_read != PASS || 40 + input->hdcp2_capable_check != PASS) { 41 + adjust->hdcp2.disable = 1; 42 + callback_in_ms(0, output); 43 + set_state_id(hdcp, output, HDCP_INITIALIZED); 44 + } else { 45 + callback_in_ms(0, output); 46 + set_state_id(hdcp, output, H2_A1_SEND_AKE_INIT); 47 + } 48 + break; 49 + case H2_A1_SEND_AKE_INIT: 50 + if (input->add_topology != PASS || 51 + input->create_session != PASS || 52 + input->ake_init_prepare != PASS) { 53 + /* out of sync with psp state */ 54 + adjust->hdcp2.disable = 1; 55 + fail_and_restart_in_ms(0, &status, output); 56 + break; 57 + } else if (input->ake_init_write != PASS) { 58 + fail_and_restart_in_ms(0, &status, output); 59 + break; 60 + } 61 + set_watchdog_in_ms(hdcp, 100, output); 62 + callback_in_ms(0, output); 63 + set_state_id(hdcp, output, H2_A1_VALIDATE_AKE_CERT); 64 + break; 65 + case H2_A1_VALIDATE_AKE_CERT: 66 + if (input->ake_cert_available != PASS) { 67 + if (event_ctx->event == 68 + MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) { 69 + /* 1A-08: consider ake timeout a failure */ 70 + /* some hdmi receivers are not ready for HDCP 71 + * immediately after video becomes active, 72 + * delay 1s before retry on first HDCP message 73 + * timeout. 74 + */ 75 + fail_and_restart_in_ms(1000, &status, output); 76 + } else { 77 + /* continue ake cert polling*/ 78 + callback_in_ms(10, output); 79 + increment_stay_counter(hdcp); 80 + } 81 + break; 82 + } else if (input->ake_cert_read != PASS || 83 + input->ake_cert_validation != PASS) { 84 + /* 85 + * 1A-09: consider invalid ake cert a failure 86 + * 1A-10: consider receiver id listed in SRM a failure 87 + */ 88 + fail_and_restart_in_ms(0, &status, output); 89 + break; 90 + } 91 + if (conn->is_km_stored && 92 + !adjust->hdcp2.force_no_stored_km) { 93 + callback_in_ms(0, output); 94 + set_state_id(hdcp, output, H2_A1_SEND_STORED_KM); 95 + } else { 96 + callback_in_ms(0, output); 97 + set_state_id(hdcp, output, H2_A1_SEND_NO_STORED_KM); 98 + } 99 + break; 100 + case H2_A1_SEND_NO_STORED_KM: 101 + if (input->no_stored_km_write != PASS) { 102 + fail_and_restart_in_ms(0, &status, output); 103 + break; 104 + } 105 + if (adjust->hdcp2.increase_h_prime_timeout) 106 + set_watchdog_in_ms(hdcp, 2000, output); 107 + else 108 + set_watchdog_in_ms(hdcp, 1000, output); 109 + callback_in_ms(0, output); 110 + set_state_id(hdcp, output, H2_A1_READ_H_PRIME); 111 + break; 112 + case H2_A1_READ_H_PRIME: 113 + if (input->h_prime_available != PASS) { 114 + if (event_ctx->event == 115 + MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) { 116 + /* 1A-11-3: consider h' timeout a failure */ 117 + fail_and_restart_in_ms(0, &status, output); 118 + } else { 119 + /* continue h' polling */ 120 + callback_in_ms(100, output); 121 + increment_stay_counter(hdcp); 122 + } 123 + break; 124 + } else if (input->h_prime_read != PASS) { 125 + fail_and_restart_in_ms(0, &status, output); 126 + break; 127 + } 128 + set_watchdog_in_ms(hdcp, 200, output); 129 + callback_in_ms(0, output); 130 + set_state_id(hdcp, output, H2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME); 131 + break; 132 + case H2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME: 133 + if (input->pairing_available != PASS) { 134 + if (event_ctx->event == 135 + MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) { 136 + /* 1A-12: consider pairing info timeout 137 + * a failure 138 + */ 139 + fail_and_restart_in_ms(0, &status, output); 140 + } else { 141 + /* continue pairing info polling */ 142 + callback_in_ms(20, output); 143 + increment_stay_counter(hdcp); 144 + } 145 + break; 146 + } else if (input->pairing_info_read != PASS || 147 + input->h_prime_validation != PASS) { 148 + /* 1A-11-1: consider invalid h' a failure */ 149 + fail_and_restart_in_ms(0, &status, output); 150 + break; 151 + } 152 + callback_in_ms(0, output); 153 + set_state_id(hdcp, output, H2_A2_LOCALITY_CHECK); 154 + break; 155 + case H2_A1_SEND_STORED_KM: 156 + if (input->stored_km_write != PASS) { 157 + fail_and_restart_in_ms(0, &status, output); 158 + break; 159 + } 160 + set_watchdog_in_ms(hdcp, 200, output); 161 + callback_in_ms(0, output); 162 + set_state_id(hdcp, output, H2_A1_VALIDATE_H_PRIME); 163 + break; 164 + case H2_A1_VALIDATE_H_PRIME: 165 + if (input->h_prime_available != PASS) { 166 + if (event_ctx->event == 167 + MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) { 168 + /* 1A-11-2: consider h' timeout a failure */ 169 + fail_and_restart_in_ms(0, &status, output); 170 + } else { 171 + /* continue h' polling */ 172 + callback_in_ms(20, output); 173 + increment_stay_counter(hdcp); 174 + } 175 + break; 176 + } else if (input->h_prime_read != PASS) { 177 + fail_and_restart_in_ms(0, &status, output); 178 + break; 179 + } else if (input->h_prime_validation != PASS) { 180 + /* 1A-11-1: consider invalid h' a failure */ 181 + adjust->hdcp2.force_no_stored_km = 1; 182 + fail_and_restart_in_ms(0, &status, output); 183 + break; 184 + } 185 + callback_in_ms(0, output); 186 + set_state_id(hdcp, output, H2_A2_LOCALITY_CHECK); 187 + break; 188 + case H2_A2_LOCALITY_CHECK: 189 + if (hdcp->state.stay_count > 10 || 190 + input->lc_init_prepare != PASS || 191 + input->lc_init_write != PASS || 192 + input->l_prime_available_poll != PASS || 193 + input->l_prime_read != PASS) { 194 + /* 195 + * 1A-05: consider disconnection after LC init a failure 196 + * 1A-13-1: consider invalid l' a failure 197 + * 1A-13-2: consider l' timeout a failure 198 + */ 199 + fail_and_restart_in_ms(0, &status, output); 200 + break; 201 + } else if (input->l_prime_validation != PASS) { 202 + callback_in_ms(0, output); 203 + increment_stay_counter(hdcp); 204 + break; 205 + } 206 + callback_in_ms(0, output); 207 + set_state_id(hdcp, output, H2_A3_EXCHANGE_KS_AND_TEST_FOR_REPEATER); 208 + break; 209 + case H2_A3_EXCHANGE_KS_AND_TEST_FOR_REPEATER: 210 + if (input->eks_prepare != PASS || 211 + input->eks_write != PASS) { 212 + fail_and_restart_in_ms(0, &status, output); 213 + break; 214 + } 215 + if (conn->is_repeater) { 216 + set_watchdog_in_ms(hdcp, 3000, output); 217 + callback_in_ms(0, output); 218 + set_state_id(hdcp, output, H2_A6_WAIT_FOR_RX_ID_LIST); 219 + } else { 220 + /* some CTS equipment requires a delay GREATER than 221 + * 200 ms, so delay 210 ms instead of 200 ms 222 + */ 223 + callback_in_ms(210, output); 224 + set_state_id(hdcp, output, H2_ENABLE_ENCRYPTION); 225 + } 226 + break; 227 + case H2_ENABLE_ENCRYPTION: 228 + if (input->rxstatus_read != PASS || 229 + input->reauth_request_check != PASS) { 230 + /* 231 + * 1A-07: restart hdcp on REAUTH_REQ 232 + * 1B-08: restart hdcp on REAUTH_REQ 233 + */ 234 + fail_and_restart_in_ms(0, &status, output); 235 + break; 236 + } else if (event_ctx->rx_id_list_ready && conn->is_repeater) { 237 + callback_in_ms(0, output); 238 + set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK); 239 + break; 240 + } else if (input->enable_encryption != PASS) { 241 + fail_and_restart_in_ms(0, &status, output); 242 + break; 243 + } 244 + callback_in_ms(0, output); 245 + set_state_id(hdcp, output, H2_A5_AUTHENTICATED); 246 + HDCP_FULL_DDC_TRACE(hdcp); 247 + break; 248 + case H2_A5_AUTHENTICATED: 249 + if (input->rxstatus_read != PASS || 250 + input->reauth_request_check != PASS) { 251 + fail_and_restart_in_ms(0, &status, output); 252 + break; 253 + } else if (event_ctx->rx_id_list_ready && conn->is_repeater) { 254 + callback_in_ms(0, output); 255 + set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK); 256 + break; 257 + } 258 + callback_in_ms(500, output); 259 + increment_stay_counter(hdcp); 260 + break; 261 + case H2_A6_WAIT_FOR_RX_ID_LIST: 262 + if (input->rxstatus_read != PASS || 263 + input->reauth_request_check != PASS) { 264 + fail_and_restart_in_ms(0, &status, output); 265 + break; 266 + } else if (!event_ctx->rx_id_list_ready) { 267 + if (event_ctx->event == MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) { 268 + /* 1B-02: consider rx id list timeout a failure */ 269 + /* some CTS equipment's actual timeout 270 + * measurement is slightly greater than 3000 ms. 271 + * Delay 100 ms to ensure it is fully timeout 272 + * before re-authentication. 273 + */ 274 + fail_and_restart_in_ms(100, &status, output); 275 + } else { 276 + callback_in_ms(300, output); 277 + increment_stay_counter(hdcp); 278 + } 279 + break; 280 + } 281 + callback_in_ms(0, output); 282 + set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK); 283 + break; 284 + case H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK: 285 + if (input->rxstatus_read != PASS || 286 + input->reauth_request_check != PASS || 287 + input->rx_id_list_read != PASS || 288 + input->device_count_check != PASS || 289 + input->rx_id_list_validation != PASS || 290 + input->repeater_auth_ack_write != PASS) { 291 + /* 1B-03: consider invalid v' a failure 292 + * 1B-04: consider MAX_DEVS_EXCEEDED a failure 293 + * 1B-05: consider MAX_CASCADE_EXCEEDED a failure 294 + * 1B-06: consider invalid seq_num_V a failure 295 + * 1B-09: consider seq_num_V rollover a failure 296 + */ 297 + fail_and_restart_in_ms(0, &status, output); 298 + break; 299 + } 300 + callback_in_ms(0, output); 301 + set_state_id(hdcp, output, H2_A9_SEND_STREAM_MANAGEMENT); 302 + break; 303 + case H2_A9_SEND_STREAM_MANAGEMENT: 304 + if (input->rxstatus_read != PASS || 305 + input->reauth_request_check != PASS) { 306 + fail_and_restart_in_ms(0, &status, output); 307 + break; 308 + } else if (event_ctx->rx_id_list_ready && conn->is_repeater) { 309 + callback_in_ms(0, output); 310 + set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK); 311 + break; 312 + } else if (input->prepare_stream_manage != PASS || 313 + input->stream_manage_write != PASS) { 314 + fail_and_restart_in_ms(0, &status, output); 315 + break; 316 + } 317 + set_watchdog_in_ms(hdcp, 100, output); 318 + callback_in_ms(0, output); 319 + set_state_id(hdcp, output, H2_A9_VALIDATE_STREAM_READY); 320 + break; 321 + case H2_A9_VALIDATE_STREAM_READY: 322 + if (input->rxstatus_read != PASS || 323 + input->reauth_request_check != PASS) { 324 + fail_and_restart_in_ms(0, &status, output); 325 + break; 326 + } else if (event_ctx->rx_id_list_ready && conn->is_repeater) { 327 + callback_in_ms(0, output); 328 + set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK); 329 + break; 330 + } else if (input->stream_ready_available != PASS) { 331 + if (event_ctx->event == MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) { 332 + /* 1B-10-2: restart content stream management on 333 + * stream ready timeout 334 + */ 335 + hdcp->auth.count.stream_management_retry_count++; 336 + callback_in_ms(0, output); 337 + set_state_id(hdcp, output, H2_A9_SEND_STREAM_MANAGEMENT); 338 + } else { 339 + callback_in_ms(10, output); 340 + increment_stay_counter(hdcp); 341 + } 342 + break; 343 + } else if (input->stream_ready_read != PASS || 344 + input->stream_ready_validation != PASS) { 345 + /* 346 + * 1B-10-1: restart content stream management 347 + * on invalid M' 348 + */ 349 + if (hdcp->auth.count.stream_management_retry_count > 10) { 350 + fail_and_restart_in_ms(0, &status, output); 351 + } else { 352 + hdcp->auth.count.stream_management_retry_count++; 353 + callback_in_ms(0, output); 354 + set_state_id(hdcp, output, H2_A9_SEND_STREAM_MANAGEMENT); 355 + } 356 + break; 357 + } 358 + callback_in_ms(200, output); 359 + set_state_id(hdcp, output, H2_ENABLE_ENCRYPTION); 360 + break; 361 + default: 362 + status = MOD_HDCP_STATUS_INVALID_STATE; 363 + fail_and_restart_in_ms(0, &status, output); 364 + break; 365 + } 366 + 367 + return status; 368 + } 369 + 370 + enum mod_hdcp_status mod_hdcp_hdcp2_dp_transition(struct mod_hdcp *hdcp, 371 + struct mod_hdcp_event_context *event_ctx, 372 + struct mod_hdcp_transition_input_hdcp2 *input, 373 + struct mod_hdcp_output *output) 374 + { 375 + enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 376 + struct mod_hdcp_connection *conn = &hdcp->connection; 377 + struct mod_hdcp_link_adjustment *adjust = &hdcp->connection.link.adjust; 378 + 379 + switch (current_state(hdcp)) { 380 + case D2_A0_DETERMINE_RX_HDCP_CAPABLE: 381 + if (input->rx_caps_read_dp != PASS || 382 + input->hdcp2_capable_check != PASS) { 383 + adjust->hdcp2.disable = 1; 384 + callback_in_ms(0, output); 385 + set_state_id(hdcp, output, HDCP_INITIALIZED); 386 + } else { 387 + callback_in_ms(0, output); 388 + set_state_id(hdcp, output, D2_A1_SEND_AKE_INIT); 389 + } 390 + break; 391 + case D2_A1_SEND_AKE_INIT: 392 + if (input->add_topology != PASS || 393 + input->create_session != PASS || 394 + input->ake_init_prepare != PASS) { 395 + /* out of sync with psp state */ 396 + adjust->hdcp2.disable = 1; 397 + fail_and_restart_in_ms(0, &status, output); 398 + break; 399 + } else if (input->ake_init_write != PASS) { 400 + /* possibly display not ready */ 401 + fail_and_restart_in_ms(0, &status, output); 402 + break; 403 + } 404 + callback_in_ms(100, output); 405 + set_state_id(hdcp, output, D2_A1_VALIDATE_AKE_CERT); 406 + break; 407 + case D2_A1_VALIDATE_AKE_CERT: 408 + if (input->ake_cert_read != PASS || 409 + input->ake_cert_validation != PASS) { 410 + /* 411 + * 1A-08: consider invalid ake cert a failure 412 + * 1A-09: consider receiver id listed in SRM a failure 413 + */ 414 + fail_and_restart_in_ms(0, &status, output); 415 + break; 416 + } 417 + if (conn->is_km_stored && 418 + !adjust->hdcp2.force_no_stored_km) { 419 + callback_in_ms(0, output); 420 + set_state_id(hdcp, output, D2_A1_SEND_STORED_KM); 421 + } else { 422 + callback_in_ms(0, output); 423 + set_state_id(hdcp, output, D2_A1_SEND_NO_STORED_KM); 424 + } 425 + break; 426 + case D2_A1_SEND_NO_STORED_KM: 427 + if (input->no_stored_km_write != PASS) { 428 + fail_and_restart_in_ms(0, &status, output); 429 + break; 430 + } 431 + if (adjust->hdcp2.increase_h_prime_timeout) 432 + set_watchdog_in_ms(hdcp, 2000, output); 433 + else 434 + set_watchdog_in_ms(hdcp, 1000, output); 435 + set_state_id(hdcp, output, D2_A1_READ_H_PRIME); 436 + break; 437 + case D2_A1_READ_H_PRIME: 438 + if (input->h_prime_available != PASS) { 439 + if (event_ctx->event == 440 + MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) 441 + /* 1A-10-3: consider h' timeout a failure */ 442 + fail_and_restart_in_ms(0, &status, output); 443 + else 444 + increment_stay_counter(hdcp); 445 + break; 446 + } else if (input->h_prime_read != PASS) { 447 + fail_and_restart_in_ms(0, &status, output); 448 + break; 449 + } 450 + set_watchdog_in_ms(hdcp, 200, output); 451 + set_state_id(hdcp, output, D2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME); 452 + break; 453 + case D2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME: 454 + if (input->pairing_available != PASS) { 455 + if (event_ctx->event == 456 + MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) 457 + /* 458 + * 1A-11: consider pairing info timeout 459 + * a failure 460 + */ 461 + fail_and_restart_in_ms(0, &status, output); 462 + else 463 + increment_stay_counter(hdcp); 464 + break; 465 + } else if (input->pairing_info_read != PASS || 466 + input->h_prime_validation != PASS) { 467 + /* 1A-10-1: consider invalid h' a failure */ 468 + fail_and_restart_in_ms(0, &status, output); 469 + break; 470 + } 471 + callback_in_ms(0, output); 472 + set_state_id(hdcp, output, D2_A2_LOCALITY_CHECK); 473 + break; 474 + case D2_A1_SEND_STORED_KM: 475 + if (input->stored_km_write != PASS) { 476 + fail_and_restart_in_ms(0, &status, output); 477 + break; 478 + } 479 + set_watchdog_in_ms(hdcp, 200, output); 480 + set_state_id(hdcp, output, D2_A1_VALIDATE_H_PRIME); 481 + break; 482 + case D2_A1_VALIDATE_H_PRIME: 483 + if (input->h_prime_available != PASS) { 484 + if (event_ctx->event == 485 + MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) 486 + /* 1A-10-2: consider h' timeout a failure */ 487 + fail_and_restart_in_ms(0, &status, output); 488 + else 489 + increment_stay_counter(hdcp); 490 + break; 491 + } else if (input->h_prime_read != PASS) { 492 + fail_and_restart_in_ms(0, &status, output); 493 + break; 494 + } else if (input->h_prime_validation != PASS) { 495 + /* 1A-10-1: consider invalid h' a failure */ 496 + adjust->hdcp2.force_no_stored_km = 1; 497 + fail_and_restart_in_ms(0, &status, output); 498 + break; 499 + } 500 + callback_in_ms(0, output); 501 + set_state_id(hdcp, output, D2_A2_LOCALITY_CHECK); 502 + break; 503 + case D2_A2_LOCALITY_CHECK: 504 + if (hdcp->state.stay_count > 10 || 505 + input->lc_init_prepare != PASS || 506 + input->lc_init_write != PASS || 507 + input->l_prime_read != PASS) { 508 + /* 1A-12: consider invalid l' a failure */ 509 + fail_and_restart_in_ms(0, &status, output); 510 + break; 511 + } else if (input->l_prime_validation != PASS) { 512 + callback_in_ms(0, output); 513 + increment_stay_counter(hdcp); 514 + break; 515 + } 516 + callback_in_ms(0, output); 517 + set_state_id(hdcp, output, D2_A34_EXCHANGE_KS_AND_TEST_FOR_REPEATER); 518 + break; 519 + case D2_A34_EXCHANGE_KS_AND_TEST_FOR_REPEATER: 520 + if (input->eks_prepare != PASS || 521 + input->eks_write != PASS) { 522 + fail_and_restart_in_ms(0, &status, output); 523 + break; 524 + } 525 + if (conn->is_repeater) { 526 + set_watchdog_in_ms(hdcp, 3000, output); 527 + set_state_id(hdcp, output, D2_A6_WAIT_FOR_RX_ID_LIST); 528 + } else { 529 + callback_in_ms(0, output); 530 + set_state_id(hdcp, output, D2_SEND_CONTENT_STREAM_TYPE); 531 + } 532 + break; 533 + case D2_SEND_CONTENT_STREAM_TYPE: 534 + if (input->rxstatus_read != PASS || 535 + input->reauth_request_check != PASS || 536 + input->link_integrity_check_dp != PASS || 537 + input->content_stream_type_write != PASS) { 538 + fail_and_restart_in_ms(0, &status, output); 539 + break; 540 + } 541 + callback_in_ms(210, output); 542 + set_state_id(hdcp, output, D2_ENABLE_ENCRYPTION); 543 + break; 544 + case D2_ENABLE_ENCRYPTION: 545 + if (input->rxstatus_read != PASS || 546 + input->reauth_request_check != PASS || 547 + input->link_integrity_check_dp != PASS) { 548 + /* 549 + * 1A-07: restart hdcp on REAUTH_REQ 550 + * 1B-08: restart hdcp on REAUTH_REQ 551 + */ 552 + fail_and_restart_in_ms(0, &status, output); 553 + break; 554 + } else if (event_ctx->rx_id_list_ready && conn->is_repeater) { 555 + callback_in_ms(0, output); 556 + set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK); 557 + break; 558 + } else if (input->enable_encryption != PASS || 559 + (is_dp_mst_hdcp(hdcp) && input->stream_encryption_dp != PASS)) { 560 + fail_and_restart_in_ms(0, &status, output); 561 + break; 562 + } 563 + set_state_id(hdcp, output, D2_A5_AUTHENTICATED); 564 + HDCP_FULL_DDC_TRACE(hdcp); 565 + break; 566 + case D2_A5_AUTHENTICATED: 567 + if (input->rxstatus_read != PASS || 568 + input->reauth_request_check != PASS) { 569 + fail_and_restart_in_ms(0, &status, output); 570 + break; 571 + } else if (input->link_integrity_check_dp != PASS) { 572 + if (hdcp->connection.hdcp2_retry_count >= 1) 573 + adjust->hdcp2.disable_type1 = 1; 574 + fail_and_restart_in_ms(0, &status, output); 575 + break; 576 + } else if (event_ctx->rx_id_list_ready && conn->is_repeater) { 577 + callback_in_ms(0, output); 578 + set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK); 579 + break; 580 + } 581 + increment_stay_counter(hdcp); 582 + break; 583 + case D2_A6_WAIT_FOR_RX_ID_LIST: 584 + if (input->rxstatus_read != PASS || 585 + input->reauth_request_check != PASS || 586 + input->link_integrity_check_dp != PASS) { 587 + fail_and_restart_in_ms(0, &status, output); 588 + break; 589 + } else if (!event_ctx->rx_id_list_ready) { 590 + if (event_ctx->event == MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) 591 + /* 1B-02: consider rx id list timeout a failure */ 592 + fail_and_restart_in_ms(0, &status, output); 593 + else 594 + increment_stay_counter(hdcp); 595 + break; 596 + } 597 + callback_in_ms(0, output); 598 + set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK); 599 + break; 600 + case D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK: 601 + if (input->rxstatus_read != PASS || 602 + input->reauth_request_check != PASS || 603 + input->link_integrity_check_dp != PASS || 604 + input->rx_id_list_read != PASS || 605 + input->device_count_check != PASS || 606 + input->rx_id_list_validation != PASS || 607 + input->repeater_auth_ack_write != PASS) { 608 + /* 609 + * 1B-03: consider invalid v' a failure 610 + * 1B-04: consider MAX_DEVS_EXCEEDED a failure 611 + * 1B-05: consider MAX_CASCADE_EXCEEDED a failure 612 + * 1B-06: consider invalid seq_num_V a failure 613 + * 1B-09: consider seq_num_V rollover a failure 614 + */ 615 + fail_and_restart_in_ms(0, &status, output); 616 + break; 617 + } 618 + callback_in_ms(0, output); 619 + set_state_id(hdcp, output, D2_A9_SEND_STREAM_MANAGEMENT); 620 + break; 621 + case D2_A9_SEND_STREAM_MANAGEMENT: 622 + if (input->rxstatus_read != PASS || 623 + input->reauth_request_check != PASS || 624 + input->link_integrity_check_dp != PASS) { 625 + fail_and_restart_in_ms(0, &status, output); 626 + break; 627 + } else if (event_ctx->rx_id_list_ready) { 628 + callback_in_ms(0, output); 629 + set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK); 630 + break; 631 + } else if (input->prepare_stream_manage != PASS || 632 + input->stream_manage_write != PASS) { 633 + fail_and_restart_in_ms(0, &status, output); 634 + break; 635 + } 636 + callback_in_ms(100, output); 637 + set_state_id(hdcp, output, D2_A9_VALIDATE_STREAM_READY); 638 + break; 639 + case D2_A9_VALIDATE_STREAM_READY: 640 + if (input->rxstatus_read != PASS || 641 + input->reauth_request_check != PASS || 642 + input->link_integrity_check_dp != PASS) { 643 + fail_and_restart_in_ms(0, &status, output); 644 + break; 645 + } else if (event_ctx->rx_id_list_ready) { 646 + callback_in_ms(0, output); 647 + set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK); 648 + break; 649 + } else if (input->stream_ready_read != PASS || 650 + input->stream_ready_validation != PASS) { 651 + /* 652 + * 1B-10-1: restart content stream management 653 + * on invalid M' 654 + * 1B-10-2: consider stream ready timeout a failure 655 + */ 656 + if (hdcp->auth.count.stream_management_retry_count > 10) { 657 + fail_and_restart_in_ms(0, &status, output); 658 + } else { 659 + hdcp->auth.count.stream_management_retry_count++; 660 + callback_in_ms(0, output); 661 + set_state_id(hdcp, output, D2_A9_SEND_STREAM_MANAGEMENT); 662 + } 663 + break; 664 + } 665 + callback_in_ms(200, output); 666 + set_state_id(hdcp, output, D2_ENABLE_ENCRYPTION); 667 + break; 668 + default: 669 + status = MOD_HDCP_STATUS_INVALID_STATE; 670 + fail_and_restart_in_ms(0, &status, output); 671 + break; 672 + } 673 + return status; 674 + }
+2
drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
··· 77 77 MOD_HDCP_STATUS_HDCP2_H_PRIME_PENDING, 78 78 MOD_HDCP_STATUS_HDCP2_PAIRING_INFO_PENDING, 79 79 MOD_HDCP_STATUS_HDCP2_VALIDATE_AKE_CERT_FAILURE, 80 + MOD_HDCP_STATUS_HDCP2_AKE_CERT_REVOKED, 80 81 MOD_HDCP_STATUS_HDCP2_VALIDATE_H_PRIME_FAILURE, 81 82 MOD_HDCP_STATUS_HDCP2_VALIDATE_PAIRING_INFO_FAILURE, 82 83 MOD_HDCP_STATUS_HDCP2_PREP_LC_INIT_FAILURE, ··· 87 86 MOD_HDCP_STATUS_HDCP2_ENABLE_ENCRYPTION_FAILURE, 88 87 MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY, 89 88 MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE, 89 + MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_REVOKED, 90 90 MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION, 91 91 MOD_HDCP_STATUS_HDCP2_STREAM_READY_PENDING, 92 92 MOD_HDCP_STATUS_HDCP2_VALIDATE_STREAM_READY_FAILURE,