dp: New version v2.0.

Copied v1.0 directory to v2.0.

Deprecated version 1.0.

Signed-off-by: Andrei-Liviu Simion <andrei.simion@xilinx.com>
This commit is contained in:
Andrei-Liviu Simion 2015-02-07 17:08:55 -07:00 committed by Nava kishore Manne
parent ce10360848
commit 903d859429
24 changed files with 15446 additions and 0 deletions

View file

@ -0,0 +1,7 @@
xdp_selftest_example.c=xdp_selftest_example.c
xdp_rx_intr_timer_example.c=xdp_rx_intr_timer_example.c
xdp_tx_audio_example.c=xdp_tx_example_common.h,xdp_tx_example_common.c
xdp_tx_intr_example.c=xdp_tx_example_common.h,xdp_tx_example_common.c
xdp_tx_mst_example.c=xdp_tx_example_common.h,xdp_tx_example_common.c
xdp_tx_poll_example.c=xdp_tx_example_common.h,xdp_tx_example_common.c
xdp_tx_timer_example.c=xdp_tx_example_common.h,xdp_tx_example_common.c

View file

@ -0,0 +1,42 @@
##******************************************************************************
##
## Copyright (C) 2014 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.
##
##*****************************************************************************/
OPTION psf_version = 2.1;
BEGIN driver dp
OPTION supported_peripherals = (displayport);
OPTION driver_state = ACTIVE;
OPTION depends = (video_common_v1_0);
OPTION copyfiles = all;
OPTION VERSION = 1.0;
OPTION NAME = dp;
END driver

View file

@ -0,0 +1,186 @@
##******************************************************************************
##
## Copyright (C) 2014 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.
##
##*****************************************************************************/
proc generate {drv_handle} {
xdefine_include_file $drv_handle "xparameters.h" "XDp" "NUM_INSTANCES" "DEVICE_ID" "C_BASEADDR" "C_LANE_COUNT" "C_LINK_RATE" "C_MAX_BITS_PER_COLOR" "C_QUAD_PIXEL_ENABLE" "C_DUAL_PIXEL_ENABLE" "C_YCRCB_ENABLE" "C_YONLY_ENABLE" "C_GT_DATAWIDTH" "C_SECONDARY_SUPPORT" "C_AUDIO_CHANNELS" "C_MST_ENABLE" "C_NUMBER_OF_MST_STREAMS" "C_PROTOCOL_SELECTION" "C_FLOW_DIRECTION" "S_AXI_ACLK"
::hsi::utils::define_config_file $drv_handle "xdp_g.c" "XDp" "DEVICE_ID" "C_BASEADDR" "S_AXI_ACLK" "C_LANE_COUNT" "C_LINK_RATE" "C_MAX_BITS_PER_COLOR" "C_QUAD_PIXEL_ENABLE" "C_DUAL_PIXEL_ENABLE" "C_YCRCB_ENABLE" "C_YONLY_ENABLE" "C_GT_DATAWIDTH" "C_SECONDARY_SUPPORT" "C_AUDIO_CHANNELS" "C_MST_ENABLE" "C_NUMBER_OF_MST_STREAMS" "C_PROTOCOL_SELECTION" "C_FLOW_DIRECTION"
xdefine_canonical_xpars $drv_handle "xparameters.h" "XDp" "NUM_INSTANCES" "DEVICE_ID" "C_BASEADDR" "C_LANE_COUNT" "C_LINK_RATE" "C_MAX_BITS_PER_COLOR" "C_QUAD_PIXEL_ENABLE" "C_DUAL_PIXEL_ENABLE" "C_YCRCB_ENABLE" "C_YONLY_ENABLE" "C_GT_DATAWIDTH" "C_SECONDARY_SUPPORT" "C_AUDIO_CHANNELS" "C_MST_ENABLE" "C_NUMBER_OF_MST_STREAMS" "C_PROTOCOL_SELECTION" "C_FLOW_DIRECTION" "S_AXI_ACLK"
}
#
# Given a list of arguments, define them all in an include file.
# Handles IP model/user parameters, as well as the special parameters NUM_INSTANCES,
# DEVICE_ID
# Will not work for a processor.
#
proc xdefine_include_file {drv_handle file_name drv_string args} {
set args [get_exact_arg_list $args]
# Open include file
set file_handle [xopen_include_file $file_name]
# Get all peripherals connected to this driver
set periphs [xget_sw_iplist_for_driver $drv_handle]
# Handle special cases
set arg "NUM_INSTANCES"
set posn [lsearch -exact $args $arg]
if {$posn > -1} {
puts $file_handle "/* Definitions for driver [string toupper [get_property name $drv_handle]] */"
# Define NUM_INSTANCES
puts $file_handle "#define [xget_dname $drv_string $arg] [llength $periphs]"
set args [lreplace $args $posn $posn]
}
# Check if it is a driver parameter
lappend newargs
foreach arg $args {
set value [get_property CONFIG.$arg $drv_handle]
if {[llength $value] == 0} {
lappend newargs $arg
} else {
puts $file_handle "#define [xget_dname $drv_string $arg] [get_property $arg $drv_handle]"
}
}
set args $newargs
# Print all parameters for all peripherals
set device_id 0
foreach periph $periphs {
puts $file_handle ""
puts $file_handle "/* Definitions for peripheral [string toupper [get_property NAME $periph]] */"
foreach arg $args {
if {[string compare -nocase "DEVICE_ID" $arg] == 0} {
set value $device_id
incr device_id
} elseif {[string compare -nocase "S_AXI_ACLK" $arg] == 0} {
set freq [xget_ip_clk_pin_freq $periph $arg]
if {[llength $freq] == 0} {
set freq 0
puts "WARNING: Clock frequency information is not available in the design, \
for peripheral $periph_name. This will not work."
}
set value $freq
} else {
set value [get_property CONFIG.$arg $periph]
}
if {[llength $value] == 0} {
set value 0
}
set value [xformat_addr_string $value $arg]
if {[string compare -nocase "HW_VER" $arg] == 0} {
puts $file_handle "#define [xget_name $periph $arg] \"$value\""
} else {
puts $file_handle "#define [xget_name $periph $arg] $value"
}
}
puts $file_handle ""
}
puts $file_handle "\n/******************************************************************/\n"
close $file_handle
}
#
# xdefine_canonical_xpars - Used to print out canonical defines for a driver.
# Given a list of arguments, define each as a canonical constant name, using
# the driver name, in an include file.
#
proc xdefine_canonical_xpars {drv_handle file_name drv_string args} {
set args [get_exact_arg_list $args]
# Open include file
set file_handle [xopen_include_file $file_name]
# Get all the peripherals connected to this driver
set periphs [xget_sw_iplist_for_driver $drv_handle]
# Get the names of all the peripherals connected to this driver
foreach periph $periphs {
set peripheral_name [string toupper [get_property NAME $periph]]
lappend peripherals $peripheral_name
}
# Get possible canonical names for all the peripherals connected to this
# driver
set device_id 0
foreach periph $periphs {
set canonical_name [string toupper [format "%s_%s" $drv_string $device_id]]
lappend canonicals $canonical_name
# Create a list of IDs of the peripherals whose hardware instance name
# doesn't match the canonical name. These IDs can be used later to
# generate canonical definitions
if { [lsearch $peripherals $canonical_name] < 0 } {
lappend indices $device_id
}
incr device_id
}
set i 0
foreach periph $periphs {
set periph_name [string toupper [get_property NAME $periph]]
# Generate canonical definitions only for the peripherals whose
# canonical name is not the same as hardware instance name
if { [lsearch $canonicals $periph_name] < 0 } {
puts $file_handle "/* Canonical definitions for peripheral $periph_name */"
set canonical_name [format "%s_%s" $drv_string [lindex $indices $i]]
foreach arg $args {
set lvalue [xget_dname $canonical_name $arg]
# The commented out rvalue is the name of the instance-specific constant
# set rvalue [xget_name $periph $arg]
# The rvalue set below is the actual value of the parameter
if {[string compare -nocase "S_AXI_ACLK" $arg] == 0} {
set freq [xget_ip_clk_pin_freq $periph $arg]
if {[llength $freq] == 0} {
set freq 0
puts "WARNING: Clock frequency information is not available in the design, \
for peripheral $periph_name. This will not work."
}
set rvalue $freq
} else {
set rvalue [xget_param_value $periph $arg]
if {[llength $rvalue] == 0} {
set rvalue 0
}
set rvalue [xformat_addr_string $rvalue $arg]
}
puts $file_handle "#define $lvalue $rvalue"
}
puts $file_handle ""
incr i
}
}
puts $file_handle "\n/******************************************************************/\n"
close $file_handle
}

View file

@ -0,0 +1,23 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Driver example applications</title>
<link rel="stylesheet" type="text/css" href="../help.css">
</head>
<body bgcolor="#FFFFFF">
<h1> Example applications for the dp_v1_0 driver. </h1>
<HR>
<ul>
<li>xdp_selftest_example.c <a href="xdptx_selftest_example.c">(source)</a> </li>
<li>xdp_rx_intr_timer_example.c <a href="xdprx_intr_timer_example.c">(source)</a> </li>
<li>xdp_tx_audio_example.c <a href="xdptx_audio_example.c">(source)</a> </li>
<li>xdp_tx_intr_example.c <a href="xdptx_intr_example.c">(source)</a> </li>
<li>xdp_tx_mst_example.c <a href="xdptx_mst_example.c">(source)</a> </li>
<li>xdp_tx_poll_example.c <a href="xdptx_poll_example.c">(source)</a> </li>
<li>xdp_tx_timer_example.c <a href="xdptx_timer_example.c">(source)</a> </li>
</ul>
<p><font face="Times New Roman" color="#800000">Copyright © 1995-2015 Xilinx, Inc. All rights reserved.</font></p>
</body>
</html>

View file

@ -0,0 +1,76 @@
There is 1 DisplayPort RX example included in this directory:
1) xdp_rx_intr_timer_example.c : This interrupt with timer example shows how to
set up both the interrupt system with interrupt handlers and how to override
the default sleep/delay functionality for MicroBlaze. A timer needs to exist
in the hardware system and will be used for sleep/delay functionality inside
of a callback function. The default behavior in MicroBlaze for sleep/delay is
to call MB_Sleep from microblaze_sleep.h, which has only millisecond
accuracy. For ARM/Zynq SoC systems, the supplied callback function will be
ignored - the usleep function will be called since the SoC has a timer
built-in.
Note: All example functions start with Dprx_*, while all driver functions start
with XDp_*.
There are 6 DisplayPort TX examples included in this directory:
1) xdp_tx_audio_example.c : This audio example, apart from training the main
link and outputting video, illustrates the sequence required for setting up
audio in the DisplayPort TX. This example requires that an audio source, such
as a S/PDIF instance be present and connected to the DisplayPort TX in the
hardware system, and for the audio enable configuration parameter to be set
for the instantiated DisplayPort TX. For audio to output, the user will need
to implement the following functions:
a) Dptx_ConfigureAudioSrc : This function needs to configure the audio source
to output to the DisplayPort TX.
b) Dptx_AudioSendInfoFrame : This function needs to set up and write an audio
info frame as per user requirements.
2) xdp_tx_intr_example.c : This interrupt example shows how to set up the
interrupt system and specify the interrupt handlers for when a DisplayPort
interrupt event occurs. An interrupt controller with a connection to the
DisplayPort interrupt signal needs to exist in the hardware system.
3) xdp_tx_mst_example.c : This multi-stream transport (MST) example shows how to
use the driver's MST capabilities. Streams can be directed at sinks using two
methods:
a) After topology discover has created a sink list, streams may be assigned
to sinks using the index in the sink list.
b) The streams may be assigned to sinks directly without using topology
discovery if their relative addresses (and total number of DisplayPort
links) from the DisplayPort source is known beforehand.
4) xdp_tx_poll_example.c : This interrupt example shows how to poll the
DisplayPort TX instance's registers for DisplayPort interrupt events.
5) xdp_tx_timer_example.c : This timer example shows how to override the default
sleep/delay functionality for MicroBlaze. A timer needs to exist in the
hardware system and will be used for sleep/delay functionality inside of a
callback function. The default behavior in MicroBlaze for sleep/delay is to
call MB_Sleep from microblaze_sleep.h, which has only millisecond accuracy.
For ARM/Zynq SoC systems, the supplied callback function will be ignored -
the usleep function will be called since the SoC has a timer built-in.
6) xdp_tx_selftest_example.c : This self test example will perform a sanity
check on the state of the DisplayPort TX instance. It may be called prior to
usage of the core or after a reset to ensure that (a subset of) the registers
hold their default values.
Each of these examples are meant to be used in conjunction with
xdp_tx_example_common.[ch] which holds common functionality for all examples.
After importing the examples, these files will need to be manually copied into
the example src/ directory.
This code shows how to train the main link and set up a video stream.
Additionally, in order to be able to use the interrupt, polling, and timer
examples, the user will need to implement and link the following functions:
1) Dptx_InitPlatform : This function needs to do all hardware system
initialization.
2) Dptx_StreamSrc* : These function need to configure the source of the stream
(pattern generators, video input, etc.) such that a video stream, with
timings and video attributes that correspond to the main stream attributes
(MSA) configuration, is received by the DisplayPort Tx. The examples call
this function from the Dptx_Run->Dptx_StartVideoStream functions in
xdp_tx_example_common.c.
Note: All example functions start with Dptx_*, while all driver functions start
with XDp_*.

View file

@ -0,0 +1,713 @@
/*******************************************************************************
*
* 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 xdp_rx_intr_timer_example.c
*
* Contains a design example using the XDp driver with a user-defined hook
* for delay. The reasoning behind this is that MicroBlaze sleep is not very
* accurate without a hardware timer. For systems that have a hardware timer,
* the user may override the default MicroBlaze sleep with a function that will
* use the hardware timer.
* Also, this example sets up the interrupt controller and defines handlers for
* various interrupt types. In this way, the RX interrupt handler will arbitrate
* the different interrupts to their respective interrupt handlers defined in
* this example.
* This example will print out the detected resolution of the incoming
* DisplayPort video stream.
* This example is meant to take in the incoming DisplayPort video stream and
* pass it through using the Dprd_Vidpipe* functions which are left for the user
* to implement.
*
* @note This example requires an AXI timer in the system.
* @note For this example to work, the user will need to implement
* initialization of the system (Dprx_PlatformInit) as this is
* system-specific.
* @note For this example to display output, the user will need to
* implement the Dprx_Vidpipe* functions which configure and
* reset the video pipeline as required as this is system-specific.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 01/20/15 Initial creation.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xdp.h"
#include "xparameters.h"
#ifdef XPAR_INTC_0_DEVICE_ID
/* For MicroBlaze systems. */
#include "xintc.h"
#else
/* For ARM/Zynq SoC systems. */
#include "xscugic.h"
#endif /* XPAR_INTC_0_DEVICE_ID */
#include "xtmrctr.h"
/**************************** Constant Definitions ****************************/
/* The following constants map to the XPAR parameters created in the
* xparameters.h file. */
#define DPRX_DEVICE_ID XPAR_DISPLAYPORT_0_DEVICE_ID
#ifdef XPAR_INTC_0_DEVICE_ID
#define DP_INTERRUPT_ID \
XPAR_PROCESSOR_SUBSYSTEM_INTERCONNECT_AXI_INTC_1_DISPLAYPORT_0_AXI_INT_INTR
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
#else
#define DP_INTERRUPT_ID XPAR_FABRIC_DISPLAYPORT_0_AXI_INT_INTR
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#endif /* XPAR_INTC_0_DEVICE_ID */
/****************************** Type Definitions ******************************/
/* Depending on whether the system is a MicroBlaze or ARM/Zynq SoC system,
* different drivers and associated types will be used. */
#ifdef XPAR_INTC_0_DEVICE_ID
#define INTC XIntc
#define INTC_HANDLER XIntc_InterruptHandler
#else
#define INTC XScuGic
#define INTC_HANDLER XScuGic_InterruptHandler
#endif /* XPAR_INTC_0_DEVICE_ID */
/**************************** Function Prototypes *****************************/
u32 Dprx_IntrTimerExample(XDp *InstancePtr, u16 DeviceId, INTC *IntcPtr,
u16 IntrId, u16 DpIntrId, XTmrCtr *TimerCounterPtr);
static u32 Dprx_SetupExample(XDp *InstancePtr, u16 DeviceId);
static u32 Dprx_SetupInterruptHandler(XDp *InstancePtr, INTC *IntcPtr,
u16 IntrId, u16 DpIntrId);
static void Dprx_CustomWaitUs(void *InstancePtr, u32 MicroSeconds);
static void Dprx_ResetVideoOutput(void *InstancePtr);
static void Dprx_DetectResolution(void *InstancePtr);
static void Dprx_InterruptHandlerVmChange(void *InstancePtr);
static void Dprx_InterruptHandlerPowerState(void *InstancePtr);
static void Dprx_InterruptHandlerNoVideo(void *InstancePtr);
static void Dprx_InterruptHandlerVBlank(void *InstancePtr);
static void Dprx_InterruptHandlerTrainingLost(void *InstancePtr);
static void Dprx_InterruptHandlerVideo(void *InstancePtr);
static void Dprx_InterruptHandlerTrainingDone(void *InstancePtr);
static void Dprx_InterruptHandlerBwChange(void *InstancePtr);
static void Dprx_InterruptHandlerTp1(void *InstancePtr);
static void Dprx_InterruptHandlerTp2(void *InstancePtr);
static void Dprx_InterruptHandlerTp3(void *InstancePtr);
extern void Dprx_VidpipeConfig(XDp *InstancePtr);
extern void Dprx_VidpipeReset(void);
/*************************** Variable Declarations ****************************/
XDp DpInstance; /* The Dp instance. */
INTC IntcInstance; /* The interrupt controller instance. */
XTmrCtr TimerCounterInst; /* The timer counter instance. */
/* Used by interrupt handlers. */
u8 VBlankEnable;
u8 VBlankCount;
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function is the main function of the XDp (operating in RX mode)
* interrupt with timer example. If the Dprx_IntrTimerExample function, which
* sets up the system succeeds, this function will wait for interrupts.
*
* @param None.
*
* @return
* - XST_FAILURE if the interrupt example was unsuccessful - system
* setup failed.
*
* @note Unless setup failed, main will never return since
* Dprx_IntrTimerExample is blocking.
*
*******************************************************************************/
int main(void)
{
u32 Status;
/* Run the XDp (in RX mode) interrupt with timer example. */
Status = Dprx_IntrTimerExample(&DpInstance, DPRX_DEVICE_ID,
&IntcInstance, INTC_DEVICE_ID, DP_INTERRUPT_ID,
&TimerCounterInst);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
* The main entry point for the interrupt with timer example using the XDp
* driver. This function will set up the system, interrupt controller and
* interrupt handlers, and the custom sleep handler.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param DeviceId is the unique device ID of the DisplayPort RX core
* instance.
* @param IntcPtr is a pointer to the interrupt instance.
* @param IntrId is the unique device ID of the interrupt controller.
* @param DpIntrId is the interrupt ID of the DisplayPort RX connection to
* the interrupt controller.
* @param TimerCounterPtr is a pointer to the timer instance.
*
* @return
* - XST_SUCCESS if the system was set up correctly and link
* training was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
u32 Dprx_IntrTimerExample(XDp *InstancePtr, u16 DeviceId, INTC *IntcPtr,
u16 IntrId, u16 DpIntrId, XTmrCtr *TimerCounterPtr)
{
u32 Status;
/* Do platform initialization here. This is hardware system specific -
* it is up to the user to implement this function. */
Dprx_PlatformInit(InstancePtr);
/*******************/
Status = Dprx_SetupExample(InstancePtr, DeviceId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Set a custom timer handler for improved delay accuracy on MicroBlaze
* systems since the driver does not assume/have a dependency on the
* system having a timer in the FPGA.
* Note: This only has an affect for MicroBlaze systems since the Zynq
* ARM SoC contains a timer, which is used when the driver calls the
* delay function. */
XDp_SetUserTimerHandler(InstancePtr, &Dprx_CustomWaitUs,
TimerCounterPtr);
/* Setup interrupt handling in the system. */
Status = Dprx_SetupInterruptHandler(InstancePtr, IntcPtr, IntrId,
DpIntrId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Do not return in order to allow interrupt handling to run. */
while (1);
return XST_SUCCESS;
}
/******************************************************************************/
/**
* This function will setup and initialize the DisplayPort RX core. The core's
* configuration parameters will be retrieved based on the configuration
* to the DisplayPort RX core instance with the specified device ID.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param DeviceId is the unique device ID of the DisplayPort RX core
* instance.
*
* @return
* - XST_SUCCESS if the device configuration was found and obtained
* and if the main link was successfully established.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
static u32 Dprx_SetupExample(XDp *InstancePtr, u16 DeviceId)
{
XDp_Config *ConfigPtr;
u32 Status;
/* Obtain the device configuration for the DisplayPort RX core. */
ConfigPtr = XDp_LookupConfig(DeviceId);
if (!ConfigPtr) {
return XST_FAILURE;
}
/* Copy the device configuration into the InstancePtr's Config
* structure. */
XDp_CfgInitialize(InstancePtr, ConfigPtr, ConfigPtr->BaseAddr);
XDp_RxSetLaneCount(InstancePtr, InstancePtr->Config.MaxLaneCount);
XDp_RxSetLinkRate(InstancePtr, InstancePtr->Config.MaxLinkRate);
/* Initialize the DisplayPort RX core. */
Status = XDp_Initialize(InstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
* This function sets up the interrupt system such that interrupts caused by
* Hot-Plug-Detect (HPD) events and pulses are handled. This function is
* application-specific for systems that have an interrupt controller connected
* to the processor. The user should modify this function to fit the
* application.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param IntcPtr is a pointer to the interrupt instance.
* @param IntrId is the unique device ID of the interrupt controller.
* @param DpIntrId is the interrupt ID of the DisplayPort RX connection to
* the interrupt controller.
*
* @return
* - XST_SUCCESS if the interrupt system was successfully set up.
* - XST_FAILURE otherwise.
*
* @note An interrupt controller must be present in the system, connected
* to the processor and the DisplayPort RX core.
*
*******************************************************************************/
static u32 Dprx_SetupInterruptHandler(XDp *InstancePtr, INTC *IntcPtr,
u16 IntrId, u16 DpIntrId)
{
u32 Status;
/* Set the HPD interrupt handlers. */
XDp_RxSetIntrVmChangeHandler(InstancePtr,
Dprx_InterruptHandlerVmChange, InstancePtr);
XDp_RxSetIntrPowerStateHandler(InstancePtr,
Dprx_InterruptHandlerPowerState, InstancePtr);
XDp_RxSetIntrNoVideoHandler(InstancePtr,
Dprx_InterruptHandlerNoVideo, InstancePtr);
XDp_RxSetIntrVBlankHandler(InstancePtr,
Dprx_InterruptHandlerVBlank, InstancePtr);
XDp_RxSetIntrTrainingLostHandler(InstancePtr,
Dprx_InterruptHandlerTrainingLost, InstancePtr);
XDp_RxSetIntrVideoHandler(InstancePtr,
Dprx_InterruptHandlerVideo, InstancePtr);
XDp_RxSetIntrTrainingDoneHandler(InstancePtr,
Dprx_InterruptHandlerTrainingDone, InstancePtr);
XDp_RxSetIntrBwChangeHandler(InstancePtr,
Dprx_InterruptHandlerBwChange, InstancePtr);
XDp_RxSetIntrTp1Handler(InstancePtr,
Dprx_InterruptHandlerTp1, InstancePtr);
XDp_RxSetIntrTp2Handler(InstancePtr,
Dprx_InterruptHandlerTp2, InstancePtr);
XDp_RxSetIntrTp3Handler(InstancePtr,
Dprx_InterruptHandlerTp3, InstancePtr);
/* Initialize interrupt controller driver. */
#ifdef XPAR_INTC_0_DEVICE_ID
Status = XIntc_Initialize(IntcPtr, IntrId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#else
XScuGic_Config *IntcConfig;
IntcConfig = XScuGic_LookupConfig(IntrId);
Status = XScuGic_CfgInitialize(IntcPtr, IntcConfig,
IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XScuGic_SetPriorityTriggerType(IntcPtr, DpIntrId, 0xA0, 0x1);
#endif /* XPAR_INTC_0_DEVICE_ID */
/* Connect the device driver handler that will be called when an
* interrupt for the device occurs, the handler defined above performs
* the specific interrupt processing for the device. */
#ifdef XPAR_INTC_0_DEVICE_ID
Status = XIntc_Connect(IntcPtr, DpIntrId,
(XInterruptHandler)XDp_InterruptHandler, InstancePtr);
#else
Status = XScuGic_Connect(IntcPtr, DpIntrId,
(Xil_InterruptHandler)XDp_InterruptHandler, InstancePtr);
#endif /* XPAR_INTC_0_DEVICE_ID */
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Start the interrupt controller. */
#ifdef XPAR_INTC_0_DEVICE_ID
Status = XIntc_Start(IntcPtr, XIN_REAL_MODE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XIntc_Enable(IntcPtr, DpIntrId);
#else
XScuGic_Enable(IntcPtr, DpIntrId);
#endif /* XPAR_INTC_0_DEVICE_ID */
/* Initialize the exception table. */
Xil_ExceptionInit();
/* Register the interrupt controller handler with the exception
* table. */
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)INTC_HANDLER, IntcPtr);
/* Enable exceptions. */
Xil_ExceptionEnable();
return XST_SUCCESS;
}
/******************************************************************************/
/**
* This function is used to override the driver's default sleep functionality.
* For MicroBlaze systems, the XDp_WaitUs driver function's default behavior
* is to use the MB_Sleep function from microblaze_sleep.h, which is implemented
* in software and only has millisecond accuracy. For this reason, using a
* hardware timer is preferrable. For ARM/Zynq SoC systems, the SoC's timer is
* used - XDp_WaitUs will ignore this custom timer handler.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note Use the XDp_SetUserTimerHandler driver function to set this
* function as the handler for when the XDp_WaitUs driver
* function is called.
*
*******************************************************************************/
static void Dprx_CustomWaitUs(void *InstancePtr, u32 MicroSeconds)
{
XDp *XDp_InstancePtr = (XDp *)InstancePtr;
u32 TimerVal;
XTmrCtr_Start(XDp_InstancePtr->UserTimerPtr, 0);
/* Wait specified number of useconds. */
do {
TimerVal = XTmrCtr_GetValue(XDp_InstancePtr->UserTimerPtr, 0);
}
while (TimerVal < (MicroSeconds *
(XDp_InstancePtr->Config.SAxiClkHz / 1000000)));
XTmrCtr_Stop(XDp_InstancePtr->UserTimerPtr, 0);
}
/******************************************************************************/
/**
* This function is used to reset video output for this example.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void Dprx_ResetVideoOutput(void *InstancePtr)
{
xil_printf("\tDisabling the display timing generator.\n");
XDp_RxDtgDis(InstancePtr);
xil_printf("\tResetting the video output pipeline.\n");
/* This is hardware system specific - it is up to the user to implement
* this function if needed. */
Dprx_VidpipeReset();
/*******************/
xil_printf("\tConfiguring the video output pipeline.\n");
/* This is hardware system specific - it is up to the user to implement
* this function if needed. */
Dprx_VidpipeConfig(InstancePtr);
/*******************/
xil_printf("\tRe-enabling the display timing generator.\n");
XDp_RxDtgEn(InstancePtr);
}
/******************************************************************************/
/**
* This function will present the resolution of the incoming video stream.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note The resolution will be rounded up to the nearest resolution
* present in the XVidC_VideoTimingModes table.
*
*******************************************************************************/
static void Dprx_DetectResolution(void *InstancePtr)
{
u32 DpHres, DpVres;
u32 GetResCount = 0;
do {
DpHres = (XDp_ReadReg(((XDp *)InstancePtr)->Config.BaseAddr,
XDP_RX_MSA_HRES));
DpVres = (XDp_ReadReg(((XDp *)InstancePtr)->Config.BaseAddr,
XDP_RX_MSA_VHEIGHT));
GetResCount++;
XDp_WaitUs(InstancePtr, 1000);
} while (((DpHres == 0) || (DpVres == 0)) && (GetResCount < 2000));
xil_printf("\n*** Detected resolution: %d x %d ***\n", DpHres, DpVres);
}
/******************************************************************************/
/**
* This function is the callback function for when a video mode chang interrupt
* occurs.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void Dprx_InterruptHandlerVmChange(void *InstancePtr)
{
u32 Status;
xil_printf("> Interrupt: video mode change.\n");
Status = XDp_RxCheckLinkStatus(InstancePtr);
if ((Status == XST_SUCCESS) && (VBlankCount >= 20)) {
Dprx_ResetVideoOutput(InstancePtr);
Dprx_DetectResolution(InstancePtr);
}
}
/******************************************************************************/
/**
* This function is the callback function for when the power state interrupt
* occurs.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void Dprx_InterruptHandlerPowerState(void *InstancePtr)
{
xil_printf("> Interrupt: power state change request.\n");
}
/******************************************************************************/
/**
* This function is the callback function for when a no video interrupt occurs.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void Dprx_InterruptHandlerNoVideo(void *InstancePtr)
{
xil_printf("> Interrupt: no-video flags in the VBID field after active "
"video has been received.\n");
}
/******************************************************************************/
/**
* This function is the callback function for when a vertical blanking interrupt
* occurs.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void Dprx_InterruptHandlerVBlank(void *InstancePtr)
{
u32 Status;
if (VBlankEnable) {
VBlankCount++;
xil_printf("> Interrupt: vertical blanking (frame %d).\n",
VBlankCount);
/* Wait until 20 frames have been received before forwarding or
* outputting any video stream. */
if (VBlankCount >= 20) {
VBlankEnable = 0;
XDp_RxInterruptDisable(InstancePtr,
XDP_RX_INTERRUPT_MASK_VBLANK_MASK);
Status = XDp_RxCheckLinkStatus(InstancePtr);
if (Status == XST_SUCCESS) {
Dprx_ResetVideoOutput(InstancePtr);
Dprx_DetectResolution(InstancePtr);
}
}
}
}
/******************************************************************************/
/**
* This function is the callback function for when a training lost interrupt
* occurs.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void Dprx_InterruptHandlerTrainingLost(void *InstancePtr)
{
xil_printf("> Interrupt: training lost.\n");
/* Re-enable vertical blanking interrupt and counter. */
VBlankEnable = 1;
XDp_RxInterruptEnable(InstancePtr, XDP_RX_INTERRUPT_MASK_VBLANK_MASK);
VBlankCount = 0;
xil_printf("\tDisabling the display timing generator.\n");
XDp_RxDtgDis(InstancePtr);
xil_printf("\tResetting the video output pipeline.\n");
/* This is hardware system specific - it is up to the user to implement
* this function if needed. */
Dprx_VidpipeReset();
/*******************/
}
/******************************************************************************/
/**
* This function is the callback function for when a valid video interrupt
* occurs.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void Dprx_InterruptHandlerVideo(void *InstancePtr)
{
xil_printf("> Interrupt: a valid video frame is detected on main "
"link.\n");
}
/******************************************************************************/
/**
* This function is the callback function for when a training done interrupt
* occurs.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void Dprx_InterruptHandlerTrainingDone(void *InstancePtr)
{
xil_printf("> Interrupt: training done.\n");
}
/******************************************************************************/
/**
* This function is the callback function for when a bandwidth change interrupt
* occurs.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void Dprx_InterruptHandlerBwChange(void *InstancePtr)
{
xil_printf("> Interrupt: bandwidth change.\n");
}
/******************************************************************************/
/**
* This function is the callback function for when a training pattern 1
* interrupt occurs.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void Dprx_InterruptHandlerTp1(void *InstancePtr)
{
xil_printf("> Interrupt: training pattern 1.\n");
}
/******************************************************************************/
/**
* This function is the callback function for when a training pattern 2
* interrupt occurs.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void Dprx_InterruptHandlerTp2(void *InstancePtr)
{
xil_printf("> Interrupt: training pattern 2.\n");
}
/******************************************************************************/
/**
* This function is the callback function for when a training pattern 3
* interrupt occurs.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void Dprx_InterruptHandlerTp3(void *InstancePtr)
{
xil_printf("> Interrupt: training pattern 3.\n");
}

View file

@ -0,0 +1,137 @@
/*******************************************************************************
*
* Copyright (C) 2014 - 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 xdp_selftest_example.c
*
* Contains a design example using the XDp driver. It performs a self test on
* the DisplayPort TX/RX core that will compare many of the DisplayPort core's
* registers against their default reset values.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 01/20/15 Initial creation.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xdp.h"
#include "xparameters.h"
/**************************** Constant Definitions ****************************/
#define DP_DEVICE_ID XPAR_DISPLAYPORT_0_DEVICE_ID
/**************************** Function Prototypes *****************************/
u32 Dp_SelfTestExample(XDp *InstancePtr, u16 DeviceId);
/*************************** Variable Declarations ****************************/
XDp DpInstance;
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function is the main function of the XDp selftest example.
*
* @param None.
*
* @return
* - XST_SUCCESS if the self test example passed.
* - XST_FAILURE if the self test example was unsuccessful - the
* DisplayPort TX's registers do not match their default values
* or no DisplayPort TX instance was found.
*
* @note None.
*
*******************************************************************************/
int main(void)
{
u32 Status;
Status = Dp_SelfTestExample(&DpInstance, DP_DEVICE_ID);
if (Status != XST_SUCCESS) {
xil_printf("XDp_SelfTest failed, check register values.\n");
return XST_FAILURE;
}
xil_printf("XDp_SelfTest passed.\n");
return Status;
}
/******************************************************************************/
/**
* The main entry point for the selftest example using the XDp driver. This
* function will check whether or not the DisplayPort TX's registers are at
* their default reset values to ensure that the core is in a known and working
* state.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param DeviceId is the unique device ID of the DisplayPort TX core
* instance.
*
* @return
* - XST_SUCCESS if the DisplayPort TX's registers are at their
* default reset values.
* - XST_FAILURE if the DisplayPort TX's registers do not match
* their default values or no DisplayPort TX instance was found.
*
* @note None.
*
*******************************************************************************/
u32 Dp_SelfTestExample(XDp *InstancePtr, u16 DeviceId)
{
u32 Status;
XDp_Config *ConfigPtr;
/* Obtain the device configuration for the DisplayPort TX core. */
ConfigPtr = XDp_LookupConfig(DeviceId);
if (!ConfigPtr) {
return XST_FAILURE;
}
/* Copy the device configuration into the InstancePtr's Config
* structure. */
XDp_CfgInitialize(InstancePtr, ConfigPtr, ConfigPtr->BaseAddr);
/* Run the self test. */
Status = XDp_SelfTest(InstancePtr);
return Status;
}

View file

@ -0,0 +1,268 @@
/*******************************************************************************
*
* Copyright (C) 2014 - 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 xdp_tx_audio_example.c
*
* Contains a design example using the XDp driver (operating in TX mode) to
* train the main link and to display video. In this example application, the
* sequence to enable audio is illustrated.
*
* @note This example requires an audio source such as an S/PDIF instance
* to be part of the hardware system. See XAPP1178 for reference.
* @note This example requires that the audio enable configuration
* parameter for DisplayPort be turned on when creating the
* hardware design.
* @note For this example to output audio, the user will need to
* implement initialization of the system (Dptx_PlatformInit),
* configuration of the audio source (Dptx_ConfigureAudioSrc) and,
* depending on the hardware system, will need to implement sending
* of an info frame (Dptx_AudioSendInfoFrame). See XAPP1178 and the
* IP documentation for reference.
* @note For this example to display output, after training is complete,
* the user will need to implement configuration of the video
* stream source in order to provide the DisplayPort core with
* input (Dptx_StreamSrc* - called in xdp_tx_example_common.c). See
* XAPP1178 for reference.
* @note The functions Dptx_PlatformInit and Dptx_StreamSrc* are declared
* extern in xdp_tx_example_common.h and are left up to the user to
* implement. The functions Dptx_ConfigureAudioSrc and
* Dptx_AudioSendInfoFrame are present in this file and are also
* left for the user to implement.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 01/20/15 Initial creation.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xdp_tx_example_common.h"
/**************************** Function Prototypes *****************************/
u32 Dptx_AudioExample(XDp *InstancePtr, u16 DeviceId);
static void Dptx_AudioInit(XDp *InstancePtr);
static void Dptx_ConfigureAudioSrc(XDp *InstancePtr);
static void Dptx_AudioSendInfoFrame(XDp *InstancePtr);
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function is the main function of the XDp audio example.
*
* @param None.
*
* @return
* - XST_SUCCESS if the audio example finished successfully.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
int main(void)
{
u32 Status;
/* Run the XDp audio example. */
Status = Dptx_AudioExample(&DpInstance, DPTX_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
* The main entry point for the audio example using the XDp driver. This
* function will set up audio, initiate link training, and a video stream will
* start being sent over the main link.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param DeviceId is the unique device ID of the DisplayPort TX core
* instance.
*
* @return
* - XST_SUCCESS if the system was set up correctly and link
* training was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
u32 Dptx_AudioExample(XDp *InstancePtr, u16 DeviceId)
{
u32 Status;
/* Use single-stream transport (SST) mode for this example. Audio is
* not supported in multi-stream transport (MST) mode. */
XDp_TxMstCfgModeDisable(InstancePtr);
/* Do platform initialization here. This is hardware system specific -
* it is up to the user to implement this function. */
Dptx_PlatformInit();
/*******************/
Status = Dptx_SetupExample(InstancePtr, DeviceId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Initialize DisplayPort audio. */
Dptx_AudioInit(InstancePtr);
XDp_TxEnableTrainAdaptive(InstancePtr, TRAIN_ADAPTIVE);
XDp_TxSetHasRedriverInPath(InstancePtr, TRAIN_HAS_REDRIVER);
/* A sink monitor must be connected at this point. See the polling or
* interrupt examples for how to wait for a connection event. */
Status = Dptx_Run(InstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
* This function will set up audio in the DisplayPort TX. The user will need
* to implement configuration of the audio stream and, if needed, sending of
* the info frame.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note The user needs to implement the Dptx_ConfigureAudioSrc and
* the Dptx_AudioSendInfoFrame functions to fulfill audio
* initialization.
*
*******************************************************************************/
static void Dptx_AudioInit(XDp *InstancePtr)
{
u32 Fs;
u32 MAud;
u32 NAud;
u32 NumChs;
/* Disable audio in the DisplayPort TX. This will also flush the buffers
* in the DisplayPort TX and set MUTE bit in VB-ID. */
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_TX_AUDIO_CONTROL, 0x0);
/* Configure the audio source (the S/PDIF controller). It is up to the
* user to implement this function. */
Dptx_ConfigureAudioSrc(InstancePtr);
/*******************/
/* Write audio info frame as per user requirements. This may be optional
* for some systems. 8 writes are required to register
* XDP_TX_AUDIO_INFO_DATA. It is up to the user to implement this
* function. */
Dptx_AudioSendInfoFrame(InstancePtr);
/*******************/
Fs = 48; /* KHz (32 | 44.1 | 48) */
if (InstancePtr->TxInstance.LinkConfig.LinkRate ==
XDP_TX_LINK_BW_SET_540GBPS) {
MAud = 512 * Fs;
}
else if (InstancePtr->TxInstance.LinkConfig.LinkRate ==
XDP_TX_LINK_BW_SET_270GBPS) {
MAud = 512 * Fs;
}
else if (InstancePtr->TxInstance.LinkConfig.LinkRate ==
XDP_TX_LINK_BW_SET_162GBPS) {
MAud = 512 * Fs;
}
/* Write the channel count. The value is (actual count - 1). */
NumChs = 2;
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_TX_AUDIO_CHANNELS,
NumChs - 1);
/* NAud = 540000 | 270000 | 162000 */
NAud = 27 * InstancePtr->TxInstance.LinkConfig.LinkRate * 1000;
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_TX_AUDIO_MAUD, MAud);
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_TX_AUDIO_NAUD, NAud);
/* Enable audio in the DisplayPort TX. */
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_TX_AUDIO_CONTROL,
0x1);
}
/******************************************************************************/
/**
* This function needs to configure the audio source.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note The user needs to implement this. See XAPP1178 and the IP
* documentation for reference.
*
*******************************************************************************/
static void Dptx_ConfigureAudioSrc(XDp *InstancePtr)
{
xil_printf("Dptx_ConfigureAudioSrc: User defined function here.\n");
}
/******************************************************************************/
/**
* This function needs to send an info frame as per user requirements.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note The user needs to implement this. See XAPP1178 and the IP
* documentation for reference.
* @note This may be optional for some systems.
* @note A sequence of 8 writes are required to register
* XDP_TX_AUDIO_INFO_DATA. See XAPP1178 and the IP documentation
* for reference.
*
*******************************************************************************/
static void Dptx_AudioSendInfoFrame(XDp *InstancePtr)
{
xil_printf("Dptx_AudioSendInfoFrame: User defined function here.\n");
}

View file

@ -0,0 +1,349 @@
/*******************************************************************************
*
* Copyright (C) 2014 - 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 xdp_tx_example_common.c
*
* Contains a design example using the XDp driver (operating in TX mode). It
* performs a self test on the DisplayPort TX core by training the main link at
* the maximum common capabilities between the TX and RX and checking the lane
* status.
*
* @note The DisplayPort TX core does not work alone - video/audio
* sources need to be set up in the system correctly, as well as
* setting up the output path (for example, configuring the
* hardware system with the DisplayPort TX core output to an FMC
* card with DisplayPort output capabilities. Some platform
* initialization will need to happen prior to calling XDp driver
* functions. See XAPP1178 as a reference.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 01/20/15 Initial creation.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xdp_tx_example_common.h"
/**************************** Function Prototypes *****************************/
static void Dptx_StartVideoStream(XDp *InstancePtr);
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function will configure and establish a link with the receiver device,
* afterwards, a video stream will start to be sent over the main link.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param LaneCount is the number of lanes to use over the main link.
* @param LinkRate is the link rate to use over the main link.
*
* @return
* - XST_SUCCESS if main link was successfully established.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
u32 Dptx_Run(XDp *InstancePtr)
{
u32 Status;
/* Configure and establish a link. */
Status = Dptx_StartLink(InstancePtr);
if (Status == XST_SUCCESS) {
/* Start the video stream. */
Dptx_StartVideoStream(InstancePtr);
} else {
xil_printf("<-- Failed to establish/train the link.\n");
return XST_FAILURE;
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
* This function will setup and initialize the DisplayPort TX core. The core's
* configuration parameters will be retrieved based on the configuration
* to the DisplayPort TX core instance with the specified device ID.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param DeviceId is the unique device ID of the DisplayPort TX core
* instance.
*
* @return
* - XST_SUCCESS if the device configuration was found and obtained
* and if the main link was successfully established.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
u32 Dptx_SetupExample(XDp *InstancePtr, u16 DeviceId)
{
XDp_Config *ConfigPtr;
u32 Status;
/* Obtain the device configuration for the DisplayPort TX core. */
ConfigPtr = XDp_LookupConfig(DeviceId);
if (!ConfigPtr) {
return XST_FAILURE;
}
/* Copy the device configuration into the InstancePtr's Config
* structure. */
XDp_CfgInitialize(InstancePtr, ConfigPtr, ConfigPtr->BaseAddr);
/* Initialize the DisplayPort TX core. */
Status = XDp_Initialize(InstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
* This function will configure and establish a link with the receiver device.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return
* - XST_SUCCESS the if main link was successfully established.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
u32 Dptx_StartLink(XDp *InstancePtr)
{
u32 VsLevelTx;
u32 PeLevelTx;
u32 Status;
u8 LaneCount;
u8 LinkRate;
/* Obtain the capabilities of the RX device by reading the monitor's
* DPCD. */
Status = XDp_TxGetRxCapabilities(InstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#if (TRAIN_USE_MAX_LINK == 1)
LaneCount = InstancePtr->TxInstance.LinkConfig.MaxLaneCount;
LinkRate = InstancePtr->TxInstance.LinkConfig.MaxLinkRate;
#else
LaneCount = TRAIN_USE_LANE_COUNT;
LinkRate = TRAIN_USE_LINK_RATE;
#endif
/* Check if the link is already trained */
Status = XDp_TxCheckLinkStatus(InstancePtr, LaneCount);
if (Status == XST_SUCCESS) {
xil_printf("-> Link is already trained on %d lanes.\n",
LaneCount);
if (XDp_ReadReg(InstancePtr->Config.BaseAddr,
XDP_TX_LINK_BW_SET) == LinkRate) {
xil_printf("-> Link needs to be re-trained %d Mbps.\n",
(270 * LinkRate));
}
else {
xil_printf("-> Link is already trained at %d Mbps.\n",
(270 * LinkRate));
return XST_SUCCESS;
}
}
else if (Status == XST_FAILURE) {
xil_printf("-> Needs training.\n");
}
else {
/* Either a connection does not exist or the supplied lane count
* is invalid. */
xil_printf("-> Error checking link status.\n");
return XST_FAILURE;
}
XDp_TxSetEnhancedFrameMode(InstancePtr, 1);
XDp_TxSetDownspread(InstancePtr, 0);
#if (TRAIN_USE_MAX_LINK == 1)
/* Configure the main link based on the maximum common capabilities of
* the DisplayPort TX core and the receiver device. */
Status = XDp_TxCfgMainLinkMax(InstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#else
XDp_TxSetLinkRate(InstancePtr, LinkRate);
XDp_TxSetLaneCount(InstancePtr, LaneCount);
#endif
/* Train the link. */
xil_printf("******************************************\n");
Status = XDp_TxEstablishLink(InstancePtr);
if (Status != XST_SUCCESS) {
xil_printf("!!! Training failed !!!\n");
xil_printf("******************************************\n");
return XST_FAILURE;
}
VsLevelTx = XDp_ReadReg(InstancePtr->Config.BaseAddr,
XDP_TX_PHY_VOLTAGE_DIFF_LANE_0);
PeLevelTx = XDp_ReadReg(InstancePtr->Config.BaseAddr,
XDP_TX_PHY_POSTCURSOR_LANE_0);
xil_printf("!!! Training passed at LR:0x%02lx LC:%d !!!\n",
InstancePtr->TxInstance.LinkConfig.LinkRate,
InstancePtr->TxInstance.LinkConfig.LaneCount);
xil_printf("VS:%d (TX:%d) PE:%d (TX:%d)\n",
InstancePtr->TxInstance.LinkConfig.VsLevel, VsLevelTx,
InstancePtr->TxInstance.LinkConfig.PeLevel, PeLevelTx);
xil_printf("******************************************\n");
return XST_SUCCESS;
}
/******************************************************************************/
/**
* This function will start sending a video stream over the main link. The
* settings to be used are as follows:
* - 8 bits per color.
* - Video timing and screen resolution used:
* - The connected monitor's preferred timing is used to determine the
* video resolution (and associated timings) for the stream.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note The Dptx_StreamSrc* are intentionally left for the user to
* implement since configuration of the stream source is
* application-specific.
* @note The Extended Display Identification Data (EDID) is read in order
* to obtain the video resolution and timings. If this read fails,
* a resolution of 640x480 is used at a refresh rate of 60Hz.
*
*******************************************************************************/
static void Dptx_StartVideoStream(XDp *InstancePtr)
{
u32 Status;
u8 Edid[XDP_EDID_BLOCK_SIZE];
/* Set the bits per color. If not set, the default is 6. */
XDp_TxCfgMsaSetBpc(InstancePtr, XDP_TX_STREAM_ID1, 8);
/* Set synchronous clock mode. */
XDp_TxCfgMsaEnSynchClkMode(InstancePtr, XDP_TX_STREAM_ID1, 1);
XDp_TxClearMsaValues(InstancePtr, XDP_TX_STREAM_ID1);
XDp_TxClearMsaValues(InstancePtr, XDP_TX_STREAM_ID2);
XDp_TxClearMsaValues(InstancePtr, XDP_TX_STREAM_ID3);
XDp_TxClearMsaValues(InstancePtr, XDP_TX_STREAM_ID4);
/* Choose a method for selecting the video mode. There are 3 ways to do this:
* 1) Use the preferred timing from the monitor's EDID:
* u8 Edid[XDP_EDID_BLOCK_SIZE];
* XDp_TxGetEdid(InstancePtr, Edid);
* XDp_TxCfgMsaUseEdidPreferredTiming(InstancePtr, XDP_TX_STREAM_ID1,
* Edid);
*
* 2) Use a standard video timing mode (see mode_table.h):
* XDp_TxCfgMsaUseStandardVideoMode(InstancePtr, XDP_TX_STREAM_ID1,
XVIDC_VM_640x480_60_P);
*
* 3) Use a custom configuration for the main stream attributes (MSA):
* XDp_TxMainStreamAttributes MsaConfigCustom;
* MsaConfigCustom.Dmt.HResolution = 1280;
* MsaConfigCustom.Dmt.VResolution = 1024;
* MsaConfigCustom.Dmt.PixelClkKhz = 108000;
* MsaConfigCustom.Dmt.HSyncPolarity = 0;
* MsaConfigCustom.Dmt.VSyncPolarity = 0;
* MsaConfigCustom.Dmt.HFrontPorch = 48;
* MsaConfigCustom.Dmt.HSyncPulseWidth = 112;
* MsaConfigCustom.Dmt.HBackPorch = 248;
* MsaConfigCustom.Dmt.VFrontPorch = 1;
* MsaConfigCustom.Dmt.VSyncPulseWidth = 3;
* MsaConfigCustom.Dmt.VBackPorch = 38;
* XDp_TxCfgMsaUseCustom(InstancePtr, XDP_TX_STREAM_ID1,
* &MsaConfigCustom, 1);
*
* To override the user pixel width:
* InstancePtr->TxInstance.MsaConfig[_STREAM#_].OverrideUserPixelWidth = 1;
* InstancePtr->TxInstance.MsaConfig[_STREAM#_].UserPixelWidth =
* _DESIRED_VALUE_;
* Then, use one of the methods above to calculate the rest of the MSA.
*/
Status = XDp_TxGetEdid(InstancePtr, Edid);
if (Status == XST_SUCCESS) {
XDp_TxCfgMsaUseEdidPreferredTiming(InstancePtr,
XDP_TX_STREAM_ID1, Edid);
}
else {
XDp_TxCfgMsaUseStandardVideoMode(InstancePtr, XDP_TX_STREAM_ID1,
XVIDC_VM_640x480_60_P);
}
/* Disable MST for this example. */
XDp_TxMstDisable(InstancePtr);
/* Disable main stream to force sending of IDLE patterns. */
XDp_TxDisableMainLink(InstancePtr);
/* Reset the transmitter. */
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_TX_SOFT_RESET,
XDP_TX_SOFT_RESET_VIDEO_STREAM_ALL_MASK);
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_TX_SOFT_RESET, 0x0);
/* Set the DisplayPort TX video mode. */
XDp_TxSetVideoMode(InstancePtr, XDP_TX_STREAM_ID1);
/* Configure video stream source or generator here. These function need
* to be implemented in order for video to be displayed and is hardware
* system specific. It is up to the user to implement these
* functions. */
Dptx_StreamSrcSetup(InstancePtr);
Dptx_StreamSrcConfigure(InstancePtr);
Dptx_StreamSrcSync(InstancePtr);
/*********************************/
XDp_TxEnableMainLink(InstancePtr);
}

View file

@ -0,0 +1,135 @@
/*******************************************************************************
*
* Copyright (C) 2014 - 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 xdp_tx_example_common.h
*
* Contains a design example using the XDp driver (operating in TX mode). It
* performs a self test on the DisplayPort TX core by training the main link at
* the maximum common capabilities between the TX and RX and checking the lane
* status.
*
* @note The DisplayPort TX core does not work alone - video/audio
* sources need to be set up in the system correctly, as well as
* setting up the output path (for example, configuring the
* hardware system with the DisplayPort TX core output to an FMC
* card with DisplayPort output capabilities. Some platform
* initialization will need to happen prior to calling XDp driver
* functions. See XAPP1178 as a reference.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 01/20/15 Initial creation.
* </pre>
*
*******************************************************************************/
#ifndef XDP_TX_EXAMPLE_COMMON_H_
/* Prevent circular inclusions by using protection macros. */
#define XDP_TX_EXAMPLE_COMMON_H_
/******************************* Include Files ********************************/
#include "xdp.h"
#include "xil_printf.h"
#include "xparameters.h"
/**************************** Constant Definitions ****************************/
/* The unique device ID of the DisplayPort TX core instance to be used with the
* examples. */
#define DPTX_DEVICE_ID XPAR_DISPLAYPORT_0_DEVICE_ID
/* If set to 1, the link training process will continue training despite failing
* by attempting training at a reduced link rate. It will also continue
* attempting to train the link at a reduced lane count if needed. With this
* option enabled, link training will return failure only when all link rate and
* lane count combinations have been exhausted - that is, training fails using
* 1-lane and a 1.62Gbps link rate.
* If set to 0, link training will return failure if the training failed using
* the current lane count and link rate settings.
* TRAIN_ADAPTIVE is used by the examples as input to the
* XDp_TxEnableTrainAdaptive driver function. */
#define TRAIN_ADAPTIVE 1
/* A value of 1 is used to indicate that the DisplayPort output path has a
* redriver on the board that adjusts the voltage swing and pre-emphasis levels
* that are outputted from the FPGA. If this is the case, the voltage swing and
* pre-emphasis values supplied to the DisplayPort TX core will be evenly
* distributed among the available levels as specified in the IP documentation.
* Otherwise, a value of 0 is used to indicate that no redriver is present. In
* order to meet the necessary voltage swing and pre-emphasis levels required by
* a DisplayPort RX device, the level values specified to the DisplayPort TX
* core will require some compensation.
* TRAIN_HAS_REDRIVER is used by the examples as input to the
* XDp_TxSetHasRedriverInPath driver function.
* Note: There are 16 possible voltage swing levels and 32 possible pre-emphasis
* levels in the DisplayPort TX core that will be mapped to 4 possible
* voltage swing and 4 possible pre-emphasis levels in the RX device. */
#define TRAIN_HAS_REDRIVER 1
/* The link rate setting to begin link training with. Valid values are:
* XDP_TX_LINK_BW_SET_540GBPS, XDP_TX_LINK_BW_SET_270GBPS, and
* XDP_TX_LINK_BW_SET_162GBPS. */
#define TRAIN_USE_LINK_RATE XDP_TX_LINK_BW_SET_540GBPS
/* The lane count setting to begin link training with. Valid values are:
* XDP_TX_LANE_COUNT_SET_4, XDP_TX_LANE_COUNT_SET_2, and
* XDP_TX_LANE_COUNT_SET_1. */
#define TRAIN_USE_LANE_COUNT XDP_TX_LANE_COUNT_SET_4
/* If set to 1, TRAIN_USE_LINK_RATE and TRAIN_USE_LANE_COUNT will be ignored.
* Instead, the maximum common link capabilities between the DisplayPort TX core
* and the RX device will be used when establishing a link.
* If set to 0, TRAIN_USE_LINK_RATE and TRAIN_USE_LANE_COUNT will determine the
* link rate and lane count settings that the link training process will begin
* with. */
#define TRAIN_USE_MAX_LINK 1
/**************************** Function Prototypes *****************************/
extern u32 Dptx_PlatformInit(void);
extern u32 Dptx_StreamSrcSync(XDp *InstancePtr);
extern u32 Dptx_StreamSrcSetup(XDp *InstancePtr);
extern u32 Dptx_StreamSrcConfigure(XDp *InstancePtr);
u32 Dptx_SetupExample(XDp *InstancePtr, u16 DeviceId);
u32 Dptx_StartLink(XDp *InstancePtr);
u32 Dptx_Run(XDp *InstancePtr);
/*************************** Variable Declarations ****************************/
XDp DpInstance;
#endif /* XDP_TX_EXAMPLE_COMMON_H_ */

View file

@ -0,0 +1,352 @@
/*******************************************************************************
*
* Copyright (C) 2014 - 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 xdp_tx_intr_example.c
*
* Contains a design example using the XDp driver (operating in TX mode) with
* interrupts. Upon Hot-Plug-Detect (HPD - DisplayPort cable is
* plugged/unplugged or the monitor is turned on/off), the main link will be
* trained.
*
* @note This example requires an interrupt controller connected to the
* processor and the DisplayPort TX core in the system.
* @note For this example to display output, the user will need to
* implement initialization of the system (Dptx_PlatformInit) and,
* after training is complete, implement configuration of the video
* stream source in order to provide the DisplayPort core with
* input (Dptx_StreamSrc* - called in xdp_tx_example_common.c). See
* XAPP1178 for reference.
* @note The functions Dptx_PlatformInit and Dptx_StreamSrc* are declared
* extern in xdp_tx_example_common.h and are left up to the user to
* implement.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 01/20/15 Initial creation.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xdp_tx_example_common.h"
#ifdef XPAR_INTC_0_DEVICE_ID
/* For MicroBlaze systems. */
#include "xintc.h"
#else
/* For ARM/Zynq SoC systems. */
#include "xscugic.h"
#endif /* XPAR_INTC_0_DEVICE_ID */
/**************************** Constant Definitions ****************************/
/* The following constants map to the XPAR parameters created in the
* xparameters.h file. */
#ifdef XPAR_INTC_0_DEVICE_ID
#define DP_INTERRUPT_ID XPAR_AXI_INTC_1_DISPLAYPORT_0_AXI_INT_INTR
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
#else
#define DP_INTERRUPT_ID XPAR_FABRIC_DISPLAYPORT_0_AXI_INT_INTR
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#endif /* XPAR_INTC_0_DEVICE_ID */
/****************************** Type Definitions ******************************/
/* Depending on whether the system is a MicroBlaze or ARM/Zynq SoC system,
* different drivers and associated types will be used. */
#ifdef XPAR_INTC_0_DEVICE_ID
#define INTC XIntc
#define INTC_HANDLER XIntc_InterruptHandler
#else
#define INTC XScuGic
#define INTC_HANDLER XScuGic_InterruptHandler
#endif /* XPAR_INTC_0_DEVICE_ID */
/**************************** Function Prototypes *****************************/
u32 Dptx_IntrExample(XDp *InstancePtr, u16 DeviceId, INTC *IntcPtr,
u16 IntrId, u16 DpIntrId, XDp_IntrHandler HpdEventHandler,
XDp_IntrHandler HpdPulseHandler);
static u32 Dptx_SetupInterruptHandler(XDp *InstancePtr, INTC *IntcPtr,
u16 IntrId, u16 DpIntrId, XDp_IntrHandler HpdEventHandler,
XDp_IntrHandler HpdPulseHandler);
static void Dptx_HpdEventHandler(void *InstancePtr);
static void Dptx_HpdPulseHandler(void *InstancePtr);
/**************************** Variable Definitions ****************************/
INTC IntcInstance; /* The interrupt controller instance. */
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function is the main function of the XDptx interrupt example. If the
* DptxIntrExample function, which sets up the system succeeds, this function
* will wait for interrupts. Once a connection event or pulse is detected, link
* training will commence (if needed) and a video stream will start being sent
* over the main link.
*
* @param None.
*
* @return
* - XST_FAILURE if the interrupt example was unsuccessful - system
* setup failed.
*
* @note Unless setup failed, main will never return since
* DptxIntrExample is blocking (it is waiting on interrupts for
* Hot-Plug-Detect (HPD) events.
*
*******************************************************************************/
int main(void)
{
/* Run the XDptx interrupt example. */
Dptx_IntrExample(&DpInstance, DPTX_DEVICE_ID,
&IntcInstance, INTC_DEVICE_ID, DP_INTERRUPT_ID,
&Dptx_HpdEventHandler, &Dptx_HpdPulseHandler);
return XST_FAILURE;
}
/******************************************************************************/
/**
* The main entry point for the interrupt example using the XDp driver. This
* function will set up the system with interrupts and set up the Hot-Plug-Event
* (HPD) handlers.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param DeviceId is the unique device ID of the DisplayPort TX core
* instance.
* @param IntcPtr is a pointer to the interrupt instance.
* @param IntrId is the unique device ID of the interrupt controller.
* @param DpIntrId is the interrupt ID of the DisplayPort TX connection to
* the interrupt controller.
* @param HpdEventHandler is a pointer to the handler called when an HPD
* event occurs.
* @param HpdPulseHandler is a pointer to the handler called when an HPD
* pulse occurs.
*
* @return
* - XST_FAILURE if the system setup failed.
* - XST_SUCCESS should never return since this function, if setup
* was successful, is blocking.
*
* @note If system setup was successful, this function is blocking in
* order to illustrate interrupt handling taking place for HPD
* events.
*
*******************************************************************************/
u32 Dptx_IntrExample(XDp *InstancePtr, u16 DeviceId, INTC *IntcPtr,
u16 IntrId, u16 DpIntrId, XDp_IntrHandler HpdEventHandler,
XDp_IntrHandler HpdPulseHandler)
{
u32 Status;
/* Use single-stream transport (SST) mode for this example. */
XDp_TxMstCfgModeDisable(InstancePtr);
/* Do platform initialization here. This is hardware system specific -
* it is up to the user to implement this function. */
Dptx_PlatformInit();
/******************/
Status = Dptx_SetupExample(InstancePtr, DeviceId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XDp_TxEnableTrainAdaptive(InstancePtr, TRAIN_ADAPTIVE);
XDp_TxSetHasRedriverInPath(InstancePtr, TRAIN_HAS_REDRIVER);
/* Setup interrupt handling in the system. */
Status = Dptx_SetupInterruptHandler(InstancePtr, IntcPtr, IntrId,
DpIntrId, HpdEventHandler, HpdPulseHandler);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Do not return in order to allow interrupt handling to run. HPD events
* (connect, disconnect, and pulse) will be detected and handled. */
while (1);
return XST_SUCCESS;
}
/******************************************************************************/
/**
* This function sets up the interrupt system such that interrupts caused by
* Hot-Plug-Detect (HPD) events and pulses are handled. This function is
* application-specific for systems that have an interrupt controller connected
* to the processor. The user should modify this function to fit the
* application.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param IntcPtr is a pointer to the interrupt instance.
* @param IntrId is the unique device ID of the interrupt controller.
* @param DpIntrId is the interrupt ID of the DisplayPort TX connection to
* the interrupt controller.
* @param HpdEventHandler is a pointer to the handler called when an HPD
* event occurs.
* @param HpdPulseHandler is a pointer to the handler called when an HPD
* pulse occurs.
*
* @return
* - XST_SUCCESS if the interrupt system was successfully set up.
* - XST_FAILURE otherwise.
*
* @note An interrupt controller must be present in the system, connected
* to the processor and the DisplayPort TX core.
*
*******************************************************************************/
static u32 Dptx_SetupInterruptHandler(XDp *InstancePtr, INTC *IntcPtr,
u16 IntrId, u16 DpIntrId, XDp_IntrHandler HpdEventHandler,
XDp_IntrHandler HpdPulseHandler)
{
u32 Status;
/* Set the HPD interrupt handlers. */
XDp_TxSetHpdEventHandler(InstancePtr, HpdEventHandler, InstancePtr);
XDp_TxSetHpdPulseHandler(InstancePtr, HpdPulseHandler, InstancePtr);
/* Initialize interrupt controller driver. */
#ifdef XPAR_INTC_0_DEVICE_ID
Status = XIntc_Initialize(IntcPtr, IntrId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#else
XScuGic_Config *IntcConfig;
IntcConfig = XScuGic_LookupConfig(IntrId);
Status = XScuGic_CfgInitialize(IntcPtr, IntcConfig,
IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XScuGic_SetPriorityTriggerType(IntcPtr, DpIntrId, 0xA0, 0x1);
#endif /* XPAR_INTC_0_DEVICE_ID */
/* Connect the device driver handler that will be called when an
* interrupt for the device occurs, the handler defined above performs
* the specific interrupt processing for the device. */
#ifdef XPAR_INTC_0_DEVICE_ID
Status = XIntc_Connect(IntcPtr, DpIntrId,
(XInterruptHandler)XDp_InterruptHandler, InstancePtr);
#else
Status = XScuGic_Connect(IntcPtr, DpIntrId,
(Xil_InterruptHandler)XDp_InterruptHandler, InstancePtr);
#endif /* XPAR_INTC_0_DEVICE_ID */
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Start the interrupt controller. */
#ifdef XPAR_INTC_0_DEVICE_ID
Status = XIntc_Start(IntcPtr, XIN_REAL_MODE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XIntc_Enable(IntcPtr, DpIntrId);
#else
XScuGic_Enable(IntcPtr, DpIntrId);
#endif /* XPAR_INTC_0_DEVICE_ID */
/* Initialize the exception table. */
Xil_ExceptionInit();
/* Register the interrupt controller handler with the exception table. */
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)INTC_HANDLER, IntcPtr);
/* Enable exceptions. */
Xil_ExceptionEnable();
return XST_SUCCESS;
}
/******************************************************************************/
/**
* This function is called when a Hot-Plug-Detect (HPD) event is received by the
* DisplayPort TX core. The XDP_TX_INTERRUPT_STATUS_HPD_EVENT_MASK bit of the
* core's XDP_TX_INTERRUPT_STATUS register indicates that an HPD event has
* occurred.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note Use the XDp_TxSetHpdEventHandler driver function to set this
* function as the handler for HPD pulses.
*
*******************************************************************************/
static void Dptx_HpdEventHandler(void *InstancePtr)
{
XDp *XDp_InstancePtr = (XDp *)InstancePtr;
if (XDp_TxIsConnected(XDp_InstancePtr)) {
xil_printf("+===> HPD connection event detected.\n");
Dptx_Run(XDp_InstancePtr);
}
else {
xil_printf("+===> HPD disconnection event detected.\n\n");
}
}
/******************************************************************************/
/**
* This function is called when a Hot-Plug-Detect (HPD) pulse is received by the
* DisplayPort TX core. The XDP_TX_INTERRUPT_STATUS_HPD_PULSE_DETECTED_MASK bit
* of the core's XDP_TX_INTERRUPT_STATUS register indicates that an HPD event
* has occurred.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note Use the XDp_TxSetHpdPulseHandler driver function to set this
* function as the handler for HPD pulses.
*
*******************************************************************************/
static void Dptx_HpdPulseHandler(void *InstancePtr)
{
XDp *XDp_InstancePtr = (XDp *)InstancePtr;
xil_printf("===> HPD pulse detected.\n");
Dptx_Run(XDp_InstancePtr);
}

View file

@ -0,0 +1,387 @@
/*******************************************************************************
*
* Copyright (C) 2014 - 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 xdp_tx_mst_example.c
*
* Contains a design example using the XDp driver (operating in TX mode) in
* multi-stream transport (MST) mode.
*
* @note For this example to display output, the user will need to
* implement initialization of the system (Dptx_PlatformInit) and,
* after training is complete, implement configuration of the video
* stream source in order to provide the DisplayPort core with
* input. See XAPP1178 for reference.
* @note The functions Dptx_PlatformInit and Dptx_StreamSrc* are declared
* extern in xdp_tx_example_common.h and are left up to the user to
* implement.
* @note Some setups may require introduction of delays when sending
* sideband messages.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 01/20/15 Initial creation.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xdp_tx_example_common.h"
/**************************** Constant Definitions ****************************/
/* The maximum number of streams to enable. */
#define NUM_STREAMS 4
/* This enables topology discovery which will create a list of sinks in the
* topology. If ALLOCATE_FROM_SINKLIST is defined, the streams will sent to
* to the sinks with the corresponding index. See the function calls for
* the XDp_TxSetStreamSelectFromSinkList driver function below. */
#define ALLOCATE_FROM_SINKLIST
#ifdef ALLOCATE_FROM_SINKLIST
/* Define the mapping between sinks and streams. The sink numbers are in the
* order that they are discovered by the XDp_TxFindAccessibleDpDevices driver
* function. */
#define STREAM1_USE_SINKNUM 0
#define STREAM2_USE_SINKNUM 1
#define STREAM3_USE_SINKNUM 2
#define STREAM4_USE_SINKNUM 3
#endif
/* The video resolution from the display mode timings (DMT) table to use for
* each stream. */
#define USE_VIDEO_MODE XVIDC_VM_1920x1080_60_P
/* The color depth (bits per color component) to use for each stream. */
#define USE_BPC 8
/* Some MST configurations may require delays when sending sideband messages. By
* default, disable these delays.*/
#undef USE_DELAYS_FOR_MST
/**************************** Function Prototypes *****************************/
u32 Dptx_MstExample(XDp *InstancePtr, u16 DeviceId);
u32 Dptx_MstExampleRun(XDp *InstancePtr);
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function is the main function of the XDptx multi-stream transport (MST)
* example.
*
* @param None.
*
* @return
* - XST_FAILURE if the MST example was unsuccessful - system
* setup failed.
*
* @note Unless setup failed, main will never return since
* Dptx_MstExample is blocking.
*
*******************************************************************************/
int main(void)
{
/* Run the XDptx MST example. */
Dptx_MstExample(&DpInstance, DPTX_DEVICE_ID);
return XST_FAILURE;
}
/******************************************************************************/
/**
* The main entry point for the multi-stream transport (MST) example using the
* XDp driver. This function will either discover the topology and map streams
* to the sinks in the sink list, or map streams to relative addresses.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param DeviceId is the unique device ID of the DisplayPort TX core
* instance.
*
* @return
* - XST_FAILURE if the system setup failed.
* - XST_SUCCESS should never return since this function, if setup
* was successful, is blocking.
*
* @note If system setup was successful, this function is blocking.
*
*******************************************************************************/
u32 Dptx_MstExample(XDp *InstancePtr, u16 DeviceId)
{
u32 Status;
/* Do platform initialization here. This is hardware system specific -
* it is up to the user to implement this function. */
Dptx_PlatformInit();
/******************/
Status = Dptx_SetupExample(InstancePtr, DeviceId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
Status = XDp_TxMstCapable(InstancePtr);
if (Status != XST_SUCCESS) {
/* If the immediate downstream RX device is an MST monitor and
* the DisplayPort Configuration Data (DPCD) does not indicate
* MST capability, it is likely that the MST or DisplayPort v1.2
* option must be selected from the monitor's option menu.
* Likewise, the DisplayPort TX core must be configured to
* support MST mode. */
xil_printf("!!! Verify DisplayPort MST capabilities in the TX "
"and/or RX device.\n");
return XST_FAILURE;
}
do {
Status = Dptx_MstExampleRun(InstancePtr);
if (Status == XST_DATA_LOST) {
xil_printf("!!! Link lost... Need to re-train.\n");
}
} while (Status != XST_SUCCESS);
/* Do not return. */
xil_printf("MST example DONE.\n");
while (1);
return XST_SUCCESS;
}
/******************************************************************************/
/**
* This function trains the link and allocates stream payloads.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param DeviceId is the unique device ID of the DisplayPort TX core
* instance.
*
* @return
* - XST_SUCCESS if MST allocation was successful.
* - XST_ERROR_COUNT_MAX if the ACT trigger was lost.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
u32 Dptx_MstExampleRun(XDp *InstancePtr)
{
u32 Status;
u32 MaskVal;
u8 StreamIndex;
XVidC_VideoMode VideoMode = USE_VIDEO_MODE;
u8 Bpc = USE_BPC;
u8 NumStreams = NUM_STREAMS;
/* Limit the number of streams to configure based on the configuration
* of the DisplayPort core. */
if (NumStreams > InstancePtr->Config.NumMstStreams) {
NumStreams = InstancePtr->Config.NumMstStreams;
}
XDp_TxEnableTrainAdaptive(InstancePtr, TRAIN_ADAPTIVE);
XDp_TxSetHasRedriverInPath(InstancePtr, TRAIN_HAS_REDRIVER);
/* A DisplayPort connection must exist at this point. See the interrupt
* and polling examples for waiting for connection events. */
Status = Dptx_StartLink(InstancePtr);
if (Status != XST_SUCCESS) {
xil_printf("Link Training failed.\n");
return XST_FAILURE;
}
#ifdef USE_DELAYS_FOR_MST
InstancePtr->TxInstance.AuxDelayUs = 30000;
InstancePtr->TxInstance.SbMsgDelayUs = 100000;
#else
InstancePtr->TxInstance.AuxDelayUs = 0;
InstancePtr->TxInstance.SbMsgDelayUs = 0;
#endif
XDp_TxClearMsaValues(InstancePtr, XDP_TX_STREAM_ID1);
XDp_TxClearMsaValues(InstancePtr, XDP_TX_STREAM_ID2);
XDp_TxClearMsaValues(InstancePtr, XDP_TX_STREAM_ID3);
XDp_TxClearMsaValues(InstancePtr, XDP_TX_STREAM_ID4);
#ifdef ALLOCATE_FROM_SINKLIST
/* Run topology discovery to determine what devices are accessible to
* the DisplayPort TX. */
xil_printf("Find topology >>>\n");
InstancePtr->TxInstance.Topology.NodeTotal = 0;
InstancePtr->TxInstance.Topology.SinkTotal = 0;
Status = XDp_TxDiscoverTopology(InstancePtr);
if (Status != XST_SUCCESS) {
xil_printf("!!! A LINK_ADDRESS response from a branch device "
"in the MST topology was not successfully received.\n");
return XST_FAILURE;
}
xil_printf("<<< Find topology DONE; # of sinks found = %d.\n",
InstancePtr->TxInstance.Topology.SinkTotal);
if (NumStreams > InstancePtr->TxInstance.Topology.SinkTotal) {
NumStreams = InstancePtr->TxInstance.Topology.SinkTotal;
}
#endif
/* Enable multi-stream transport (MST) mode for this example. */
XDp_TxMstCfgModeEnable(InstancePtr);
for (StreamIndex = 0; StreamIndex < NumStreams; StreamIndex++) {
XDp_TxMstCfgStreamEnable(InstancePtr, XDP_TX_STREAM_ID1 +
StreamIndex);
}
for (StreamIndex = NumStreams; StreamIndex < 4; StreamIndex++) {
XDp_TxMstCfgStreamDisable(InstancePtr, XDP_TX_STREAM_ID1 +
StreamIndex);
}
/* Specify the DisplayPort sink devices that each enabled stream will be
* directed towards. */
#ifndef ALLOCATE_FROM_SINKLIST
/* If topology discovery is not used, specify the relative addresses of
* the DisplayPort sink devices. */
u8 Lct;
u8 Rad[15];
if (XDp_TxMstStreamIsEnabled(InstancePtr, XDP_TX_STREAM_ID1)) {
Lct = 2; Rad[0] = 8;
XDp_TxSetStreamSinkRad(InstancePtr, XDP_TX_STREAM_ID1, Lct,
Rad);
}
if (XDp_TxMstStreamIsEnabled(InstancePtr, XDP_TX_STREAM_ID2)) {
Lct = 3; Rad[0] = 1; Rad[1] = 8;
XDp_TxSetStreamSinkRad(InstancePtr, XDP_TX_STREAM_ID2, Lct,
Rad);
}
if (XDp_TxMstStreamIsEnabled(InstancePtr, XDP_TX_STREAM_ID3)) {
Lct = 4; Rad[0] = 1; Rad[1] = 1; Rad[2] = 8;
XDp_TxSetStreamSinkRad(InstancePtr, XDP_TX_STREAM_ID3, Lct,
Rad);
}
if (XDp_TxMstStreamIsEnabled(InstancePtr, XDP_TX_STREAM_ID4)) {
Lct = 4; Rad[0] = 1; Rad[1] = 1; Rad[2] = 9;
XDp_TxSetStreamSinkRad(InstancePtr, XDP_TX_STREAM_ID4, Lct,
Rad);
}
#else
/* If topology discovery is used, associate a stream number with a sink
* number from the sink list obtained during topology discovery. The
* sinks are numbered in the order that they were found during topology
* discovery. */
if (XDp_TxMstStreamIsEnabled(InstancePtr, XDP_TX_STREAM_ID1)) {
XDp_TxSetStreamSelectFromSinkList(InstancePtr,
XDP_TX_STREAM_ID1, STREAM1_USE_SINKNUM);
}
if (XDp_TxMstStreamIsEnabled(InstancePtr, XDP_TX_STREAM_ID2)) {
XDp_TxSetStreamSelectFromSinkList(InstancePtr,
XDP_TX_STREAM_ID2, STREAM2_USE_SINKNUM);
}
if (XDp_TxMstStreamIsEnabled(InstancePtr, XDP_TX_STREAM_ID3)) {
XDp_TxSetStreamSelectFromSinkList(InstancePtr,
XDP_TX_STREAM_ID3, STREAM3_USE_SINKNUM);
}
if (XDp_TxMstStreamIsEnabled(InstancePtr, XDP_TX_STREAM_ID4)) {
XDp_TxSetStreamSelectFromSinkList(InstancePtr,
XDP_TX_STREAM_ID4, STREAM4_USE_SINKNUM);
}
#endif
/* Reset MST mode in both the RX and TX. */
XDp_TxMstDisable(InstancePtr);
XDp_TxMstEnable(InstancePtr);
/* Set the main stream attributes (MSA) for each enabled stream (each
* stream has an identical configuration). Then, set the configuration
* for that stream in the corresponding DisplayPort TX registers. */
for (StreamIndex = 0; StreamIndex < 4; StreamIndex++) {
if (XDp_TxMstStreamIsEnabled(InstancePtr,
XDP_TX_STREAM_ID1 + StreamIndex)) {
XDp_TxCfgMsaSetBpc(InstancePtr, XDP_TX_STREAM_ID1 +
StreamIndex, Bpc);
XDp_TxCfgMsaEnSynchClkMode(InstancePtr,
XDP_TX_STREAM_ID1 + StreamIndex, 1);
XDp_TxCfgMsaUseStandardVideoMode(InstancePtr,
XDP_TX_STREAM_ID1 + StreamIndex, VideoMode);
XDp_TxSetVideoMode(InstancePtr, XDP_TX_STREAM_ID1 +
StreamIndex);
}
}
/* Configure video stream source or generator here. This function needs
* to be implemented in order for video to be displayed and is hardware
* system specific. It is up to the user to implement this function. */
Dptx_StreamSrcSetup(InstancePtr);
Dptx_StreamSrcConfigure(InstancePtr);
Dptx_StreamSrcSync(InstancePtr);
////////////////////////////////////
/* Mask interrupts while allocating payloads. */
MaskVal = XDp_ReadReg(InstancePtr->Config.BaseAddr,
XDP_TX_INTERRUPT_MASK);
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_TX_INTERRUPT_MASK, 0x3F);
/* Clear the payload ID table first. */
Status = XDp_TxClearPayloadVcIdTable(InstancePtr);
if (Status != XST_SUCCESS) {
return XST_DATA_LOST;
}
/* Allocate payloads. */
Status = XDp_TxAllocatePayloadStreams(InstancePtr);
if (Status != XST_SUCCESS) {
return XST_DATA_LOST;
}
/* Enable the main link. */
XDp_TxEnableMainLink(InstancePtr);
/* Unmask interrupts. */
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_TX_INTERRUPT_MASK,
MaskVal);
/* Do a final check to verify that the link wasn't lost. */
Status = XDp_TxCheckLinkStatus(InstancePtr,
InstancePtr->TxInstance.LinkConfig.LaneCount);
if (Status != XST_SUCCESS) {
XDp_WaitUs(InstancePtr, 10000);
return XST_DATA_LOST;
}
return XST_SUCCESS;
}

View file

@ -0,0 +1,201 @@
/*******************************************************************************
*
* Copyright (C) 2014 - 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 xdp_tx_poll_example.c
*
* Contains a design example using the XDp driver (operating in TX mode) with
* polling. Once the polling detects a Hot-Plug-Detect event (HPD - DisplayPort
* cable is plugged/unplugged or the monitor is turned on/off), the main link
* will be trained.
*
* @note For this example to display output, the user will need to
* implement initialization of the system (Dptx_PlatformInit) and,
* after training is complete, implement configuration of the video
* stream source in order to provide the DisplayPort core with
* input (Dptx_StreamSrc* - called in xdp_tx_example_common.c). See
* XAPP1178 for reference.
* @note The functions Dptx_PlatformInit and Dptx_StreamSrc* are declared
* extern in xdp_tx_example_common.h and are left up to the user to
* implement.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 01/20/15 Initial creation.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xdp_tx_example_common.h"
/**************************** Function Prototypes *****************************/
u32 Dptx_PollExample(XDp *InstancePtr, u16 DeviceId);
static void Dptx_HpdPoll(XDp *InstancePtr);
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function is the main function of the XDp polling example.
*
* @param None.
*
* @return
* - XST_FAILURE if the polling example was unsuccessful - system
* setup failed.
*
* @note Unless setup failed, main will never return since
* Dptx_PollExample is blocking (it is continuously polling for
* Hot-Plug-Detect (HPD) events.
*
*******************************************************************************/
int main(void)
{
/* Run the XDp polling example. */
Dptx_PollExample(&DpInstance, DPTX_DEVICE_ID);
return XST_FAILURE;
}
/******************************************************************************/
/**
* The main entry point for the polling example using the XDp driver. This
* function will set up the system. If this is successful, this example will
* begin polling the Hot-Plug-Detect (HPD) status registers for HPD events. Once
* a connection event or a pulse is detected, link training will commence (if
* needed) and a video stream will start being sent over the main link.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param DeviceId is the unique device ID of the DisplayPort TX core
* instance.
*
* @return
* - XST_FAILURE if the system setup failed.
* - XST_SUCCESS should never return since this function, if setup
* was successful, is blocking.
*
* @note If system setup was successful, this function is blocking in
* order to illustrate polling taking place for HPD events.
*
*******************************************************************************/
u32 Dptx_PollExample(XDp *InstancePtr, u16 DeviceId)
{
u32 Status;
/* Do platform initialization here. This is hardware system specific -
* it is up to the user to implement this function. */
Dptx_PlatformInit();
/******************/
Status = Dptx_SetupExample(InstancePtr, DeviceId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XDp_TxEnableTrainAdaptive(InstancePtr, TRAIN_ADAPTIVE);
XDp_TxSetHasRedriverInPath(InstancePtr, TRAIN_HAS_REDRIVER);
/* Continuously poll for HPD events. */
while (1) {
Dptx_HpdPoll(InstancePtr);
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
* This function polls the XDP_TX_INTERRUPT_SIG_STATE and
* XDP_TX_INTERRUPT_STATUS registers for Hot-Plug-Detect (HPD) events and
* handles them accordingly. If a connection or pulse event is detected, link
* training will begin (if required) and a video stream will be initiated.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void Dptx_HpdPoll(XDp *InstancePtr)
{
u32 InterruptSignalState;
u32 InterruptStatus;
u32 HpdState;
u32 HpdEvent;
u32 HpdPulseDetected;
u32 HpdDuration;
/* Read interrupt registers. */
InterruptSignalState = XDp_ReadReg(InstancePtr->Config.BaseAddr,
XDP_TX_INTERRUPT_SIG_STATE);
InterruptStatus = XDp_ReadReg(InstancePtr->Config.BaseAddr,
XDP_TX_INTERRUPT_STATUS);
/* Check for HPD events. */
HpdState = InterruptSignalState &
XDP_TX_INTERRUPT_SIG_STATE_HPD_STATE_MASK;
HpdEvent = InterruptStatus & XDP_TX_INTERRUPT_STATUS_HPD_EVENT_MASK;
HpdPulseDetected = InterruptStatus &
XDP_TX_INTERRUPT_STATUS_HPD_PULSE_DETECTED_MASK;
if (HpdPulseDetected) {
HpdDuration = XDp_ReadReg(InstancePtr->Config.BaseAddr,
XDP_TX_HPD_DURATION);
}
/* HPD event handling. */
if (HpdState && HpdEvent) {
xil_printf("+===> HPD connection event detected.\n");
/* Initiate link training. */
Dptx_Run(InstancePtr);
}
else if (HpdState && HpdPulseDetected && (HpdDuration >= 250)) {
xil_printf("===> HPD pulse detected.\n");
/* Re-train if needed. */
Dptx_Run(InstancePtr);
}
else if (!HpdState && HpdEvent) {
xil_printf("+===> HPD disconnection event detected.\n\n");
/* Disable main link. */
XDp_TxDisableMainLink(InstancePtr);
}
}

View file

@ -0,0 +1,201 @@
/*******************************************************************************
*
* Copyright (C) 2014 - 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 xdp_tx_timer_example.c
*
* Contains a design example using the XDp driver (operating in TX mode) with a
* user-defined hook for delay. The reasoning behind this is that MicroBlaze
* sleep is not very accurate without a hardware timer. For systems that have a
* hardware timer, the user may override the default MicroBlaze sleep with a
* function that will use the hardware timer.
*
* @note This example requires an AXI timer in the system.
* @note For this example to display output, the user will need to
* implement initialization of the system (Dptx_PlatformInit) and,
* after training is complete, implement configuration of the video
* stream source in order to provide the DisplayPort core with
* input (Dptx_StreamSrc* - called in xdp_tx_example_common.c). See
* XAPP1178 for reference.
* @note The functions Dptx_PlatformInit and Dptx_StreamSrc* are declared
* extern in xdp_tx_example_common.h and are left up to the user to
* implement.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 01/20/15 Initial creation.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xdp_tx_example_common.h"
#include "xtmrctr.h"
/**************************** Function Prototypes *****************************/
u32 Dptx_TimerExample(XDp *InstancePtr, u16 DeviceId,
XTmrCtr *TimerCounterPtr, XDp_TimerHandler UserSleepFunc);
static void Dptx_CustomWaitUs(void *InstancePtr, u32 MicroSeconds);
/*************************** Variable Declarations ****************************/
XTmrCtr TimerCounterInst; /* The timer counter instance. */
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function is the main function of the XDptx timer example.
*
* @param None.
*
* @return
* - XST_SUCCESS if the timer example finished successfully.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
int main(void)
{
u32 Status;
/* Run the XDptx timer example. */
Status = Dptx_TimerExample(&DpInstance, DPTX_DEVICE_ID,
&TimerCounterInst, &Dptx_CustomWaitUs);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
* The main entry point for the timer example using the XDp driver. This
* function will set up the system and the custom sleep handler. If this is
* successful, link training will commence and a video stream will start being
* sent over the main link.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param DeviceId is the unique device ID of the DisplayPort TX core
* instance.
* @param TimerCounterPtr is a pointer to the timer instance.
* @param UserSleepFunc is a pointer to the custom handler for sleep.
*
* @return
* - XST_SUCCESS if the system was set up correctly and link
* training was successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
u32 Dptx_TimerExample(XDp *InstancePtr, u16 DeviceId,
XTmrCtr *TimerCounterPtr, XDp_TimerHandler UserSleepFunc)
{
u32 Status;
/* Use single-stream transport (SST) mode for this example. */
XDp_TxMstCfgModeDisable(InstancePtr);
/* Do platform initialization here. This is hardware system specific -
* it is up to the user to implement this function. */
Dptx_PlatformInit();
/*******************/
/* Set a custom timer handler for improved delay accuracy on MicroBlaze
* systems since the driver does not assume/have a dependency on the
* system having a timer in the FPGA.
* Note: This only has an affect for MicroBlaze systems since the Zynq
* ARM SoC contains a timer, which is used when the driver calls the
* delay function. */
XDp_SetUserTimerHandler(InstancePtr, UserSleepFunc, TimerCounterPtr);
Status = Dptx_SetupExample(InstancePtr, DeviceId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XDp_TxEnableTrainAdaptive(InstancePtr, TRAIN_ADAPTIVE);
XDp_TxSetHasRedriverInPath(InstancePtr, TRAIN_HAS_REDRIVER);
/* A sink monitor must be connected at this point. See the polling or
* interrupt examples for how to wait for a connection event. */
Status = Dptx_Run(InstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
* This function is used to override the driver's default sleep functionality.
* For MicroBlaze systems, the XDp_WaitUs driver function's default behavior
* is to use the MB_Sleep function from microblaze_sleep.h, which is implemented
* in software and only has millisecond accuracy. For this reason, using a
* hardware timer is preferrable. For ARM/Zynq SoC systems, the SoC's timer is
* used - XDp_WaitUs will ignore this custom timer handler.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note Use the XDp_SetUserTimerHandler driver function to set this
* function as the handler for when the XDp_WaitUs driver
* function is called.
*
*******************************************************************************/
static void Dptx_CustomWaitUs(void *InstancePtr, u32 MicroSeconds)
{
XDp *XDp_InstancePtr = (XDp *)InstancePtr;
u32 TimerVal;
XTmrCtr_Start(XDp_InstancePtr->UserTimerPtr, 0);
/* Wait specified number of useconds. */
do {
TimerVal = XTmrCtr_GetValue(XDp_InstancePtr->UserTimerPtr, 0);
}
while (TimerVal < (MicroSeconds *
(XDp_InstancePtr->Config.SAxiClkHz / 1000000)));
XTmrCtr_Stop(XDp_InstancePtr->UserTimerPtr, 0);
}

View file

@ -0,0 +1,40 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
CC_FLAGS = $(COMPILER_FLAGS)
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
OUTS = *.o
LIBSOURCES:=*.c
INCLUDEFILES:=*.h
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
libs: banner xdp_libs clean
%.o: %.c
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
banner:
echo "Compiling dp"
xdp_libs: ${OBJECTS}
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
.PHONY: include
include: xdp_includes
xdp_includes:
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
clean:
rm -rf ${OBJECTS}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,416 @@
/*******************************************************************************
*
* 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 xdp_edid.c
*
* This file contains functions related to accessing the Extended Display
* Identification Data (EDID) of a specified sink using the XDp driver operating
* in TX mode.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 01/20/15 Initial release. TX code merged from the dptx driver.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xdp.h"
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function retrieves an immediately connected RX device's Extended Display
* Identification Data (EDID) structure.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Edid is a pointer to the Edid buffer to save to.
*
* @return
* - XST_SUCCESS if the I2C transactions to read the EDID were
* successful.
* - XST_ERROR_COUNT_MAX if the EDID read request timed out.
* - XST_DEVICE_NOT_FOUND if no RX device is connected.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
u32 XDp_TxGetEdid(XDp *InstancePtr, u8 *Edid)
{
u32 Status;
/* Verify arguments. */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertNonvoid(Edid != NULL);
/* Retrieve the base EDID block = EDID block #0. */
Status = XDp_TxGetEdidBlock(InstancePtr, Edid, 0);
return Status;
}
/******************************************************************************/
/**
* This function retrieves a remote RX device's Extended Display Identification
* Data (EDID) structure.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param LinkCountTotal is the number of DisplayPort links from the
* DisplayPort source to the target DisplayPort device.
* @param RelativeAddress is the relative address from the DisplayPort
* source to the target DisplayPort device.
* @param Edid is a pointer to the Edid buffer to save to.
*
* @return
* - XST_SUCCESS if the I2C transactions to read the EDID were
* successful.
* - XST_ERROR_COUNT_MAX if the EDID read request timed out.
* - XST_DEVICE_NOT_FOUND if no RX device is connected.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
u32 XDp_TxGetRemoteEdid(XDp *InstancePtr, u8 LinkCountTotal,
u8 *RelativeAddress, u8 *Edid)
{
u32 Status;
/* Verify arguments. */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertNonvoid(LinkCountTotal > 0);
Xil_AssertNonvoid((RelativeAddress != NULL) || (LinkCountTotal == 1));
Xil_AssertNonvoid(Edid != NULL);
/* Retrieve the base EDID block = EDID block #0. */
Status = XDp_TxGetRemoteEdidBlock(InstancePtr, Edid, 0, LinkCountTotal,
RelativeAddress);
return Status;
}
/******************************************************************************/
/**
* Retrieve an immediately connected RX device's Extended Display Identification
* Data (EDID) block given the block number. A block number of 0 represents the
* base EDID and subsequent block numbers represent EDID extension blocks.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Data is a pointer to the data buffer to save the block data to.
* @param BlockNum is the EDID block number to retrieve.
*
* @return
* - XST_SUCCESS if the block read has successfully completed with
* no errors.
* - XST_ERROR_COUNT_MAX if a time out occurred while attempting to
* read the requested block.
* - XST_DEVICE_NOT_FOUND if no RX device is connected.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
u32 XDp_TxGetEdidBlock(XDp *InstancePtr, u8 *Data, u8 BlockNum)
{
u32 Status;
u16 Offset;
/* Verify arguments. */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertNonvoid(Data != NULL);
/* Calculate the I2C offset for the specified EDID block. */
Offset = BlockNum * XDP_EDID_BLOCK_SIZE;
/* Issue the I2C read for the specified EDID block. */
Status = XDp_TxIicRead(InstancePtr, XDP_EDID_ADDR, Offset,
XDP_EDID_BLOCK_SIZE, Data);
return Status;
}
/******************************************************************************/
/**
* Retrieve a downstream DisplayPort device's Extended Display Identification
* Data (EDID) block given the block number. A block number of 0 represents the
* base EDID and subsequent block numbers represent EDID extension blocks.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Data is a pointer to the data buffer to save the block data to.
* @param BlockNum is the EDID block number to retrieve.
* @param LinkCountTotal is the total DisplayPort links connecting the
* DisplayPort TX to the targeted downstream device.
* @param RelativeAddress is the relative address from the DisplayPort
* source to the targeted DisplayPort device.
*
* @return
* - XST_SUCCESS if the block read has successfully completed with
* no errors.
* - XST_ERROR_COUNT_MAX if a time out occurred while attempting to
* read the requested block.
* - XST_DEVICE_NOT_FOUND if no RX device is connected.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
u32 XDp_TxGetRemoteEdidBlock(XDp *InstancePtr, u8 *Data, u8 BlockNum,
u8 LinkCountTotal, u8 *RelativeAddress)
{
u32 Status;
u16 Offset;
/* Verify arguments. */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertNonvoid(LinkCountTotal > 0);
Xil_AssertNonvoid((RelativeAddress != NULL) || (LinkCountTotal == 1));
Xil_AssertNonvoid(Data != NULL);
/* Calculate the I2C offset for the specified EDID block. */
Offset = BlockNum * XDP_EDID_BLOCK_SIZE;
/* Issue the I2C read for the specified EDID block. */
Status = XDp_TxRemoteIicRead(InstancePtr, LinkCountTotal,
RelativeAddress, XDP_EDID_ADDR, Offset, XDP_EDID_BLOCK_SIZE,
Data);
return Status;
}
/******************************************************************************/
/**
* Search for and retrieve a downstream DisplayPort device's Extended Display
* Identification Data (EDID) extension block of type DisplayID.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Data is a pointer to the data buffer to save the DisplayID to.
* @param LinkCountTotal is the total DisplayPort links connecting the
* DisplayPort TX to the targeted downstream device.
* @param RelativeAddress is the relative address from the DisplayPort
* source to the targeted DisplayPort device.
*
* @return
* - XST_SUCCESS a DisplayID extension block was found.
* - XST_ERROR_COUNT_MAX if a time out occurred while attempting to
* read an extension block.
* - XST_DEVICE_NOT_FOUND if no RX device is connected.
* - XST_FAILURE if no DisplayID extension block was found or some
* error occurred in the search.
*
* @note None.
*
*******************************************************************************/
u32 XDp_TxGetRemoteEdidDispIdExt(XDp *InstancePtr, u8 *Data,
u8 LinkCountTotal, u8 *RelativeAddress)
{
u32 Status;
u8 NumExt;
u8 ExtIndex;
/* Verify arguments. */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertNonvoid(LinkCountTotal > 0);
Xil_AssertNonvoid((RelativeAddress != NULL) || (LinkCountTotal == 1));
Xil_AssertNonvoid(Data != NULL);
/* Get the base EDID block. */
Status = XDp_TxGetRemoteEdid(InstancePtr, LinkCountTotal,
RelativeAddress, Data);
if (Status != XST_SUCCESS) {
return Status;
}
NumExt = Data[XDP_EDID_EXT_BLOCK_COUNT];
for (ExtIndex = 0; ExtIndex < NumExt; ExtIndex++) {
/* Get an EDID extension block. */
Status = XDp_TxGetRemoteEdidBlock(InstancePtr, Data,
ExtIndex + 1, LinkCountTotal, RelativeAddress);
if (Status != XST_SUCCESS) {
return Status;
}
if (XDp_TxIsEdidExtBlockDispId(Data)) {
/* The current extension block is of type DisplayID. */
return XST_SUCCESS;
}
}
/* All extension blocks have been searched; no DisplayID extension block
* exists in sink's EDID structure. */
return XST_FAILURE;
}
/******************************************************************************/
/**
* Given a section tag, search for and retrieve the appropriate section data
* block that is part of the specified DisplayID structure.
*
* @param DisplayIdRaw is a pointer to the DisplayID data.
* @param SectionTag is the tag to search for that represents the desired
* section data block.
* @param DataBlockPtr will be set by this function to point to the
* appropriate section data block that is part of the DisplayIdRaw.
*
* @return
* - XST_SUCCESS if the section data block with the specified tag
* was found.
* - XST_FAILURE otherwise.
*
* @note The DataBlockPtr argument is modified to point to the entry
* in DisplayIdRaw that represents the beginning of the desired
* section data block.
*
*******************************************************************************/
u32 XDp_TxGetDispIdDataBlock(u8 *DisplayIdRaw, u8 SectionTag, u8 **DataBlockPtr)
{
u8 Index;
u8 DispIdSize = DisplayIdRaw[XDP_TX_DISPID_SIZE];
u8 *DataBlock;
/* Verify arguments. */
Xil_AssertNonvoid(DisplayIdRaw != NULL);
/* Search for a section data block matching the specified tag. */
for (Index = XDP_TX_DISPID_PAYLOAD_START; Index < DispIdSize; Index++) {
DataBlock = &DisplayIdRaw[Index];
/* Check if the tag mataches the current section data block. */
if (DataBlock[XDP_TX_DISPID_DB_SEC_TAG] == SectionTag) {
*DataBlockPtr = DataBlock;
return XST_SUCCESS;
}
if (DataBlock[XDP_TX_DISPID_DB_SEC_SIZE] == 0) {
/* End of valid section data blocks. */
break;
}
else {
/* Increment the search index to skip the remaining
* bytes of the current section data block. */
Index += (XDP_TX_DISPID_DB_SEC_SIZE +
DataBlock[XDP_TX_DISPID_DB_SEC_SIZE]);
}
}
/* The entire DisplayID was searched or the search ended due to data
* no longer containing a valid section data block. No section data
* block with the specified tag was found. */
return XST_FAILURE;
}
/******************************************************************************/
/**
* Search for and retrieve a downstream DisplayPort device's Tiled Display
* Topology (TDT) section data block that is part of the downstream device's
* DisplayID structure. The DisplayID structure is part of the Extended Display
* Identification Data (EDID) in the form of an extension block.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param EdidExt is a pointer to the data area that will be filled by the
* retrieved DisplayID extension block.
* @param LinkCountTotal is the total DisplayPort links connecting the
* DisplayPort TX to the targeted downstream device.
* @param RelativeAddress is the relative address from the DisplayPort
* source to the targeted DisplayPort device.
* @param DataBlockPtr will be set by this function to point to the TDT
* data block that is part of the EdidExt extension block.
*
* @return
* - XST_SUCCESS a DisplayID extension block was found.
* - XST_ERROR_COUNT_MAX if a time out occurred while attempting to
* read an extension block.
* - XST_DEVICE_NOT_FOUND if no RX device is connected.
* - XST_FAILURE if no DisplayID extension block was found or some
* error occurred in the search.
*
* @note The EdidExt will be filled with the DisplayID EDID extension
* block and the DataBlockPtr argument is modified to point to the
* EdidExt entry representing the TDT section data block.
*
*******************************************************************************/
u32 XDp_TxGetRemoteTiledDisplayDb(XDp *InstancePtr, u8 *EdidExt,
u8 LinkCountTotal, u8 *RelativeAddress, u8 **DataBlockPtr)
{
u32 Status;
u8 *EdidExtDispId;
/* Verify arguments. */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertNonvoid(LinkCountTotal > 0);
Xil_AssertNonvoid((RelativeAddress != NULL) || (LinkCountTotal == 1));
Xil_AssertNonvoid(EdidExt != NULL);
/* Obtain a DisplayID EDID extension block. */
Status = XDp_TxGetRemoteEdidDispIdExt(InstancePtr, EdidExt,
LinkCountTotal, RelativeAddress);
if (Status != XST_SUCCESS) {
/* The sink does not have a DisplayID EDID extension block. */
return Status;
}
/* The first byte of the extension block is the tag. */
EdidExtDispId = &EdidExt[0x01];
/* Obtain the tiled display topology block data from the DisplayId EDID
* extension block. */
Status = XDp_TxGetDispIdDataBlock(EdidExtDispId, XDP_TX_DISPID_TDT_TAG,
DataBlockPtr);
if (Status != XST_SUCCESS) {
/* The sink does not possess a DisplayID EDID data block with
* the specified tag. */
return Status;
}
return XST_SUCCESS;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,761 @@
/*******************************************************************************
*
* 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 xdp_intr.c
*
* This file contains functions related to XDp interrupt handling.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 01/20/15 Initial release. TX code merged from the dptx driver.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xdp.h"
/**************************** Function Prototypes *****************************/
static void XDp_TxInterruptHandler(XDp *InstancePtr);
static void XDp_RxInterruptHandler(XDp *InstancePtr);
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function is the interrupt handler for the XDp driver.
* When an interrupt happens, this interrupt handler will check which TX/RX mode
* of operation the core is running in, and will call the appropriate interrupt
* handler. The called interrupt handler will first detect what kind of
* interrupt happened, then decides which callback function to invoke.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void XDp_InterruptHandler(XDp *InstancePtr)
{
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
if (XDp_GetCoreType(InstancePtr) == XDP_TX) {
XDp_TxInterruptHandler(InstancePtr);
}
else {
XDp_RxInterruptHandler(InstancePtr);
}
}
/******************************************************************************/
/**
* This function generates a pulse on the hot-plug-detect (HPD) line of the
* specified duration.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param DurationUs is the duration of the HPD pulse, in microseconds.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void XDp_RxGenerateHpdInterrupt(XDp *InstancePtr, u16 DurationUs)
{
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_RX);
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_RX_HPD_INTERRUPT,
(DurationUs << XDP_RX_HPD_INTERRUPT_LENGTH_US_SHIFT) |
XDP_RX_HPD_INTERRUPT_ASSERT_MASK);
}
/******************************************************************************/
/**
* This function enables interrupts associated with the specified mask.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Mask specifies which interrupts should be enabled. Bits set to
* 1 will enable the corresponding interrupts.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void XDp_RxInterruptEnable(XDp *InstancePtr, u32 Mask)
{
u32 MaskVal;
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_RX);
MaskVal = XDp_ReadReg(InstancePtr->Config.BaseAddr,
XDP_RX_INTERRUPT_CAUSE);
MaskVal &= ~Mask;
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_RX_INTERRUPT_MASK,
MaskVal);
}
/******************************************************************************/
/**
* This function disables interrupts associated with the specified mask.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Mask specifies which interrupts should be disabled. Bits set to
* 1 will disable the corresponding interrupts.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void XDp_RxInterruptDisable(XDp *InstancePtr, u32 Mask)
{
u32 MaskVal;
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_RX);
MaskVal = XDp_ReadReg(InstancePtr->Config.BaseAddr,
XDP_RX_INTERRUPT_CAUSE);
MaskVal |= Mask;
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_RX_INTERRUPT_MASK,
MaskVal);
}
/******************************************************************************/
/**
* This function installs a callback function for when a hot-plug-detect 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_TxSetHpdEventHandler(XDp *InstancePtr,
XDp_IntrHandler CallbackFunc, void *CallbackRef)
{
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertVoid(CallbackFunc != NULL);
Xil_AssertVoid(CallbackRef != NULL);
InstancePtr->TxInstance.HpdEventHandler = CallbackFunc;
InstancePtr->TxInstance.HpdEventCallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function installs a callback function for when a hot-plug-detect pulse
* 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_TxSetHpdPulseHandler(XDp *InstancePtr,
XDp_IntrHandler CallbackFunc, void *CallbackRef)
{
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertVoid(CallbackFunc != NULL);
Xil_AssertVoid(CallbackRef != NULL);
InstancePtr->TxInstance.HpdPulseHandler = CallbackFunc;
InstancePtr->TxInstance.HpdPulseCallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function installs a callback function for when a video mode change
* 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_RxSetIntrVmChangeHandler(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.IntrVmChangeHandler = CallbackFunc;
InstancePtr->RxInstance.IntrVmChangeCallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function installs a callback function for when the power state 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_RxSetIntrPowerStateHandler(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.IntrPowerStateHandler = CallbackFunc;
InstancePtr->RxInstance.IntrPowerStateCallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function installs a callback function for when a no video 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_RxSetIntrNoVideoHandler(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.IntrNoVideoHandler = CallbackFunc;
InstancePtr->RxInstance.IntrNoVideoCallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function installs a callback function for when a vertical blanking
* 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_RxSetIntrVBlankHandler(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.IntrVBlankHandler = CallbackFunc;
InstancePtr->RxInstance.IntrVBlankCallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function installs a callback function for when a training lost 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_RxSetIntrTrainingLostHandler(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.IntrTrainingLostHandler = CallbackFunc;
InstancePtr->RxInstance.IntrTrainingLostCallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function installs a callback function for when a valid video 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_RxSetIntrVideoHandler(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.IntrVideoHandler = CallbackFunc;
InstancePtr->RxInstance.IntrVideoCallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function installs a callback function for when an audio info packet
* 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_RxSetIntrInfoPktHandler(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.IntrInfoPktHandler = CallbackFunc;
InstancePtr->RxInstance.IntrInfoPktCallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function installs a callback function for when an audio extension packet
* 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_RxSetIntrExtPktHandler(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.IntrExtPktHandler = CallbackFunc;
InstancePtr->RxInstance.IntrExtPktCallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function installs a callback function for when a training done 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_RxSetIntrTrainingDoneHandler(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.IntrTrainingDoneHandler = CallbackFunc;
InstancePtr->RxInstance.IntrTrainingDoneCallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function installs a callback function for when a bandwidth change
* 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_RxSetIntrBwChangeHandler(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.IntrBwChangeHandler = CallbackFunc;
InstancePtr->RxInstance.IntrBwChangeCallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function installs a callback function for when a training pattern 1
* 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_RxSetIntrTp1Handler(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.IntrTp1Handler = CallbackFunc;
InstancePtr->RxInstance.IntrTp1CallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function installs a callback function for when a training pattern 2
* 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_RxSetIntrTp2Handler(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.IntrTp2Handler = CallbackFunc;
InstancePtr->RxInstance.IntrTp2CallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function installs a callback function for when a training pattern 3
* 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_RxSetIntrTp3Handler(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.IntrTp3Handler = CallbackFunc;
InstancePtr->RxInstance.IntrTp3CallbackRef = CallbackRef;
}
/******************************************************************************/
/**
* This function is the interrupt handler for the XDp driver operating in TX
* mode.
*
* When an interrupt happens, it first detects what kind of interrupt happened,
* then decides which callback function to invoke.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void XDp_TxInterruptHandler(XDp *InstancePtr)
{
u32 IntrStatus;
u8 HpdEventDetected;
u8 HpdPulseDetected;
u32 HpdDuration;
u32 IntrMask;
/* Determine what kind of interrupt occurred.
* Note: XDP_TX_INTERRUPT_STATUS is an RC (read-clear) register. */
IntrStatus = XDp_ReadReg(InstancePtr->Config.BaseAddr,
XDP_TX_INTERRUPT_STATUS);
IntrStatus &= ~XDp_ReadReg(InstancePtr->Config.BaseAddr,
XDP_TX_INTERRUPT_MASK);
IntrMask = XDp_ReadReg(InstancePtr->Config.BaseAddr,
XDP_TX_INTERRUPT_MASK);
HpdEventDetected = IntrStatus & XDP_TX_INTERRUPT_STATUS_HPD_EVENT_MASK;
HpdPulseDetected = IntrStatus &
XDP_TX_INTERRUPT_STATUS_HPD_PULSE_DETECTED_MASK;
if (HpdEventDetected) {
/* Mask interrupts while event handling is taking place. API
* will error out in case of a disconnection event anyway. */
XDp_WriteReg(InstancePtr->Config.BaseAddr,
XDP_TX_INTERRUPT_MASK, IntrMask |
XDP_TX_INTERRUPT_MASK_HPD_EVENT_MASK);
InstancePtr->TxInstance.HpdEventHandler(
InstancePtr->TxInstance.HpdEventCallbackRef);
}
else if (HpdPulseDetected && XDp_TxIsConnected(InstancePtr)) {
/* Mask interrupts while event handling is taking place. */
XDp_WriteReg(InstancePtr->Config.BaseAddr,
XDP_TX_INTERRUPT_MASK, IntrMask |
XDP_TX_INTERRUPT_MASK_HPD_PULSE_DETECTED_MASK);
/* The source device must debounce the incoming HPD signal by
* sampling the value at an interval greater than 0.500 ms. An
* HPD pulse should be of width 0.5 ms - 1.0 ms. */
HpdDuration = XDp_ReadReg(InstancePtr->Config.BaseAddr,
XDP_TX_HPD_DURATION);
if (HpdDuration >= 500) {
InstancePtr->TxInstance.HpdPulseHandler(
InstancePtr->TxInstance.HpdPulseCallbackRef);
}
}
/* Unmask previously masked interrupts once handling is done. */
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_TX_INTERRUPT_MASK,
IntrMask);
}
/******************************************************************************/
/**
* This function is the interrupt handler for the XDp driver operating in RX
* mode.
*
* When an interrupt happens, it first detects what kind of interrupt happened,
* then decides which callback function to invoke.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void XDp_RxInterruptHandler(XDp *InstancePtr)
{
u32 IntrStatus;
/* Determine what kind of interrupts have occurred.
* Note: XDP_RX_INTERRUPT_CAUSE is a RC (read-clear) register. */
IntrStatus = XDp_ReadReg(InstancePtr->Config.BaseAddr,
XDP_RX_INTERRUPT_CAUSE);
/* Training pattern 1 has started. */
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_TP1_MASK) {
InstancePtr->RxInstance.IntrTp1Handler(
InstancePtr->RxInstance.IntrTp1CallbackRef);
}
/* Training pattern 2 has started. */
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_TP2_MASK) {
InstancePtr->RxInstance.IntrTp2Handler(
InstancePtr->RxInstance.IntrTp2CallbackRef);
}
/* Training pattern 3 has started. */
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_TP3_MASK) {
InstancePtr->RxInstance.IntrTp3Handler(
InstancePtr->RxInstance.IntrTp3CallbackRef);
}
/* Training lost - the link has been lost. */
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_TRAINING_LOST_MASK) {
InstancePtr->RxInstance.IntrTrainingLostHandler(
InstancePtr->RxInstance.IntrTrainingLostCallbackRef);
}
/* The link has been trained. */
else if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_TRAINING_DONE_MASK) {
InstancePtr->RxInstance.IntrTrainingDoneHandler(
InstancePtr->RxInstance.IntrTrainingDoneCallbackRef);
}
/* A change has been detected in the current video transmitted on the
* link as indicated by the main stream attributes (MSA) fields. The
* horizontal and vertical resolution parameters are monitored for
* changes. */
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_VM_CHANGE_MASK) {
InstancePtr->RxInstance.IntrVmChangeHandler(
InstancePtr->RxInstance.IntrVmChangeCallbackRef);
}
/* The VerticalBlanking_Flag in the VB-ID field of the received stream
* indicates the start of the vertical blanking interval. */
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_VBLANK_MASK) {
InstancePtr->RxInstance.IntrVBlankHandler(
InstancePtr->RxInstance.IntrVBlankCallbackRef);
}
/* The receiver has detected the no-video flags in the VB-ID field after
* active video has been received. */
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_NO_VIDEO_MASK) {
InstancePtr->RxInstance.IntrNoVideoHandler(
InstancePtr->RxInstance.IntrNoVideoCallbackRef);
}
/* A valid video frame is detected on the main link. */
else if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_VIDEO_MASK) {
InstancePtr->RxInstance.IntrVideoHandler(
InstancePtr->RxInstance.IntrVideoCallbackRef);
}
/* The transmitter has requested a change in the current power state of
* the receiver core. */
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_POWER_STATE_MASK) {
InstancePtr->RxInstance.IntrPowerStateHandler(
InstancePtr->RxInstance.IntrPowerStateCallbackRef);
}
/* A change in the bandwidth has been detected. */
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_BW_CHANGE_MASK) {
InstancePtr->RxInstance.IntrBwChangeHandler(
InstancePtr->RxInstance.IntrBwChangeCallbackRef);
}
/* An audio info packet has been received. */
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_INFO_PKT_MASK) {
InstancePtr->RxInstance.IntrInfoPktHandler(
InstancePtr->RxInstance.IntrInfoPktCallbackRef);
}
/* An audio extension packet has been received. */
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_EXT_PKT_MASK) {
InstancePtr->RxInstance.IntrExtPktHandler(
InstancePtr->RxInstance.IntrExtPktCallbackRef);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,339 @@
/*******************************************************************************
*
* 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 xdp_selftest.c
*
* This file contains a diagnostic self-test function for the XDp driver. It
* will check many of the DisplayPort core's register values against the default
* reset values as a sanity-check that the core is ready to be used.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 01/20/15 Initial release. TX code merged from the dptx driver.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xdp.h"
/**************************** Function Prototypes *****************************/
static u32 XDp_TxSelfTest(XDp *InstancePtr);
static u32 XDp_RxSelfTest(XDp *InstancePtr);
/**************************** Variable Definitions ****************************/
/**
* This table contains the default values for the DisplayPort TX core's general
* usage registers.
*/
u32 TxResetValues[53][2] =
{
{XDP_TX_LINK_BW_SET, 0},
{XDP_TX_LANE_COUNT_SET, 0},
{XDP_TX_ENHANCED_FRAME_EN, 0},
{XDP_TX_TRAINING_PATTERN_SET, 0},
{XDP_TX_LINK_QUAL_PATTERN_SET, 0},
{XDP_TX_SCRAMBLING_DISABLE, 0},
{XDP_TX_DOWNSPREAD_CTRL, 0},
{XDP_TX_SOFT_RESET, 0},
{XDP_TX_ENABLE, 0},
{XDP_TX_ENABLE_MAIN_STREAM, 0},
{XDP_TX_ENABLE_SEC_STREAM, 0},
{XDP_TX_FORCE_SCRAMBLER_RESET, 0},
{XDP_TX_MST_CONFIG, 0},
{XDP_TX_AUX_CMD, 0},
{XDP_TX_AUX_WRITE_FIFO, 0},
{XDP_TX_AUX_ADDRESS, 0},
{XDP_TX_AUX_CLK_DIVIDER, 0},
{XDP_TX_USER_FIFO_OVERFLOW, 0},
{XDP_TX_AUX_REPLY_DATA, 0},
{XDP_TX_AUX_REPLY_CODE, 0},
{XDP_TX_AUX_REPLY_COUNT, 0},
{XDP_TX_INTERRUPT_MASK, 0x3F},
{XDP_TX_REPLY_DATA_COUNT, 0},
{XDP_TX_REPLY_STATUS, 0x10},
{XDP_TX_STREAM1, 0},
{XDP_TX_STREAM2, 0},
{XDP_TX_STREAM3, 0},
{XDP_TX_STREAM4, 0},
{XDP_TX_PHY_CONFIG, 0x03},
{XDP_TX_PHY_VOLTAGE_DIFF_LANE_0, 0},
{XDP_TX_PHY_VOLTAGE_DIFF_LANE_1, 0},
{XDP_TX_PHY_VOLTAGE_DIFF_LANE_2, 0},
{XDP_TX_PHY_VOLTAGE_DIFF_LANE_3, 0},
{XDP_TX_PHY_TRANSMIT_PRBS7, 0},
{XDP_TX_PHY_CLOCK_SELECT, 0},
{XDP_TX_PHY_POWER_DOWN, 0},
{XDP_TX_PHY_PRECURSOR_LANE_0, 0},
{XDP_TX_PHY_PRECURSOR_LANE_1, 0},
{XDP_TX_PHY_PRECURSOR_LANE_2, 0},
{XDP_TX_PHY_PRECURSOR_LANE_3, 0},
{XDP_TX_PHY_POSTCURSOR_LANE_0, 0},
{XDP_TX_PHY_POSTCURSOR_LANE_1, 0},
{XDP_TX_PHY_POSTCURSOR_LANE_2, 0},
{XDP_TX_PHY_POSTCURSOR_LANE_3, 0},
{XDP_TX_GT_DRP_COMMAND, 0},
{XDP_TX_GT_DRP_READ_DATA, 0},
{XDP_TX_GT_DRP_CHANNEL_STATUS, 0},
{XDP_TX_AUDIO_CONTROL, 0},
{XDP_TX_AUDIO_CHANNELS, 0},
{XDP_TX_AUDIO_INFO_DATA(1), 0},
{XDP_TX_AUDIO_MAUD, 0},
{XDP_TX_AUDIO_NAUD, 0},
{XDP_TX_AUDIO_EXT_DATA(1), 0}
};
/**
* This table contains the default values for the DisplayPort TX core's main
* stream attribute (MSA) registers.
*/
u32 TxResetValuesMsa[20][2] =
{
{XDP_TX_MAIN_STREAM_HTOTAL, 0},
{XDP_TX_MAIN_STREAM_VTOTAL, 0},
{XDP_TX_MAIN_STREAM_POLARITY, 0},
{XDP_TX_MAIN_STREAM_HSWIDTH, 0},
{XDP_TX_MAIN_STREAM_VSWIDTH, 0},
{XDP_TX_MAIN_STREAM_HRES, 0},
{XDP_TX_MAIN_STREAM_VRES, 0},
{XDP_TX_MAIN_STREAM_HSTART, 0},
{XDP_TX_MAIN_STREAM_VSTART, 0},
{XDP_TX_MAIN_STREAM_MISC0, 0},
{XDP_TX_MAIN_STREAM_MISC1, 0},
{XDP_TX_M_VID, 0},
{XDP_TX_TU_SIZE, 0},
{XDP_TX_N_VID, 0},
{XDP_TX_USER_PIXEL_WIDTH, 0},
{XDP_TX_USER_DATA_COUNT_PER_LANE, 0},
{XDP_TX_MAIN_STREAM_INTERLACED, 0},
{XDP_TX_MIN_BYTES_PER_TU, 0},
{XDP_TX_FRAC_BYTES_PER_TU, 0},
{XDP_TX_INIT_WAIT, 32}
};
/**
* This table contains the default values for the DisplayPort RX core's general
* usage registers.
*/
u32 RxResetValues[46][2] =
{
{XDP_RX_LINK_ENABLE, 0},
{XDP_RX_AUX_CLK_DIVIDER, 0},
{XDP_RX_DTG_ENABLE, 0},
{XDP_RX_USER_PIXEL_WIDTH, 0},
{XDP_RX_INTERRUPT_MASK, 0x7FFF},
{XDP_RX_MISC_CTRL, 0},
{XDP_RX_SOFT_RESET, 0},
{XDP_RX_AUX_REQ_IN_PROGRESS, 0},
{XDP_RX_REQ_ERROR_COUNT, 0},
{XDP_RX_REQ_COUNT, 0},
{XDP_RX_HPD_INTERRUPT, 0},
{XDP_RX_REQ_CLK_WIDTH, 0},
{XDP_RX_REQ_CMD, 0},
{XDP_RX_REQ_ADDRESS, 0},
{XDP_RX_REQ_LENGTH, 0},
{XDP_RX_INTERRUPT_CAUSE, 0},
{XDP_RX_INTERRUPT_MASK_1, 0},
{XDP_RX_INTERRUPT_CAUSE_1, 0},
{XDP_RX_HSYNC_WIDTH, 0xF0F},
{XDP_RX_FAST_I2C_DIVIDER, 0},
{XDP_RX_LOCAL_EDID_VIDEO, 0},
{XDP_RX_LOCAL_EDID_AUDIO, 0},
{XDP_RX_REMOTE_CMD, 0},
{XDP_RX_DEVICE_SERVICE_IRQ, 0},
{XDP_RX_VIDEO_UNSUPPORTED, 0},
{XDP_RX_AUDIO_UNSUPPORTED, 0},
{XDP_RX_OVER_LINK_BW_SET, 0},
{XDP_RX_OVER_LANE_COUNT_SET, 0},
{XDP_RX_OVER_TP_SET, 0},
{XDP_RX_OVER_TRAINING_LANE0_SET, 0},
{XDP_RX_OVER_TRAINING_LANE1_SET, 0},
{XDP_RX_OVER_TRAINING_LANE2_SET, 0},
{XDP_RX_OVER_TRAINING_LANE3_SET, 0},
{XDP_RX_OVER_CTRL_DPCD, 0},
{XDP_RX_OVER_DOWNSPREAD_CTRL, 0},
{XDP_RX_OVER_LINK_QUAL_LANE0_SET, 0},
{XDP_RX_OVER_LINK_QUAL_LANE1_SET, 0},
{XDP_RX_OVER_LINK_QUAL_LANE2_SET, 0},
{XDP_RX_OVER_LINK_QUAL_LANE3_SET, 0},
{XDP_RX_MST_CAP, 0},
{XDP_RX_SINK_COUNT, 0},
{XDP_RX_GUID0, 0},
{XDP_RX_GUID1, 0},
{XDP_RX_GUID2, 0},
{XDP_RX_GUID3, 0},
{XDP_RX_OVER_GUID, 0}
};
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function runs a self-test on the XDp driver/device depending on whether
* the core is operating in TX or RX mode. The sanity test checks whether or not
* all tested registers hold their default reset values.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return
* - XST_SUCCESS if the self-test passed - all tested registers
* hold their default reset values.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
u32 XDp_SelfTest(XDp *InstancePtr)
{
u32 Status;
/* Verify arguments. */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
if (XDp_GetCoreType(InstancePtr) == XDP_TX) {
Status = XDp_TxSelfTest(InstancePtr);
}
else {
Status = XDp_RxSelfTest(InstancePtr);
}
return Status;
}
/******************************************************************************/
/**
* This function runs a self-test on the XDp driver/device. The sanity test
* checks whether or not all tested registers hold their default reset values.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return
* - XST_SUCCESS if the self-test passed - all tested registers
* hold their default reset values.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
static u32 XDp_TxSelfTest(XDp *InstancePtr)
{
u8 Index;
u8 StreamIndex;
u32 StreamOffset;
u32 Val;
/* Compare general usage registers with their default values. */
for (Index = 0; Index < 53; Index++) {
Val = XDp_ReadReg(InstancePtr->Config.BaseAddr,
TxResetValues[Index][0]);
/* Fail if register does not hold default value. */
if (Val != TxResetValues[Index][1]) {
return XST_FAILURE;
}
}
/* Compare main stream attribute (MSA) registers for all 4 streams with
* their default values. */
for (StreamIndex = 0; StreamIndex < 4; StreamIndex++) {
/* Determine the MSA register offset for each stream. */
if (StreamIndex == 0) {
StreamOffset = 0;
}
else if (StreamIndex == 1) {
StreamOffset = XDP_TX_STREAM2_MSA_START_OFFSET;
}
else if (StreamIndex == 2) {
StreamOffset = XDP_TX_STREAM3_MSA_START_OFFSET;
}
else if (StreamIndex == 3) {
StreamOffset = XDP_TX_STREAM4_MSA_START_OFFSET;
}
for (Index = 0; Index < 20; Index++) {
Val = XDp_ReadReg(InstancePtr->Config.BaseAddr,
StreamOffset + TxResetValuesMsa[Index][0]);
/* Fail if register does not hold default value. */
if (Val != TxResetValuesMsa[Index][1]) {
return XST_FAILURE;
}
}
}
/* All tested registers hold their default reset values. */
return XST_SUCCESS;
}
/******************************************************************************/
/**
* This function runs a self-test on the XDp driver/device running in RX mode.
* The sanity test checks whether or not all tested registers hold their default
* reset values.
*
* @param InstancePtr is a pointer to the XDp instance.
*
* @return
* - XST_SUCCESS if the self-test passed - all tested registers
* hold their default reset values.
* - XST_FAILURE otherwise.
*
* @note None.
*
*******************************************************************************/
static u32 XDp_RxSelfTest(XDp *InstancePtr)
{
u8 Index;
u32 Val;
/* Compare general usage registers with their default values. */
for (Index = 0; Index < 46; Index++) {
Val = XDp_ReadReg(InstancePtr->Config.BaseAddr,
RxResetValues[Index][0]);
/* Fail if register does not hold default value. */
if (Val != RxResetValues[Index][1]) {
return XST_FAILURE;
}
}
/* All tested registers hold their default reset values. */
return XST_SUCCESS;
}

View file

@ -0,0 +1,93 @@
/*******************************************************************************
*
* 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 xdp_sinit.c
*
* This file contains static initialization methods for the XDp driver.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 01/20/15 Initial release. TX code merged from the dptx driver.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xdp.h"
#include "xparameters.h"
/*************************** Variable Declarations ****************************/
/**
* A table of configuration structures containing the configuration information
* for each DisplayPort TX core in the system.
*/
extern XDp_Config XDp_ConfigTable[XPAR_XDP_NUM_INSTANCES];
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function looks for the device configuration based on the unique device
* ID. The table XDp_ConfigTable[] contains the configuration information for
* each device in the system.
*
* @param DeviceId is the unique device ID of the device being looked up.
*
* @return A pointer to the configuration table entry corresponding to the
* given device ID, or NULL if no match is found.
*
* @note None.
*
*******************************************************************************/
XDp_Config *XDp_LookupConfig(u16 DeviceId)
{
XDp_Config *CfgPtr;
u32 Index;
for (Index = 0; Index < XPAR_XDP_NUM_INSTANCES; Index++) {
if (XDp_ConfigTable[Index].DeviceId == DeviceId) {
CfgPtr = &XDp_ConfigTable[Index];
break;
}
}
return CfgPtr;
}

View file

@ -0,0 +1,950 @@
/*******************************************************************************
*
* 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 xdp_spm.c
*
* This file contains the stream policy maker functions for the XDp driver.
* These functions set up the DisplayPort TX core's main stream attributes (MSA)
* that determine how a video stream will be displayed and also some DisplayPort
* RX MSA-related functions.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 als 01/20/15 Initial release. TX code merged from the dptx driver.
* </pre>
*
*******************************************************************************/
/******************************* Include Files ********************************/
#include "xdp.h"
/**************************** Function Prototypes *****************************/
static void XDp_TxCalculateTs(XDp *InstancePtr, u8 Stream, u8 BitsPerPixel);
/**************************** Function Definitions ****************************/
/******************************************************************************/
/**
* This function calculates the following Main Stream Attributes (MSA):
* - Transfer unit size
* - User pixel width
* - Horizontal start
* - Vertical start
* - Horizontal total clock
* - Vertical total clock
* - Misc0
* - Misc1
* - Data per lane
* - Average number of bytes per transfer unit
* - Number of initial wait cycles
* These values are derived from:
* - Bits per color
* - Horizontal resolution
* - Vertical resolution
* - Pixel clock (in KHz)
* - Horizontal sync polarity
* - Vertical sync polarity
* - Horizontal front porch
* - Horizontal sync pulse width
* - Horizontal back porch
* - Vertical front porch
* - Vertical sync pulse width
* - Vertical back porch
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Stream is the stream number for which to calculate the MSA
* values.
*
* @return None.
*
* @note The MsaConfig structure is modified with the new, calculated
* values. The main stream attributes that were used to derive the
* calculated values are untouched in the MsaConfig structure.
*
*******************************************************************************/
void XDp_TxCfgMsaRecalculate(XDp *InstancePtr, u8 Stream)
{
u32 VideoBw;
u32 LinkBw;
u32 WordsPerLine;
u8 BitsPerPixel;
XDp_TxMainStreamAttributes *MsaConfig;
XDp_TxLinkConfig *LinkConfig;
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertVoid((Stream == XDP_TX_STREAM_ID1) ||
(Stream == XDP_TX_STREAM_ID2) || (Stream == XDP_TX_STREAM_ID3) ||
(Stream == XDP_TX_STREAM_ID4));
MsaConfig = &InstancePtr->TxInstance.MsaConfig[Stream - 1];
LinkConfig = &InstancePtr->TxInstance.LinkConfig;
/* Verify the rest of the values used. */
Xil_AssertVoid((LinkConfig->LinkRate == XDP_TX_LINK_BW_SET_162GBPS) ||
(LinkConfig->LinkRate == XDP_TX_LINK_BW_SET_270GBPS) ||
(LinkConfig->LinkRate == XDP_TX_LINK_BW_SET_540GBPS));
Xil_AssertVoid((LinkConfig->LaneCount == XDP_TX_LANE_COUNT_SET_1) ||
(LinkConfig->LaneCount == XDP_TX_LANE_COUNT_SET_2) ||
(LinkConfig->LaneCount == XDP_TX_LANE_COUNT_SET_4));
Xil_AssertVoid((MsaConfig->SynchronousClockMode == 0) ||
(MsaConfig->SynchronousClockMode == 1));
Xil_AssertVoid((MsaConfig->DynamicRange == 0) ||
(MsaConfig->DynamicRange == 1));
Xil_AssertVoid((MsaConfig->YCbCrColorimetry == 0) ||
(MsaConfig->YCbCrColorimetry == 1));
Xil_AssertVoid((MsaConfig->BitsPerColor == 6) ||
(MsaConfig->BitsPerColor == 8) ||
(MsaConfig->BitsPerColor == 10) ||
(MsaConfig->BitsPerColor == 12) ||
(MsaConfig->BitsPerColor == 16));
/* Set the user pixel width to handle clocks that exceed the
* capabilities of the DisplayPort TX core. */
if (MsaConfig->OverrideUserPixelWidth == 0) {
if ((MsaConfig->PixelClockHz > 300000000) &&
(LinkConfig->LaneCount == XDP_TX_LANE_COUNT_SET_4)) {
MsaConfig->UserPixelWidth = 4;
}
else if ((MsaConfig->PixelClockHz > 75000000) &&
(LinkConfig->LaneCount != XDP_TX_LANE_COUNT_SET_1)) {
MsaConfig->UserPixelWidth = 2;
}
else {
MsaConfig->UserPixelWidth = 1;
}
}
/* Compute the rest of the MSA values. */
MsaConfig->NVid = 27 * 1000 * LinkConfig->LinkRate;
MsaConfig->HStart = MsaConfig->Vtm.Timing.HSyncWidth +
MsaConfig->Vtm.Timing.HBackPorch;
MsaConfig->VStart = MsaConfig->Vtm.Timing.F0PVSyncWidth +
MsaConfig->Vtm.Timing.F0PVBackPorch;
/* Miscellaneous attributes. */
if (MsaConfig->BitsPerColor == 6) {
MsaConfig->Misc0 = XDP_TX_MAIN_STREAMX_MISC0_BDC_6BPC;
}
else if (MsaConfig->BitsPerColor == 8) {
MsaConfig->Misc0 = XDP_TX_MAIN_STREAMX_MISC0_BDC_8BPC;
}
else if (MsaConfig->BitsPerColor == 10) {
MsaConfig->Misc0 = XDP_TX_MAIN_STREAMX_MISC0_BDC_10BPC;
}
else if (MsaConfig->BitsPerColor == 12) {
MsaConfig->Misc0 = XDP_TX_MAIN_STREAMX_MISC0_BDC_12BPC;
}
else if (MsaConfig->BitsPerColor == 16) {
MsaConfig->Misc0 = XDP_TX_MAIN_STREAMX_MISC0_BDC_16BPC;
}
MsaConfig->Misc0 = (MsaConfig->Misc0 <<
XDP_TX_MAIN_STREAMX_MISC0_BDC_SHIFT) |
(MsaConfig->YCbCrColorimetry <<
XDP_TX_MAIN_STREAMX_MISC0_YCBCR_COLORIMETRY_SHIFT) |
(MsaConfig->DynamicRange <<
XDP_TX_MAIN_STREAMX_MISC0_DYNAMIC_RANGE_SHIFT) |
(MsaConfig->ComponentFormat <<
XDP_TX_MAIN_STREAMX_MISC0_COMPONENT_FORMAT_SHIFT) |
(MsaConfig->SynchronousClockMode);
MsaConfig->Misc1 = 0;
/* Determine the number of bits per pixel for the specified color
* component format. */
if (MsaConfig->ComponentFormat ==
XDP_TX_MAIN_STREAMX_MISC0_COMPONENT_FORMAT_YCBCR422) {
/* YCbCr422 color component format. */
BitsPerPixel = MsaConfig->BitsPerColor * 2;
}
else {
/* RGB or YCbCr 4:4:4 color component format. */
BitsPerPixel = MsaConfig->BitsPerColor * 3;
}
/* Calculate the data per lane. */
WordsPerLine = (MsaConfig->Vtm.Timing.HActive * BitsPerPixel);
if ((WordsPerLine % 16) != 0) {
WordsPerLine += 16;
}
WordsPerLine /= 16;
MsaConfig->DataPerLane = WordsPerLine - LinkConfig->LaneCount;
if ((WordsPerLine % LinkConfig->LaneCount) != 0) {
MsaConfig->DataPerLane +=
(WordsPerLine % LinkConfig->LaneCount);
}
if (InstancePtr->TxInstance.MstEnable == 1) {
/* Do time slot (and payload bandwidth number) calculations for
* MST. */
XDp_TxCalculateTs(InstancePtr, Stream, BitsPerPixel);
MsaConfig->InitWait = 0;
}
else {
/* Allocate a fixed size for single-stream transport (SST)
* operation. */
MsaConfig->TransferUnitSize = 64;
/* Calculate the average number of bytes per transfer unit.
* Note: Both the integer and the fractional part is stored in
* AvgBytesPerTU. */
VideoBw = ((MsaConfig->PixelClockHz / 1000) * BitsPerPixel) / 8;
LinkBw = (LinkConfig->LaneCount * LinkConfig->LinkRate * 27);
MsaConfig->AvgBytesPerTU = (VideoBw *
MsaConfig->TransferUnitSize) / LinkBw;
/* The number of initial wait cycles at the start of a new line
* by the framing logic. This allows enough data to be buffered
* in the input FIFO before video is sent. */
if ((MsaConfig->AvgBytesPerTU / 1000) <= 4) {
MsaConfig->InitWait = 64;
}
else {
MsaConfig->InitWait = MsaConfig->TransferUnitSize -
(MsaConfig->AvgBytesPerTU / 1000);
}
}
}
/******************************************************************************/
/**
* This function sets the Main Stream Attribute (MSA) values in the
* configuration structure to match one of the standard display mode timings
* from the XDp_TxDmtModes[] standard Display Monitor Timing (DMT) table. The
* XDp_TxVideoMode enumeration in xvidc.h lists the available video modes.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Stream is the stream number for which the MSA values will be
* used for.
* @param VideoMode is one of the enumerated standard video modes that is
* used to determine the MSA values to be used.
*
* @return None.
*
* @note The InstancePtr->TxInstance.MsaConfig structure is modified to
* reflect the MSA values associated to the specified video mode.
*
*******************************************************************************/
void XDp_TxCfgMsaUseStandardVideoMode(XDp *InstancePtr, u8 Stream,
XVidC_VideoMode VideoMode)
{
XDp_TxMainStreamAttributes *MsaConfig;
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertVoid(VideoMode < XVIDC_VM_NUM_SUPPORTED);
Xil_AssertVoid((Stream == XDP_TX_STREAM_ID1) ||
(Stream == XDP_TX_STREAM_ID2) || (Stream == XDP_TX_STREAM_ID3) ||
(Stream == XDP_TX_STREAM_ID4));
MsaConfig = &InstancePtr->TxInstance.MsaConfig[Stream - 1];
/* Configure the MSA values from the display monitor DMT table. */
MsaConfig->Vtm.VmId = XVidC_VideoTimingModes[VideoMode].VmId;
MsaConfig->Vtm.FrameRate = XVidC_VideoTimingModes[VideoMode].FrameRate;
MsaConfig->Vtm.Timing.HActive =
XVidC_VideoTimingModes[VideoMode].Timing.HActive;
MsaConfig->Vtm.Timing.HFrontPorch =
XVidC_VideoTimingModes[VideoMode].Timing.HFrontPorch;
MsaConfig->Vtm.Timing.HSyncWidth =
XVidC_VideoTimingModes[VideoMode].Timing.HSyncWidth;
MsaConfig->Vtm.Timing.HBackPorch =
XVidC_VideoTimingModes[VideoMode].Timing.HBackPorch;
MsaConfig->Vtm.Timing.HTotal =
XVidC_VideoTimingModes[VideoMode].Timing.HTotal;
MsaConfig->Vtm.Timing.HSyncPolarity =
XVidC_VideoTimingModes[VideoMode].Timing.HSyncPolarity;
MsaConfig->Vtm.Timing.VActive =
XVidC_VideoTimingModes[VideoMode].Timing.VActive;
MsaConfig->Vtm.Timing.F0PVFrontPorch =
XVidC_VideoTimingModes[VideoMode].Timing.F0PVFrontPorch;
MsaConfig->Vtm.Timing.F0PVSyncWidth =
XVidC_VideoTimingModes[VideoMode].Timing.F0PVSyncWidth;
MsaConfig->Vtm.Timing.F0PVBackPorch =
XVidC_VideoTimingModes[VideoMode].Timing.F0PVBackPorch;
MsaConfig->Vtm.Timing.F0PVTotal =
XVidC_VideoTimingModes[VideoMode].Timing.F0PVTotal;
MsaConfig->Vtm.Timing.F1VFrontPorch =
XVidC_VideoTimingModes[VideoMode].Timing.F1VFrontPorch;
MsaConfig->Vtm.Timing.F1VSyncWidth =
XVidC_VideoTimingModes[VideoMode].Timing.F1VSyncWidth;
MsaConfig->Vtm.Timing.F1VBackPorch =
XVidC_VideoTimingModes[VideoMode].Timing.F1VBackPorch;
MsaConfig->Vtm.Timing.F1VTotal =
XVidC_VideoTimingModes[VideoMode].Timing.F1VTotal;
MsaConfig->Vtm.Timing.VSyncPolarity =
XVidC_VideoTimingModes[VideoMode].Timing.VSyncPolarity;
/* Calculate the pixel clock frequency. */
MsaConfig->PixelClockHz =
XVidC_GetPixelClockHzByVmId(MsaConfig->Vtm.VmId);
/* Calculate the rest of the MSA values. */
XDp_TxCfgMsaRecalculate(InstancePtr, Stream);
}
/******************************************************************************/
/**
* This function sets the main stream attribute values in the configuration
* structure to match the preferred timing of the sink monitor. This Preferred
* Timing Mode (PTM) information is stored in the sink's Extended Display
* Identification Data (EDID).
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Stream is the stream number for which the MSA values will be
* used for.
* @param Edid is a pointer to the Edid to use for the specified stream.
*
* @return None.
*
* @note The InstancePtr->TxInstance.MsaConfig structure is modified to
* reflect the main stream attribute values associated to the
* preferred timing of the sink monitor.
*
*******************************************************************************/
void XDp_TxCfgMsaUseEdidPreferredTiming(XDp *InstancePtr, u8 Stream, u8 *Edid)
{
XDp_TxMainStreamAttributes *MsaConfig;
u8 *Ptm;
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertVoid((Stream == XDP_TX_STREAM_ID1) ||
(Stream == XDP_TX_STREAM_ID2) ||
(Stream == XDP_TX_STREAM_ID3) ||
(Stream == XDP_TX_STREAM_ID4));
Xil_AssertVoid(Edid != NULL);
MsaConfig = &InstancePtr->TxInstance.MsaConfig[Stream - 1];
Ptm = &Edid[XDP_EDID_PTM];
/* Configure the MSA values with the PTM information as
* specified by the preferred Detailed Timing Descriptor (DTD) of the
* monitor's EDID.
* Note, the PTM is only required for EDID versions 1.3 a newer. Earlier
* versions may not contain this information. */
u16 HBlank = ((Ptm[XDP_EDID_DTD_HRES_HBLANK_U4] &
XDP_EDID_DTD_XRES_XBLANK_U4_XBLANK_MASK) << 8) |
Ptm[XDP_EDID_DTD_HBLANK_LSB];
u16 VBlank = ((Ptm[XDP_EDID_DTD_VRES_VBLANK_U4] &
XDP_EDID_DTD_XRES_XBLANK_U4_XBLANK_MASK) << 8) |
Ptm[XDP_EDID_DTD_VBLANK_LSB];
MsaConfig->Vtm.Timing.HActive =
(((Ptm[XDP_EDID_DTD_HRES_HBLANK_U4] &
XDP_EDID_DTD_XRES_XBLANK_U4_XRES_MASK) >>
XDP_EDID_DTD_XRES_XBLANK_U4_XRES_SHIFT) << 8) |
Ptm[XDP_EDID_DTD_HRES_LSB];
MsaConfig->Vtm.Timing.VActive =
(((Ptm[XDP_EDID_DTD_VRES_VBLANK_U4] &
XDP_EDID_DTD_XRES_XBLANK_U4_XRES_MASK) >>
XDP_EDID_DTD_XRES_XBLANK_U4_XRES_SHIFT) << 8) |
Ptm[XDP_EDID_DTD_VRES_LSB];
MsaConfig->PixelClockHz = (((Ptm[XDP_EDID_DTD_PIXEL_CLK_KHZ_MSB] <<
8) | Ptm[XDP_EDID_DTD_PIXEL_CLK_KHZ_LSB]) * 10) * 1000;
MsaConfig->Vtm.Timing.HFrontPorch =
(((Ptm[XDP_EDID_DTD_XFPORCH_XSPW_U2] &
XDP_EDID_DTD_XFPORCH_XSPW_U2_HFPORCH_MASK) >>
XDP_EDID_DTD_XFPORCH_XSPW_U2_HFPORCH_SHIFT) << 8) |
Ptm[XDP_EDID_DTD_HFPORCH_LSB];
MsaConfig->Vtm.Timing.HSyncWidth =
(((Ptm[XDP_EDID_DTD_XFPORCH_XSPW_U2] &
XDP_EDID_DTD_XFPORCH_XSPW_U2_HSPW_MASK) >>
XDP_EDID_DTD_XFPORCH_XSPW_U2_HSPW_SHIFT) << 8) |
Ptm[XDP_EDID_DTD_HSPW_LSB];
MsaConfig->Vtm.Timing.F0PVFrontPorch =
(((Ptm[XDP_EDID_DTD_XFPORCH_XSPW_U2] &
XDP_EDID_DTD_XFPORCH_XSPW_U2_VFPORCH_MASK) >>
XDP_EDID_DTD_XFPORCH_XSPW_U2_VFPORCH_SHIFT) << 8) |
((Ptm[XDP_EDID_DTD_VFPORCH_VSPW_L4] &
XDP_EDID_DTD_VFPORCH_VSPW_L4_VFPORCH_MASK) >>
XDP_EDID_DTD_VFPORCH_VSPW_L4_VFPORCH_SHIFT);
MsaConfig->Vtm.Timing.F0PVSyncWidth =
((Ptm[XDP_EDID_DTD_XFPORCH_XSPW_U2] &
XDP_EDID_DTD_XFPORCH_XSPW_U2_VSPW_MASK) << 8) |
(Ptm[XDP_EDID_DTD_VFPORCH_VSPW_L4] &
XDP_EDID_DTD_VFPORCH_VSPW_L4_VSPW_MASK);
/* Compute video mode timing values. */
MsaConfig->Vtm.Timing.HBackPorch = HBlank -
(MsaConfig->Vtm.Timing.HFrontPorch +
MsaConfig->Vtm.Timing.HSyncWidth);
MsaConfig->Vtm.Timing.F0PVBackPorch = VBlank -
(MsaConfig->Vtm.Timing.F0PVFrontPorch +
MsaConfig->Vtm.Timing.F0PVSyncWidth);
MsaConfig->Vtm.Timing.HTotal = (MsaConfig->Vtm.Timing.HSyncWidth +
MsaConfig->Vtm.Timing.HFrontPorch +
MsaConfig->Vtm.Timing.HActive +
MsaConfig->Vtm.Timing.HBackPorch);
MsaConfig->Vtm.Timing.F0PVTotal = (MsaConfig->Vtm.Timing.F0PVSyncWidth +
MsaConfig->Vtm.Timing.F0PVFrontPorch +
MsaConfig->Vtm.Timing.VActive +
MsaConfig->Vtm.Timing.F0PVBackPorch);
MsaConfig->Vtm.FrameRate = MsaConfig->PixelClockHz /
(MsaConfig->Vtm.Timing.HTotal *
MsaConfig->Vtm.Timing.F0PVTotal);
MsaConfig->Vtm.VmId = XVIDC_VM_USE_EDID_PREFERRED;
/* Calculate the rest of the MSA values. */
XDp_TxCfgMsaRecalculate(InstancePtr, Stream);
}
/******************************************************************************/
/**
* This function takes a the main stream attributes from MsaConfigCustom and
* copies them into InstancePtr->TxInstance.MsaConfig. If desired, given a base
* set of attributes, the rest of the attributes may be derived. The minimal
* required main stream attributes (MSA) that must be contained in the
* MsaConfigCustom structure are:
* - Pixel clock (in Hz)
* - Frame rate
* - Horizontal active resolution
* - Horizontal front porch
* - Horizontal sync pulse width
* - Horizontal back porch
* - Horizontal total
* - Horizontal sync polarity
* - Vertical active resolution
* - Vertical back porch
* - Vertical sync pulse width
* - Vertical front porch
* - Vertical total
* - Vertical sync polarity
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Stream is the stream number for which the MSA values will be
* used for.
* @param MsaConfigCustom is the structure that will be used to copy the
* main stream attributes from (into
* InstancePtr->TxInstance.MsaConfig).
* @param Recalculate is a boolean enable that determines whether or not
* the main stream attributes should be recalculated.
*
* @return None.
*
* @note The InstancePtr->TxInstance.MsaConfig structure is modified with
* the new values.
*
*******************************************************************************/
void XDp_TxCfgMsaUseCustom(XDp *InstancePtr, u8 Stream,
XDp_TxMainStreamAttributes *MsaConfigCustom, u8 Recalculate)
{
XDp_TxMainStreamAttributes *MsaConfig;
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertVoid((Stream == XDP_TX_STREAM_ID1) ||
(Stream == XDP_TX_STREAM_ID2) ||
(Stream == XDP_TX_STREAM_ID3) ||
(Stream == XDP_TX_STREAM_ID4));
Xil_AssertVoid(MsaConfigCustom != NULL);
MsaConfig = &InstancePtr->TxInstance.MsaConfig[Stream - 1];
/* Copy the MSA values from the user configuration structure. */
MsaConfig->PixelClockHz = MsaConfigCustom->PixelClockHz;
MsaConfig->Vtm.VmId = MsaConfigCustom->Vtm.VmId;
MsaConfig->Vtm.FrameRate = MsaConfigCustom->Vtm.FrameRate;
MsaConfig->Vtm.Timing.HActive =
MsaConfigCustom->Vtm.Timing.HActive;
MsaConfig->Vtm.Timing.HFrontPorch =
MsaConfigCustom->Vtm.Timing.HFrontPorch;
MsaConfig->Vtm.Timing.HSyncWidth =
MsaConfigCustom->Vtm.Timing.HSyncWidth;
MsaConfig->Vtm.Timing.HBackPorch =
MsaConfigCustom->Vtm.Timing.HBackPorch;
MsaConfig->Vtm.Timing.HTotal =
MsaConfigCustom->Vtm.Timing.HTotal;
MsaConfig->Vtm.Timing.HSyncPolarity =
MsaConfigCustom->Vtm.Timing.HSyncPolarity;
MsaConfig->Vtm.Timing.VActive =
MsaConfigCustom->Vtm.Timing.VActive;
MsaConfig->Vtm.Timing.F0PVFrontPorch =
MsaConfigCustom->Vtm.Timing.F0PVFrontPorch;
MsaConfig->Vtm.Timing.F0PVSyncWidth =
MsaConfigCustom->Vtm.Timing.F0PVSyncWidth;
MsaConfig->Vtm.Timing.F0PVBackPorch =
MsaConfigCustom->Vtm.Timing.F0PVBackPorch;
MsaConfig->Vtm.Timing.F0PVTotal =
MsaConfigCustom->Vtm.Timing.F0PVTotal;
MsaConfig->Vtm.Timing.F1VFrontPorch =
MsaConfigCustom->Vtm.Timing.F1VFrontPorch;
MsaConfig->Vtm.Timing.F1VSyncWidth =
MsaConfigCustom->Vtm.Timing.F1VSyncWidth;
MsaConfig->Vtm.Timing.F1VBackPorch =
MsaConfigCustom->Vtm.Timing.F1VBackPorch;
MsaConfig->Vtm.Timing.F1VTotal =
MsaConfigCustom->Vtm.Timing.F1VTotal;
MsaConfig->Vtm.Timing.VSyncPolarity =
MsaConfigCustom->Vtm.Timing.VSyncPolarity;
if (Recalculate) {
/* Calculate the rest of the MSA values. */
XDp_TxCfgMsaRecalculate(InstancePtr, Stream);
}
else {
/* Use the custom values for the rest. */
MsaConfig->TransferUnitSize = MsaConfigCustom->TransferUnitSize;
MsaConfig->UserPixelWidth = MsaConfigCustom->UserPixelWidth;
MsaConfig->NVid = MsaConfigCustom->NVid;
MsaConfig->HStart = MsaConfigCustom->HStart;
MsaConfig->VStart = MsaConfigCustom->VStart;
MsaConfig->Misc0 = MsaConfigCustom->Misc0;
MsaConfig->Misc1 = MsaConfigCustom->Misc1;
MsaConfig->DataPerLane = MsaConfigCustom->DataPerLane;
MsaConfig->AvgBytesPerTU = MsaConfigCustom->AvgBytesPerTU;
MsaConfig->InitWait = MsaConfigCustom->InitWait;
}
}
/******************************************************************************/
/**
* This function sets the bits per color value of the video stream.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Stream is the stream number for which to set the color depth.
* @param BitsPerColor is the new number of bits per color to use.
*
* @return None.
*
* @note The InstancePtr->TxInstance.MsaConfig structure is modified to
* reflect the new main stream attributes associated with a new
* bits per color value.
*
*******************************************************************************/
void XDp_TxCfgMsaSetBpc(XDp *InstancePtr, u8 Stream, u8 BitsPerColor)
{
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertVoid((Stream == XDP_TX_STREAM_ID1) ||
(Stream == XDP_TX_STREAM_ID2) ||
(Stream == XDP_TX_STREAM_ID3) ||
(Stream == XDP_TX_STREAM_ID4));
Xil_AssertVoid((BitsPerColor == 6) || (BitsPerColor == 8) ||
(BitsPerColor == 10) || (BitsPerColor == 12) ||
(BitsPerColor == 16));
InstancePtr->TxInstance.MsaConfig[Stream - 1].BitsPerColor =
BitsPerColor;
/* Calculate the rest of the MSA values. */
XDp_TxCfgMsaRecalculate(InstancePtr, Stream);
}
/******************************************************************************/
/**
* This function enables or disables synchronous clock mode for a video stream.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Stream is the stream number for which to enable or disable
* synchronous clock mode.
* @param Enable if set to 1, will enable synchronous clock mode.
* Otherwise, if set to 0, synchronous clock mode will be disabled.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void XDp_TxCfgMsaEnSynchClkMode(XDp *InstancePtr, u8 Stream, u8 Enable)
{
XDp_TxMainStreamAttributes *MsaConfig;
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertVoid((Stream == XDP_TX_STREAM_ID1) ||
(Stream == XDP_TX_STREAM_ID2) ||
(Stream == XDP_TX_STREAM_ID3) ||
(Stream == XDP_TX_STREAM_ID4));
Xil_AssertVoid((Enable == 0) || (Enable == 1));
MsaConfig = &InstancePtr->TxInstance.MsaConfig[Stream - 1];
MsaConfig->SynchronousClockMode = Enable;
if (Enable == 1) {
MsaConfig->Misc0 |= (1 <<
XDP_TX_MAIN_STREAMX_MISC0_COMPONENT_FORMAT_SHIFT);
}
else {
MsaConfig->Misc0 &= ~(1 <<
XDP_TX_MAIN_STREAMX_MISC0_COMPONENT_FORMAT_SHIFT);
}
}
/******************************************************************************/
/**
* This function clears the main stream attributes registers of the DisplayPort
* TX core and sets them to the values specified in the main stream attributes
* configuration structure.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Stream is the stream number for which to set the MSA values for.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void XDp_TxSetVideoMode(XDp *InstancePtr, u8 Stream)
{
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid((Stream == XDP_TX_STREAM_ID1) ||
(Stream == XDP_TX_STREAM_ID2) ||
(Stream == XDP_TX_STREAM_ID3) ||
(Stream == XDP_TX_STREAM_ID4));
XDp_TxClearMsaValues(InstancePtr, Stream);
XDp_TxSetMsaValues(InstancePtr, Stream);
}
/******************************************************************************/
/**
* This function clears the main stream attributes registers of the DisplayPort
* TX core.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Stream is the stream number for which to clear the MSA values.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void XDp_TxClearMsaValues(XDp *InstancePtr, u8 Stream)
{
XDp_Config *Config;
u32 StreamOffset[4] = {0, XDP_TX_STREAM2_MSA_START_OFFSET,
XDP_TX_STREAM3_MSA_START_OFFSET,
XDP_TX_STREAM4_MSA_START_OFFSET};
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertVoid((Stream == XDP_TX_STREAM_ID1) ||
(Stream == XDP_TX_STREAM_ID2) ||
(Stream == XDP_TX_STREAM_ID3) ||
(Stream == XDP_TX_STREAM_ID4));
Config = &InstancePtr->Config;
XDp_WriteReg(Config->BaseAddr, XDP_TX_MAIN_STREAM_HTOTAL +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_MAIN_STREAM_VTOTAL +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_MAIN_STREAM_POLARITY +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_MAIN_STREAM_HSWIDTH +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_MAIN_STREAM_VSWIDTH +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_MAIN_STREAM_HRES +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_MAIN_STREAM_VRES +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_MAIN_STREAM_HSTART +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_MAIN_STREAM_VSTART +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_MAIN_STREAM_MISC0 +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_MAIN_STREAM_MISC1 +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_USER_PIXEL_WIDTH +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_USER_DATA_COUNT_PER_LANE +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_M_VID +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_N_VID +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_STREAM1 + (Stream - 1) * 4, 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_TU_SIZE +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_MIN_BYTES_PER_TU +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_FRAC_BYTES_PER_TU +
StreamOffset[Stream - 1], 0);
XDp_WriteReg(Config->BaseAddr, XDP_TX_INIT_WAIT +
StreamOffset[Stream - 1], 0);
}
/******************************************************************************/
/**
* This function sets the main stream attributes registers of the DisplayPort TX
* core with the values specified in the main stream attributes configuration
* structure.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Stream is the stream number for which to set the MSA values for.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void XDp_TxSetMsaValues(XDp *InstancePtr, u8 Stream)
{
XDp_Config *ConfigPtr;
XDp_TxMainStreamAttributes *MsaConfig;
u32 StreamOffset[4] = {0, XDP_TX_STREAM2_MSA_START_OFFSET,
XDP_TX_STREAM3_MSA_START_OFFSET,
XDP_TX_STREAM4_MSA_START_OFFSET};
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_TX);
Xil_AssertVoid((Stream == XDP_TX_STREAM_ID1) ||
(Stream == XDP_TX_STREAM_ID2) ||
(Stream == XDP_TX_STREAM_ID3) ||
(Stream == XDP_TX_STREAM_ID4));
ConfigPtr = &InstancePtr->Config;
MsaConfig = &InstancePtr->TxInstance.MsaConfig[Stream - 1];
/* Set the main stream attributes to the associated DisplayPort TX core
* registers. */
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_MAIN_STREAM_HTOTAL +
StreamOffset[Stream - 1], MsaConfig->Vtm.Timing.HTotal);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_MAIN_STREAM_VTOTAL +
StreamOffset[Stream - 1],
MsaConfig->Vtm.Timing.F0PVTotal);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_MAIN_STREAM_POLARITY +
StreamOffset[Stream - 1],
MsaConfig->Vtm.Timing.HSyncPolarity |
(MsaConfig->Vtm.Timing.VSyncPolarity <<
XDP_TX_MAIN_STREAMX_POLARITY_VSYNC_POL_SHIFT));
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_MAIN_STREAM_HSWIDTH +
StreamOffset[Stream - 1], MsaConfig->Vtm.Timing.HSyncWidth);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_MAIN_STREAM_VSWIDTH +
StreamOffset[Stream - 1], MsaConfig->Vtm.Timing.F0PVSyncWidth);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_MAIN_STREAM_HRES +
StreamOffset[Stream - 1],
MsaConfig->Vtm.Timing.HActive);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_MAIN_STREAM_VRES +
StreamOffset[Stream - 1],
MsaConfig->Vtm.Timing.VActive);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_MAIN_STREAM_HSTART +
StreamOffset[Stream - 1], MsaConfig->HStart);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_MAIN_STREAM_VSTART +
StreamOffset[Stream - 1], MsaConfig->VStart);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_MAIN_STREAM_MISC0 +
StreamOffset[Stream - 1], MsaConfig->Misc0);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_MAIN_STREAM_MISC1 +
StreamOffset[Stream - 1], MsaConfig->Misc1);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_M_VID +
StreamOffset[Stream - 1],
MsaConfig->PixelClockHz / 1000);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_N_VID +
StreamOffset[Stream - 1], MsaConfig->NVid);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_USER_PIXEL_WIDTH +
StreamOffset[Stream - 1], MsaConfig->UserPixelWidth);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_USER_DATA_COUNT_PER_LANE +
StreamOffset[Stream - 1], MsaConfig->DataPerLane);
/* Set the transfer unit values to the associated DisplayPort TX core
* registers. */
if (InstancePtr->TxInstance.MstEnable == 1) {
XDp_WriteReg(ConfigPtr->BaseAddr,
XDP_TX_STREAM1 + (Stream - 1) * 4,
((MsaConfig->AvgBytesPerTU / 1000) << 16) |
(MsaConfig->AvgBytesPerTU % 1000));
}
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_TU_SIZE +
StreamOffset[Stream - 1], MsaConfig->TransferUnitSize);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_MIN_BYTES_PER_TU +
StreamOffset[Stream - 1], MsaConfig->AvgBytesPerTU / 1000);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_FRAC_BYTES_PER_TU +
StreamOffset[Stream - 1], MsaConfig->AvgBytesPerTU % 1000);
XDp_WriteReg(ConfigPtr->BaseAddr, XDP_TX_INIT_WAIT +
StreamOffset[Stream - 1], MsaConfig->InitWait);
}
/******************************************************************************/
/**
* This function configures the number of pixels output through the user data
* interface.
*
* @param InstancePtr is a pointer to the XDp instance.
* @param UserPixelWidth is the user pixel width to be configured.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void XDp_RxSetUserPixelWidth(XDp *InstancePtr, u8 UserPixelWidth)
{
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(XDp_GetCoreType(InstancePtr) == XDP_RX);
Xil_AssertVoid((UserPixelWidth == 1) || (UserPixelWidth == 2) ||
(UserPixelWidth == 4));
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_RX_USER_PIXEL_WIDTH,
UserPixelWidth);
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_RX_SOFT_RESET, 0x1);
XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_RX_SOFT_RESET, 0x0);
}
/******************************************************************************/
/**
* When the driver is in multi-stream transport (MST) mode, this function will
* make the necessary calculations to describe a stream in MST mode. The key
* values are the payload bandwidth number (PBN), the number of timeslots
* required for allocating the bandwidth, and the average bytes per transfer
* unit (both the integer and the fractional part).
*
* @param InstancePtr is a pointer to the XDp instance.
* @param Stream is the stream number to make the calculations for.
* @param BitsPerPixel is the number of bits that is used to store one
* pixel.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
static void XDp_TxCalculateTs(XDp *InstancePtr, u8 Stream, u8 BitsPerPixel)
{
XDp_TxMainStreamAttributes *MsaConfig =
&InstancePtr->TxInstance.MsaConfig[Stream - 1];
XDp_TxLinkConfig *LinkConfig = &InstancePtr->TxInstance.LinkConfig;
double PeakPixelBw;
u32 LinkBw;
double Average_StreamSymbolTimeSlotsPerMTP;
double Target_Average_StreamSymbolTimeSlotsPerMTP;
double MaximumTarget_Average_StreamSymbolTimeSlotsPerMTP;
u32 TsInt;
u32 TsFrac;
PeakPixelBw = ((double)MsaConfig->PixelClockHz / 1000000) *
((double)BitsPerPixel / 8);
LinkBw = (LinkConfig->LaneCount * LinkConfig->LinkRate * 27);
/* Calculate the payload bandiwdth number (PBN). */
InstancePtr->TxInstance.MstStreamConfig[Stream - 1].MstPbn =
1.006 * PeakPixelBw * ((double)64 / 54);
/* Ceil - round up if required, avoiding overhead of math.h. */
if ((double)(1.006 * PeakPixelBw * ((double)64 / 54)) >
((double)InstancePtr->TxInstance.MstStreamConfig[
Stream - 1].MstPbn)) {
InstancePtr->TxInstance.MstStreamConfig[Stream - 1].MstPbn++;
}
/* Calculate the average stream symbol time slots per MTP. */
Average_StreamSymbolTimeSlotsPerMTP = (64.0 * PeakPixelBw / LinkBw);
MaximumTarget_Average_StreamSymbolTimeSlotsPerMTP = (54.0 *
((double)InstancePtr->TxInstance.MstStreamConfig[Stream - 1].
MstPbn / LinkBw));
/* The target value to be found needs to follow the condition:
* Average_StreamSymbolTimeSlotsPerMTP <=
* Target_Average_StreamSymbolTimeSlotsPerMTP
* >= MaximumTarget_Average_StreamSymbolTimeSlotsPerMTP
* Obtain the greatest target value that satisfies the above condition
* and still a multiple of 1/TsFrac_Denominator.
* Note: TsFrac_Denominator = 8. */
/* Round down. */
Target_Average_StreamSymbolTimeSlotsPerMTP =
(u32)Average_StreamSymbolTimeSlotsPerMTP;
/* Find the greatest multiple that is less than the maximum. */
Target_Average_StreamSymbolTimeSlotsPerMTP += ((1.0 / 8.0) * (u32)(8.0 *
(MaximumTarget_Average_StreamSymbolTimeSlotsPerMTP -
Target_Average_StreamSymbolTimeSlotsPerMTP)));
/* Determine the integer and the fractional part of the number of time
* slots that will be allocated for the stream. */
TsInt = Target_Average_StreamSymbolTimeSlotsPerMTP;
TsFrac = (((double)Target_Average_StreamSymbolTimeSlotsPerMTP * 1000) -
(TsInt * 1000));
/* Store TsInt and TsFrac in AvgBytesPerTU. */
MsaConfig->AvgBytesPerTU = TsInt * 1000 + TsFrac;
/* Set the number of time slots to allocate for this stream. */
MsaConfig->TransferUnitSize = TsInt;
if (TsFrac != 0) {
/* Round up. */
MsaConfig->TransferUnitSize++;
}
if ((InstancePtr->Config.PayloadDataWidth == 4) &&
(MsaConfig->TransferUnitSize % 4) != 0) {
/* Set to a multiple of 4 boundary. */
MsaConfig->TransferUnitSize += (4 -
(MsaConfig->TransferUnitSize % 4));
}
else if ((MsaConfig->TransferUnitSize % 2) != 0) {
/* Set to an even boundary. */
MsaConfig->TransferUnitSize++;
}
/* Determine the PBN for the stream. */
InstancePtr->TxInstance.MstStreamConfig[Stream - 1].MstPbn =
MsaConfig->TransferUnitSize *
(LinkConfig->LaneCount * LinkConfig->LinkRate / 2);
}