
Signed-off-by: Andrei-Liviu Simion <andrei.simion@xilinx.com> Acked by: Rohit Consul <rohitco@xilinx.com>
1252 lines
36 KiB
C
1252 lines
36 KiB
C
/******************************************************************************
|
|
*
|
|
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* Use of the Software is limited solely to applications:
|
|
* (a) running on a Xilinx device, or
|
|
* (b) that interact with a Xilinx device through a bus or interconnect.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
|
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
* Except as contained in this notice, the name of the Xilinx shall not be used
|
|
* in advertising or otherwise to promote the sale, use or other dealings in
|
|
* this Software without prior written authorization from Xilinx.
|
|
*
|
|
******************************************************************************/
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* @file xhdcp1x_cipher.c
|
|
* @addtogroup hdcp1x_v1_0
|
|
* @{
|
|
*
|
|
* This file contains the main implementation of the driver associated with
|
|
* the Xilinx HDCP Cipher core.
|
|
*
|
|
* <pre>
|
|
* MODIFICATION HISTORY:
|
|
*
|
|
* Ver Who Date Changes
|
|
* ----- ------ -------- --------------------------------------------------
|
|
* 1.00 fidus 07/16/15 Initial release.
|
|
* </pre>
|
|
*
|
|
******************************************************************************/
|
|
|
|
/***************************** Include Files *********************************/
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "xhdcp1x.h"
|
|
#include "xhdcp1x_cipher.h"
|
|
#include "xil_assert.h"
|
|
#include "xil_types.h"
|
|
|
|
/************************** Constant Definitions *****************************/
|
|
|
|
/**************************** Type Definitions *******************************/
|
|
|
|
/***************** Macros (Inline Functions) Definitions *********************/
|
|
|
|
/*************************** Function Prototypes *****************************/
|
|
|
|
/************************** Function Definitions *****************************/
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function initializes an HDCP cipher.
|
|
*
|
|
* @param InstancePtr is the device to initialize.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void XHdcp1x_CipherInit(XHdcp1x *InstancePtr)
|
|
{
|
|
u32 Value = 0;
|
|
|
|
/* Reset it */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value |= XHDCP1X_CIPHER_BITMASK_CONTROL_RESET;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_CONTROL_RESET;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
/* Ensure all interrupts are disabled and cleared */
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_INTERRUPT_MASK, (u32)(-1));
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_INTERRUPT_STATUS, (u32)(-1));
|
|
|
|
/* Check for DP */
|
|
if (XHdcp1x_IsDP(InstancePtr)) {
|
|
/* Configure for four lanes SST */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_CONTROL_NUM_LANES;
|
|
Value |= (4u << 4);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
}
|
|
|
|
/* Ensure that the register update bit is set */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value |= XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function queries the link state of a cipher device.
|
|
*
|
|
* @param InstancePtr is the device to query.
|
|
*
|
|
* @return Truth value.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int XHdcp1x_CipherIsLinkUp(const XHdcp1x *InstancePtr)
|
|
{
|
|
u32 Value;
|
|
int IsUp = FALSE;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check for currently enabled */
|
|
if (XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_STATUS);
|
|
if ((Value & XHDCP1X_CIPHER_BITMASK_INTERRUPT_LINK_FAIL) != 0) {
|
|
IsUp = TRUE;
|
|
}
|
|
}
|
|
|
|
return (IsUp);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function enables a HDCP cipher.
|
|
*
|
|
* @param InstancePtr is the device to enable.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful.
|
|
* - XST_FAILURE otherwise.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int XHdcp1x_CipherEnable(XHdcp1x *InstancePtr)
|
|
{
|
|
u32 Value = 0;
|
|
int Status = XST_SUCCESS;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check for currently disabled */
|
|
if (XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (XST_FAILURE);
|
|
}
|
|
|
|
/* Clear the register update bit */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
/* Ensure that all encryption is disabled for now */
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_ENCRYPT_ENABLE_H, 0x00ul);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_ENCRYPT_ENABLE_L, 0x00ul);
|
|
|
|
/* Ensure that XOR is disabled on tx and enabled for rx to start */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_CIPHER_CONTROL_XOR_ENABLE;
|
|
if (XHdcp1x_IsRX(InstancePtr)) {
|
|
Value |= XHDCP1X_CIPHER_BITMASK_CIPHER_CONTROL_XOR_ENABLE;
|
|
}
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_CONTROL, Value);
|
|
|
|
/* Enable it */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value |= XHDCP1X_CIPHER_BITMASK_CONTROL_ENABLE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
/* Ensure that the register update bit is set */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value |= XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function disables a HDCP cipher.
|
|
*
|
|
* @param InstancePtr is the device to disable.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int XHdcp1x_CipherDisable(XHdcp1x *InstancePtr)
|
|
{
|
|
u32 Value = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Ensure all interrupts are disabled */
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_INTERRUPT_MASK, 0xFFFFFFFFul);
|
|
|
|
/* Enable bypass operation */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_CONTROL_ENABLE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
/* Ensure that all encryption is disabled for now */
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_ENCRYPT_ENABLE_H, 0x00ul);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_ENCRYPT_ENABLE_L, 0x00ul);
|
|
|
|
/* Ensure that XOR is disabled */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_CIPHER_CONTROL_XOR_ENABLE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_CONTROL, Value);
|
|
|
|
/* Ensure that the register update bit is set */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value |= XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
/* Wait until the XOR has actually stopped */
|
|
while (XHdcp1x_CipherXorInProgress(InstancePtr));
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function configures the key selection value.
|
|
*
|
|
* @param InstancePtr is the device to configure.
|
|
* @param KeySelect is the desired key select value.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int XHdcp1x_CipherSetKeySelect(XHdcp1x *InstancePtr, u8 KeySelect)
|
|
{
|
|
int Status = XST_SUCCESS;
|
|
u32 Value = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(KeySelect < 8);
|
|
|
|
/* Update the device */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KEYMGMT_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_KEYMGMT_CONTROL_SET_SELECT;
|
|
Value |= (KeySelect << 16);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KEYMGMT_CONTROL, Value);
|
|
|
|
return (Status);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function initiates a request within the HDCP cipher.
|
|
*
|
|
* @param InstancePtr is the device to submit the request to.
|
|
* @param Request is the request to submit.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful.
|
|
* - XST_NOT_ENABLE if the core is disabled.
|
|
* - XST_DEVICE_BUSY if the core is busy.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int XHdcp1x_CipherDoRequest(XHdcp1x *InstancePtr,
|
|
XHdcp1x_CipherRequestType Request)
|
|
{
|
|
u32 Value = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(Request >= (XHDCP1X_CIPHER_REQUEST_BLOCK));
|
|
|
|
/* Check that it is not disabled */
|
|
if (!XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (XST_NOT_ENABLED);
|
|
}
|
|
|
|
/* Determine if there is a request in progress */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_STATUS);
|
|
Value &= XHDCP1X_CIPHER_BITMASK_CIPHER_STATUS_REQUEST_IN_PROG;
|
|
|
|
/* Check that it is not busy */
|
|
if (Value != 0) {
|
|
return (XST_DEVICE_BUSY);
|
|
}
|
|
|
|
/* Ensure that the register update bit is set */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value |= XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
/* Set the appropriate request bit and ensure that Km is always used */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_CIPHER_CONTROL_REQUEST;
|
|
Value |= (XHDCP1X_CIPHER_VALUE_CIPHER_CONTROL_REQUEST_BLOCK << Request);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_CONTROL, Value);
|
|
|
|
/* Ensure that the request bit(s) get cleared for next time */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_CIPHER_CONTROL_REQUEST;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_CONTROL, Value);
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function queries the progress of the current request.
|
|
*
|
|
* @param InstancePtr is the device to query.
|
|
*
|
|
* @return Truth value.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int XHdcp1x_CipherIsRequestComplete(const XHdcp1x *InstancePtr)
|
|
{
|
|
u32 Value = 0;
|
|
int IsComplete = TRUE;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Determine Value */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_STATUS);
|
|
Value &= XHDCP1X_CIPHER_BITMASK_CIPHER_STATUS_REQUEST_IN_PROG;
|
|
|
|
/* Update IsComplete */
|
|
if (Value != 0) {
|
|
IsComplete = FALSE;
|
|
}
|
|
|
|
return (IsComplete);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function retrieves the current number of lanes of the HDCP cipher.
|
|
*
|
|
* @param InstancePtr is the device to query.
|
|
*
|
|
* @return The current number of lanes.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
u32 XHdcp1x_CipherGetNumLanes(const XHdcp1x *InstancePtr)
|
|
{
|
|
u32 NumLanes = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check for currently enabled */
|
|
if (XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
/* Determine NumLanes */
|
|
NumLanes = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
NumLanes &= XHDCP1X_CIPHER_BITMASK_CONTROL_NUM_LANES;
|
|
NumLanes >>= 4;
|
|
}
|
|
|
|
return (NumLanes);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function configures the number of lanes of the HDCP cipher.
|
|
*
|
|
* @param InstancePtr is the device to configure.
|
|
* @param NumLanes is the number of lanes to configure.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int XHdcp1x_CipherSetNumLanes(XHdcp1x *InstancePtr, u32 NumLanes)
|
|
{
|
|
int Status = XST_SUCCESS;
|
|
u32 Value = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(NumLanes > 0);
|
|
Xil_AssertNonvoid(NumLanes <= 4);
|
|
|
|
/* Check for HDMI */
|
|
if (XHdcp1x_IsHDMI(InstancePtr)) {
|
|
/* Verify NumLanes (again) */
|
|
Xil_AssertNonvoid(NumLanes == 1);
|
|
|
|
/* Update the control register */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_CONTROL_NUM_LANES;
|
|
Value |= (NumLanes << 4);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
}
|
|
/* Otherwise - must be DP */
|
|
else {
|
|
/* Verify NumLanes (again) */
|
|
Xil_AssertNonvoid(NumLanes != 3);
|
|
|
|
/* Update the control register */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_CONTROL_NUM_LANES;
|
|
Value |= (NumLanes << 4);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
}
|
|
|
|
return (Status);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function retrieves the current encryption stream map.
|
|
*
|
|
* @param InstancePtr is the device to query.
|
|
*
|
|
* @return The current encryption stream map.
|
|
*
|
|
* @note In the case of the receiver version of this core, the XOR in
|
|
* progress bit needs to be checked as well as the encryption map
|
|
* to fully determine if encryption is enabled for the SST case.
|
|
* This is the reason for the additional check in this code.
|
|
*
|
|
******************************************************************************/
|
|
u64 XHdcp1x_CipherGetEncryption(const XHdcp1x *InstancePtr)
|
|
{
|
|
u64 StreamMap = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check that it is not disabled */
|
|
if (!XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (StreamMap);
|
|
}
|
|
|
|
/* Determine StreamMap */
|
|
StreamMap = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_ENCRYPT_ENABLE_H);
|
|
StreamMap <<= 32;
|
|
StreamMap |= XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_ENCRYPT_ENABLE_L);
|
|
|
|
/* Check for special case of just XOR in progress */
|
|
if ((StreamMap == 0) && (XHdcp1x_CipherXorInProgress(InstancePtr))) {
|
|
StreamMap = 0x01ul;
|
|
}
|
|
|
|
return (StreamMap);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function enables encryption on a set of streams.
|
|
*
|
|
* @param InstancePtr is the device to configure.
|
|
* @param StreamMap is the bit map of streams to enable encryption on.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful.
|
|
* - XST_NOT_ENABLE if the core is not enabled.
|
|
* - XST_FAILURE otherwise.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int XHdcp1x_CipherEnableEncryption(XHdcp1x *InstancePtr, u64 StreamMap)
|
|
{
|
|
u32 Value = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check that it is not disabled */
|
|
if (!XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (XST_NOT_ENABLED);
|
|
}
|
|
|
|
/* Check that it is not a receiver */
|
|
if (XHdcp1x_IsRX(InstancePtr)) {
|
|
return (XST_FAILURE);
|
|
}
|
|
|
|
/* Check for nothing to do */
|
|
if (StreamMap == 0) {
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/* Clear the register update bit */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
/* Update the LS 32-bits */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_ENCRYPT_ENABLE_L);
|
|
Value |= ((u32) (StreamMap & 0xFFFFFFFFul));
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_ENCRYPT_ENABLE_L, Value);
|
|
|
|
/* Write the MS 32-bits */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_ENCRYPT_ENABLE_H);
|
|
Value |= ((u32) ((StreamMap >> 32) & 0xFFFFFFFFul));
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_ENCRYPT_ENABLE_H, Value);
|
|
|
|
/* Ensure that the XOR is enabled */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_CONTROL);
|
|
Value |= XHDCP1X_CIPHER_BITMASK_CIPHER_CONTROL_XOR_ENABLE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_CONTROL, Value);
|
|
|
|
/* Set the register update bit */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value |= XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
/* Wait until the XOR has actually started */
|
|
while (!XHdcp1x_CipherXorInProgress(InstancePtr));
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function disables encryption on a set of streams.
|
|
*
|
|
* @param InstancePtr is the device to configure.
|
|
* @param StreamMap is the bit map of streams to disable encryption on.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful.
|
|
* - XST_NOT_ENABLE if the core is not enabled.
|
|
* - XST_FAILURE otherwise.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int XHdcp1x_CipherDisableEncryption(XHdcp1x *InstancePtr, u64 StreamMap)
|
|
{
|
|
u32 Val = 0;
|
|
int DisableXor = TRUE;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check that it is not disabled */
|
|
if (!XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (XST_NOT_ENABLED);
|
|
}
|
|
|
|
/* Check that it is not a receiver */
|
|
if (XHdcp1x_IsRX(InstancePtr)) {
|
|
return (XST_FAILURE);
|
|
}
|
|
|
|
/* Check for nothing to do */
|
|
if (StreamMap == 0) {
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/* Clear the register update bit */
|
|
Val = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Val &= ~XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Val);
|
|
|
|
/* Update the LS 32-bits */
|
|
Val = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_ENCRYPT_ENABLE_L);
|
|
Val &= ~((u32) (StreamMap & 0xFFFFFFFFul));
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_ENCRYPT_ENABLE_L, Val);
|
|
if (Val != 0) {
|
|
DisableXor = FALSE;
|
|
}
|
|
|
|
/* Write the MS 32-bits */
|
|
Val = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_ENCRYPT_ENABLE_H);
|
|
Val &= ~((u32) ((StreamMap >> 32) & 0xFFFFFFFFul));
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_ENCRYPT_ENABLE_H, Val);
|
|
if (Val != 0) {
|
|
DisableXor = FALSE;
|
|
}
|
|
|
|
/* Check HDMI special case */
|
|
if (XHdcp1x_IsHDMI(InstancePtr)) {
|
|
DisableXor = TRUE;
|
|
}
|
|
|
|
/* Check for XOR disable */
|
|
if (DisableXor) {
|
|
Val = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_CONTROL);
|
|
Val &= ~XHDCP1X_CIPHER_BITMASK_CIPHER_CONTROL_XOR_ENABLE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_CONTROL, Val);
|
|
}
|
|
|
|
/* Set the register update bit */
|
|
Val = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Val |= XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Val);
|
|
|
|
/* If disabling the XOR, wait until no longer in progress */
|
|
if (DisableXor) {
|
|
while (XHdcp1x_CipherXorInProgress(InstancePtr));
|
|
}
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function reads the local KSV value from the cipher.
|
|
*
|
|
* @param InstancePtr is the device to query.
|
|
*
|
|
* @return The local KSV value.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
u64 XHdcp1x_CipherGetLocalKsv(const XHdcp1x *InstancePtr)
|
|
{
|
|
u32 Val = 0;
|
|
u32 Guard = 0x400ul;
|
|
u64 Ksv = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check that it is not disabled */
|
|
if (!XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (Ksv);
|
|
}
|
|
|
|
/* Check if the local ksv is not available */
|
|
Val = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KEYMGMT_STATUS);
|
|
Val &= XHDCP1X_CIPHER_BITMASK_KEYMGMT_STATUS_KSV_READY;
|
|
if (Val == 0) {
|
|
/* Abort any running Km calculation just in case */
|
|
Val = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KEYMGMT_CONTROL);
|
|
Val |= XHDCP1X_CIPHER_BITMASK_KEYMGMT_CONTROL_ABORT_Km;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KEYMGMT_CONTROL, Val);
|
|
Val &= ~XHDCP1X_CIPHER_BITMASK_KEYMGMT_CONTROL_ABORT_Km;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KEYMGMT_CONTROL, Val);
|
|
|
|
/* Load the local ksv */
|
|
Val = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KEYMGMT_CONTROL);
|
|
Val |= XHDCP1X_CIPHER_BITMASK_KEYMGMT_CONTROL_LOCAL_KSV;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KEYMGMT_CONTROL, Val);
|
|
Val &= ~XHDCP1X_CIPHER_BITMASK_KEYMGMT_CONTROL_LOCAL_KSV;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KEYMGMT_CONTROL, Val);
|
|
|
|
/* Wait until local KSV available */
|
|
while ((!XHdcp1x_CipherLocalKsvReady(InstancePtr)) &&
|
|
(--Guard > 0));
|
|
}
|
|
|
|
/* Confirm no timeout */
|
|
if (Guard != 0) {
|
|
/* Update Ksv */
|
|
Ksv = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KSV_LOCAL_H);
|
|
Ksv &= 0xFFul;
|
|
Ksv <<= 32;
|
|
Ksv |= XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KSV_LOCAL_L);
|
|
}
|
|
|
|
return (Ksv);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function reads the remote KSV value from the cipher.
|
|
*
|
|
* @param InstancePtr is the device to query.
|
|
*
|
|
* @return The remote KSV value.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
u64 XHdcp1x_CipherGetRemoteKsv(const XHdcp1x *InstancePtr)
|
|
{
|
|
u64 Ksv = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Determine Ksv */
|
|
Ksv = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KSV_REMOTE_H);
|
|
Ksv <<= 32;
|
|
Ksv |= XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KSV_REMOTE_L);
|
|
|
|
return (Ksv);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function writes the remote KSV value to the cipher.
|
|
*
|
|
* @param InstancePtr is the device to write to.
|
|
* @param Ksv is the remote KSV value to write.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful.
|
|
* - XST_NOT_ENABLED otherwise.
|
|
*
|
|
* @note Whenever this function is called, the underlying driver will
|
|
* initiate the calculation of the Km value and wait for it to
|
|
* complete.
|
|
*
|
|
******************************************************************************/
|
|
int XHdcp1x_CipherSetRemoteKsv(XHdcp1x *InstancePtr, u64 Ksv)
|
|
{
|
|
u32 Value = 0;
|
|
u32 Guard = 0x400ul;
|
|
int Status = XST_SUCCESS;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check that it is not disabled */
|
|
if (!XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (XST_NOT_ENABLED);
|
|
}
|
|
|
|
/* Read local ksv to put things into a known state */
|
|
XHdcp1x_CipherGetLocalKsv(InstancePtr);
|
|
|
|
/* Clear the register update bit */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
/* Write the LS 32-bits */
|
|
Value = (u32)(Ksv & 0xFFFFFFFFul);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KSV_REMOTE_L, Value);
|
|
|
|
/* Write the MS 8-bits */
|
|
Value = (u32)((Ksv >> 32) & 0xFFul);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KSV_REMOTE_H, Value);
|
|
|
|
/* Set the register update bit */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value |= XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
/* Trigger the calculation of theKm */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KEYMGMT_CONTROL);
|
|
Value &= 0xFFFFFFF0ul;
|
|
Value |= XHDCP1X_CIPHER_BITMASK_KEYMGMT_CONTROL_BEGIN_Km;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KEYMGMT_CONTROL, Value);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_KEYMGMT_CONTROL_BEGIN_Km;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_KEYMGMT_CONTROL, Value);
|
|
|
|
/* Wait until Km is available */
|
|
while ((!XHdcp1x_CipherKmReady(InstancePtr)) && (--Guard > 0));
|
|
|
|
/* Check for timeout */
|
|
if (Guard == 0) {
|
|
Status = XST_FAILURE;
|
|
}
|
|
|
|
return (Status);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function reads the contents of the B register in BM0.
|
|
*
|
|
* @param InstancePtr is the device to query.
|
|
* @param X is to be loaded with the contents of Bx.
|
|
* @param Y is to be loaded with the contents of By.
|
|
* @param Z is to be loaded with the contents of Bz.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful.
|
|
* - XST_NOT_ENABLED otherwise.
|
|
*
|
|
* @note A NULL pointer can be passed in any of X, Y and Z. If so, then
|
|
* this portion of the B register is not returned to the caller.
|
|
*
|
|
******************************************************************************/
|
|
int XHdcp1x_CipherGetB(const XHdcp1x *InstancePtr, u32 *X, u32 *Y, u32 *Z)
|
|
{
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check that it is not disabled */
|
|
if (!XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (XST_NOT_ENABLED);
|
|
}
|
|
|
|
/* Get X if requested */
|
|
if (X != NULL) {
|
|
*X = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Bx);
|
|
*X &= 0x0FFFFFFFul;
|
|
}
|
|
|
|
/* Get Y if requested */
|
|
if (Y != NULL) {
|
|
*Y = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_By);
|
|
*Y &= 0x0FFFFFFFul;
|
|
}
|
|
|
|
/* Get Z if requested */
|
|
if (Z != NULL) {
|
|
*Z = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Bz);
|
|
*Z &= 0x0FFFFFFFul;
|
|
}
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function writes the contents of the B register in BM0.
|
|
*
|
|
* @param InstancePtr is the device to write to.
|
|
* @param X is the value to be written to Bx.
|
|
* @param Y is the value to be written to By.
|
|
* @param Z is the value to be written to Bz.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful.
|
|
* - XST_NOT_ENABLED otherwise.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int XHdcp1x_CipherSetB(XHdcp1x *InstancePtr, u32 X, u32 Y, u32 Z)
|
|
{
|
|
u32 Value = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check that it is not disabled */
|
|
if (!XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (XST_NOT_ENABLED);
|
|
}
|
|
|
|
/* Clear the register update bit */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
/* Update the Bx */
|
|
Value = (X & 0x0FFFFFFFul);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Bx, Value);
|
|
|
|
/* Update the By */
|
|
Value = (Y & 0x0FFFFFFFul);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_By, Value);
|
|
|
|
/* Update the Bz */
|
|
Value = (Z & 0x0FFFFFFFul);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Bz, Value);
|
|
|
|
/* Set the register update bit */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value |= XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function reads the contents of the K register in BM0.
|
|
*
|
|
* @param InstancePtr is the device to query.
|
|
* @param X is to be loaded with the contents of Kx.
|
|
* @param Y is to be loaded with the contents of Ky.
|
|
* @param Z is to be loaded with the contents of Kz.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful.
|
|
* - XST_NOT_ENABLED otherwise.
|
|
*
|
|
* @note A NULL pointer can be passed in any of X, Y and Z. If so, then
|
|
* this portion of the K register is not returned to the caller.
|
|
*
|
|
******************************************************************************/
|
|
int XHdcp1x_CipherGetK(const XHdcp1x *InstancePtr, u32 *X, u32 *Y, u32 *Z)
|
|
{
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check that it is not disabled */
|
|
if (!XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (XST_NOT_ENABLED);
|
|
}
|
|
|
|
/* Get X if requested */
|
|
if (X != NULL) {
|
|
*X = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Kx);
|
|
*X &= 0x0FFFFFFFul;
|
|
}
|
|
|
|
/* Get Y if requested */
|
|
if (Y != NULL) {
|
|
*Y = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Ky);
|
|
*Y &= 0x0FFFFFFFul;
|
|
}
|
|
|
|
/* Get Z if requested */
|
|
if (Z != NULL) {
|
|
*Z = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Kz);
|
|
*Z &= 0x0FFFFFFFul;
|
|
}
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function writes the contents of the K register in BM0.
|
|
*
|
|
* @param InstancePtr is the device to write to.
|
|
* @param X is the value to be written to Kx.
|
|
* @param Y is the value to be written to Ky.
|
|
* @param Z is the value to be written to Kz.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful.
|
|
* - XST_NOT_ENABLED otherwise.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int XHdcp1x_CipherSetK(XHdcp1x *InstancePtr, u32 X, u32 Y, u32 Z)
|
|
{
|
|
u32 Value = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check that it is not disabled */
|
|
if (!XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (XST_NOT_ENABLED);
|
|
}
|
|
|
|
/* Clear the register update bit */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value &= ~XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
/* Update the Kx */
|
|
Value = (X & 0x0FFFFFFFul);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Kx, Value);
|
|
|
|
/* Update the Ky */
|
|
Value = (Y & 0x0FFFFFFFul);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Ky, Value);
|
|
|
|
/* Update the Kz */
|
|
Value = (Z & 0x0FFFFFFFul);
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Kz, Value);
|
|
|
|
/* Set the register update bit */
|
|
Value = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL);
|
|
Value |= XHDCP1X_CIPHER_BITMASK_CONTROL_UPDATE;
|
|
XHdcp1x_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CONTROL, Value);
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function reads the contents of the Mi/An register of BM0.
|
|
*
|
|
* @param InstancePtr is the device to query.
|
|
*
|
|
* @return The contents of the register.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
u64 XHdcp1x_CipherGetMi(const XHdcp1x *InstancePtr)
|
|
{
|
|
u64 Mi = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check that it is not disabled */
|
|
if (!XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (XST_NOT_ENABLED);
|
|
}
|
|
|
|
/* Update Mi */
|
|
Mi = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Mi_H);
|
|
Mi <<= 32;
|
|
Mi |= XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Mi_L);
|
|
|
|
return (Mi);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function reads the contents of the Ri register of BM0.
|
|
*
|
|
* @param InstancePtr is the device to query.
|
|
*
|
|
* @return The contents of the register.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
u16 XHdcp1x_CipherGetRi(const XHdcp1x *InstancePtr)
|
|
{
|
|
u16 Ri = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check that it is not disabled */
|
|
if (!XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (XST_NOT_ENABLED);
|
|
}
|
|
|
|
/* Determine Ri */
|
|
Ri = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Ri);
|
|
|
|
return (Ri);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function reads the contents of the Mo register of the device.
|
|
*
|
|
* @param InstancePtr is the device to query.
|
|
*
|
|
* @return The contents of the Mo register.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
u64 XHdcp1x_CipherGetMo(const XHdcp1x *InstancePtr)
|
|
{
|
|
u64 Mo = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check that it is not disabled */
|
|
if (!XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (XST_NOT_ENABLED);
|
|
}
|
|
|
|
/* Determine Mo */
|
|
Mo = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Mo_H);
|
|
Mo <<= 32;
|
|
Mo |= XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Mo_L);
|
|
|
|
return (Mo);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function reads the contents of the Ro register of the device.
|
|
*
|
|
* @param InstancePtr is the device to query.
|
|
*
|
|
* @return The contents of the Ro register.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
u16 XHdcp1x_CipherGetRo(const XHdcp1x *InstancePtr)
|
|
{
|
|
u16 Ro = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Check that it is not disabled */
|
|
if (!XHdcp1x_CipherIsEnabled(InstancePtr)) {
|
|
return (XST_NOT_ENABLED);
|
|
}
|
|
|
|
/* Determine Ro */
|
|
Ro = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_CIPHER_Ro);
|
|
|
|
return (Ro);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function reads the version of the HDCP cipher core.
|
|
*
|
|
* @param InstancePtr is the device to query.
|
|
*
|
|
* @return The version of the HDCP cipher device.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
u32 XHdcp1x_CipherGetVersion(const XHdcp1x *InstancePtr)
|
|
{
|
|
u32 Version = 0;
|
|
|
|
/* Verify arguments. */
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
|
|
/* Determine Version */
|
|
Version = XHdcp1x_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XHDCP1X_CIPHER_REG_VERSION);
|
|
|
|
return (Version);
|
|
}
|