Home | History | Annotate | Line # | Download | only in hdcp
      1 /*	$NetBSD: hdcp.h,v 1.3 2021/12/19 12:02:39 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2019 Advanced Micro Devices, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors: AMD
     25  *
     26  */
     27 
     28 #ifndef HDCP_H_
     29 #define HDCP_H_
     30 
     31 #include "mod_hdcp.h"
     32 #include "hdcp_log.h"
     33 
     34 #include <drm/drm_hdcp.h>
     35 #include <drm/drm_dp_helper.h>
     36 
     37 enum mod_hdcp_trans_input_result {
     38 	UNKNOWN = 0,
     39 	PASS,
     40 	FAIL
     41 };
     42 
     43 struct mod_hdcp_transition_input_hdcp1 {
     44 	uint8_t bksv_read;
     45 	uint8_t bksv_validation;
     46 	uint8_t add_topology;
     47 	uint8_t create_session;
     48 	uint8_t an_write;
     49 	uint8_t aksv_write;
     50 	uint8_t ainfo_write;
     51 	uint8_t bcaps_read;
     52 	uint8_t r0p_read;
     53 	uint8_t rx_validation;
     54 	uint8_t encryption;
     55 	uint8_t link_maintenance;
     56 	uint8_t ready_check;
     57 	uint8_t bstatus_read;
     58 	uint8_t max_cascade_check;
     59 	uint8_t max_devs_check;
     60 	uint8_t device_count_check;
     61 	uint8_t ksvlist_read;
     62 	uint8_t vp_read;
     63 	uint8_t ksvlist_vp_validation;
     64 
     65 	uint8_t hdcp_capable_dp;
     66 	uint8_t binfo_read_dp;
     67 	uint8_t r0p_available_dp;
     68 	uint8_t link_integrity_check;
     69 	uint8_t reauth_request_check;
     70 	uint8_t stream_encryption_dp;
     71 };
     72 
     73 struct mod_hdcp_transition_input_hdcp2 {
     74 	uint8_t hdcp2version_read;
     75 	uint8_t hdcp2_capable_check;
     76 	uint8_t add_topology;
     77 	uint8_t create_session;
     78 	uint8_t ake_init_prepare;
     79 	uint8_t ake_init_write;
     80 	uint8_t rxstatus_read;
     81 	uint8_t ake_cert_available;
     82 	uint8_t ake_cert_read;
     83 	uint8_t ake_cert_validation;
     84 	uint8_t stored_km_write;
     85 	uint8_t no_stored_km_write;
     86 	uint8_t h_prime_available;
     87 	uint8_t h_prime_read;
     88 	uint8_t pairing_available;
     89 	uint8_t pairing_info_read;
     90 	uint8_t h_prime_validation;
     91 	uint8_t lc_init_prepare;
     92 	uint8_t lc_init_write;
     93 	uint8_t l_prime_available_poll;
     94 	uint8_t l_prime_read;
     95 	uint8_t l_prime_validation;
     96 	uint8_t eks_prepare;
     97 	uint8_t eks_write;
     98 	uint8_t enable_encryption;
     99 	uint8_t reauth_request_check;
    100 	uint8_t rx_id_list_read;
    101 	uint8_t device_count_check;
    102 	uint8_t rx_id_list_validation;
    103 	uint8_t repeater_auth_ack_write;
    104 	uint8_t prepare_stream_manage;
    105 	uint8_t stream_manage_write;
    106 	uint8_t stream_ready_available;
    107 	uint8_t stream_ready_read;
    108 	uint8_t stream_ready_validation;
    109 
    110 	uint8_t rx_caps_read_dp;
    111 	uint8_t content_stream_type_write;
    112 	uint8_t link_integrity_check_dp;
    113 	uint8_t stream_encryption_dp;
    114 };
    115 
    116 union mod_hdcp_transition_input {
    117 	struct mod_hdcp_transition_input_hdcp1 hdcp1;
    118 	struct mod_hdcp_transition_input_hdcp2 hdcp2;
    119 };
    120 
    121 struct mod_hdcp_message_hdcp1 {
    122 	uint8_t		an[8];
    123 	uint8_t		aksv[5];
    124 	uint8_t		ainfo;
    125 	uint8_t		bksv[5];
    126 	uint16_t	r0p;
    127 	uint8_t		bcaps;
    128 	uint16_t	bstatus;
    129 	uint8_t		ksvlist[635];
    130 	uint16_t	ksvlist_size;
    131 	uint8_t		vp[20];
    132 
    133 	uint16_t	binfo_dp;
    134 };
    135 
    136 struct mod_hdcp_message_hdcp2 {
    137 	uint8_t		hdcp2version_hdmi;
    138 	uint8_t		rxcaps_dp[3];
    139 	uint8_t		rxstatus[2];
    140 
    141 	uint8_t		ake_init[12];
    142 	uint8_t		ake_cert[534];
    143 	uint8_t		ake_no_stored_km[129];
    144 	uint8_t		ake_stored_km[33];
    145 	uint8_t		ake_h_prime[33];
    146 	uint8_t		ake_pairing_info[17];
    147 	uint8_t		lc_init[9];
    148 	uint8_t		lc_l_prime[33];
    149 	uint8_t		ske_eks[25];
    150 	uint8_t		rx_id_list[177]; // 22 + 5 * 31
    151 	uint16_t	rx_id_list_size;
    152 	uint8_t		repeater_auth_ack[17];
    153 	uint8_t		repeater_auth_stream_manage[68]; // 6 + 2 * 31
    154 	uint16_t	stream_manage_size;
    155 	uint8_t		repeater_auth_stream_ready[33];
    156 	uint8_t		rxstatus_dp;
    157 	uint8_t		content_stream_type_dp[2];
    158 };
    159 
    160 union mod_hdcp_message {
    161 	struct mod_hdcp_message_hdcp1 hdcp1;
    162 	struct mod_hdcp_message_hdcp2 hdcp2;
    163 };
    164 
    165 struct mod_hdcp_auth_counters {
    166 	uint8_t stream_management_retry_count;
    167 };
    168 
    169 /* contains values per connection */
    170 struct mod_hdcp_connection {
    171 	struct mod_hdcp_link link;
    172 	struct mod_hdcp_display displays[MAX_NUM_OF_DISPLAYS];
    173 	uint8_t is_repeater;
    174 	uint8_t is_km_stored;
    175 	uint8_t is_hdcp2_revoked;
    176 	struct mod_hdcp_trace trace;
    177 	uint8_t hdcp1_retry_count;
    178 	uint8_t hdcp2_retry_count;
    179 };
    180 
    181 /* contains values per authentication cycle */
    182 struct mod_hdcp_authentication {
    183 	uint32_t id;
    184 	union mod_hdcp_message msg;
    185 	union mod_hdcp_transition_input trans_input;
    186 	struct mod_hdcp_auth_counters count;
    187 };
    188 
    189 /* contains values per state change */
    190 struct mod_hdcp_state {
    191 	uint8_t id;
    192 	uint32_t stay_count;
    193 };
    194 
    195 /* per event in a state */
    196 struct mod_hdcp_event_context {
    197 	enum mod_hdcp_event event;
    198 	uint8_t rx_id_list_ready;
    199 	uint8_t unexpected_event;
    200 };
    201 
    202 struct mod_hdcp {
    203 	/* per link */
    204 	struct mod_hdcp_config config;
    205 	/* per connection */
    206 	struct mod_hdcp_connection connection;
    207 	/* per authentication attempt */
    208 	struct mod_hdcp_authentication auth;
    209 	/* per state in an authentication */
    210 	struct mod_hdcp_state state;
    211 	/* reserved memory buffer */
    212 	uint8_t buf[2025];
    213 };
    214 
    215 enum mod_hdcp_initial_state_id {
    216 	HDCP_UNINITIALIZED = 0x0,
    217 	HDCP_INITIAL_STATE_START = HDCP_UNINITIALIZED,
    218 	HDCP_INITIALIZED,
    219 	HDCP_CP_NOT_DESIRED,
    220 	HDCP_INITIAL_STATE_END = HDCP_CP_NOT_DESIRED
    221 };
    222 
    223 enum mod_hdcp_hdcp1_state_id {
    224 	HDCP1_STATE_START = HDCP_INITIAL_STATE_END,
    225 	H1_A0_WAIT_FOR_ACTIVE_RX,
    226 	H1_A1_EXCHANGE_KSVS,
    227 	H1_A2_COMPUTATIONS_A3_VALIDATE_RX_A6_TEST_FOR_REPEATER,
    228 	H1_A45_AUTHENTICATED,
    229 	H1_A8_WAIT_FOR_READY,
    230 	H1_A9_READ_KSV_LIST,
    231 	HDCP1_STATE_END = H1_A9_READ_KSV_LIST
    232 };
    233 
    234 enum mod_hdcp_hdcp1_dp_state_id {
    235 	HDCP1_DP_STATE_START = HDCP1_STATE_END,
    236 	D1_A0_DETERMINE_RX_HDCP_CAPABLE,
    237 	D1_A1_EXCHANGE_KSVS,
    238 	D1_A23_WAIT_FOR_R0_PRIME,
    239 	D1_A2_COMPUTATIONS_A3_VALIDATE_RX_A5_TEST_FOR_REPEATER,
    240 	D1_A4_AUTHENTICATED,
    241 	D1_A6_WAIT_FOR_READY,
    242 	D1_A7_READ_KSV_LIST,
    243 	HDCP1_DP_STATE_END = D1_A7_READ_KSV_LIST,
    244 };
    245 
    246 enum mod_hdcp_hdcp2_state_id {
    247 	HDCP2_STATE_START = HDCP1_DP_STATE_END,
    248 	H2_A0_KNOWN_HDCP2_CAPABLE_RX,
    249 	H2_A1_SEND_AKE_INIT,
    250 	H2_A1_VALIDATE_AKE_CERT,
    251 	H2_A1_SEND_NO_STORED_KM,
    252 	H2_A1_READ_H_PRIME,
    253 	H2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME,
    254 	H2_A1_SEND_STORED_KM,
    255 	H2_A1_VALIDATE_H_PRIME,
    256 	H2_A2_LOCALITY_CHECK,
    257 	H2_A3_EXCHANGE_KS_AND_TEST_FOR_REPEATER,
    258 	H2_ENABLE_ENCRYPTION,
    259 	H2_A5_AUTHENTICATED,
    260 	H2_A6_WAIT_FOR_RX_ID_LIST,
    261 	H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK,
    262 	H2_A9_SEND_STREAM_MANAGEMENT,
    263 	H2_A9_VALIDATE_STREAM_READY,
    264 	HDCP2_STATE_END = H2_A9_VALIDATE_STREAM_READY,
    265 };
    266 
    267 enum mod_hdcp_hdcp2_dp_state_id {
    268 	HDCP2_DP_STATE_START = HDCP2_STATE_END,
    269 	D2_A0_DETERMINE_RX_HDCP_CAPABLE,
    270 	D2_A1_SEND_AKE_INIT,
    271 	D2_A1_VALIDATE_AKE_CERT,
    272 	D2_A1_SEND_NO_STORED_KM,
    273 	D2_A1_READ_H_PRIME,
    274 	D2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME,
    275 	D2_A1_SEND_STORED_KM,
    276 	D2_A1_VALIDATE_H_PRIME,
    277 	D2_A2_LOCALITY_CHECK,
    278 	D2_A34_EXCHANGE_KS_AND_TEST_FOR_REPEATER,
    279 	D2_SEND_CONTENT_STREAM_TYPE,
    280 	D2_ENABLE_ENCRYPTION,
    281 	D2_A5_AUTHENTICATED,
    282 	D2_A6_WAIT_FOR_RX_ID_LIST,
    283 	D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK,
    284 	D2_A9_SEND_STREAM_MANAGEMENT,
    285 	D2_A9_VALIDATE_STREAM_READY,
    286 	HDCP2_DP_STATE_END = D2_A9_VALIDATE_STREAM_READY,
    287 	HDCP_STATE_END = HDCP2_DP_STATE_END,
    288 };
    289 
    290 /* hdcp1 executions and transitions */
    291 typedef enum mod_hdcp_status (*mod_hdcp_action)(struct mod_hdcp *hdcp);
    292 uint8_t mod_hdcp_execute_and_set(
    293 		mod_hdcp_action func, uint8_t *flag,
    294 		enum mod_hdcp_status *status, struct mod_hdcp *hdcp, const char *str);
    295 enum mod_hdcp_status mod_hdcp_hdcp1_execution(struct mod_hdcp *hdcp,
    296 	struct mod_hdcp_event_context *event_ctx,
    297 	struct mod_hdcp_transition_input_hdcp1 *input);
    298 enum mod_hdcp_status mod_hdcp_hdcp1_dp_execution(struct mod_hdcp *hdcp,
    299 	struct mod_hdcp_event_context *event_ctx,
    300 	struct mod_hdcp_transition_input_hdcp1 *input);
    301 enum mod_hdcp_status mod_hdcp_hdcp1_transition(struct mod_hdcp *hdcp,
    302 	struct mod_hdcp_event_context *event_ctx,
    303 	struct mod_hdcp_transition_input_hdcp1 *input,
    304 	struct mod_hdcp_output *output);
    305 enum mod_hdcp_status mod_hdcp_hdcp1_dp_transition(struct mod_hdcp *hdcp,
    306 	struct mod_hdcp_event_context *event_ctx,
    307 	struct mod_hdcp_transition_input_hdcp1 *input,
    308 	struct mod_hdcp_output *output);
    309 
    310 /* hdcp2 executions and transitions */
    311 enum mod_hdcp_status mod_hdcp_hdcp2_execution(struct mod_hdcp *hdcp,
    312 	struct mod_hdcp_event_context *event_ctx,
    313 	struct mod_hdcp_transition_input_hdcp2 *input);
    314 enum mod_hdcp_status mod_hdcp_hdcp2_dp_execution(struct mod_hdcp *hdcp,
    315 	struct mod_hdcp_event_context *event_ctx,
    316 	struct mod_hdcp_transition_input_hdcp2 *input);
    317 enum mod_hdcp_status mod_hdcp_hdcp2_transition(struct mod_hdcp *hdcp,
    318 	struct mod_hdcp_event_context *event_ctx,
    319 	struct mod_hdcp_transition_input_hdcp2 *input,
    320 	struct mod_hdcp_output *output);
    321 enum mod_hdcp_status mod_hdcp_hdcp2_dp_transition(struct mod_hdcp *hdcp,
    322 	struct mod_hdcp_event_context *event_ctx,
    323 	struct mod_hdcp_transition_input_hdcp2 *input,
    324 	struct mod_hdcp_output *output);
    325 
    326 /* log functions */
    327 void mod_hdcp_dump_binary_message(uint8_t *msg, uint32_t msg_size,
    328 		uint8_t *buf, uint32_t buf_size);
    329 /* TODO: add adjustment log */
    330 
    331 /* psp functions */
    332 enum mod_hdcp_status mod_hdcp_add_display_topology(
    333 		struct mod_hdcp *hdcp);
    334 enum mod_hdcp_status mod_hdcp_remove_display_topology(
    335 		struct mod_hdcp *hdcp);
    336 enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp);
    337 enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(struct mod_hdcp *hdcp);
    338 enum mod_hdcp_status mod_hdcp_hdcp1_validate_rx(struct mod_hdcp *hdcp);
    339 enum mod_hdcp_status mod_hdcp_hdcp1_enable_encryption(struct mod_hdcp *hdcp);
    340 enum mod_hdcp_status mod_hdcp_hdcp1_validate_ksvlist_vp(struct mod_hdcp *hdcp);
    341 enum mod_hdcp_status mod_hdcp_hdcp1_enable_dp_stream_encryption(
    342 	struct mod_hdcp *hdcp);
    343 enum mod_hdcp_status mod_hdcp_hdcp1_link_maintenance(struct mod_hdcp *hdcp);
    344 enum mod_hdcp_status mod_hdcp_hdcp1_get_link_encryption_status(struct mod_hdcp *hdcp,
    345 							       enum mod_hdcp_encryption_status *encryption_status);
    346 enum mod_hdcp_status mod_hdcp_hdcp2_create_session(struct mod_hdcp *hdcp);
    347 enum mod_hdcp_status mod_hdcp_hdcp2_destroy_session(struct mod_hdcp *hdcp);
    348 enum mod_hdcp_status mod_hdcp_hdcp2_prepare_ake_init(struct mod_hdcp *hdcp);
    349 enum mod_hdcp_status mod_hdcp_hdcp2_validate_ake_cert(struct mod_hdcp *hdcp);
    350 enum mod_hdcp_status mod_hdcp_hdcp2_validate_h_prime(struct mod_hdcp *hdcp);
    351 enum mod_hdcp_status mod_hdcp_hdcp2_prepare_lc_init(struct mod_hdcp *hdcp);
    352 enum mod_hdcp_status mod_hdcp_hdcp2_validate_l_prime(struct mod_hdcp *hdcp);
    353 enum mod_hdcp_status mod_hdcp_hdcp2_prepare_eks(struct mod_hdcp *hdcp);
    354 enum mod_hdcp_status mod_hdcp_hdcp2_enable_encryption(struct mod_hdcp *hdcp);
    355 enum mod_hdcp_status mod_hdcp_hdcp2_validate_rx_id_list(struct mod_hdcp *hdcp);
    356 enum mod_hdcp_status mod_hdcp_hdcp2_enable_dp_stream_encryption(
    357 		struct mod_hdcp *hdcp);
    358 enum mod_hdcp_status mod_hdcp_hdcp2_prepare_stream_management(
    359 		struct mod_hdcp *hdcp);
    360 enum mod_hdcp_status mod_hdcp_hdcp2_validate_stream_ready(
    361 		struct mod_hdcp *hdcp);
    362 enum mod_hdcp_status mod_hdcp_hdcp2_get_link_encryption_status(struct mod_hdcp *hdcp,
    363 							       enum mod_hdcp_encryption_status *encryption_status);
    364 
    365 /* ddc functions */
    366 enum mod_hdcp_status mod_hdcp_read_bksv(struct mod_hdcp *hdcp);
    367 enum mod_hdcp_status mod_hdcp_read_bcaps(struct mod_hdcp *hdcp);
    368 enum mod_hdcp_status mod_hdcp_read_bstatus(struct mod_hdcp *hdcp);
    369 enum mod_hdcp_status mod_hdcp_read_r0p(struct mod_hdcp *hdcp);
    370 enum mod_hdcp_status mod_hdcp_read_ksvlist(struct mod_hdcp *hdcp);
    371 enum mod_hdcp_status mod_hdcp_read_vp(struct mod_hdcp *hdcp);
    372 enum mod_hdcp_status mod_hdcp_read_binfo(struct mod_hdcp *hdcp);
    373 enum mod_hdcp_status mod_hdcp_write_aksv(struct mod_hdcp *hdcp);
    374 enum mod_hdcp_status mod_hdcp_write_ainfo(struct mod_hdcp *hdcp);
    375 enum mod_hdcp_status mod_hdcp_write_an(struct mod_hdcp *hdcp);
    376 enum mod_hdcp_status mod_hdcp_read_hdcp2version(struct mod_hdcp *hdcp);
    377 enum mod_hdcp_status mod_hdcp_read_rxcaps(struct mod_hdcp *hdcp);
    378 enum mod_hdcp_status mod_hdcp_read_rxstatus(struct mod_hdcp *hdcp);
    379 enum mod_hdcp_status mod_hdcp_read_ake_cert(struct mod_hdcp *hdcp);
    380 enum mod_hdcp_status mod_hdcp_read_h_prime(struct mod_hdcp *hdcp);
    381 enum mod_hdcp_status mod_hdcp_read_pairing_info(struct mod_hdcp *hdcp);
    382 enum mod_hdcp_status mod_hdcp_read_l_prime(struct mod_hdcp *hdcp);
    383 enum mod_hdcp_status mod_hdcp_read_rx_id_list(struct mod_hdcp *hdcp);
    384 enum mod_hdcp_status mod_hdcp_read_stream_ready(struct mod_hdcp *hdcp);
    385 enum mod_hdcp_status mod_hdcp_write_ake_init(struct mod_hdcp *hdcp);
    386 enum mod_hdcp_status mod_hdcp_write_no_stored_km(struct mod_hdcp *hdcp);
    387 enum mod_hdcp_status mod_hdcp_write_stored_km(struct mod_hdcp *hdcp);
    388 enum mod_hdcp_status mod_hdcp_write_lc_init(struct mod_hdcp *hdcp);
    389 enum mod_hdcp_status mod_hdcp_write_eks(struct mod_hdcp *hdcp);
    390 enum mod_hdcp_status mod_hdcp_write_repeater_auth_ack(struct mod_hdcp *hdcp);
    391 enum mod_hdcp_status mod_hdcp_write_stream_manage(struct mod_hdcp *hdcp);
    392 enum mod_hdcp_status mod_hdcp_write_content_type(struct mod_hdcp *hdcp);
    393 
    394 /* hdcp version helpers */
    395 static inline uint8_t is_dp_hdcp(struct mod_hdcp *hdcp)
    396 {
    397 	return (hdcp->connection.link.mode == MOD_HDCP_MODE_DP ||
    398 			hdcp->connection.link.mode == MOD_HDCP_MODE_DP_MST);
    399 }
    400 
    401 static inline uint8_t is_dp_mst_hdcp(struct mod_hdcp *hdcp)
    402 {
    403 	return (hdcp->connection.link.mode == MOD_HDCP_MODE_DP_MST);
    404 }
    405 
    406 static inline uint8_t is_hdmi_dvi_sl_hdcp(struct mod_hdcp *hdcp)
    407 {
    408 	return (hdcp->connection.link.mode == MOD_HDCP_MODE_DEFAULT);
    409 }
    410 
    411 /* hdcp state helpers */
    412 static inline uint8_t current_state(struct mod_hdcp *hdcp)
    413 {
    414 	return hdcp->state.id;
    415 }
    416 
    417 static inline void set_state_id(struct mod_hdcp *hdcp,
    418 		struct mod_hdcp_output *output, uint8_t id)
    419 {
    420 	memset(&hdcp->state, 0, sizeof(hdcp->state));
    421 	hdcp->state.id = id;
    422 	/* callback timer should be reset per state */
    423 	output->callback_stop = 1;
    424 	output->watchdog_timer_stop = 1;
    425 	HDCP_NEXT_STATE_TRACE(hdcp, id, output);
    426 }
    427 
    428 static inline uint8_t is_in_hdcp1_states(struct mod_hdcp *hdcp)
    429 {
    430 	return (current_state(hdcp) > HDCP1_STATE_START &&
    431 			current_state(hdcp) <= HDCP1_STATE_END);
    432 }
    433 
    434 static inline uint8_t is_in_hdcp1_dp_states(struct mod_hdcp *hdcp)
    435 {
    436 	return (current_state(hdcp) > HDCP1_DP_STATE_START &&
    437 			current_state(hdcp) <= HDCP1_DP_STATE_END);
    438 }
    439 
    440 static inline uint8_t is_in_hdcp2_states(struct mod_hdcp *hdcp)
    441 {
    442 	return (current_state(hdcp) > HDCP2_STATE_START &&
    443 			current_state(hdcp) <= HDCP2_STATE_END);
    444 }
    445 
    446 static inline uint8_t is_in_hdcp2_dp_states(struct mod_hdcp *hdcp)
    447 {
    448 	return (current_state(hdcp) > HDCP2_DP_STATE_START &&
    449 			current_state(hdcp) <= HDCP2_DP_STATE_END);
    450 }
    451 
    452 static inline uint8_t is_hdcp1(struct mod_hdcp *hdcp)
    453 {
    454 	return (is_in_hdcp1_states(hdcp) || is_in_hdcp1_dp_states(hdcp));
    455 }
    456 
    457 static inline uint8_t is_hdcp2(struct mod_hdcp *hdcp)
    458 {
    459 	return (is_in_hdcp2_states(hdcp) || is_in_hdcp2_dp_states(hdcp));
    460 }
    461 
    462 static inline uint8_t is_in_cp_not_desired_state(struct mod_hdcp *hdcp)
    463 {
    464 	return current_state(hdcp) == HDCP_CP_NOT_DESIRED;
    465 }
    466 
    467 static inline uint8_t is_in_initialized_state(struct mod_hdcp *hdcp)
    468 {
    469 	return current_state(hdcp) == HDCP_INITIALIZED;
    470 }
    471 
    472 /* transition operation helpers */
    473 static inline void increment_stay_counter(struct mod_hdcp *hdcp)
    474 {
    475 	hdcp->state.stay_count++;
    476 }
    477 
    478 static inline void fail_and_restart_in_ms(uint16_t time,
    479 		enum mod_hdcp_status *status,
    480 		struct mod_hdcp_output *output)
    481 {
    482 	output->callback_needed = 1;
    483 	output->callback_delay = time;
    484 	output->watchdog_timer_needed = 0;
    485 	output->watchdog_timer_delay = 0;
    486 	*status = MOD_HDCP_STATUS_RESET_NEEDED;
    487 }
    488 
    489 static inline void callback_in_ms(uint16_t time, struct mod_hdcp_output *output)
    490 {
    491 	output->callback_needed = 1;
    492 	output->callback_delay = time;
    493 }
    494 
    495 static inline void set_watchdog_in_ms(struct mod_hdcp *hdcp, uint16_t time,
    496 		struct mod_hdcp_output *output)
    497 {
    498 	output->watchdog_timer_needed = 1;
    499 	output->watchdog_timer_delay = time;
    500 }
    501 
    502 /* connection topology helpers */
    503 static inline uint8_t is_display_active(struct mod_hdcp_display *display)
    504 {
    505 	return display->state >= MOD_HDCP_DISPLAY_ACTIVE;
    506 }
    507 
    508 static inline uint8_t is_display_added(struct mod_hdcp_display *display)
    509 {
    510 	return display->state >= MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED;
    511 }
    512 
    513 static inline uint8_t is_display_encryption_enabled(struct mod_hdcp_display *display)
    514 {
    515 	return display->state >= MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;
    516 }
    517 
    518 static inline uint8_t get_active_display_count(struct mod_hdcp *hdcp)
    519 {
    520 	uint8_t added_count = 0;
    521 	uint8_t i;
    522 
    523 	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
    524 		if (is_display_active(&hdcp->connection.displays[i]))
    525 			added_count++;
    526 	return added_count;
    527 }
    528 
    529 static inline uint8_t get_added_display_count(struct mod_hdcp *hdcp)
    530 {
    531 	uint8_t added_count = 0;
    532 	uint8_t i;
    533 
    534 	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
    535 		if (is_display_added(&hdcp->connection.displays[i]))
    536 			added_count++;
    537 	return added_count;
    538 }
    539 
    540 static inline struct mod_hdcp_display *get_first_added_display(
    541 		struct mod_hdcp *hdcp)
    542 {
    543 	uint8_t i;
    544 	struct mod_hdcp_display *display = NULL;
    545 
    546 	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
    547 		if (is_display_added(&hdcp->connection.displays[i])) {
    548 			display = &hdcp->connection.displays[i];
    549 			break;
    550 		}
    551 	return display;
    552 }
    553 
    554 static inline struct mod_hdcp_display *get_active_display_at_index(
    555 		struct mod_hdcp *hdcp, uint8_t index)
    556 {
    557 	uint8_t i;
    558 	struct mod_hdcp_display *display = NULL;
    559 
    560 	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
    561 		if (hdcp->connection.displays[i].index == index &&
    562 				is_display_active(&hdcp->connection.displays[i])) {
    563 			display = &hdcp->connection.displays[i];
    564 			break;
    565 		}
    566 	return display;
    567 }
    568 
    569 static inline struct mod_hdcp_display *get_empty_display_container(
    570 		struct mod_hdcp *hdcp)
    571 {
    572 	uint8_t i;
    573 	struct mod_hdcp_display *display = NULL;
    574 
    575 	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
    576 		if (!is_display_active(&hdcp->connection.displays[i])) {
    577 			display = &hdcp->connection.displays[i];
    578 			break;
    579 		}
    580 	return display;
    581 }
    582 
    583 static inline void reset_retry_counts(struct mod_hdcp *hdcp)
    584 {
    585 	hdcp->connection.hdcp1_retry_count = 0;
    586 	hdcp->connection.hdcp2_retry_count = 0;
    587 }
    588 
    589 #endif /* HDCP_H_ */
    590