misc: hdcp: SmcInvoke support for hdcp driver
SmcInvoke support for hdcp driver on haliday. Change-Id: I125fe031e09cdb9ad23005993ecde29ecf7276cd Signed-off-by: Sheik Anwar Shabic Y <quic_sheikanw@quicinc.com>
This commit is contained in:
parent
34adf267e9
commit
3f637ed5ce
@ -479,16 +479,6 @@ config QSEECOM
|
||||
Manager (SCM) interface. It exposes APIs for both userspace and
|
||||
kernel clients.
|
||||
|
||||
config HDCP_QSEECOM
|
||||
tristate "QTI High-Bandwidth Digital Content Protection Module"
|
||||
depends on QSEECOM
|
||||
help
|
||||
This module implements HDCP 2.2 features over external interfaces
|
||||
such as the DisplayPort interface. It exposes APIs for the interface
|
||||
driver to communicate with QTI Secure Execution Environment (QSEE)
|
||||
via the QSEECOM Driver and also communicates with the Receiver via
|
||||
APIs exposed by the interface driver.
|
||||
|
||||
config WIGIG_SENSING_SPI
|
||||
tristate "Sensing over 60GHz using wil6210 / SPI bus"
|
||||
depends on SPI && WIL6210
|
||||
@ -536,4 +526,5 @@ source "drivers/misc/cardreader/Kconfig"
|
||||
source "drivers/misc/habanalabs/Kconfig"
|
||||
source "drivers/misc/isl97900_led/Kconfig"
|
||||
source "drivers/misc/uacce/Kconfig"
|
||||
source "drivers/misc/hdcp/Kconfig"
|
||||
endmenu
|
||||
|
@ -49,7 +49,7 @@ obj-$(CONFIG_SRAM) += sram.o
|
||||
obj-$(CONFIG_SRAM_EXEC) += sram-exec.o
|
||||
obj-$(CONFIG_GENWQE) += genwqe/
|
||||
obj-$(CONFIG_ECHO) += echo/
|
||||
obj-$(CONFIG_HDCP_QSEECOM) += hdcp_qseecom.o
|
||||
obj-$(CONFIG_HDCP_QSEECOM) += hdcp/
|
||||
obj-$(CONFIG_CXL_BASE) += cxl/
|
||||
obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
|
||||
obj-$(CONFIG_OCXL) += ocxl/
|
||||
|
10
drivers/misc/hdcp/Kconfig
Normal file
10
drivers/misc/hdcp/Kconfig
Normal file
@ -0,0 +1,10 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config HDCP_QSEECOM
|
||||
tristate "QTI High-Bandwidth Digital Content Protection Module"
|
||||
depends on QSEECOM
|
||||
help
|
||||
This module implements HDCP 2.2 features over external interfaces
|
||||
such as the DisplayPort interface. It exposes APIs for the interface
|
||||
driver to communicate with QTI Secure Execution Environment (QSEE)
|
||||
via the QSEECOM Driver and also communicates with the Receiver via
|
||||
APIs exposed by the interface driver.
|
6
drivers/misc/hdcp/Makefile
Normal file
6
drivers/misc/hdcp/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
obj-$(CONFIG_HDCP_QSEECOM) += hdcp.o
|
||||
|
||||
hdcp-y += hdcp_main.o hdcp_qseecom.o hdcp_smcinvoke.o
|
||||
|
123
drivers/misc/hdcp/hdcp1.h
Normal file
123
drivers/misc/hdcp/hdcp1.h
Normal file
@ -0,0 +1,123 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
// AUTOGENERATED FILE: DO NOT EDIT
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <soc/qcom/smci_object.h>
|
||||
|
||||
#define HDCP1_PROVISION 0
|
||||
#define HDCP1_VERIFY 1
|
||||
#define HDCP1_SET_ENCRYPTION 2
|
||||
#define HDCP1_SET_ENCRYPTION_V2 3
|
||||
#define HDCP1_SET_KEY 4
|
||||
#define HDCP1_SET_KEY_V2 5
|
||||
#define HDCP1_SET_MODE 6
|
||||
|
||||
static inline int32_t hdcp1_release(struct smci_object self)
|
||||
{
|
||||
return smci_object_invoke(self, SMCI_OBJECT_OP_RELEASE, 0, 0);
|
||||
}
|
||||
|
||||
static inline int32_t hdcp1_retain(struct smci_object self)
|
||||
{
|
||||
return smci_object_invoke(self, SMCI_OBJECT_OP_RETAIN, 0, 0);
|
||||
}
|
||||
|
||||
static inline int32_t hdcp1_provision(struct smci_object self, uint32_t keyFormat_val,
|
||||
const void *key_ptr, size_t key_len,
|
||||
const void *dps_ptr, size_t dps_len)
|
||||
{
|
||||
union smci_object_arg a[3] = {{{0, 0}}};
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&keyFormat_val, sizeof(uint32_t)};
|
||||
a[1].bi = (struct smci_object_buf_in) {key_ptr, key_len * 1};
|
||||
a[2].bi = (struct smci_object_buf_in) {dps_ptr, dps_len * 1};
|
||||
|
||||
return smci_object_invoke(self, HDCP1_PROVISION, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(3, 0, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp1_verify(struct smci_object self, uint32_t deviceType_val)
|
||||
{
|
||||
union smci_object_arg a[1] = {{{0, 0}}};
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&deviceType_val, sizeof(uint32_t)};
|
||||
|
||||
return smci_object_invoke(self, HDCP1_VERIFY, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 0, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp1_set_encryption(struct smci_object self, uint32_t enable_val)
|
||||
{
|
||||
union smci_object_arg a[1] = {{{0, 0}}};
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&enable_val, sizeof(uint32_t)};
|
||||
|
||||
return smci_object_invoke(self, HDCP1_SET_ENCRYPTION, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 0, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp1_set_encryption_v2(struct smci_object self, uint32_t enable_val,
|
||||
uint32_t deviceType_val)
|
||||
{
|
||||
union smci_object_arg a[1] = {{{0, 0}}};
|
||||
struct {
|
||||
uint32_t m_enable;
|
||||
uint32_t m_deviceType;
|
||||
} i;
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&i, 8};
|
||||
i.m_enable = enable_val;
|
||||
i.m_deviceType = deviceType_val;
|
||||
|
||||
return smci_object_invoke(self, HDCP1_SET_ENCRYPTION_V2, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 0, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp1_set_key(struct smci_object self, void *ksv_ptr, size_t ksv_len,
|
||||
size_t *ksv_lenout)
|
||||
{
|
||||
union smci_object_arg a[1] = {{{0, 0}}};
|
||||
int32_t result = 0;
|
||||
|
||||
a[0].b = (struct smci_object_buf) {ksv_ptr, ksv_len * 1};
|
||||
|
||||
result = smci_object_invoke(self, HDCP1_SET_KEY, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(0, 1, 0, 0));
|
||||
|
||||
*ksv_lenout = a[0].b.size / 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline int32_t hdcp1_set_key_v2(struct smci_object self, void *ksv_ptr,
|
||||
size_t ksv_len, size_t *ksv_lenout,
|
||||
uint32_t deviceType_val)
|
||||
{
|
||||
union smci_object_arg a[2] = {{{0, 0}}};
|
||||
int32_t result = 0;
|
||||
|
||||
a[1].b = (struct smci_object_buf) {ksv_ptr, ksv_len * 1};
|
||||
a[0].b = (struct smci_object_buf) {&deviceType_val, sizeof(uint32_t)};
|
||||
|
||||
result = smci_object_invoke(self, HDCP1_SET_KEY_V2, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 1, 0, 0));
|
||||
|
||||
*ksv_lenout = a[1].b.size / 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline int32_t hdcp1_set_mode(struct smci_object self, int32_t mode_val)
|
||||
{
|
||||
union smci_object_arg a[1] = {{{0, 0}}};
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&mode_val, sizeof(int32_t)};
|
||||
|
||||
return smci_object_invoke(self, HDCP1_SET_MODE, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 0, 0, 0));
|
||||
}
|
27
drivers/misc/hdcp/hdcp1_ops.h
Normal file
27
drivers/misc/hdcp/hdcp1_ops.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
// AUTOGENERATED FILE: DO NOT EDIT
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <soc/qcom/smci_object.h>
|
||||
|
||||
#define IHDCP1OPS_NOTIFY_TOPOLOGY_CHANGE 0
|
||||
|
||||
static inline int32_t hdcp1_ops_release(struct smci_object self)
|
||||
{
|
||||
return smci_object_invoke(self, SMCI_OBJECT_OP_RELEASE, 0, 0);
|
||||
}
|
||||
|
||||
static inline int32_t hdcp1_ops_retain(struct smci_object self)
|
||||
{
|
||||
return smci_object_invoke(self, SMCI_OBJECT_OP_RETAIN, 0, 0);
|
||||
}
|
||||
|
||||
static inline int32_t hdcp1_ops_notify_topology_change(struct smci_object self)
|
||||
{
|
||||
return smci_object_invoke(self, IHDCP1OPS_NOTIFY_TOPOLOGY_CHANGE, 0, 0);
|
||||
}
|
303
drivers/misc/hdcp/hdcp2p2.h
Normal file
303
drivers/misc/hdcp/hdcp2p2.h
Normal file
@ -0,0 +1,303 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
// AUTOGENERATED FILE: DO NOT EDIT
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <soc/qcom/smci_object.h>
|
||||
|
||||
#define HDCP2P2_PROVISION_KEY 0
|
||||
#define HDCP2P2_VERIFY_KEY 1
|
||||
#define HDCP2P2_TX_INIT 2
|
||||
#define HDCP2P2_TX_DEINIT 3
|
||||
#define HDCP2P2_RCVD_MSG 4
|
||||
#define HDCP2P2_SEND_TIMEOUT 5
|
||||
#define HDCP2P2_SET_HW_KEY 6
|
||||
#define HDCP2P2_QUERY_STREAM_TYPE 7
|
||||
#define HDCP2P2_INIT 8
|
||||
#define HDCP2P2_DEINIT 9
|
||||
#define HDCP2P2_VERSION 10
|
||||
#define HDCP2P2_SESSION_INIT 11
|
||||
#define HDCP2P2_SESSION_DEINIT 12
|
||||
#define HDCP2P2_START_AUTH 13
|
||||
#define HDCP2P2_SESSION_OPEN_STREAM 14
|
||||
#define HDCP2P2_SESSION_CLOSE_STREAM 15
|
||||
#define HDCP2P2_FORCE_ENCRYPTION 16
|
||||
#define HDCP2P2_DELETE_PAIRING_INFO 17
|
||||
|
||||
static inline int32_t hdcp2p2_release(struct smci_object self)
|
||||
{
|
||||
return smci_object_invoke(self, SMCI_OBJECT_OP_RELEASE, 0, 0);
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_retain(struct smci_object self)
|
||||
{
|
||||
return smci_object_invoke(self, SMCI_OBJECT_OP_RETAIN, 0, 0);
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_provision_key(struct smci_object self, const void *key_ptr,
|
||||
size_t key_len,
|
||||
const void *dps_ptr,
|
||||
size_t dps_len)
|
||||
{
|
||||
union smci_object_arg a[2] = {{{0, 0}}};
|
||||
|
||||
a[0].bi = (struct smci_object_buf_in) {key_ptr, key_len * 1};
|
||||
a[1].bi = (struct smci_object_buf_in) {dps_ptr, dps_len * 1};
|
||||
|
||||
return smci_object_invoke(self, HDCP2P2_PROVISION_KEY, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(2, 0, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_verify_key(struct smci_object self)
|
||||
{
|
||||
return smci_object_invoke(self, HDCP2P2_VERIFY_KEY, 0, 0);
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_tx_init(struct smci_object self, uint32_t sessionid_val,
|
||||
uint32_t *ctxhandle_ptr)
|
||||
{
|
||||
union smci_object_arg a[2] = {{{0, 0}}};
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&sessionid_val, sizeof(uint32_t)};
|
||||
a[1].b = (struct smci_object_buf) {ctxhandle_ptr, sizeof(uint32_t)};
|
||||
|
||||
return smci_object_invoke(self, HDCP2P2_TX_INIT, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 1, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_tx_deinit(struct smci_object self, uint32_t ctxhandle_val)
|
||||
{
|
||||
union smci_object_arg a[1] = {{{0, 0}}};
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&ctxhandle_val, sizeof(uint32_t)};
|
||||
|
||||
return smci_object_invoke(self, HDCP2P2_TX_DEINIT, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 0, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_rcvd_msg(
|
||||
struct smci_object self, const void *reqMsg_ptr, size_t reqMsg_len,
|
||||
uint32_t ctxhandle_val, void *resMsg_ptr, size_t resMsg_len,
|
||||
size_t *resMsg_lenout, uint32_t *timeout_ptr, uint32_t *flag_ptr)
|
||||
{
|
||||
union smci_object_arg a[4] = {{{0, 0}}};
|
||||
int32_t result = 0;
|
||||
struct {
|
||||
uint32_t m_timeout;
|
||||
uint32_t m_flag;
|
||||
} o;
|
||||
|
||||
a[2].b = (struct smci_object_buf) {&o, 8};
|
||||
a[0].bi = (struct smci_object_buf_in) {reqMsg_ptr, reqMsg_len * 1};
|
||||
a[1].b = (struct smci_object_buf) {&ctxhandle_val, sizeof(uint32_t)};
|
||||
a[3].b = (struct smci_object_buf) {resMsg_ptr, resMsg_len * 1};
|
||||
|
||||
result = smci_object_invoke(self, HDCP2P2_RCVD_MSG, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(2, 2, 0, 0));
|
||||
|
||||
*resMsg_lenout = a[3].b.size / 1;
|
||||
*timeout_ptr = o.m_timeout;
|
||||
*flag_ptr = o.m_flag;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_send_timeout(struct smci_object self, uint32_t ctxhandle_val,
|
||||
void *resMsg_ptr, size_t resMsg_len,
|
||||
size_t *resMsg_lenout,
|
||||
uint32_t *timeout_ptr)
|
||||
{
|
||||
union smci_object_arg a[3] = {{{0, 0}}};
|
||||
int32_t result = 0;
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&ctxhandle_val, sizeof(uint32_t)};
|
||||
a[1].b = (struct smci_object_buf) {resMsg_ptr, resMsg_len * 1};
|
||||
a[2].b = (struct smci_object_buf) {timeout_ptr, sizeof(uint32_t)};
|
||||
|
||||
result = smci_object_invoke(self, HDCP2P2_SEND_TIMEOUT, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 2, 0, 0));
|
||||
|
||||
*resMsg_lenout = a[1].b.size / 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_set_hw_key(struct smci_object self, uint32_t ctxhandle_val)
|
||||
{
|
||||
union smci_object_arg a[1] = {{{0, 0}}};
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&ctxhandle_val, sizeof(uint32_t)};
|
||||
|
||||
return smci_object_invoke(self, HDCP2P2_SET_HW_KEY, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 0, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_query_stream_type(
|
||||
struct smci_object self, uint32_t ctxhandle_val, void *resMsg_ptr, size_t resMsg_len,
|
||||
size_t *resMsg_lenout, uint32_t *timeout_ptr)
|
||||
{
|
||||
union smci_object_arg a[3] = {{{0, 0}}};
|
||||
int32_t result = 0;
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&ctxhandle_val, sizeof(uint32_t)};
|
||||
a[1].b = (struct smci_object_buf) {resMsg_ptr, resMsg_len * 1};
|
||||
a[2].b = (struct smci_object_buf) {timeout_ptr, sizeof(uint32_t)};
|
||||
|
||||
result = smci_object_invoke(self, HDCP2P2_QUERY_STREAM_TYPE, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 2, 0, 0));
|
||||
|
||||
*resMsg_lenout = a[1].b.size / 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_init(struct smci_object self, uint32_t clientVersion_val,
|
||||
uint32_t *appversion_ptr)
|
||||
{
|
||||
union smci_object_arg a[2] = {{{0, 0}}};
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&clientVersion_val, sizeof(uint32_t)};
|
||||
a[1].b = (struct smci_object_buf) {appversion_ptr, sizeof(uint32_t)};
|
||||
|
||||
return smci_object_invoke(self, HDCP2P2_INIT, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 1, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_deinit(struct smci_object self)
|
||||
{
|
||||
return smci_object_invoke(self, HDCP2P2_DEINIT, 0, 0);
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_version(struct smci_object self, uint32_t *appversion_ptr)
|
||||
{
|
||||
union smci_object_arg a[1] = {{{0, 0}}};
|
||||
|
||||
a[0].b = (struct smci_object_buf) {appversion_ptr, sizeof(uint32_t)};
|
||||
|
||||
return smci_object_invoke(self, HDCP2P2_VERSION, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(0, 1, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_session_init(struct smci_object self, uint32_t deviceId_val,
|
||||
uint32_t *sessionId_ptr)
|
||||
{
|
||||
union smci_object_arg a[2] = {{{0, 0}}};
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&deviceId_val, sizeof(uint32_t)};
|
||||
a[1].b = (struct smci_object_buf) {sessionId_ptr, sizeof(uint32_t)};
|
||||
|
||||
return smci_object_invoke(self, HDCP2P2_SESSION_INIT, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 1, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_session_deinit(struct smci_object self,
|
||||
uint32_t sessionId_val)
|
||||
{
|
||||
union smci_object_arg a[1] = {{{0, 0}}};
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&sessionId_val, sizeof(uint32_t)};
|
||||
|
||||
return smci_object_invoke(self, HDCP2P2_SESSION_DEINIT, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 0, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_start_auth(struct smci_object self, uint32_t ctxhandle_val,
|
||||
void *resMsg_ptr, size_t resMsg_len,
|
||||
size_t *resMsg_lenout,
|
||||
uint32_t *timeout_ptr,
|
||||
uint32_t *flag_ptr,
|
||||
uint32_t *tzctxhandle_ptr)
|
||||
{
|
||||
union smci_object_arg a[3] = {{{0, 0}}};
|
||||
int32_t result = 0;
|
||||
struct {
|
||||
uint32_t m_timeout;
|
||||
uint32_t m_flag;
|
||||
uint32_t m_tzctxhandle;
|
||||
} o;
|
||||
|
||||
a[1].b = (struct smci_object_buf) {&o, 12};
|
||||
a[0].b = (struct smci_object_buf) {&ctxhandle_val, sizeof(uint32_t)};
|
||||
a[2].b = (struct smci_object_buf) {resMsg_ptr, resMsg_len * 1};
|
||||
|
||||
result = smci_object_invoke(self, HDCP2P2_START_AUTH, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 2, 0, 0));
|
||||
|
||||
*resMsg_lenout = a[2].b.size / 1;
|
||||
*timeout_ptr = o.m_timeout;
|
||||
*flag_ptr = o.m_flag;
|
||||
*tzctxhandle_ptr = o.m_tzctxhandle;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_session_open_stream(struct smci_object self,
|
||||
uint32_t sessionid_val,
|
||||
uint32_t vcpayloadid_val,
|
||||
uint32_t stream_number_val,
|
||||
uint32_t streamMediaType_val,
|
||||
uint32_t *resStreamId_ptr)
|
||||
{
|
||||
union smci_object_arg a[2] = {{{0, 0}}};
|
||||
struct {
|
||||
uint32_t m_sessionid;
|
||||
uint32_t m_vcpayloadid;
|
||||
uint32_t m_stream_number;
|
||||
uint32_t m_streamMediaType;
|
||||
} i;
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&i, 16};
|
||||
i.m_sessionid = sessionid_val;
|
||||
i.m_vcpayloadid = vcpayloadid_val;
|
||||
i.m_stream_number = stream_number_val;
|
||||
i.m_streamMediaType = streamMediaType_val;
|
||||
a[1].b = (struct smci_object_buf) {resStreamId_ptr, sizeof(uint32_t)};
|
||||
|
||||
return smci_object_invoke(self, HDCP2P2_SESSION_OPEN_STREAM, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 1, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_session_close_stream(struct smci_object self,
|
||||
uint32_t sessionid_val,
|
||||
uint32_t streamId_val)
|
||||
{
|
||||
union smci_object_arg a[1] = {{{0, 0}}};
|
||||
struct {
|
||||
uint32_t m_sessionid;
|
||||
uint32_t m_streamId;
|
||||
} i;
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&i, 8};
|
||||
i.m_sessionid = sessionid_val;
|
||||
i.m_streamId = streamId_val;
|
||||
|
||||
return smci_object_invoke(self, HDCP2P2_SESSION_CLOSE_STREAM, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 0, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_force_encryption(struct smci_object self,
|
||||
uint32_t ctxhandle_val,
|
||||
uint32_t enable_val)
|
||||
{
|
||||
union smci_object_arg a[1] = {{{0, 0}}};
|
||||
struct {
|
||||
uint32_t m_ctxhandle;
|
||||
uint32_t m_enable;
|
||||
} i;
|
||||
|
||||
a[0].b = (struct smci_object_buf) {&i, 8};
|
||||
i.m_ctxhandle = ctxhandle_val;
|
||||
i.m_enable = enable_val;
|
||||
|
||||
return smci_object_invoke(self, HDCP2P2_FORCE_ENCRYPTION, a,
|
||||
SMCI_OBJECT_COUNTS_PACK(1, 0, 0, 0));
|
||||
}
|
||||
|
||||
static inline int32_t hdcp2p2_delete_pairing_info(struct smci_object self)
|
||||
{
|
||||
return smci_object_invoke(self, HDCP2P2_DELETE_PAIRING_INFO, 0, 0);
|
||||
}
|
314
drivers/misc/hdcp/hdcp_main.c
Normal file
314
drivers/misc/hdcp/hdcp_main.c
Normal file
@ -0,0 +1,314 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "hdcp_main.h"
|
||||
#include "hdcp_qseecom.h"
|
||||
#include "hdcp_smcinvoke.h"
|
||||
|
||||
struct hdcp_ta_interface ta_interface;
|
||||
static DEFINE_MUTEX(hdcp1_mutex_g);
|
||||
static DEFINE_MUTEX(hdcp2_mutex_g);
|
||||
|
||||
void select_interface(bool use_smcinvoke)
|
||||
{
|
||||
if (use_smcinvoke) {
|
||||
ta_interface.trusted_app_hdcp1_init = &hdcp1_init_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp1_feature_supported =
|
||||
&hdcp1_feature_supported_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp1_set_enc = &hdcp1_set_enc_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp1_ops_notify = &hdcp1_ops_notify_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp1_start = &hdcp1_start_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp1_stop = &hdcp1_stop_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp2_init = &hdcp2_init_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp2_deinit = &hdcp2_deinit_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp2_app_start = &hdcp2_app_start_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp2_app_start_auth = &hdcp2_app_start_auth_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp2_app_process_msg = &hdcp2_app_process_msg_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp2_app_enable_encryption =
|
||||
&hdcp2_app_enable_encryption_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp2_app_query_stream = &hdcp2_app_query_stream_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp2_app_stop = &hdcp2_app_stop_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp2_feature_supported =
|
||||
&hdcp2_feature_supported_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp2_force_encryption = &hdcp2_force_encryption_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp2_open_stream = &hdcp2_open_stream_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp2_close_stream = &hdcp2_close_stream_smcinvoke;
|
||||
ta_interface.trusted_app_hdcp2_update_app_data = &hdcp2_update_app_data_smcinvoke;
|
||||
} else {
|
||||
ta_interface.trusted_app_hdcp1_init = &hdcp1_init_qseecom;
|
||||
ta_interface.trusted_app_hdcp1_feature_supported = &hdcp1_feature_supported_qseecom;
|
||||
ta_interface.trusted_app_hdcp1_set_enc = &hdcp1_set_enc_qseecom;
|
||||
ta_interface.trusted_app_hdcp1_ops_notify = &hdcp1_ops_notify_qseecom;
|
||||
ta_interface.trusted_app_hdcp1_start = &hdcp1_start_qseecom;
|
||||
ta_interface.trusted_app_hdcp1_stop = &hdcp1_stop_qseecom;
|
||||
ta_interface.trusted_app_hdcp2_init = &hdcp2_init_qseecom;
|
||||
ta_interface.trusted_app_hdcp2_deinit = &hdcp2_deinit_qseecom;
|
||||
ta_interface.trusted_app_hdcp2_app_start = &hdcp2_app_start_qseecom;
|
||||
ta_interface.trusted_app_hdcp2_app_start_auth = &hdcp2_app_start_auth_qseecom;
|
||||
ta_interface.trusted_app_hdcp2_app_process_msg = &hdcp2_app_process_msg_qseecom;
|
||||
ta_interface.trusted_app_hdcp2_app_enable_encryption =
|
||||
&hdcp2_app_enable_encryption_qseecom;
|
||||
ta_interface.trusted_app_hdcp2_app_query_stream = &hdcp2_app_query_stream_qseecom;
|
||||
ta_interface.trusted_app_hdcp2_app_stop = &hdcp2_app_stop_qseecom;
|
||||
ta_interface.trusted_app_hdcp2_feature_supported = &hdcp2_feature_supported_qseecom;
|
||||
ta_interface.trusted_app_hdcp2_force_encryption = &hdcp2_force_encryption_qseecom;
|
||||
ta_interface.trusted_app_hdcp2_open_stream = &hdcp2_open_stream_qseecom;
|
||||
ta_interface.trusted_app_hdcp2_close_stream = &hdcp2_close_stream_qseecom;
|
||||
ta_interface.trusted_app_hdcp2_update_app_data = &hdcp2_update_app_data_qseecom;
|
||||
}
|
||||
}
|
||||
|
||||
int hdcp1_count_ones(u8 *array, u8 len)
|
||||
{
|
||||
int i, j, count = 0;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
for (j = 0; j < 8; j++)
|
||||
count += (((array[i] >> j) & 0x1) ? 1 : 0);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int hdcp1_validate_aksv(u32 aksv_msb, u32 aksv_lsb)
|
||||
{
|
||||
int const number_of_ones = 20;
|
||||
u8 aksv[5] = {0};
|
||||
|
||||
pr_debug("AKSV=%02x%08x\n", aksv_msb, aksv_lsb);
|
||||
|
||||
aksv[0] = aksv_lsb & 0xFF;
|
||||
aksv[1] = (aksv_lsb >> 8) & 0xFF;
|
||||
aksv[2] = (aksv_lsb >> 16) & 0xFF;
|
||||
aksv[3] = (aksv_lsb >> 24) & 0xFF;
|
||||
aksv[4] = aksv_msb & 0xFF;
|
||||
|
||||
/* check there are 20 ones in AKSV */
|
||||
if (hdcp1_count_ones(aksv, 5) != number_of_ones) {
|
||||
pr_err("AKSV bit count failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool hdcp2_feature_supported(void *data)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&hdcp2_mutex_g);
|
||||
ret = ta_interface.trusted_app_hdcp2_feature_supported(data);
|
||||
mutex_unlock(&hdcp2_mutex_g);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(hdcp2_feature_supported);
|
||||
|
||||
int hdcp2_force_encryption(void *ctx, uint32_t enable)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&hdcp2_mutex_g);
|
||||
ret = ta_interface.trusted_app_hdcp2_force_encryption(ctx, enable);
|
||||
mutex_unlock(&hdcp2_mutex_g);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(hdcp2_force_encryption);
|
||||
|
||||
int hdcp2_app_comm(void *ctx, enum hdcp2_app_cmd cmd,
|
||||
struct hdcp2_app_data *app_data)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t req_len = 0;
|
||||
|
||||
if (!ctx || !app_data) {
|
||||
pr_err("invalid input\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
req_len = app_data->request.length;
|
||||
|
||||
mutex_lock(&hdcp2_mutex_g);
|
||||
switch (cmd) {
|
||||
case HDCP2_CMD_START:
|
||||
ret = ta_interface.trusted_app_hdcp2_app_start(ctx, req_len);
|
||||
break;
|
||||
case HDCP2_CMD_START_AUTH:
|
||||
ret = ta_interface.trusted_app_hdcp2_app_start_auth(ctx, req_len);
|
||||
break;
|
||||
case HDCP2_CMD_PROCESS_MSG:
|
||||
ret = ta_interface.trusted_app_hdcp2_app_process_msg(ctx, req_len);
|
||||
break;
|
||||
case HDCP2_CMD_TIMEOUT:
|
||||
ret = ta_interface.trusted_app_hdcp2_app_timeout(ctx, req_len);
|
||||
break;
|
||||
case HDCP2_CMD_EN_ENCRYPTION:
|
||||
ret = ta_interface.trusted_app_hdcp2_app_enable_encryption(ctx, req_len);
|
||||
break;
|
||||
case HDCP2_CMD_QUERY_STREAM:
|
||||
ret = ta_interface.trusted_app_hdcp2_app_query_stream(ctx, req_len);
|
||||
break;
|
||||
case HDCP2_CMD_STOP:
|
||||
ret = ta_interface.trusted_app_hdcp2_app_stop(ctx);
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
ret = ta_interface.trusted_app_hdcp2_update_app_data(ctx, app_data);
|
||||
|
||||
error:
|
||||
mutex_unlock(&hdcp2_mutex_g);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(hdcp2_app_comm);
|
||||
|
||||
int hdcp2_open_stream(void *ctx, uint8_t vc_payload_id, uint8_t stream_number,
|
||||
uint32_t *stream_id)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&hdcp2_mutex_g);
|
||||
ret = ta_interface.trusted_app_hdcp2_open_stream(ctx, vc_payload_id, stream_number,
|
||||
stream_id);
|
||||
mutex_unlock(&hdcp2_mutex_g);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(hdcp2_open_stream);
|
||||
|
||||
int hdcp2_close_stream(void *ctx, uint32_t stream_id)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&hdcp2_mutex_g);
|
||||
ret = ta_interface.trusted_app_hdcp2_close_stream(ctx, stream_id);
|
||||
mutex_unlock(&hdcp2_mutex_g);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(hdcp2_close_stream);
|
||||
|
||||
void *hdcp2_init(u32 device_type)
|
||||
{
|
||||
void *data = NULL;
|
||||
|
||||
mutex_lock(&hdcp2_mutex_g);
|
||||
data = ta_interface.trusted_app_hdcp2_init(device_type);
|
||||
mutex_unlock(&hdcp2_mutex_g);
|
||||
|
||||
return data;
|
||||
}
|
||||
EXPORT_SYMBOL(hdcp2_init);
|
||||
|
||||
void hdcp2_deinit(void *ctx)
|
||||
{
|
||||
ta_interface.trusted_app_hdcp2_deinit(ctx);
|
||||
}
|
||||
EXPORT_SYMBOL(hdcp2_deinit);
|
||||
|
||||
void *hdcp1_init(void)
|
||||
{
|
||||
void *data = NULL;
|
||||
|
||||
mutex_lock(&hdcp1_mutex_g);
|
||||
data = ta_interface.trusted_app_hdcp1_init();
|
||||
mutex_unlock(&hdcp1_mutex_g);
|
||||
|
||||
return data;
|
||||
}
|
||||
EXPORT_SYMBOL(hdcp1_init);
|
||||
|
||||
void hdcp1_deinit(void *data)
|
||||
{
|
||||
kfree(data);
|
||||
}
|
||||
EXPORT_SYMBOL(hdcp1_deinit);
|
||||
|
||||
bool hdcp1_feature_supported(void *data)
|
||||
{
|
||||
bool supported = false;
|
||||
|
||||
mutex_lock(&hdcp1_mutex_g);
|
||||
supported = ta_interface.trusted_app_hdcp1_feature_supported(data);
|
||||
mutex_unlock(&hdcp1_mutex_g);
|
||||
|
||||
return supported;
|
||||
}
|
||||
EXPORT_SYMBOL(hdcp1_feature_supported);
|
||||
|
||||
int hdcp1_set_enc(void *data, bool enable)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&hdcp1_mutex_g);
|
||||
ret = ta_interface.trusted_app_hdcp1_set_enc(data, enable);
|
||||
mutex_unlock(&hdcp1_mutex_g);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(hdcp1_set_enc);
|
||||
|
||||
int hdcp1_ops_notify(void *data, void *topo, bool is_authenticated)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = ta_interface.trusted_app_hdcp1_ops_notify(data, topo, is_authenticated);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(hdcp1_ops_notify);
|
||||
|
||||
int hdcp1_start(void *data, u32 *aksv_msb, u32 *aksv_lsb)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&hdcp1_mutex_g);
|
||||
ret = ta_interface.trusted_app_hdcp1_start(data, aksv_msb, aksv_lsb);
|
||||
mutex_unlock(&hdcp1_mutex_g);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(hdcp1_start);
|
||||
|
||||
void hdcp1_stop(void *data)
|
||||
{
|
||||
mutex_lock(&hdcp1_mutex_g);
|
||||
ta_interface.trusted_app_hdcp1_stop(data);
|
||||
mutex_unlock(&hdcp1_mutex_g);
|
||||
}
|
||||
EXPORT_SYMBOL(hdcp1_stop);
|
||||
|
||||
static int __init hdcp_module_init(void)
|
||||
{
|
||||
struct device_node *np = NULL;
|
||||
bool use_smcinvoke = false;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "qcom,hdcp");
|
||||
if (!np) {
|
||||
/*select qseecom interface as default if hdcp node
|
||||
*is not present in dtsi
|
||||
*/
|
||||
select_interface(use_smcinvoke);
|
||||
return 0;
|
||||
}
|
||||
|
||||
use_smcinvoke = of_property_read_bool(np, "qcom,use-smcinvoke");
|
||||
|
||||
select_interface(use_smcinvoke);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static void __exit hdcp_module_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("HDCP driver");
|
||||
|
||||
module_init(hdcp_module_init);
|
||||
module_exit(hdcp_module_exit);
|
107
drivers/misc/hdcp/hdcp_main.h
Normal file
107
drivers/misc/hdcp/hdcp_main.h
Normal file
@ -0,0 +1,107 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HDCP_MAIN_H__
|
||||
#define __HDCP_MAIN_H__
|
||||
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/hdcp_qseecom.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ion.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <misc/qseecom_kernel.h>
|
||||
|
||||
#define HDCP2P2_APP_NAME "hdcp2p2"
|
||||
#define HDCP1_APP_NAME "hdcp1"
|
||||
#define HDCP1OPS_APP_NAME "ops"
|
||||
#define HDCPSRM_APP_NAME "hdcpsrm"
|
||||
#define QSEECOM_SBUFF_SIZE 0x1000
|
||||
|
||||
#define MAX_REC_ID_LIST_SIZE 160
|
||||
#define MAX_TX_MESSAGE_SIZE 129
|
||||
#define MAX_RX_MESSAGE_SIZE 534
|
||||
#define MAX_TOPOLOGY_ELEMS 32
|
||||
#define HDCP1_NOTIFY_TOPOLOGY 1
|
||||
#define HDCP1_AKSV_SIZE 8
|
||||
|
||||
#define HDCP_CLIENT_MAKE_VERSION(maj, min, patch) \
|
||||
((((maj)&0xFF) << 16) | (((min)&0xFF) << 8) | ((patch)&0xFF))
|
||||
|
||||
#define HCDP_TXMTR_GET_MAJOR_VERSION(v) (((v) >> 16) & 0xFF)
|
||||
#define HCDP_TXMTR_GET_MINOR_VERSION(v) (((v) >> 8) & 0xFF)
|
||||
#define HCDP_TXMTR_GET_PATCH_VERSION(v) ((v)&0xFF)
|
||||
|
||||
#define HDCP_CLIENT_MAJOR_VERSION 2
|
||||
#define HDCP_CLIENT_MINOR_VERSION 1
|
||||
#define HDCP_CLIENT_PATCH_VERSION 0
|
||||
|
||||
#define HDCP_SUCCESS 0
|
||||
|
||||
/* Wait 200ms after authentication */
|
||||
#define SLEEP_FORCE_ENCRYPTION_MS 200
|
||||
|
||||
#define SLEEP_SET_HW_KEY_MS 300
|
||||
|
||||
/* flags set by tz in response message */
|
||||
#define HDCP_TXMTR_SUBSTATE_INIT 0
|
||||
#define HDCP_TXMTR_SUBSTATE_WAITING_FOR_RECIEVERID_LIST 1
|
||||
#define HDCP_TXMTR_SUBSTATE_PROCESSED_RECIEVERID_LIST 2
|
||||
#define HDCP_TXMTR_SUBSTATE_WAITING_FOR_STREAM_READY_MESSAGE 3
|
||||
#define HDCP_TXMTR_SUBSTATE_REPEATER_AUTH_COMPLETE 4
|
||||
|
||||
enum hdcp_state {
|
||||
HDCP_STATE_INIT = 0x00,
|
||||
HDCP_STATE_APP_LOADED = 0x01,
|
||||
HDCP_STATE_SESSION_INIT = 0x02,
|
||||
HDCP_STATE_TXMTR_INIT = 0x04,
|
||||
HDCP_STATE_AUTHENTICATED = 0x08,
|
||||
HDCP_STATE_ERROR = 0x10
|
||||
};
|
||||
|
||||
struct hdcp_ta_interface {
|
||||
void *(*trusted_app_hdcp1_init)(void);
|
||||
bool (*trusted_app_hdcp1_feature_supported)(void *data);
|
||||
int (*trusted_app_hdcp1_set_enc)(void *data, bool enable);
|
||||
int (*trusted_app_hdcp1_ops_notify)(void *data, void *topo,
|
||||
bool is_authenticated);
|
||||
int (*trusted_app_hdcp1_start)(void *data, u32 *aksv_msb,
|
||||
u32 *aksv_lsb);
|
||||
void (*trusted_app_hdcp1_stop)(void *data);
|
||||
void *(*trusted_app_hdcp2_init)(u32 device_type);
|
||||
void (*trusted_app_hdcp2_deinit)(void *ctx);
|
||||
int (*trusted_app_hdcp2_app_start)(void *ctx, uint32_t req_len);
|
||||
int (*trusted_app_hdcp2_app_start_auth)(void *ctx, uint32_t req_len);
|
||||
int (*trusted_app_hdcp2_app_process_msg)(void *ctx, uint32_t req_len);
|
||||
int (*trusted_app_hdcp2_app_timeout)(void *ctx, uint32_t req_len);
|
||||
int (*trusted_app_hdcp2_app_enable_encryption)(void *ctx, uint32_t req_len);
|
||||
int (*trusted_app_hdcp2_app_query_stream)(void *ctx, uint32_t req_len);
|
||||
int (*trusted_app_hdcp2_app_stop)(void *ctx);
|
||||
bool (*trusted_app_hdcp2_feature_supported)(void *ctx);
|
||||
int (*trusted_app_hdcp2_force_encryption)(void *ctx, uint32_t enable);
|
||||
int (*trusted_app_hdcp2_open_stream)(void *ctx, uint8_t vc_payload_id,
|
||||
uint8_t stream_number, uint32_t *stream_id);
|
||||
int (*trusted_app_hdcp2_close_stream)(void *ctx, uint32_t stream_id);
|
||||
int (*trusted_app_hdcp2_update_app_data)(void *ctx,
|
||||
struct hdcp2_app_data *app_data);
|
||||
};
|
||||
|
||||
int hdcp1_validate_aksv(u32 aksv_msb, u32 aksv_lsb);
|
||||
|
||||
#endif /* __HDCP_MAIN_H__ */
|
1403
drivers/misc/hdcp/hdcp_qseecom.c
Normal file
1403
drivers/misc/hdcp/hdcp_qseecom.c
Normal file
File diff suppressed because it is too large
Load Diff
326
drivers/misc/hdcp/hdcp_qseecom.h
Normal file
326
drivers/misc/hdcp/hdcp_qseecom.h
Normal file
@ -0,0 +1,326 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HDCP_QSEECOM_H__
|
||||
#define __HDCP_QSEECOM_H__
|
||||
|
||||
#include <linux/hdcp_qseecom.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "hdcp_main.h"
|
||||
|
||||
struct hdcp1_qsee_handle {
|
||||
struct qseecom_handle *qseecom_handle;
|
||||
struct qseecom_handle *hdcpops_handle;
|
||||
bool feature_supported;
|
||||
uint32_t device_type;
|
||||
enum hdcp_state hdcp_state;
|
||||
char *app_name;
|
||||
};
|
||||
|
||||
struct hdcp2_qsee_handle {
|
||||
struct hdcp2_app_data app_data;
|
||||
uint32_t tz_ctxhandle;
|
||||
bool feature_supported;
|
||||
enum hdcp_state hdcp_state;
|
||||
struct qseecom_handle *qseecom_handle;
|
||||
struct qseecom_handle *hdcpsrm_qseecom_handle;
|
||||
uint32_t session_id;
|
||||
bool legacy_app;
|
||||
uint32_t device_type;
|
||||
char *app_name;
|
||||
unsigned char *req_buf;
|
||||
unsigned char *res_buf;
|
||||
int (*app_init)(struct hdcp2_qsee_handle *handle);
|
||||
int (*tx_init)(struct hdcp2_qsee_handle *handle);
|
||||
};
|
||||
|
||||
struct hdcp1_key_set_req {
|
||||
uint32_t commandid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp1_key_set_rsp {
|
||||
uint32_t commandid;
|
||||
uint32_t ret;
|
||||
uint8_t ksv[HDCP1_AKSV_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct hdcp1_ops_notify_req {
|
||||
uint32_t commandid;
|
||||
uint32_t device_type;
|
||||
uint8_t recv_id_list[MAX_REC_ID_LIST_SIZE];
|
||||
int32_t recv_id_len;
|
||||
struct hdcp1_topology topology;
|
||||
bool is_authenticated;
|
||||
} __packed;
|
||||
|
||||
struct hdcp1_ops_notify_rsp {
|
||||
uint32_t commandid;
|
||||
uint32_t ret;
|
||||
} __packed;
|
||||
|
||||
struct hdcp1_set_enc_req {
|
||||
uint32_t commandid;
|
||||
uint32_t enable;
|
||||
} __packed;
|
||||
|
||||
struct hdcp1_set_enc_rsp {
|
||||
uint32_t commandid;
|
||||
uint32_t ret;
|
||||
} __packed;
|
||||
|
||||
struct hdcp1_key_verify_req {
|
||||
uint32_t commandid;
|
||||
uint32_t key_type;
|
||||
} __packed;
|
||||
|
||||
struct hdcp1_key_verify_rsp {
|
||||
uint32_t commandId;
|
||||
uint32_t ret;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_init_v1_req {
|
||||
uint32_t commandid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_init_v1_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
uint32_t ctxhandle;
|
||||
uint32_t timeout;
|
||||
uint32_t msglen;
|
||||
uint8_t message[MAX_TX_MESSAGE_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct hdcp_init_req {
|
||||
uint32_t commandid;
|
||||
uint32_t clientversion;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_init_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
uint32_t appversion;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_session_init_req {
|
||||
uint32_t commandid;
|
||||
uint32_t deviceid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_session_init_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
uint32_t sessionid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_tx_init_v1_req {
|
||||
uint32_t commandid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_tx_init_v1_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
uint32_t ctxhandle;
|
||||
uint32_t timeout;
|
||||
uint32_t msglen;
|
||||
uint8_t message[MAX_TX_MESSAGE_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct hdcp_tx_init_req {
|
||||
uint32_t commandid;
|
||||
uint32_t sessionid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_tx_init_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
uint32_t ctxhandle;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_version_req {
|
||||
uint32_t commandid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_version_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandId;
|
||||
uint32_t appversion;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_session_open_stream_req {
|
||||
uint32_t commandid;
|
||||
uint32_t sessionid;
|
||||
uint32_t vcpayloadid;
|
||||
uint32_t stream_number;
|
||||
uint32_t stream_media_type;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_session_open_stream_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
uint32_t streamid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_session_close_stream_req {
|
||||
uint32_t commandid;
|
||||
uint32_t sessionid;
|
||||
uint32_t streamid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_session_close_stream_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_force_encryption_req {
|
||||
uint32_t commandid;
|
||||
uint32_t ctxhandle;
|
||||
uint32_t enable;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_force_encryption_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_tx_deinit_req {
|
||||
uint32_t commandid;
|
||||
uint32_t ctxhandle;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_tx_deinit_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_session_deinit_req {
|
||||
uint32_t commandid;
|
||||
uint32_t sessionid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_session_deinit_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_deinit_req {
|
||||
uint32_t commandid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_deinit_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_query_stream_type_req {
|
||||
uint32_t commandid;
|
||||
uint32_t ctxhandle;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_query_stream_type_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
uint32_t timeout;
|
||||
uint32_t msglen;
|
||||
uint8_t msg[MAX_TX_MESSAGE_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct hdcp_set_hw_key_req {
|
||||
uint32_t commandid;
|
||||
uint32_t ctxhandle;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_set_hw_key_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_send_timeout_req {
|
||||
uint32_t commandid;
|
||||
uint32_t ctxhandle;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_send_timeout_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
uint32_t timeout;
|
||||
uint32_t msglen;
|
||||
uint8_t message[MAX_TX_MESSAGE_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct hdcp_start_auth_req {
|
||||
uint32_t commandid;
|
||||
uint32_t ctxHandle;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_start_auth_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
uint32_t ctxhandle;
|
||||
uint32_t timeout;
|
||||
uint32_t msglen;
|
||||
uint8_t message[MAX_TX_MESSAGE_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct hdcp_rcvd_msg_req {
|
||||
uint32_t commandid;
|
||||
uint32_t ctxhandle;
|
||||
uint32_t msglen;
|
||||
uint8_t msg[MAX_RX_MESSAGE_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct hdcp_rcvd_msg_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandid;
|
||||
uint32_t state;
|
||||
uint32_t timeout;
|
||||
uint32_t flag;
|
||||
uint32_t msglen;
|
||||
uint8_t msg[MAX_TX_MESSAGE_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct hdcp_verify_key_req {
|
||||
uint32_t commandid;
|
||||
} __packed;
|
||||
|
||||
struct hdcp_verify_key_rsp {
|
||||
uint32_t status;
|
||||
uint32_t commandId;
|
||||
} __packed;
|
||||
|
||||
#define HDCP1_SET_KEY 202
|
||||
#define HDCP1_KEY_VERIFY 204
|
||||
#define HDCP1_SET_ENC 205
|
||||
|
||||
/* DP device type */
|
||||
#define DEVICE_TYPE_DP 0x8002
|
||||
|
||||
void *hdcp1_init_qseecom(void);
|
||||
bool hdcp1_feature_supported_qseecom(void *data);
|
||||
int hdcp1_set_enc_qseecom(void *data, bool enable);
|
||||
int hdcp1_ops_notify_qseecom(void *data, void *topo, bool is_authenticated);
|
||||
int hdcp1_start_qseecom(void *data, u32 *aksv_msb, u32 *aksv_lsb);
|
||||
void hdcp1_stop_qseecom(void *data);
|
||||
|
||||
void *hdcp2_init_qseecom(u32 device_type);
|
||||
void hdcp2_deinit_qseecom(void *ctx);
|
||||
int hdcp2_app_start_qseecom(void *ctx, uint32_t req_len);
|
||||
int hdcp2_app_start_auth_qseecom(void *ctx, uint32_t req_len);
|
||||
int hdcp2_app_process_msg_qseecom(void *ctx, uint32_t req_len);
|
||||
int hdcp2_app_timeout_qseecom(void *ctx, uint32_t req_len);
|
||||
int hdcp2_app_enable_encryption_qseecom(void *ctx, uint32_t req_len);
|
||||
int hdcp2_app_query_stream_qseecom(void *ctx, uint32_t req_len);
|
||||
int hdcp2_app_stop_qseecom(void *ctx);
|
||||
bool hdcp2_feature_supported_qseecom(void *ctx);
|
||||
int hdcp2_force_encryption_qseecom(void *ctx, uint32_t enable);
|
||||
int hdcp2_open_stream_qseecom(void *ctx, uint8_t vc_payload_id,
|
||||
uint8_t stream_number, uint32_t *stream_id);
|
||||
int hdcp2_close_stream_qseecom(void *ctx, uint32_t stream_id);
|
||||
int hdcp2_update_app_data_qseecom(void *ctx, struct hdcp2_app_data *app_data);
|
||||
|
||||
#endif /* __HDCP_QSEECOM_H__ */
|
1088
drivers/misc/hdcp/hdcp_smcinvoke.c
Normal file
1088
drivers/misc/hdcp/hdcp_smcinvoke.c
Normal file
File diff suppressed because it is too large
Load Diff
62
drivers/misc/hdcp/hdcp_smcinvoke.h
Normal file
62
drivers/misc/hdcp/hdcp_smcinvoke.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HDCP_SMCINVOKE_H__
|
||||
#define __HDCP_SMCINVOKE_H__
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <soc/qcom/smci_object.h>
|
||||
|
||||
#include "hdcp_main.h"
|
||||
|
||||
struct hdcp1_smcinvoke_handle {
|
||||
struct smci_object hdcp1_app_obj;
|
||||
struct smci_object hdcp1_appcontroller_obj;
|
||||
struct smci_object hdcp1ops_app_obj;
|
||||
struct smci_object hdcp1ops_appcontroller_obj;
|
||||
bool feature_supported;
|
||||
uint32_t device_type;
|
||||
enum hdcp_state hdcp_state;
|
||||
};
|
||||
|
||||
struct hdcp2_smcinvoke_handle {
|
||||
struct hdcp2_app_data app_data;
|
||||
uint32_t tz_ctxhandle;
|
||||
bool feature_supported;
|
||||
enum hdcp_state hdcp_state;
|
||||
struct smci_object hdcp2_app_obj;
|
||||
struct smci_object hdcp2_appcontroller_obj;
|
||||
struct smci_object hdcpsrm_app_obj;
|
||||
struct smci_object hdcpsrm_appcontroller_obj;
|
||||
uint32_t session_id;
|
||||
uint32_t device_type;
|
||||
};
|
||||
|
||||
void *hdcp1_init_smcinvoke(void);
|
||||
bool hdcp1_feature_supported_smcinvoke(void *data);
|
||||
int hdcp1_set_enc_smcinvoke(void *data, bool enable);
|
||||
int hdcp1_ops_notify_smcinvoke(void *data, void *topo, bool is_authenticated);
|
||||
int hdcp1_start_smcinvoke(void *data, u32 *aksv_msb, u32 *aksv_lsb);
|
||||
void hdcp1_stop_smcinvoke(void *data);
|
||||
|
||||
void *hdcp2_init_smcinvoke(u32 device_type);
|
||||
void hdcp2_deinit_smcinvoke(void *ctx);
|
||||
int hdcp2_app_start_smcinvoke(void *ctx, uint32_t req_len);
|
||||
int hdcp2_app_start_auth_smcinvoke(void *ctx, uint32_t req_len);
|
||||
int hdcp2_app_process_msg_smcinvoke(void *ctx, uint32_t req_len);
|
||||
int hdcp2_app_timeout_smcinvoke(void *ctx, uint32_t req_len);
|
||||
int hdcp2_app_enable_encryption_smcinvoke(void *ctx, uint32_t req_len);
|
||||
int hdcp2_app_query_stream_smcinvoke(void *ctx, uint32_t req_len);
|
||||
int hdcp2_app_stop_smcinvoke(void *ctx);
|
||||
bool hdcp2_feature_supported_smcinvoke(void *ctx);
|
||||
int hdcp2_force_encryption_smcinvoke(void *ctx, uint32_t enable);
|
||||
int hdcp2_open_stream_smcinvoke(void *ctx, uint8_t vc_payload_id,
|
||||
uint8_t stream_number, uint32_t *stream_id);
|
||||
int hdcp2_close_stream_smcinvoke(void *ctx, uint32_t stream_id);
|
||||
int hdcp2_update_app_data_smcinvoke(void *ctx, struct hdcp2_app_data *app_data);
|
||||
|
||||
#endif /* __HDCP_SMCINVOKE_H__ */
|
Loading…
Reference in New Issue
Block a user