前言
按照HDCP规范的要求,不能将带HDCP的数字内容私自解key,变为不受HDCP保护的内容,在调试sii9136时遇到这问题,记下添加HDCP的步骤。
添加HDCP步骤
①判断HDCP是否可用,芯片端可用0X30,sink可用0X29[1]
②读Aksv(0X36)、Bksv(0X2B)验证20个1和20个0,aoc品牌电视无法单独读取Aksv和Bksv的值
③请求链路安全(0X2A)
④验证本地链路、中继链路、启用完整性检测
⑤等待link secure(链路安全)状态0X29
⑥发送安全的内容
⑦定期验证link secure状态0X29
细节
A.轮询0X29[1]直到指示HDCP可用,Bksv值仅在0X29[1]=1有效
B.使用所需设置写入0X2A[0]
C.轮询0X2A[0]直到它与刚刚设置的匹配
D.轮询0X29[7:6]直到指示所需的安全级别,由于去抖,0X29补一定及时刷新可读中断0X30 bit2 bit0
//--------------------------------------------------------------
// add hdcp funtion
//
//
//
//
//
// @make: faceyang 20190902
//--------------------------------------------------------------
#ifdef DEV_SUPPORT_HDCP
///
///
///*************************///
/// HDCP ///
///*************************///
///
///
//------------------------------------------------------------------------------
// Function Name: IsHDCP_Supported()
// Function Description: Check Tx revision number to find if this Tx supports HDCP
// by reading the HDCP revision number from TPI register 0x30.
//
// Accepts: none
// Returns: TRUE if Tx supports HDCP. FALSE if not.
// Globals: none
//------------------------------------------------------------------------------
BYTE IsHDCP_Supported (void)
{
BYTE HDCP_Rev;
BYTE HDCP_Supported;
TPI_TRACE_PRINT((">>IsHDCP_Supported()\n"));
HDCP_Supported = TRUE;
// Check Device ID
HDCP_Rev = ReadByteTPI(TPI_HDCP_REVISION_DATA_REG);
if (HDCP_Rev != (HDCP_MAJOR_REVISION_VALUE | HDCP_MINOR_REVISION_VALUE))
{
HDCP_Supported = FALSE;
}
// Even if HDCP is supported check for incorrect Device ID // for SiI_9136AYBT_DEVICEID_CHECK
HDCP_Rev = ReadByteTPI(TPI_AKSV_1_REG);
if (HDCP_Rev == 0x09)
{
HDCP_Rev = ReadByteTPI(TPI_AKSV_2_REG);
if (HDCP_Rev == 0x00)
{
HDCP_Rev = ReadByteTPI(TPI_AKSV_3_REG);
if (HDCP_Rev == 0x02)
{
HDCP_Rev = ReadByteTPI(TPI_AKSV_4_REG);
if (HDCP_Rev == 0x02)
{
HDCP_Rev = ReadByteTPI(TPI_AKSV_5_REG);
if (HDCP_Rev == 0x0a)
{
HDCP_Supported = FALSE;
TPI_TRACE_PRINT((">>SiI9136A found, NO HDCP supported\n"));
}
}
}
}
}
return HDCP_Supported;
}
//------------------------------------------------------------------------------
// Function Name: AreAKSV_OK()
// Function Description: Check if AKSVs contain 20 '0' and 20 '1'
//
// Accepts: none
// Returns: TRUE if 20 zeros and 20 ones found in AKSV. FALSE OTHERWISE
// Globals: none
//------------------------------------------------------------------------------
BYTE AreAKSV_OK (void)
{
BYTE B_Data[AKSV_SIZE];
BYTE NumOfOnes = 0;
BYTE i, j;
TPI_TRACE_PRINT((">>AreAKSV_OK()\n"));
ReadBlockTPI(TPI_AKSV_1_REG, AKSV_SIZE, B_Data);
for (i=0; i<AKSV_SIZE; i++)
{
for (j=0; j<BYTE_SIZE; j++)
{
if (B_Data[i] & 0x01)
{
NumOfOnes++;
}
B_Data[i] >>= 1;
}
}
if (NumOfOnes != NUM_OF_ONES_IN_KSV)
return FALSE;
return TRUE;
}
//------------------------------------------------------------------------------
// Function Name: HDCP_Off()
// Function Description: Switch hdcp off.
//------------------------------------------------------------------------------
void HDCP_Off (void)
{
TPI_TRACE_PRINT((">>HDCP_Off()\n"));
// AV MUTE
ReadModifyWriteTPI(TPI_SYSTEM_CONTROL_DATA_REG, AV_MUTE_MASK, AV_MUTE_MUTED);
WriteByteTPI(TPI_HDCP_CONTROL_DATA_REG, PROTECTION_LEVEL_MIN);
g_hdcp.HDCP_Started = FALSE;
g_hdcp.HDCP_LinkProtectionLevel = EXTENDED_LINK_PROTECTION_NONE | LOCAL_LINK_PROTECTION_NONE;
}
//------------------------------------------------------------------------------
// Function Name: HDCP_On()
// Function Description: Switch hdcp on.
//------------------------------------------------------------------------------
void HDCP_On (void)
{
if (g_hdcp.HDCP_Override == FALSE)
{
TPI_DEBUG_PRINT(("HDCP Started\n"));
WriteByteTPI(TPI_HDCP_CONTROL_DATA_REG, PROTECTION_LEVEL_MAX);
g_hdcp.HDCP_Started = TRUE;
}
else
{
g_hdcp.HDCP_Started = FALSE;
}
}
//------------------------------------------------------------------------------
// Function Name: RestartHDCP()
// Function Description: Restart HDCP.
//------------------------------------------------------------------------------
void RestartHDCP (void)
{
TPI_DEBUG_PRINT (("HDCP -> Restart\n"));
DisableTMDS();
HDCP_Off();
EnableTMDS();
}
//------------------------------------------------------------------------------
// Function Name: HDCP_Init()
// Function Description: Tests Tx and Rx support of HDCP. If found, checks if
// and attempts to set the security level accordingly.
//
// Accepts: none
// Returns: TRUE if HW TPI started successfully. FALSE if failed to.
// Globals: HDCP_TxSupports - initialized to FALSE, set to TRUE if supported by this device
// HDCP_AksvValid - initialized to FALSE, set to TRUE if valid AKSVs are read from this device
// HDCP_Started - initialized to FALSE
// HDCP_LinkProtectionLevel - initialized to (EXTENDED_LINK_PROTECTION_NONE | LOCAL_LINK_PROTECTION_NONE)
//------------------------------------------------------------------------------
void HDCP_Init (void)
{
TPI_TRACE_PRINT((">>HDCP_Init()\n"));
g_hdcp.HDCP_TxSupports = FALSE;
g_hdcp.HDCP_AksvValid = FALSE;
g_hdcp.HDCP_Started = FALSE;
g_hdcp.HDCP_LinkProtectionLevel = EXTENDED_LINK_PROTECTION_NONE | LOCAL_LINK_PROTECTION_NONE;
// This is TX-related... need only be done once.
if (!IsHDCP_Supported())
{
// The TX does not support HDCP, so authentication will never be attempted.
// Video will be shown as soon as TMDS is enabled.
TPI_DEBUG_PRINT(("HDCP -> TX does not support HDCP\n"));
return;
}
g_hdcp.HDCP_TxSupports = TRUE;
// This is TX-related... need only be done once.
if (!AreAKSV_OK())
{
// The TX supports HDCP, but does not have valid AKSVs.
// Video will not be shown.
TPI_DEBUG_PRINT(("HDCP -> Illegal AKSV\n"));
return;
}
g_hdcp.HDCP_AksvValid = TRUE;
TPI_DEBUG_PRINT(("HDCP -> Supported by TX, AKSVs valid\n"));
}
//------------------------------------------------------------------------------
// Function Name: HDCP_CheckStatus()
// Function Description: Check HDCP status.
//
// Accepts: InterruptStatus
// Returns: none
// Globals: none
//------------------------------------------------------------------------------
void HDCP_CheckStatus (BYTE InterruptStatusImage)
{
BYTE QueryData;
BYTE LinkStatus;
BYTE RegImage;
BYTE NewLinkProtectionLevel;
// static BYTE AvmuteFlag=1;
// QueryData = ReadByteTPI(TPI_HDCP_QUERY_DATA_REG);
// LinkStatus = ReadByteTPI(TPI_HDCP_CONTROL_DATA_REG);
// printf("********* 0X29 = %02x 0X2A = %02x\n",QueryData,LinkStatus);
if ((g_hdcp.HDCP_TxSupports == TRUE) && (g_hdcp.HDCP_AksvValid == TRUE))
{
if ((g_hdcp.HDCP_LinkProtectionLevel == (EXTENDED_LINK_PROTECTION_NONE | LOCAL_LINK_PROTECTION_NONE)) && (g_hdcp.HDCP_Started == FALSE))
{
QueryData = ReadByteTPI(TPI_HDCP_QUERY_DATA_REG);
if (QueryData & PROTECTION_TYPE_MASK) // Is HDCP avaialable
{
// AvmuteFlag=1;
HDCP_On();
}
// else
// {
// if(AvmuteFlag==1)
// {
// AvmuteFlag=0;
// ReadModifyWriteTPI(TPI_SYSTEM_CONTROL_DATA_REG, TMDS_OUTPUT_CONTROL_MASK |
// AV_MUTE_MASK, TMDS_OUTPUT_CONTROL_POWER_DOWN | AV_MUTE_MUTED);
// }
// }
}
// Check if Link Status has changed:
if (InterruptStatusImage & SECURITY_CHANGE_EVENT)
{
TPI_DEBUG_PRINT (("HDCP -> "));
LinkStatus = ReadByteTPI(TPI_HDCP_QUERY_DATA_REG);
LinkStatus &= LINK_STATUS_MASK;
ClearInterrupt(SECURITY_CHANGE_EVENT);
switch (LinkStatus)
{
case LINK_STATUS_NORMAL:
TPI_DEBUG_PRINT (("Link = Normal\n"));
break;
case LINK_STATUS_LINK_LOST:
TPI_DEBUG_PRINT (("Link = Lost\n"));
RestartHDCP();
break;
case LINK_STATUS_RENEGOTIATION_REQ:
TPI_DEBUG_PRINT (("Link = Renegotiation Required\n"));
HDCP_Off();
HDCP_On();
break;
case LINK_STATUS_LINK_SUSPENDED:
TPI_DEBUG_PRINT (("Link = Suspended\n"));
HDCP_On();
break;
}
}
// Check if HDCP state has changed:
if (InterruptStatusImage & HDCP_CHANGE_EVENT)
{
RegImage = ReadByteTPI(TPI_HDCP_QUERY_DATA_REG);
NewLinkProtectionLevel = RegImage & (EXTENDED_LINK_PROTECTION_MASK | LOCAL_LINK_PROTECTION_MASK);
if (NewLinkProtectionLevel != g_hdcp.HDCP_LinkProtectionLevel)
{
TPI_DEBUG_PRINT (("HDCP -> "));
g_hdcp.HDCP_LinkProtectionLevel = NewLinkProtectionLevel;
switch (g_hdcp.HDCP_LinkProtectionLevel)
{
case (EXTENDED_LINK_PROTECTION_NONE | LOCAL_LINK_PROTECTION_NONE):
TPI_DEBUG_PRINT (("Protection = None\n"));
RestartHDCP();
break;
case LOCAL_LINK_PROTECTION_SECURE:
if (IsHDMI_Sink())
{
ReadModifyWriteTPI(TPI_AUDIO_INTERFACE_REG, AUDIO_MUTE_MASK, AUDIO_MUTE_NORMAL);
}
ReadModifyWriteTPI(TPI_SYSTEM_CONTROL_DATA_REG, AV_MUTE_MASK, AV_MUTE_NORMAL);
TPI_DEBUG_PRINT (("Protection = Local, Video Unmuted\n"));
break;
case (EXTENDED_LINK_PROTECTION_SECURE | LOCAL_LINK_PROTECTION_SECURE):
TPI_DEBUG_PRINT (("Protection = Extended\n"));
break;
default:
TPI_DEBUG_PRINT (("Protection = Extended but not Local?\n"));
RestartHDCP();
break;
}
}
ClearInterrupt(HDCP_CHANGE_EVENT);
}
}
}
#endif
版权声明:本文为qq_42677883原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。