Skip to content

Commit

Permalink
misc/mei/hdcp: Initiate Wired HDCP2.2 Tx Session
Browse files Browse the repository at this point in the history
Request ME FW to start the HDCP2.2 session for an intel port.
Prepares payloads for command WIRED_INITIATE_HDCP2_SESSION and sends
to ME FW.

On Success, ME FW will start a HDCP2.2 session for the port and
provides the content for HDCP2.2 AKE_Init message.

v2: Rebased.
v3:
  cldev is add as a separate parameter [Tomas]
  Redundant comment and typecast are removed [Tomas]
v4:
  %zd is used for size [Alexander]
  %s/return -1/return -EIO [Alexander]
  Spellings in commit msg is fixed [Uma]
v5: Rebased.
v6:
  Collected the rb-ed by.
  Realigning the patches in the series.
v7:
  Adjust to the new mei interface.
  Fix for kdoc.
v8:
  K-Doc Addition.
  memcpy for const length.
v9:
  s/mei_hdcp_ddi/mei_fw_ddi
  s/i915_port/mei_i915_port [Tomas]
  renamed func as mei_hdcp_* [Tomas]
  Instead of macro, inline func for ddi index is used. [Tomas]
v10:
  Switch case for the coversion between i915_port to mei_ddi [Tomas]
  Kernel doc fix.
v11:
  mei_hdcp_ops is defined as const. [Tomas]

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/1550772730-23280-5-git-send-email-ramalingam.c@intel.com
  • Loading branch information
Ramalingam C authored and Daniel Vetter committed Feb 25, 2019
1 parent cf8ecce commit a37fb1e
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 0 deletions.
94 changes: 94 additions & 0 deletions drivers/misc/mei/hdcp/mei_hdcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,100 @@
#include <linux/slab.h>
#include <linux/uuid.h>
#include <linux/mei_cl_bus.h>
#include <drm/drm_connector.h>
#include <drm/i915_component.h>
#include <drm/i915_mei_hdcp_interface.h>

#include "mei_hdcp.h"

static inline u8 mei_get_ddi_index(enum port port)
{
switch (port) {
case PORT_A:
return MEI_DDI_A;
case PORT_B ... PORT_F:
return (u8)port;
default:
return MEI_DDI_INVALID_PORT;
}
}

/**
* mei_hdcp_initiate_session() - Initiate a Wired HDCP2.2 Tx Session in ME FW
* @dev: device corresponding to the mei_cl_device
* @data: Intel HW specific hdcp data
* @ake_data: AKE_Init msg output.
*
* Return: 0 on Success, <0 on Failure.
*/
static int
mei_hdcp_initiate_session(struct device *dev, struct hdcp_port_data *data,
struct hdcp2_ake_init *ake_data)
{
struct wired_cmd_initiate_hdcp2_session_in session_init_in = { { 0 } };
struct wired_cmd_initiate_hdcp2_session_out
session_init_out = { { 0 } };
struct mei_cl_device *cldev;
ssize_t byte;

if (!dev || !data || !ake_data)
return -EINVAL;

cldev = to_mei_cl_device(dev);

session_init_in.header.api_version = HDCP_API_VERSION;
session_init_in.header.command_id = WIRED_INITIATE_HDCP2_SESSION;
session_init_in.header.status = ME_HDCP_STATUS_SUCCESS;
session_init_in.header.buffer_len =
WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_IN;

session_init_in.port.integrated_port_type = data->port_type;
session_init_in.port.physical_port = mei_get_ddi_index(data->port);
session_init_in.protocol = data->protocol;

byte = mei_cldev_send(cldev, (u8 *)&session_init_in,
sizeof(session_init_in));
if (byte < 0) {
dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
return byte;
}

byte = mei_cldev_recv(cldev, (u8 *)&session_init_out,
sizeof(session_init_out));
if (byte < 0) {
dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
return byte;
}

if (session_init_out.header.status != ME_HDCP_STATUS_SUCCESS) {
dev_dbg(dev, "ME cmd 0x%08X Failed. Status: 0x%X\n",
WIRED_INITIATE_HDCP2_SESSION,
session_init_out.header.status);
return -EIO;
}

ake_data->msg_id = HDCP_2_2_AKE_INIT;
ake_data->tx_caps = session_init_out.tx_caps;
memcpy(ake_data->r_tx, session_init_out.r_tx, HDCP_2_2_RTX_LEN);

return 0;
}

static const __attribute__((unused))
struct i915_hdcp_component_ops mei_hdcp_ops = {
.owner = THIS_MODULE,
.initiate_hdcp2_session = mei_hdcp_initiate_session,
.verify_receiver_cert_prepare_km = NULL,
.verify_hprime = NULL,
.store_pairing_info = NULL,
.initiate_locality_check = NULL,
.verify_lprime = NULL,
.get_session_key = NULL,
.repeater_check_flow_prepare_ack = NULL,
.verify_mprime = NULL,
.enable_hdcp_authentication = NULL,
.close_hdcp_session = NULL,
};

static int mei_hdcp_probe(struct mei_cl_device *cldev,
const struct mei_cl_device_id *id)
Expand Down
11 changes: 11 additions & 0 deletions drivers/misc/mei/hdcp/mei_hdcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,4 +363,15 @@ struct wired_cmd_repeater_auth_stream_req_out {
struct hdcp_port_id port;
} __packed;

enum mei_fw_ddi {
MEI_DDI_INVALID_PORT = 0x0,

MEI_DDI_B = 1,
MEI_DDI_C,
MEI_DDI_D,
MEI_DDI_E,
MEI_DDI_F,
MEI_DDI_A = 7,
MEI_DDI_RANGE_END = MEI_DDI_A,
};
#endif /* __MEI_HDCP_H__ */

0 comments on commit a37fb1e

Please sign in to comment.