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:
parent
ce10360848
commit
903d859429
24 changed files with 15446 additions and 0 deletions
7
XilinxProcessorIPLib/drivers/dp/data/dependencies.props
Normal file
7
XilinxProcessorIPLib/drivers/dp/data/dependencies.props
Normal 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
|
42
XilinxProcessorIPLib/drivers/dp/data/dp.mdd
Normal file
42
XilinxProcessorIPLib/drivers/dp/data/dp.mdd
Normal 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
|
186
XilinxProcessorIPLib/drivers/dp/data/dp.tcl
Normal file
186
XilinxProcessorIPLib/drivers/dp/data/dp.tcl
Normal 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
|
||||
}
|
23
XilinxProcessorIPLib/drivers/dp/examples/index.html
Executable file
23
XilinxProcessorIPLib/drivers/dp/examples/index.html
Executable 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>
|
76
XilinxProcessorIPLib/drivers/dp/examples/readme.txt
Normal file
76
XilinxProcessorIPLib/drivers/dp/examples/readme.txt
Normal 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_*.
|
|
@ -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");
|
||||
}
|
137
XilinxProcessorIPLib/drivers/dp/examples/xdp_selftest_example.c
Normal file
137
XilinxProcessorIPLib/drivers/dp/examples/xdp_selftest_example.c
Normal 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;
|
||||
}
|
268
XilinxProcessorIPLib/drivers/dp/examples/xdp_tx_audio_example.c
Normal file
268
XilinxProcessorIPLib/drivers/dp/examples/xdp_tx_audio_example.c
Normal 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");
|
||||
}
|
349
XilinxProcessorIPLib/drivers/dp/examples/xdp_tx_example_common.c
Normal file
349
XilinxProcessorIPLib/drivers/dp/examples/xdp_tx_example_common.c
Normal 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);
|
||||
}
|
135
XilinxProcessorIPLib/drivers/dp/examples/xdp_tx_example_common.h
Normal file
135
XilinxProcessorIPLib/drivers/dp/examples/xdp_tx_example_common.h
Normal 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_ */
|
352
XilinxProcessorIPLib/drivers/dp/examples/xdp_tx_intr_example.c
Normal file
352
XilinxProcessorIPLib/drivers/dp/examples/xdp_tx_intr_example.c
Normal 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);
|
||||
}
|
387
XilinxProcessorIPLib/drivers/dp/examples/xdp_tx_mst_example.c
Normal file
387
XilinxProcessorIPLib/drivers/dp/examples/xdp_tx_mst_example.c
Normal 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;
|
||||
}
|
201
XilinxProcessorIPLib/drivers/dp/examples/xdp_tx_poll_example.c
Normal file
201
XilinxProcessorIPLib/drivers/dp/examples/xdp_tx_poll_example.c
Normal 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);
|
||||
}
|
||||
}
|
201
XilinxProcessorIPLib/drivers/dp/examples/xdp_tx_timer_example.c
Normal file
201
XilinxProcessorIPLib/drivers/dp/examples/xdp_tx_timer_example.c
Normal 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);
|
||||
}
|
40
XilinxProcessorIPLib/drivers/dp/src/Makefile
Normal file
40
XilinxProcessorIPLib/drivers/dp/src/Makefile
Normal 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}
|
3194
XilinxProcessorIPLib/drivers/dp/src/xdp.c
Normal file
3194
XilinxProcessorIPLib/drivers/dp/src/xdp.c
Normal file
File diff suppressed because it is too large
Load diff
1038
XilinxProcessorIPLib/drivers/dp/src/xdp.h
Normal file
1038
XilinxProcessorIPLib/drivers/dp/src/xdp.h
Normal file
File diff suppressed because it is too large
Load diff
416
XilinxProcessorIPLib/drivers/dp/src/xdp_edid.c
Normal file
416
XilinxProcessorIPLib/drivers/dp/src/xdp_edid.c
Normal 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;
|
||||
}
|
2467
XilinxProcessorIPLib/drivers/dp/src/xdp_hw.h
Normal file
2467
XilinxProcessorIPLib/drivers/dp/src/xdp_hw.h
Normal file
File diff suppressed because it is too large
Load diff
761
XilinxProcessorIPLib/drivers/dp/src/xdp_intr.c
Normal file
761
XilinxProcessorIPLib/drivers/dp/src/xdp_intr.c
Normal 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);
|
||||
}
|
||||
}
|
3071
XilinxProcessorIPLib/drivers/dp/src/xdp_mst.c
Normal file
3071
XilinxProcessorIPLib/drivers/dp/src/xdp_mst.c
Normal file
File diff suppressed because it is too large
Load diff
339
XilinxProcessorIPLib/drivers/dp/src/xdp_selftest.c
Normal file
339
XilinxProcessorIPLib/drivers/dp/src/xdp_selftest.c
Normal 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;
|
||||
}
|
93
XilinxProcessorIPLib/drivers/dp/src/xdp_sinit.c
Normal file
93
XilinxProcessorIPLib/drivers/dp/src/xdp_sinit.c
Normal 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;
|
||||
}
|
950
XilinxProcessorIPLib/drivers/dp/src/xdp_spm.c
Normal file
950
XilinxProcessorIPLib/drivers/dp/src/xdp_spm.c
Normal 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);
|
||||
}
|
Loading…
Add table
Reference in a new issue