From 0ebb5dbdfe95743b2b13ae74f6f2f38b13be9026 Mon Sep 17 00:00:00 2001 From: Andrei-Liviu Simion Date: Tue, 4 Aug 2015 01:38:17 -0700 Subject: [PATCH] dp: HDCP additions and unplug interrupt. Added new interrupts, callbacks, and macros related to HDCP (High-bandwidth Digital Content Protection). Added new interrupts, callbacks, and macros for an unplug event. Signed-off-by: Andrei-Liviu Simion Reviewed-by: Hyun Kwon --- XilinxProcessorIPLib/drivers/dp/src/xdp.h | 65 ++++- XilinxProcessorIPLib/drivers/dp/src/xdp_hw.h | 54 +++- .../drivers/dp/src/xdp_intr.c | 236 ++++++++++++++++++ 3 files changed, 352 insertions(+), 3 deletions(-) diff --git a/XilinxProcessorIPLib/drivers/dp/src/xdp.h b/XilinxProcessorIPLib/drivers/dp/src/xdp.h index 64bb64c6..1733cc38 100644 --- a/XilinxProcessorIPLib/drivers/dp/src/xdp.h +++ b/XilinxProcessorIPLib/drivers/dp/src/xdp.h @@ -343,6 +343,8 @@ * XDp_TxSbMsgLinkAddressReplyDeviceInfo * GUID type change for ease of use: * 'u32 Guid[4]' changed to 'u8 Guid[16]' + * Added handlers and setter functions for HDCP and unplug + * events. * * *******************************************************************************/ @@ -809,7 +811,7 @@ typedef struct { } XDp_Tx; /** - * The XDp driver instance data representing the TX mode of operation. + * The XDp driver instance data representing the RX mode of operation. */ typedef struct { XDp_RxTopology Topology; /**< Topology of connected sinks @@ -944,6 +946,53 @@ typedef struct { passed to the CRC test start callback function. */ + XDp_IntrHandler IntrHdcpDbgWrHandler; /**< Callback function for + HDCP debug register + write interrupts. */ + void *IntrHdcpDbgWrCallbackRef; /**< A pointer to the user data + passed to the hdcp + debug register write + callback function. */ + XDp_IntrHandler IntrHdcpAksvWrHandler; /**< Callback function for + HDCP Aksv MSB register + write interrupts. */ + void *IntrHdcpAksvWrCallbackRef; /**< A pointer to the user data + passed to the HDCP + Aksv MSB register write + callback function. */ + XDp_IntrHandler IntrHdcpAnWrHandler; /**< Callback function for + HDCP An MSB register + write interrupts. */ + void *IntrHdcpAnWrCallbackRef; /**< A pointer to the user data + passed to the HDCP + An MSB register write + callback function. */ + XDp_IntrHandler IntrHdcpAinfoWrHandler; /**< Callback function for + HDCP Ainfo register + write interrupts. */ + void *IntrHdcpAinfoWrCallbackRef; /**< A pointer to the user data + passed to the HDCP + Ainfo register write + callback function. */ + XDp_IntrHandler IntrHdcpRoRdHandler; /**< Callback function for + HDCP Ro register + read interrupts. */ + void *IntrHdcpRoRdCallbackRef; /**< A pointer to the user data + passed to the HDCP + Ro register read + callback function. */ + XDp_IntrHandler IntrHdcpBinfoRdHandler; /**< Callback function for + HDCP Binfo register + read interrupts. */ + void *IntrHdcpBinfoRdCallbackRef; /**< A pointer to the user data + passed to the HDCP + Binfo register read + callback function. */ + XDp_IntrHandler IntrUnplugHandler; /**< Callback function for + unplug interrupts. */ + void *IntrUnplugCallbackRef; /**< A pointer to the user data + passed to the unplug + callback function. */ } XDp_Rx; /** @@ -1088,6 +1137,20 @@ void XDp_RxSetIntrActRxHandler(XDp *InstancePtr, XDp_IntrHandler CallbackFunc, void *CallbackRef); void XDp_RxSetIntrCrcTestHandler(XDp *InstancePtr, XDp_IntrHandler CallbackFunc, void *CallbackRef); +void XDp_RxSetIntrHdcpDebugWriteHandler(XDp *InstancePtr, + XDp_IntrHandler CallbackFunc, void *CallbackRef); +void XDp_RxSetIntrHdcpAksvWriteHandler(XDp *InstancePtr, + XDp_IntrHandler CallbackFunc, void *CallbackRef); +void XDp_RxSetIntrHdcpAnWriteHandler(XDp *InstancePtr, + XDp_IntrHandler CallbackFunc, void *CallbackRef); +void XDp_RxSetIntrHdcpAinfoWriteHandler(XDp *InstancePtr, + XDp_IntrHandler CallbackFunc, void *CallbackRef); +void XDp_RxSetIntrHdcpRoReadHandler(XDp *InstancePtr, + XDp_IntrHandler CallbackFunc, void *CallbackRef); +void XDp_RxSetIntrHdcpBinfoReadHandler(XDp *InstancePtr, + XDp_IntrHandler CallbackFunc, void *CallbackRef); +void XDp_RxSetIntrUnplugHandler(XDp *InstancePtr, + XDp_IntrHandler CallbackFunc, void *CallbackRef); /* xdp_mst.c: Multi-stream transport (MST) functions for enabling or disabling * MST mode. */ diff --git a/XilinxProcessorIPLib/drivers/dp/src/xdp_hw.h b/XilinxProcessorIPLib/drivers/dp/src/xdp_hw.h index e2e5be36..1c1fcf48 100644 --- a/XilinxProcessorIPLib/drivers/dp/src/xdp_hw.h +++ b/XilinxProcessorIPLib/drivers/dp/src/xdp_hw.h @@ -300,6 +300,12 @@ extension packet. */ /* @} */ +/** @name DPTX core registers: HDCP. + * @{ + */ +#define XDP_TX_HDCP_ENABLE 0x400 /**< Enables HDCP core. */ +/* @} */ + /** @name DPTX core registers: Main stream attributes for MST STREAM2, 3, and 4. * @{ */ @@ -748,6 +754,11 @@ #define XDP_TX_GT_DRP_COMMAND_DRP_W_DATA_SHIFT \ 16 /**< Shift bits for DRP write data. */ +/* 0x400: XDP_TX_HDCP_ENABLE */ +#define XDP_TX_HDCP_ENABLE_BYPASS_DISABLE_MASK \ + 0x0001 /**< Disables bypass of the + HDCP core. */ + /* @} */ /******************************************************************************/ @@ -1128,6 +1139,13 @@ of stream 1. */ /* @} */ +/** @name DPRX core registers: DPCD registers for HDCP. + * @{ + */ +#define XDP_RX_DPCD_HDCP_TABLE 0x900 /**< HDCP register table + (0x100 bytes). */ +/* @} */ + /** @name DPRX core registers: MST field for sideband message buffers and the * virtual channel payload table. * @{ @@ -1259,6 +1277,30 @@ #define XDP_RX_INTERRUPT_MASK_TP3_MASK 0x00040000 /**< Mask the interrupt assertion for start of training pattern 3. */ +#define XDP_RX_INTERRUPT_MASK_HDCP_DEBUG_WRITE_MASK \ + 0x00080000 /**< Mask the interrupt + for a write to any HDCP + debug register. */ +#define XDP_RX_INTERRUPT_MASK_HDCP_AKSV_WRITE_MASK \ + 0x00100000 /**< Mask the interrupt + for a write to the HDCP + AKSV MSB register. */ +#define XDP_RX_INTERRUPT_MASK_HDCP_AN_WRITE_MASK \ + 0x00200000 /**< Mask the interrupt + for a write to the HDCP + An MSB register. */ +#define XDP_RX_INTERRUPT_MASK_HDCP_AINFO_WRITE_MASK \ + 0x00400000 /**< Mask the interrupt + for a write to the HDCP + AInfo register. */ +#define XDP_RX_INTERRUPT_MASK_HDCP_RO_READ_MASK \ + 0x00800000 /**< Mask the interrupt + for a read of the HDCP + Ro register. */ +#define XDP_RX_INTERRUPT_MASK_HDCP_BINFO_READ_MASK \ + 0x01000000 /**< Mask the interrupt + for a read of the HDCP + BInfo register. */ #define XDP_RX_INTERRUPT_MASK_AUDIO_OVER_MASK \ 0x08000000 /**< Mask the interrupt assertion caused for an @@ -1281,8 +1323,10 @@ 0x40000000 /**< Mask the interrupt assertion for the start of a CRC test. */ - -#define XDP_RX_INTERRUPT_MASK_ALL_MASK 0x7807FFFF /**< Mask all interrupts. */ +#define XDP_RX_INTERRUPT_MASK_UNPLUG_MASK \ + 0x80000000 /**< Mask the unplug event + interrupt. */ +#define XDP_RX_INTERRUPT_MASK_ALL_MASK 0xF9FFFFFF /**< Mask all interrupts. */ /* 0x018: MISC_CTRL */ #define XDP_RX_MISC_CTRL_USE_FILT_MSA_MASK \ 0x1 /**< When set, two matching @@ -1407,6 +1451,9 @@ #define XDP_RX_INTERRUPT_CAUSE_CRC_TEST_MASK \ XDP_RX_INTERRUPT_MASK_CRC_TEST_MASK /**< Interrupt caused by the start of a CRC test. */ +#define XDP_RX_INTERRUPT_CAUSE_UNPLUG_MASK \ + XDP_RX_INTERRUPT_MASK_UNPLUG_MASK /**< Interrupt caused by the + an unplug event. */ /* 0x044: INTERRUPT_MASK_1 */ #define XDP_RX_INTERRUPT_MASK_1_EXT_PKT_STREAM234_MASK(Stream) \ (0x00001 << ((Stream - 2) * 6)) /**< Mask the interrupt @@ -1531,6 +1578,9 @@ 0x02 /**< Reflects the SINK_SPECIFIC_IRQ state. */ +#define XDP_RX_DEVICE_SERVICE_IRQ_CP_IRQ_MASK \ + 0x04 /**< Generates a CP IRQ + event */ #define XDP_RX_DEVICE_SERVICE_IRQ_NEW_DOWN_REPLY_MASK \ 0x10 /**< Indicates a new DOWN_REPLY buffer message is diff --git a/XilinxProcessorIPLib/drivers/dp/src/xdp_intr.c b/XilinxProcessorIPLib/drivers/dp/src/xdp_intr.c index 2bcc825b..ed890f65 100644 --- a/XilinxProcessorIPLib/drivers/dp/src/xdp_intr.c +++ b/XilinxProcessorIPLib/drivers/dp/src/xdp_intr.c @@ -45,6 +45,8 @@ * ----- ---- -------- ----------------------------------------------- * 1.0 als 01/20/15 Initial release. TX code merged from the dptx driver. * 2.0 als 06/08/15 Added MST interrupt handlers for RX. + * Added HDCP interrupts. + * Added unplug interrupt. * * *******************************************************************************/ @@ -593,6 +595,174 @@ void XDp_RxSetIntrTp3Handler(XDp *InstancePtr, InstancePtr->RxInstance.IntrTp3CallbackRef = CallbackRef; } +/******************************************************************************/ +/** + * This function installs a callback function for when a write to any hdcp + * debug register occurs. + * + * @param InstancePtr is a pointer to the XDp instance. + * @param CallbackFunc is the address to the callback function. + * @param CallbackRef is the user data item that will be passed to the + * callback function when it is invoked. + * + * @return None. + * + * @note None. + * +*******************************************************************************/ +void XDp_RxSetIntrHdcpDebugWriteHandler(XDp *InstancePtr, + XDp_IntrHandler CallbackFunc, void *CallbackRef) +{ + /* Verify arguments. */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_RX); + Xil_AssertVoid(CallbackFunc != NULL); + Xil_AssertVoid(CallbackRef != NULL); + + InstancePtr->RxInstance.IntrHdcpDbgWrHandler = CallbackFunc; + InstancePtr->RxInstance.IntrHdcpDbgWrCallbackRef = CallbackRef; +} + +/******************************************************************************/ +/** + * This function installs a callback function for when a write to the hdcp + * Aksv MSB register occurs. + * + * @param InstancePtr is a pointer to the XDp instance. + * @param CallbackFunc is the address to the callback function. + * @param CallbackRef is the user data item that will be passed to the + * callback function when it is invoked. + * + * @return None. + * + * @note None. + * +*******************************************************************************/ +void XDp_RxSetIntrHdcpAksvWriteHandler(XDp *InstancePtr, + XDp_IntrHandler CallbackFunc, void *CallbackRef) +{ + /* Verify arguments. */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_RX); + Xil_AssertVoid(CallbackFunc != NULL); + Xil_AssertVoid(CallbackRef != NULL); + + InstancePtr->RxInstance.IntrHdcpAksvWrHandler = CallbackFunc; + InstancePtr->RxInstance.IntrHdcpAksvWrCallbackRef = CallbackRef; +} + +/******************************************************************************/ +/** + * This function installs a callback function for when a write to the hdcp + * An MSB register occurs. + * + * @param InstancePtr is a pointer to the XDp instance. + * @param CallbackFunc is the address to the callback function. + * @param CallbackRef is the user data item that will be passed to the + * callback function when it is invoked. + * + * @return None. + * + * @note None. + * +*******************************************************************************/ +void XDp_RxSetIntrHdcpAnWriteHandler(XDp *InstancePtr, + XDp_IntrHandler CallbackFunc, void *CallbackRef) +{ + /* Verify arguments. */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_RX); + Xil_AssertVoid(CallbackFunc != NULL); + Xil_AssertVoid(CallbackRef != NULL); + + InstancePtr->RxInstance.IntrHdcpAnWrHandler = CallbackFunc; + InstancePtr->RxInstance.IntrHdcpAnWrCallbackRef = CallbackRef; +} + +/******************************************************************************/ +/** + * This function installs a callback function for when a write to the hdcp + * Ainfo MSB register occurs. + * + * @param InstancePtr is a pointer to the XDp instance. + * @param CallbackFunc is the address to the callback function. + * @param CallbackRef is the user data item that will be passed to the + * callback function when it is invoked. + * + * @return None. + * + * @note None. + * +*******************************************************************************/ +void XDp_RxSetIntrHdcpAinfoWriteHandler(XDp *InstancePtr, + XDp_IntrHandler CallbackFunc, void *CallbackRef) +{ + /* Verify arguments. */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_RX); + Xil_AssertVoid(CallbackFunc != NULL); + Xil_AssertVoid(CallbackRef != NULL); + + InstancePtr->RxInstance.IntrHdcpAinfoWrHandler = CallbackFunc; + InstancePtr->RxInstance.IntrHdcpAinfoWrCallbackRef = CallbackRef; +} + +/******************************************************************************/ +/** + * This function installs a callback function for when a read of the hdcp + * Ro/Ri MSB register occurs. + * + * @param InstancePtr is a pointer to the XDp instance. + * @param CallbackFunc is the address to the callback function. + * @param CallbackRef is the user data item that will be passed to the + * callback function when it is invoked. + * + * @return None. + * + * @note None. + * +*******************************************************************************/ +void XDp_RxSetIntrHdcpRoReadHandler(XDp *InstancePtr, + XDp_IntrHandler CallbackFunc, void *CallbackRef) +{ + /* Verify arguments. */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_RX); + Xil_AssertVoid(CallbackFunc != NULL); + Xil_AssertVoid(CallbackRef != NULL); + + InstancePtr->RxInstance.IntrHdcpRoRdHandler = CallbackFunc; + InstancePtr->RxInstance.IntrHdcpRoRdCallbackRef = CallbackRef; +} + +/******************************************************************************/ +/** + * This function installs a callback function for when a read of the hdcp + * Binfo register occurs. + * + * @param InstancePtr is a pointer to the XDp instance. + * @param CallbackFunc is the address to the callback function. + * @param CallbackRef is the user data item that will be passed to the + * callback function when it is invoked. + * + * @return None. + * + * @note None. + * +*******************************************************************************/ +void XDp_RxSetIntrHdcpBinfoReadHandler(XDp *InstancePtr, + XDp_IntrHandler CallbackFunc, void *CallbackRef) +{ + /* Verify arguments. */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_RX); + Xil_AssertVoid(CallbackFunc != NULL); + Xil_AssertVoid(CallbackRef != NULL); + + InstancePtr->RxInstance.IntrHdcpBinfoRdHandler = CallbackFunc; + InstancePtr->RxInstance.IntrHdcpBinfoRdCallbackRef = CallbackRef; +} + /******************************************************************************/ /** * This function installs a callback function for when a down request interrupt @@ -762,6 +932,34 @@ void XDp_RxSetIntrCrcTestHandler(XDp *InstancePtr, InstancePtr->RxInstance.IntrCrcTestCallbackRef = CallbackRef; } +/******************************************************************************/ +/** + * This function installs a callback function for when an unplug event interrupt + * occurs. + * + * @param InstancePtr is a pointer to the XDp instance. + * @param CallbackFunc is the address to the callback function. + * @param CallbackRef is the user data item that will be passed to the + * callback function when it is invoked. + * + * @return None. + * + * @note None. + * +*******************************************************************************/ +void XDp_RxSetIntrUnplugHandler(XDp *InstancePtr, + XDp_IntrHandler CallbackFunc, void *CallbackRef) +{ + /* Verify arguments. */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_RX); + Xil_AssertVoid(CallbackFunc != NULL); + Xil_AssertVoid(CallbackRef != NULL); + + InstancePtr->RxInstance.IntrUnplugHandler = CallbackFunc; + InstancePtr->RxInstance.IntrUnplugCallbackRef = CallbackRef; +} + /******************************************************************************/ /** * This function is the interrupt handler for the XDp driver operating in TX @@ -952,4 +1150,42 @@ static void XDp_RxInterruptHandler(XDp *InstancePtr) InstancePtr->RxInstance.IntrCrcTestHandler( InstancePtr->RxInstance.IntrCrcTestCallbackRef); } + + /* A write to one of the HDCP debug registers has been performed. */ + if (IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_DEBUG_WRITE_MASK) { + InstancePtr->RxInstance.IntrHdcpDbgWrHandler( + InstancePtr->RxInstance.IntrHdcpDbgWrCallbackRef); + } + /* A write to the HDCP Aksv MSB register has been performed. */ + if (IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_AKSV_WRITE_MASK) { + InstancePtr->RxInstance.IntrHdcpAksvWrHandler( + InstancePtr->RxInstance.IntrHdcpAksvWrCallbackRef); + } + /* A write to the HDCP An MSB register has been performed. */ + if (IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_AN_WRITE_MASK) { + InstancePtr->RxInstance.IntrHdcpAnWrHandler( + InstancePtr->RxInstance.IntrHdcpAnWrCallbackRef); + } + /* A write to the HDCP Ainfo MSB register has been performed. */ + if (IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_AINFO_WRITE_MASK) { + InstancePtr->RxInstance.IntrHdcpAinfoWrHandler( + InstancePtr->RxInstance.IntrHdcpAinfoWrCallbackRef); + } + /* A read of the HDCP Ro register has been performed. */ + if (IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_RO_READ_MASK) { + InstancePtr->RxInstance.IntrHdcpRoRdHandler( + InstancePtr->RxInstance.IntrHdcpRoRdCallbackRef); + } + /* A read of the HDCP Binfo register has been performed. */ + if (IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_BINFO_READ_MASK) { + InstancePtr->RxInstance.IntrHdcpBinfoRdHandler( + InstancePtr->RxInstance.IntrHdcpBinfoRdCallbackRef); + } + + /* An unplug event has occurred. */ + if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_UNPLUG_MASK) && + InstancePtr->RxInstance.IntrUnplugHandler) { + InstancePtr->RxInstance.IntrUnplugHandler( + InstancePtr->RxInstance.IntrUnplugCallbackRef); + } }