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