android_kernel_xiaomi_sm8350/msm/sde_hdcp_2x.h
Christopher Braga 83af37f1e5 disp: msm: make the HDCP protocol module asynchronous
Commands to the HDCP protocol layer can fail or block if
executed when the system enters suspend or shutdown.
Protocol layer blockage will occur until the system returns
into a power on state, potentially resulting in deadlocks for
clients who synchronously wait on protocol layer completion.

Asynchronously handle all requests to the protocol module to
ensure that clients can make progress regardless of the state of
the underlying HDCP handler. When an already queued request is
received by the protocol module, that request will be rescheduled
to the back of the queue.

Change-Id: I658dd09a81f21037cd90bbaa5b7d73363472e0b0
Signed-off-by: Christopher Braga <cbraga@codeaurora.org>
2019-04-24 17:42:07 -04:00

220 lines
7.1 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*/
#ifndef __SDE_HDCP_2X_H__
#define __SDE_HDCP_2X_H__
#include "sde_hdcp.h"
#define TO_STR(x) #x
#define HDCP_MAX_MESSAGE_PARTS 4
/**
* enum sde_hdcp_2x_wakeup_cmd - commands for interacting with HDCP driver
* @HDCP_2X_CMD_INVALID: initialization value
* @HDCP_2X_CMD_START: start HDCP driver
* @HDCP_2X_CMD_START_AUTH: start authentication
* @HDCP_2X_CMD_STOP: stop HDCP driver
* @HDCP_2X_CMD_MSG_SEND_SUCCESS: sending message to sink succeeded
* @HDCP_2X_CMD_MSG_SEND_FAILED: sending message to sink failed
* @HDCP_2X_CMD_MSG_SEND_TIMEOUT: sending message to sink timed out
* @HDCP_2X_CMD_MSG_RECV_SUCCESS: receiving message from sink succeeded
* @HDCP_2X_CMD_MSG_RECV_FAILED: receiving message from sink failed
* @HDCP_2X_CMD_MSG_RECV_TIMEOUT: receiving message from sink timed out
* @HDCP_2X_CMD_QUERY_STREAM_TYPE: start content stream processing
* @HDCP_2X_CMD_LINK_FAILED: link failure notification
* @HDCP_2X_CMD_MIN_ENC_LEVEL: trigger minimum encryption level change
* @HDCP_2X_CMD_OPEN_STREAMS: open a virtual channel
* @HDCP_2X_CMD_CLOSE_STREAMS: close a virtual channel
*/
enum sde_hdcp_2x_wakeup_cmd {
HDCP_2X_CMD_INVALID,
HDCP_2X_CMD_ENABLE,
HDCP_2X_CMD_DISABLE,
HDCP_2X_CMD_START,
HDCP_2X_CMD_START_AUTH,
HDCP_2X_CMD_STOP,
HDCP_2X_CMD_MSG_SEND_SUCCESS,
HDCP_2X_CMD_MSG_SEND_FAILED,
HDCP_2X_CMD_MSG_SEND_TIMEOUT,
HDCP_2X_CMD_MSG_RECV_SUCCESS,
HDCP_2X_CMD_MSG_RECV_FAILED,
HDCP_2X_CMD_MSG_RECV_TIMEOUT,
HDCP_2X_CMD_QUERY_STREAM_TYPE,
HDCP_2X_CMD_LINK_FAILED,
HDCP_2X_CMD_MIN_ENC_LEVEL,
HDCP_2X_CMD_OPEN_STREAMS,
HDCP_2X_CMD_CLOSE_STREAMS,
};
/**
* enum hdcp_transport_wakeup_cmd - commands to instruct display transport layer
* @HDCP_TRANSPORT_CMD_INVALID: initialization value
* @HDCP_TRANSPORT_CMD_SEND_MESSAGE: send message to sink
* @HDCP_TRANSPORT_CMD_RECV_MESSAGE: receive message from sink
* @HDCP_TRANSPORT_CMD_STATUS_SUCCESS: successfully communicated with TrustZone
* @HDCP_TRANSPORT_CMD_STATUS_FAILED: failed to communicate with TrustZone
* @HDCP_TRANSPORT_CMD_LINK_POLL: poll the HDCP link
* @HDCP_TRANSPORT_CMD_LINK_CHECK: check link status in response to cp_irq
* @HDCP_TRANSPORT_CMD_AUTHENTICATE: start authentication
*/
enum hdcp_transport_wakeup_cmd {
HDCP_TRANSPORT_CMD_INVALID,
HDCP_TRANSPORT_CMD_SEND_MESSAGE,
HDCP_TRANSPORT_CMD_RECV_MESSAGE,
HDCP_TRANSPORT_CMD_STATUS_SUCCESS,
HDCP_TRANSPORT_CMD_STATUS_FAILED,
HDCP_TRANSPORT_CMD_LINK_POLL,
HDCP_TRANSPORT_CMD_LINK_CHECK,
HDCP_TRANSPORT_CMD_AUTHENTICATE,
};
enum sde_hdcp_2x_device_type {
HDCP_TXMTR_HDMI = 0x8001,
HDCP_TXMTR_DP = 0x8002,
HDCP_TXMTR_DP_MST = 0x8003
};
/**
* struct sde_hdcp_2x_lib_wakeup_data - command and data send to HDCP driver
* @cmd: command type
* @device_type type of device in use by the HDCP driver
* @context: void pointer to the HDCP driver instance
* @buf: message received from the sink
* @buf_len: length of message received from the sink
* @timeout: time out value for timed transactions
* @streams: list indicating which streams need adjustment
* @num_streams: number of entries in streams
*/
struct sde_hdcp_2x_wakeup_data {
enum sde_hdcp_2x_wakeup_cmd cmd;
enum sde_hdcp_2x_device_type device_type;
void *context;
uint32_t total_message_length;
uint32_t timeout;
u8 min_enc_level;
struct stream_info *streams;
u8 num_streams;
};
/**
* struct sde_hdcp_2x_msg_part - a single part of an HDCP 2.2 message
* @name: user readable message name
* @offset: message part offset
* @length message part length
*/
struct sde_hdcp_2x_msg_part {
char *name;
uint32_t offset;
uint32_t length;
};
/**
* struct sde_hdcp_2x_msg_data - HDCP 2.2 message containing one or more parts
* @num_messages: total number of parts in a full message
* @messages: array containing num_messages parts
* @rx_status: value of rx_status register
*/
struct sde_hdcp_2x_msg_data {
uint32_t num_messages;
struct sde_hdcp_2x_msg_part messages[HDCP_MAX_MESSAGE_PARTS];
uint8_t rx_status;
};
/**
* struct hdcp_transport_wakeup_data - data sent to display transport layer
* @cmd: command type
* @context: void pointer to the display transport layer
* @send_msg_buf: buffer containing message to be sent to sink
* @send_msg_len: length of the message to be sent to sink
* @timeout: timeout value for timed transactions
* @abort_mask: mask used to determine whether HDCP link is valid
* @message_data: a pointer to the message description
*/
struct hdcp_transport_wakeup_data {
enum hdcp_transport_wakeup_cmd cmd;
void *context;
unsigned char *buf;
u32 buf_len;
u32 timeout;
u8 abort_mask;
const struct sde_hdcp_2x_msg_data *message_data;
};
static inline const char *sde_hdcp_2x_cmd_to_str(
enum sde_hdcp_2x_wakeup_cmd cmd)
{
switch (cmd) {
case HDCP_2X_CMD_START:
return TO_STR(HDCP_2X_CMD_START);
case HDCP_2X_CMD_STOP:
return TO_STR(HDCP_2X_CMD_STOP);
case HDCP_2X_CMD_MSG_SEND_SUCCESS:
return TO_STR(HDCP_2X_CMD_MSG_SEND_SUCCESS);
case HDCP_2X_CMD_MSG_SEND_FAILED:
return TO_STR(HDCP_2X_CMD_MSG_SEND_FAILED);
case HDCP_2X_CMD_MSG_SEND_TIMEOUT:
return TO_STR(HDCP_2X_CMD_MSG_SEND_TIMEOUT);
case HDCP_2X_CMD_MSG_RECV_SUCCESS:
return TO_STR(HDCP_2X_CMD_MSG_RECV_SUCCESS);
case HDCP_2X_CMD_MSG_RECV_FAILED:
return TO_STR(HDCP_2X_CMD_MSG_RECV_FAILED);
case HDCP_2X_CMD_MSG_RECV_TIMEOUT:
return TO_STR(HDCP_2X_CMD_MSG_RECV_TIMEOUT);
case HDCP_2X_CMD_QUERY_STREAM_TYPE:
return TO_STR(HDCP_2X_CMD_QUERY_STREAM_TYPE);
case HDCP_2X_CMD_OPEN_STREAMS:
return TO_STR(HDCP_2X_CMD_OPEN_STREAMS);
case HDCP_2X_CMD_CLOSE_STREAMS:
return TO_STR(HDCP_2X_CMD_CLOSE_STREAMS);
default:
return "UNKNOWN";
}
}
static inline const char *hdcp_transport_cmd_to_str(
enum hdcp_transport_wakeup_cmd cmd)
{
switch (cmd) {
case HDCP_TRANSPORT_CMD_SEND_MESSAGE:
return TO_STR(HDCP_TRANSPORT_CMD_SEND_MESSAGE);
case HDCP_TRANSPORT_CMD_RECV_MESSAGE:
return TO_STR(HDCP_TRANSPORT_CMD_RECV_MESSAGE);
case HDCP_TRANSPORT_CMD_STATUS_SUCCESS:
return TO_STR(HDCP_TRANSPORT_CMD_STATUS_SUCCESS);
case HDCP_TRANSPORT_CMD_STATUS_FAILED:
return TO_STR(HDCP_TRANSPORT_CMD_STATUS_FAILED);
case HDCP_TRANSPORT_CMD_LINK_POLL:
return TO_STR(HDCP_TRANSPORT_CMD_LINK_POLL);
case HDCP_TRANSPORT_CMD_AUTHENTICATE:
return TO_STR(HDCP_TRANSPORT_CMD_AUTHENTICATE);
default:
return "UNKNOWN";
}
}
struct sde_hdcp_2x_ops {
int (*wakeup)(struct sde_hdcp_2x_wakeup_data *data);
bool (*feature_supported)(void *data);
void (*force_encryption)(void *data, bool enable);
};
struct hdcp_transport_ops {
int (*wakeup)(struct hdcp_transport_wakeup_data *data);
};
struct sde_hdcp_2x_register_data {
struct hdcp_transport_ops *client_ops;
struct sde_hdcp_2x_ops *ops;
void *client_data;
void **hdcp_data;
};
/* functions for the HDCP 2.2 state machine module */
int sde_hdcp_2x_register(struct sde_hdcp_2x_register_data *data);
void sde_hdcp_2x_deregister(void *data);
#endif