更新UCD-API库及文档

This commit is contained in:
xinzhu.yin
2026-07-02 17:16:18 +08:00
parent a500751d85
commit 9fa811a9eb
290 changed files with 9558 additions and 2306 deletions

View File

@@ -1,6 +1,8 @@
from .link_rx_caps import LinkDisplayPortCaps
from .link_rx_status import *
from UniTAP.libs.lib_tsi.tsi_io import PortIO
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
import UniTAP.libs.lib_tsi.tsi_types as ci
from .dp_cable_info import DpCableInfo, CableCapabilitiesEnum
from .link_rx_aux_controller import DisplayPortAUXController
from UniTAP.dev.ports.modules.dpcd import DPCDRegisters
@@ -20,7 +22,7 @@ class LinkDisplayPortRx:
self.__HW_CAPS = hw_caps
self.__status = LinkDisplayPortStatusSink(port_io, self.__HW_CAPS)
self.__capabilities = LinkDisplayPortCaps(port_io, self.__HW_CAPS)
self.__cable_info = DpCableInfo(port_io, TSI_DPRX_CABLE_ATTRIBUTES_R)
self.__cable_info = DpCableInfo(port_io, p_ci.TSI_DPRX_CABLE_ATTRIBUTES_R)
self.__aux_controller = DisplayPortAUXController(port_io, dpcd)
@property
@@ -60,7 +62,7 @@ class LinkDisplayPortRx:
Args:
duration_us (int)
"""
self.__io.set(TSI_DPRX_HPD_PULSE_W, duration_us, c_int)
self.__io.set(ci.TSI_DPRX_HPD_PULSE_W, duration_us, c_int)
def set_assert_state(self, state: bool):
"""
@@ -70,7 +72,7 @@ class LinkDisplayPortRx:
state (bool)
"""
val = 0x1 if state else 0x0
self.__io.set(TSI_FORCE_HOT_PLUG_STATE_W, val)
self.__io.set(ci.TSI_FORCE_HOT_PLUG_STATE_W, val)
@property
def scrambler_seed(self) -> int:
@@ -84,7 +86,7 @@ class LinkDisplayPortRx:
warnings.warn("Scrambler Seed is not supported.")
return 0
return self.__io.get(TSI_DPRX_SCR_SEED, c_uint32)[1]
return self.__io.get(ci.TSI_DPRX_SCR_SEED, c_uint32)[1]
@scrambler_seed.setter
def scrambler_seed(self, value: int = 0):
@@ -98,7 +100,7 @@ class LinkDisplayPortRx:
raise ValueError(f"Scrambler seed {value} is not available.")
if self.__HW_CAPS.scrambler_seed:
self.__io.set(TSI_DPRX_SCR_SEED, value)
self.__io.set(ci.TSI_DPRX_SCR_SEED, value)
else:
warnings.warn("Scrambler Seed is not supported.")

View File

@@ -1,7 +1,8 @@
from ctypes import c_uint32, c_int
from typing import Optional
from UniTAP.libs.lib_tsi import PortIO
from UniTAP.libs.lib_tsi.tsi_private_types import *
from UniTAP.libs.lib_tsi.tsi_types import *
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
import UniTAP.libs.lib_tsi.tsi_types as ci
from .private_link_rx_types import RoutedLTStatusPrivate
from .link_rx_types import RoutedLTStatus, RoutedLTConfig
from UniTAP.dev.ports.modules.dpcd import DPCDRegisters
@@ -34,7 +35,7 @@ class DisplayPortAUXController:
else:
ctrl &= ~0x01
res = self.__io.set(TSI_DPRX_LT_ROUTE_CONTROL_W, ctrl, c_uint32)
res = self.__io.set(ci.TSI_DPRX_LT_ROUTE_CONTROL_W, ctrl, c_uint32)
if not res:
raise Exception("The feature requires a license key and the required license key is not installed.")
@@ -50,17 +51,18 @@ class DisplayPortAUXController:
max_rate_dp14 = 0
max_rate_dp20 = 0
if config.is128b132b:
if config.link_bw == 1:
max_rate_dp20 = 1
elif config.link_bw == 2:
max_rate_dp20 = 3
elif config.link_bw == 4:
max_rate_dp20 = 5
if not config.is_edp_lt:
if config.is128b132b:
if config.link_bw == 1:
max_rate_dp20 = 1
elif config.link_bw == 2:
max_rate_dp20 = 3
elif config.link_bw == 4:
max_rate_dp20 = 5
max_rate_dp14 = 0x1e
else:
max_rate_dp14 = config.link_bw
max_rate_dp14 = 0x1e
else:
max_rate_dp14 = config.link_bw
res = self.__set_routed_lt_config(config.int_value())
if not res:
@@ -91,12 +93,21 @@ class DisplayPortAUXController:
if config.is128b132b:
self.__dpcd.write(0x21, 0x01)
self.__dpcd.write(0x90, 0xff)
edp_data = [0x00] * 16
self.__dpcd.write(0x10, edp_data)
self.__dpcd.write(0x700, 0x00)
dsc_data = [0x0f, 0x21, 0x03, 0x03, 0xeb, 0x07, 0x01, 0x00, 0x00, 0x1f, 0x0e, 0x11, 0x08, 0x07, 0x00, 0x00]
self.__dpcd.write(0x60, dsc_data)
self.__dpcd.write(0x2217, 0x06)
else:
self.__dpcd.write(0x21, 0x00)
self.__dpcd.write(0x90, 0x00)
edp_data = [0x00] * 16
if config.is_edp_lt:
edp_data[0] = config.link_bw & 0xff
edp_data[1] = (config.link_bw >> 8) & 0xff
self.__dpcd.write(0x10, edp_data)
self.__dpcd.write(0x700, config.is_edp_lt and 0x06 or 0x00)
dsc_data = [0x00] * 16
self.__dpcd.write(0x60, dsc_data)
self.__dpcd.write(0x2217, 0x00)
@@ -200,19 +211,19 @@ class DisplayPortAUXController:
step=routed_lt_status.step)
def __set_routed_lt_config(self, value: int) -> bool:
res = self.__io.set(TSI_DPRX_LT_ROUTE_CREATE, value, c_uint32)
res = self.__io.set(ci.TSI_DPRX_LT_ROUTE_CREATE, value, c_uint32)
return res >= 0
def __set_force_cable_status_to_plugged(self, enable: bool):
val = 0x3C if enable else 0
self.__io.set(TSI_DPRX_HPD_FORCE, val, c_int)
self.__io.set(ci.TSI_DPRX_HPD_FORCE, val, c_int)
def __read_status(self) -> Optional[RoutedLTStatusPrivate]:
res, status = self.__io.get(TSI_DPRX_LT_ROUTE_STATUS_R, RoutedLTStatusPrivate)
res, status = self.__io.get(ci.TSI_DPRX_LT_ROUTE_STATUS_R, RoutedLTStatusPrivate)
if res >= 0:
return status
return None
def __generate_short_hpd_pulse(self, value: int):
self.__io.set(TSI_DPRX_HPD_PULSE_W, value, c_int)
self.__io.set(ci.TSI_DPRX_HPD_PULSE_W, value, c_int)

View File

@@ -1,10 +1,11 @@
import warnings
from ctypes import c_int, c_uint, c_uint32
from typing import List, Optional, Union, Type
from .link_rx_types import LinkCapabilities, LinkEDPCapabilities, DisplayPortLinkCaps
from .private_link_rx_types import DPRXHWCaps, DPRXLinkControl
from UniTAP.libs.lib_tsi import PortIO
from UniTAP.libs.lib_tsi.tsi_types import *
import UniTAP.libs.lib_tsi.tsi_types as ci
class LinkDisplayPortCaps:
@@ -27,7 +28,8 @@ class LinkDisplayPortCaps:
if isinstance(capabilities, LinkCapabilities):
self.__set_max_lanes(capabilities.max_lane)
self.__set_max_bitrate(capabilities.bit_rate)
self.__set_force_cable_status_to_plugged(capabilities.force_cable_status_to_plugged)
# TODO: Temporarily disabled for writing value
# self.__set_force_cable_status_to_plugged(capabilities.force_cable_status_to_plugged)
self.__set_dp_link_control(old_dp2_lt=capabilities.old_dp_2_0_lt)
self.__set_dp_128_132_bitrates(capabilities.dp_128_132_bitrates)
self.__set_bitrate_override(10.0, capabilities.override_10g)
@@ -86,10 +88,10 @@ class LinkDisplayPortCaps:
return
if lane_count not in [1, 2, 4]:
raise ValueError(f"Incorrect lane count number {lane_count}. Must be from list: 1, 2, 4")
self.__io.set(TSI_DPRX_MAX_LANES, lane_count, c_int)
self.__io.set(ci.TSI_DPRX_MAX_LANES, lane_count, c_int)
def __get_max_lanes(self) -> int:
return self.__io.get(TSI_DPRX_MAX_LANES)[1]
return self.__io.get(ci.TSI_DPRX_MAX_LANES)[1]
def __set_max_bitrate(self, bitrate: Optional[float]):
if bitrate is None:
@@ -97,10 +99,10 @@ class LinkDisplayPortCaps:
bitrate = round(bitrate / 0.27)
if bitrate not in [6, 10, 20, 25, 30]:
raise ValueError(f"Incorrect bit rate number {bitrate}. Must be from list: 1.62, 2.7, 5.4, 6.75, 8.1")
self.__io.set(TSI_DPRX_MAX_LINK_RATE, bitrate, c_int)
self.__io.set(ci.TSI_DPRX_MAX_LINK_RATE, bitrate, c_int)
def __get_max_bitrate(self) -> int:
return round(self.__io.get(TSI_DPRX_MAX_LINK_RATE)[1] * 0.27, 2)
return round(self.__io.get(ci.TSI_DPRX_MAX_LINK_RATE)[1] * 0.27, 2)
def __set_bitrate_override(self, to_override: float, with_override: Optional[float]):
if with_override is None:
@@ -109,19 +111,19 @@ class LinkDisplayPortCaps:
if not isinstance(to_override, float) or not isinstance(with_override, float):
raise TypeError("DP 128b/132b bitrate override settings must float type!")
list_value = self.__io.get(TSI_DP2RX_CUSTOM_RATE_MAP, c_uint, 3)[1]
list_value = self.__io.get(ci.TSI_DP2RX_CUSTOM_RATE_MAP, c_uint, 3)[1]
if with_override not in [2.5, 2.7, 5.0, 5.4]:
raise ValueError(f"Incorrect bit rate number {with_override}. "
f"Must be from list: 2.5, 2.7, 5.0, 5.4")
list_value[0] = int(with_override * 1000000000 / 200000)
self.__io.set(TSI_DP2RX_CUSTOM_RATE_MAP, list_value, c_uint, 3)
self.__io.set(ci.TSI_DP2RX_CUSTOM_RATE_MAP, list_value, c_uint, 3)
def __get_bitrate_override(self, to_override: float) -> Optional[float]:
if not isinstance(to_override, float):
raise TypeError("DP 128b/132b bitrate override settings must float type!")
override_list = self.__io.get(TSI_DP2RX_CUSTOM_RATE_MAP, c_uint, 3)[1]
override_list = self.__io.get(ci.TSI_DP2RX_CUSTOM_RATE_MAP, c_uint, 3)[1]
if override_list.count(0) == len(override_list):
return None
@@ -138,21 +140,21 @@ class LinkDisplayPortCaps:
if edp_aux_preamble is not None:
ctrl.edp_aux_preamble = edp_aux_preamble
self.__io.set(TSI_DPRX_LINK_CONTROL, ctrl.value(), c_uint32)
self.__io.set(ci.TSI_DPRX_LINK_CONTROL, ctrl.value(), c_uint32)
def __get_dp_link_control(self) -> DPRXLinkControl:
return self.__io.get(TSI_DPRX_LINK_CONTROL, DPRXLinkControl)[1]
return self.__io.get(ci.TSI_DPRX_LINK_CONTROL, DPRXLinkControl)[1]
def __set_dp_128_132_bitrates(self, rates: Optional[List[float]]):
flags = self.__io.get(TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
flags = self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
if rates is None:
return
elif isinstance(rates, list) and len(rates) == 0:
flags &= ~(1 << 4)
self.__io.set(TSI_DPRX_LINK_FLAGS, flags, c_int)
self.__io.set(ci.TSI_DPRX_LINK_FLAGS, flags, c_int)
else:
flags |= (1 << 4)
self.__io.set(TSI_DPRX_LINK_FLAGS, flags, c_int)
self.__io.set(ci.TSI_DPRX_LINK_FLAGS, flags, c_int)
val = 0
if 10.0 in rates:
val |= 0x01
@@ -160,12 +162,12 @@ class LinkDisplayPortCaps:
val |= 0x04
if 20.0 in rates:
val |= 0x02
self.__io.set(TSI_DP2RX_LINK_RATE_CAPS, val, c_int)
self.__io.set(ci.TSI_DP2RX_LINK_RATE_CAPS, val, c_int)
def __get_dp_128_132_bitrates(self) -> Optional[List[float]]:
val = (self.__io.get(TSI_DPRX_LINK_FLAGS)[1] >> 4) & 0x1
val = (self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] >> 4) & 0x1
if val:
rates = self.__io.get(TSI_DP2RX_LINK_RATE_CAPS)[1]
rates = self.__io.get(ci.TSI_DP2RX_LINK_RATE_CAPS)[1]
list_rates = []
if rates & 0x01:
list_rates.append(10.0)
@@ -181,47 +183,47 @@ class LinkDisplayPortCaps:
if enable is None:
return
val = 0x3C if enable else 0
self.__io.set(TSI_DPRX_HPD_FORCE, val, c_int)
self.__io.set(ci.TSI_DPRX_HPD_FORCE, val, c_int)
def __get_force_cable_status_to_plugged(self) -> bool:
return bool(self.__io.get(TSI_DPRX_HPD_FORCE)[1])
return bool(self.__io.get(ci.TSI_DPRX_HPD_FORCE)[1])
def __set_dsc(self, enable: Optional[bool]):
if enable is None:
return
val = 0x1 if enable else 0x0
if self.__caps.dsc:
self.__io.set(TSI_DPRX_DSC_CONTROL, val, c_int)
self.__io.set(ci.TSI_DPRX_DSC_CONTROL, val, c_int)
def __get_dsc(self) -> Optional[bool]:
if self.__io.get(TSI_DPRX_DSC_STATUS_R)[1] & 0x1:
return bool(self.__io.get(TSI_DPRX_DSC_CONTROL)[1] & 0x1)
if self.__io.get(ci.TSI_DPRX_DSC_STATUS_R)[1] & 0x1:
return bool(self.__io.get(ci.TSI_DPRX_DSC_CONTROL)[1] & 0x1)
def __set_fec(self, enable: Optional[bool]):
if enable is None:
return
val = 0x1 if enable else 0x0
if self.__caps.fec:
self.__io.set(TSI_DPRX_FEC_CONTROL, val, c_int)
self.__io.set(ci.TSI_DPRX_FEC_CONTROL, val, c_int)
def __get_fec(self) -> Optional[bool]:
if self.__caps.fec:
return bool(self.__io.get(TSI_DPRX_FEC_CONTROL)[1] & 0x1)
return bool(self.__io.get(ci.TSI_DPRX_FEC_CONTROL)[1] & 0x1)
def __set_mst(self, enable: Optional[bool]):
if enable is None:
return
flags = self.__io.get(TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
flags = self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
if enable:
flags |= 1
else:
flags &= ~1
if self.__caps.mst:
self.__io.set(TSI_DPRX_LINK_FLAGS, flags, c_int)
self.__io.set(ci.TSI_DPRX_LINK_FLAGS, flags, c_int)
def __get_mst(self) -> Optional[bool]:
if self.__caps.mst:
return bool(self.__io.get(TSI_DPRX_LINK_FLAGS)[1] & 0x1)
return bool(self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] & 0x1)
def __set_mst_sink_count(self, count: int):
if count is None:
@@ -230,73 +232,73 @@ class LinkDisplayPortCaps:
if count > self.__caps.mst_stream_count:
warnings.warn(f"Maximum sink count: {self.__caps.mst_stream_count}")
else:
self.__io.set(TSI_DPRX_MST_SINK_COUNT, count, c_uint32)
self.__io.set(ci.TSI_DPRX_MST_SINK_COUNT, count, c_uint32)
else:
warnings.warn("MST or Custom Sink Count are not supported")
def __get_mst_sink_count(self) -> int:
if self.__caps.sink_cnt_config and self.__caps.mst:
return int(self.__io.get(TSI_DPRX_MST_SINK_COUNT)[1])
return int(self.__io.get(ci.TSI_DPRX_MST_SINK_COUNT)[1])
else:
return 0
def __set_tps3(self, enable: Optional[bool]):
if enable is None:
return
flags = self.__io.get(TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
flags = self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
if enable:
flags |= (1 << 1)
else:
flags &= ~(1 << 1)
if self.__caps.fec:
self.__io.set(TSI_DPRX_LINK_FLAGS, flags, c_int)
self.__io.set(ci.TSI_DPRX_LINK_FLAGS, flags, c_int)
def __get_tps3(self) -> Optional[bool]:
if self.__caps.fec:
return bool((self.__io.get(TSI_DPRX_LINK_FLAGS)[1] >> 1) & 0x1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] >> 1) & 0x1)
def __set_tps4(self, enable: Optional[bool]):
if enable is None:
return
flags = self.__io.get(TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
flags = self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
if enable:
flags |= (1 << 2)
else:
flags &= ~(1 << 2)
if self.__caps.fec:
self.__io.set(TSI_DPRX_LINK_FLAGS, flags, c_int)
self.__io.set(ci.TSI_DPRX_LINK_FLAGS, flags, c_int)
def __get_tps4(self) -> Optional[bool]:
if self.__caps.fec:
return bool((self.__io.get(TSI_DPRX_LINK_FLAGS)[1] >> 2) & 0x1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] >> 2) & 0x1)
def __set_ss_sbm(self, enable: bool):
if enable is None:
return
if self.__caps.dp2_support_rates:
flags = self.__io.get(TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
flags = self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
if enable:
flags |= (1 << 5)
else:
flags &= ~(1 << 5)
self.__io.set(TSI_DPRX_LINK_FLAGS, flags, c_int)
self.__io.set(ci.TSI_DPRX_LINK_FLAGS, flags, c_int)
def __get_ss_sbm(self) -> Optional[bool]:
if self.__caps.dp2_support_rates:
return bool((self.__io.get(TSI_DPRX_LINK_FLAGS)[1] >> 5) & 0x1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] >> 5) & 0x1)
def __set_edp_support(self, enable: bool):
if self.__caps.edp:
flags = self.__io.get(TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
flags = self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
if enable:
flags |= (1 << 3)
else:
flags &= ~(1 << 3)
self.__io.set(TSI_DPRX_LINK_FLAGS, flags, c_int)
self.__io.set(ci.TSI_DPRX_LINK_FLAGS, flags, c_int)
def __get_edp_support(self) -> Optional[bool]:
if self.__caps.edp:
return bool((self.__io.get(TSI_DPRX_LINK_FLAGS)[1] >> 3) & 0x1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] >> 3) & 0x1)
def __set_edp_sel_rates(self, rates: List[float]):
if self.__caps.edp:
@@ -310,11 +312,11 @@ class LinkDisplayPortCaps:
j += 1
rates.sort()
self.__io.set(TSI_DPRX_EDP_SEL_RATES, to_write_list, data_type=c_uint32, data_count=8)
self.__io.set(ci.TSI_DPRX_EDP_SEL_RATES, to_write_list, data_type=c_uint32, data_count=8)
def __get_edp_sel_rates(self) -> List[float]:
if self.__caps.edp:
rates = self.__io.get(TSI_DPRX_EDP_SEL_RATES, data_type=c_uint32, data_count=8)[1]
rates = self.__io.get(ci.TSI_DPRX_EDP_SEL_RATES, data_type=c_uint32, data_count=8)[1]
res_rates = []
for rate in rates:
if rate == 0:
@@ -324,7 +326,7 @@ class LinkDisplayPortCaps:
def __get_edp_caps_rates(self) -> List[float]:
if self.__caps.edp:
rates = self.__io.get(TSI_DPRX_EDP_CAPS_RATES_R, data_type=c_uint32, data_count=32)[1]
rates = self.__io.get(ci.TSI_DPRX_EDP_CAPS_RATES_R, data_type=c_uint32, data_count=32)[1]
new_rates = []
for rate in rates:
if rate > 0:

View File

@@ -1,11 +1,12 @@
import time
import warnings
from ctypes import c_int, c_uint32, c_uint8, c_uint
from typing import Optional
from UniTAP.libs.lib_tsi import PortIO
from UniTAP.libs.lib_tsi.tsi_private_types import *
from UniTAP.libs.lib_tsi.tsi_types import *
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
import UniTAP.libs.lib_tsi.tsi_types as ci
from UniTAP.utils.function_wrapper import function_scheduler
from .private_link_rx_types import DPRXHWCaps
from .link_status_common import *
@@ -48,7 +49,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of int type
"""
res, value = self.__io.get(TSI_DPRX_MST_STATUS_R, c_uint)
res, value = self.__io.get(p_ci.TSI_DPRX_MST_STATUS_R, c_uint)
return value >> 8
@property
@@ -59,7 +60,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of int type
"""
return self.__io.get(TSI_DPRX_LINK_LANE_COUNT_R, c_int)[1]
return self.__io.get(ci.TSI_DPRX_LINK_LANE_COUNT_R, c_int)[1]
@property
def link_encoding(self) -> DpLinkEncoding:
@@ -69,7 +70,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of `DpLinkEncoding` type
"""
result, value = self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint)
result, value = self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint)
if value >> 20 & 1:
return DpLinkEncoding.LE_128b132b
@@ -84,7 +85,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of float type
"""
current_link_rate = self.__io.get(TSI_DPRX_LINK_BR_R, c_int)[1]
current_link_rate = self.__io.get(ci.TSI_DPRX_LINK_BR_R, c_int)[1]
if self.link_encoding == DpLinkEncoding.LE_8b10b:
return round(current_link_rate * 0.27, 2)
else:
@@ -105,7 +106,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool(self.__io.get(TSI_DPRX_HPD_STATUS_R, c_int)[1] & 1)
return bool(self.__io.get(ci.TSI_DPRX_HPD_STATUS_R, c_int)[1] & 1)
@property
def cable_state(self) -> bool:
@@ -115,7 +116,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool(self.__io.get(TSI_DPRX_HPD_STATUS_R, c_int)[1] & 4)
return bool(self.__io.get(ci.TSI_DPRX_HPD_STATUS_R, c_int)[1] & 4)
@property
def enhanced_framing(self) -> bool:
@@ -125,7 +126,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool((self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 17) & 1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 17) & 1)
@property
def scrambling_enabled(self) -> bool:
@@ -135,7 +136,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool((self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 18) & 1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 18) & 1)
@property
def dsc_enabled(self) -> Union[bool, None]:
@@ -146,7 +147,7 @@ class LinkDisplayPortStatusSink:
object of bool|None type
"""
if self.__caps.dsc or self.__caps.dsc2:
return bool((self.__io.get(TSI_DPRX_DSC_STATUS_R)[1] >> 1) & 1)
return bool((self.__io.get(ci.TSI_DPRX_DSC_STATUS_R)[1] >> 1) & 1)
else:
return None
@@ -159,7 +160,7 @@ class LinkDisplayPortStatusSink:
object of bool|None type
"""
if self.__caps.fec or self.__caps.fec2:
return bool(self.__io.get(TSI_DPRX_FEC_STATUS_R)[1] & 1)
return bool(self.__io.get(ci.TSI_DPRX_FEC_STATUS_R)[1] & 1)
else:
return None
@@ -172,7 +173,7 @@ class LinkDisplayPortStatusSink:
object of bool|None type
"""
if self.__caps.mst:
return bool((self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 19) & 1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 19) & 1)
else:
return None
@@ -184,8 +185,8 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool|None type
"""
if (self.__io.get(TSI_DPRX_SSC_STATUS_R, c_int)[1] >> 1) & 1:
return bool(self.__io.get(TSI_DPRX_SSC_STATUS_R, c_int)[1] & 1)
if (self.__io.get(ci.TSI_DPRX_SSC_STATUS_R, c_int)[1] >> 1) & 1:
return bool(self.__io.get(ci.TSI_DPRX_SSC_STATUS_R, c_int)[1] & 1)
else:
return None
@@ -197,7 +198,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool((self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 16) & 1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 16) & 1)
@property
def eq_ila(self) -> bool:
@@ -207,7 +208,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool((self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 30) & 1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 30) & 1)
@property
def cds_ila(self) -> bool:
@@ -217,7 +218,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool((self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 29) & 1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 29) & 1)
@property
def lt_fail(self) -> bool:
@@ -227,7 +228,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool((self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 28) & 1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 28) & 1)
def lane(self, lane_number: int) -> LaneStatus:
"""
@@ -242,10 +243,10 @@ class LinkDisplayPortStatusSink:
if not (0 <= lane_number <= 3):
raise ValueError(f"Incorrect lane number {lane_number}. Available range: 0-{self.lane_count}")
status = self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1]
voltage_swing = self.__io.get(TSI_DPRX_LINK_VS_R, c_uint32)[1]
pre_emphasis = self.__io.get(TSI_DPRX_LINK_PE_R, c_uint32)[1]
_, error_counters = self.__io.get(TSI_DPRX_GET_ERROR_COUNTS_R, c_uint32 * 4)
status = self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1]
voltage_swing = self.__io.get(ci.TSI_DPRX_LINK_VS_R, c_uint32)[1]
pre_emphasis = self.__io.get(ci.TSI_DPRX_LINK_PE_R, c_uint32)[1]
_, error_counters = self.__io.get(ci.TSI_DPRX_GET_ERROR_COUNTS_R, c_uint32 * 4)
lane_status = LaneStatus()
@@ -273,7 +274,7 @@ class LinkDisplayPortStatusSink:
if self.__caps.dp2_support_rates and self.link_encoding == DpLinkEncoding.LE_128b132b:
lane_status.voltage_swing = 0
lane_status.pre_emphasis = 0
_, ffe_preset = self.__io.get(TSI_DP2RX_LINK_FFE_PRESET_R, c_uint32)
_, ffe_preset = self.__io.get(ci.TSI_DP2RX_LINK_FFE_PRESET_R, c_uint32)
lane_status.ffe_preset = (ffe_preset >> (8 * lane_number)) & 0xF
else:
lane_status.voltage_swing = (voltage_swing >> (8 * lane_number)) & 0x3
@@ -297,7 +298,7 @@ class LinkDisplayPortStatusSink:
raise ValueError(f"Selected stream {stream_index} is not available. "
f"Available stream number: {self.mst_stream_count}")
res = self.__io.get(TSI_DPRX_VC_TABLE_R, VCPTable, 4)[1]
res = self.__io.get(ci.TSI_DPRX_VC_TABLE_R, VCPTable, 4)[1]
if self.mst_enabled:
status = VCPStatus()
@@ -316,7 +317,7 @@ class LinkDisplayPortStatusSink:
def __check_video(self) -> bool:
def is_msa_available(io):
result, msa_info, size = io.get(TSI_DPRX_MSA_INFO_R, DpMsa, 4)
result, msa_info, size = io.get(p_ci.TSI_DPRX_MSA_INFO_R, DpMsa, 4)
return size > 0
return function_scheduler(is_msa_available, self.__io, interval=5, timeout=10)
@@ -339,7 +340,7 @@ class LinkDisplayPortStatusSink:
time.sleep(1)
result, msa_info, size = self.__io.get(TSI_DPRX_MSA_INFO_R, DpMsa, 4)
result, msa_info, size = self.__io.get(p_ci.TSI_DPRX_MSA_INFO_R, DpMsa, 4)
if stream_index < size:
msa_info_private = MSAInfo(msa_info[stream_index])
@@ -348,22 +349,22 @@ class LinkDisplayPortStatusSink:
stream_status.mvid = msa_info_private.m_video
stream_status.nvid = msa_info_private.n_video
result = self.__io.get(TSI_DPRX_CRC_LOG_R, DpCrc, self.mst_stream_count)
if result[0] >= TSI_SUCCESS and self.mst_stream_count > 1:
result = self.__io.get(ci.TSI_DPRX_CRC_LOG_R, DpCrc, self.mst_stream_count)
if result[0] >= ci.TSI_SUCCESS and self.mst_stream_count > 1:
stream_status.crc = [result[1][stream_index].r, result[1][stream_index].g, result[1][stream_index].b]
elif result[0] >= TSI_SUCCESS and size == 1:
elif result[0] >= ci.TSI_SUCCESS and size == 1:
stream_status.crc = [result[1].r, result[1].g, result[1].b]
result = self.__io.get(TSI_DPRX_DSC_CRC_R, DpCrc, self.mst_stream_count)
if result[0] >= TSI_SUCCESS and self.mst_stream_count > 1:
result = self.__io.get(ci.TSI_DPRX_DSC_CRC_R, DpCrc, self.mst_stream_count)
if result[0] >= ci.TSI_SUCCESS and self.mst_stream_count > 1:
stream_status.dsc_crc = [result[1][stream_index].r, result[1][stream_index].g, result[1][stream_index].b]
elif result[0] >= TSI_SUCCESS and size == 1:
elif result[0] >= ci.TSI_SUCCESS and size == 1:
stream_status.dsc_crc = [result[1].r, result[1].g, result[1].b]
if self.__caps.dp2_support_rates:
res = self.__io.get(TSI_DPRX_SDP_CRC16_CTRL, c_uint32)
stream_status.sdp_crc16.state = False if res[0] < TSI_SUCCESS else (res[1] & 0x1 == 1)
stream_status.sdp_crc16.errors = self.__io.get(TSI_DPRX_SDP_CRC16_COUNTERS, c_uint8,
res = self.__io.get(p_ci.TSI_DPRX_SDP_CRC16_CTRL, c_uint32)
stream_status.sdp_crc16.state = False if res[0] < ci.TSI_SUCCESS else (res[1] & 0x1 == 1)
stream_status.sdp_crc16.errors = self.__io.get(p_ci.TSI_DPRX_SDP_CRC16_COUNTERS, c_uint8,
self.__caps.mst_stream_count)[1][stream_index]
else:
raise ValueError(f"Selected stream {stream_index} is not available. "
@@ -378,7 +379,7 @@ class LinkDisplayPortStatusSink:
if not self.__caps.dp2_support_rates:
warnings.warn("SDP CRC16 is not supported. Cannot reset errors.")
return
self.__io.set(TSI_DPRX_SDP_CRC16_COUNTERS, 0)
self.__io.set(p_ci.TSI_DPRX_SDP_CRC16_COUNTERS, 0)
def __str__(self) -> str:
lane_status_str = ""

View File

@@ -78,6 +78,7 @@ class RoutedLTConfig:
def __init__(self):
self.__is128b132b = False
self.__is_old_dp20_lt = False
self.__is_edp_lt = False
self.__vs = 0
self.__pe = 0
self.__ffe = 0
@@ -100,13 +101,21 @@ class RoutedLTConfig:
def is_old_dp20_lt(self, value: bool = False):
self.__is_old_dp20_lt = value
@property
def is_edp_lt(self) -> bool:
return self.__is_edp_lt
@is_edp_lt.setter
def is_edp_lt(self, value: bool = False):
self.__is_edp_lt = value
@property
def vs(self) -> int:
return self.__vs
@vs.setter
def vs(self, value: int):
if not (0 <= value < 3):
if not (0 <= value <= 0x3):
raise ValueError(f"VS cannot be less than 0 and more than 3")
self.__vs = value
@@ -136,8 +145,8 @@ class RoutedLTConfig:
@link_bw.setter
def link_bw(self, value: int):
if not (0 <= value <= 0xFF):
raise ValueError(f"link_bw cannot be less than 0 and more than 0xFF")
if not (0 <= value <= 0xFFFF):
raise ValueError(f"link_bw cannot be less than 0 and more than 0xFFFF")
self.__link_bw = value
@property
@@ -151,8 +160,9 @@ class RoutedLTConfig:
self.__lane_count = value
def int_value(self) -> int:
val = (self.ffe << 8) if self.is128b132b else ((self.vs << 8) | (self.pe << 10))
return self.is128b132b | (self.__is_old_dp20_lt << 1) | val | (self.link_bw << 16) | (self.lane_count << 24)
val = (self.ffe << 4) if self.is128b132b else ((self.vs << 4) | (self.pe << 6))
return self.is128b132b | (self.__is_old_dp20_lt << 1) | (self.__is_edp_lt << 2) | val | \
(self.lane_count << 8) | (self.link_bw << 16)
class RoutedLTStatus:

View File

@@ -1,8 +1,12 @@
import warnings
from ctypes import c_uint, c_uint8
from typing import List
from warnings import warn
from UniTAP.libs.lib_tsi import *
from UniTAP.dev.ports.modules.link.dp.link_status_common import DpLinkTrainingResult
from UniTAP.libs.lib_tsi.tsi_io import PortIO
import UniTAP.libs.lib_tsi.tsi_types as ci
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
from UniTAP.utils.function_wrapper import *
from .link_tx_status import LinkDisplayPortStatusSource
from .link_tx_config import LinkDisplayPortConfig
@@ -34,7 +38,7 @@ class LinkDisplayPortTx:
self.__status = LinkDisplayPortStatusSource(self.__io, self.__HW_CAPS, dpcd)
self.__config = LinkDisplayPortConfig(self.__io, self.__HW_CAPS)
self.__force_config = LinkDisplayPortForceConfig(self.__io, self.__HW_CAPS)
self.__cable_info = DpCableInfo(port_io, TSI_DPTX_CABLE_ATTRIBUTES_R)
self.__cable_info = DpCableInfo(port_io, p_ci.TSI_DPTX_CABLE_ATTRIBUTES_R)
@property
def status(self) -> LinkDisplayPortStatusSource:
@@ -86,7 +90,7 @@ class LinkDisplayPortTx:
def is_link_training_success(link: LinkDisplayPortTx):
return link.last_lt_result() == DpLinkTrainingResult.LTR_SUCCESS
self.__io.set(TSI_W_DPTX_COMMAND, 1, c_uint32)
self.__io.set(ci.TSI_W_DPTX_COMMAND, 1, c_uint32)
return function_scheduler(is_link_training_success, self, interval=0.1, timeout=5)
@@ -97,7 +101,7 @@ class LinkDisplayPortTx:
Returns:
object of `DpLinkTrainingResult` type
"""
_, value = self.__io.get(TSI_DPTX_LT_RESULT_R, c_uint)
_, value = self.__io.get(ci.TSI_DPTX_LT_RESULT_R, c_uint)
return DpLinkTrainingResult(value)
@property
@@ -112,7 +116,7 @@ class LinkDisplayPortTx:
warnings.warn("Scrambler Seed is not supported.")
return 0
return self.__io.get(TSI_DPTX_SCR_SEED, c_uint32)[1]
return self.__io.get(ci.TSI_DPTX_SCR_SEED, c_uint32)[1]
@scrambler_seed.setter
def scrambler_seed(self, value: int = 0):
@@ -126,7 +130,7 @@ class LinkDisplayPortTx:
warnings.warn("Scrambler Seed is not supported.")
return
if self.config._read_lt_features().auto_seed is not None and not self.config._read_lt_features().auto_seed:
self.__io.set(TSI_DPTX_SCR_SEED, value, c_uint32)
self.__io.set(ci.TSI_DPTX_SCR_SEED, value, c_uint32)
else:
warnings.warn("AutoSeed has already enabled. Transferred value will not be written")
@@ -160,7 +164,7 @@ class LinkDisplayPortTx:
old_value = self.__get_override_voltage()
old_value &= ~(3 << (stream_index * 8))
old_value |= (value << (stream_index * 8))
self.__io.set(TSI_DPTX_OVERRIDE_VOLTAGE_SWING, old_value, c_uint32)
self.__io.set(ci.TSI_DPTX_OVERRIDE_VOLTAGE_SWING, old_value, c_uint32)
def get_override_pre_emp(self, stream_index: int) -> int:
"""
@@ -192,7 +196,7 @@ class LinkDisplayPortTx:
old_value = self.__get_override_pre_emp()
old_value &= ~(3 << (stream_index * 8))
old_value |= (value << (stream_index * 8))
self.__io.set(TSI_DPTX_OVERRIDE_PRE_EMPHASIS, old_value, c_uint32)
self.__io.set(ci.TSI_DPTX_OVERRIDE_PRE_EMPHASIS, old_value, c_uint32)
@property
def override_ffe_presets(self) -> list:
@@ -205,7 +209,7 @@ class LinkDisplayPortTx:
if not self.__HW_CAPS.dp2_custom_rates:
warnings.warn("FFE presets does not support.")
return []
return self.__io.get(TSI_DP2TX_OUT_FFE, c_uint8, 4)[1]
return self.__io.get(ci.TSI_DP2TX_OUT_FFE, c_uint8, 4)[1]
@override_ffe_presets.setter
def override_ffe_presets(self, value: List[int]):
@@ -219,13 +223,13 @@ class LinkDisplayPortTx:
warnings.warn("FFE presets does not support.")
return
new_value = value[0] | (value[0] << 8) | (value[0] << 16) | (value[0] << 32)
self.__io.set(TSI_DP2TX_OUT_FFE, new_value)
self.__io.set(ci.TSI_DP2TX_OUT_FFE, new_value)
def __get_override_voltage(self) -> int:
return self.__io.get(TSI_DPTX_OVERRIDE_VOLTAGE_SWING, c_uint32)[1]
return self.__io.get(ci.TSI_DPTX_OVERRIDE_VOLTAGE_SWING, c_uint32)[1]
def __get_override_pre_emp(self) -> int:
return self.__io.get(TSI_DPTX_OVERRIDE_PRE_EMPHASIS, c_uint32)[1]
return self.__io.get(ci.TSI_DPTX_OVERRIDE_PRE_EMPHASIS, c_uint32)[1]
@property
def link_pattern(self) -> DPLinkPattern:
@@ -235,7 +239,7 @@ class LinkDisplayPortTx:
Returns:
object of `DPLinkPattern` type
"""
return DPLinkPattern(self.__io.get(TSI_DPTX_OUTPUT_PATTERN, c_uint32)[1])
return DPLinkPattern(self.__io.get(ci.TSI_DPTX_OUTPUT_PATTERN, c_uint32)[1])
def set_link_pattern(self, pattern: DPLinkPattern, additional_param: int = 1):
"""
@@ -247,16 +251,16 @@ class LinkDisplayPortTx:
"""
if not self.__HW_CAPS.dp2_custom_rates and pattern not in [e.value for e in DPLinkPattern]:
raise ValueError(f"Current pattern {pattern.name} is not supported")
self.__io.set(TSI_DPTX_OUTPUT_PATTERN, pattern.value, c_uint32)
self.__io.set(ci.TSI_DPTX_OUTPUT_PATTERN, pattern.value, c_uint32)
if pattern == DPLinkPattern.LinkSquarePattern:
self.__io.set(TSI_DPTX_SQUARE_PATTERN_NUMBER, additional_param, c_uint32)
self.__io.set(ci.TSI_DPTX_SQUARE_PATTERN_NUMBER, additional_param, c_uint32)
def set_force_link_mode(self, link_mode: DPOutLinkMode):
self.__io.set(TSI_DPTX_OUT_LINK_MODE, link_mode.value, c_uint32)
self.__io.set(p_ci.TSI_DPTX_OUT_LINK_MODE, link_mode.value, c_uint32)
def get_force_link_mode(self) -> DPOutLinkMode:
return DPOutLinkMode(self.__io.get(TSI_DPTX_OUT_LINK_MODE, c_uint32)[1])
return DPOutLinkMode(self.__io.get(p_ci.TSI_DPTX_OUT_LINK_MODE, c_uint32)[1])
def cable_rx_type(self) -> CableCapabilitiesEnum:
"""

View File

@@ -1,6 +1,9 @@
from typing import Optional, Union, Type
from ctypes import c_uint, c_int
from typing import Optional, Union, Type, List
from UniTAP.libs.lib_tsi import PortIO
from UniTAP.libs.lib_tsi.tsi_private_types import *
import UniTAP.libs.lib_tsi.tsi_types as ci
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
from .link_tx_types import *
from .private_link_tx_types import *
from .link_status_common import *
@@ -123,10 +126,10 @@ class LinkDisplayPortConfig:
return link_status
def _read_lt_features(self) -> LTFeatures:
return self.__io.get(TSI_DPTX_LT_FEATURES, LTFeatures)[1]
return self.__io.get(ci.TSI_DPTX_LT_FEATURES, LTFeatures)[1]
def __get_post_lt_features(self) -> PostLtFeatures:
return self.__io.get(TSI_DPTX_POST_LT_FEATURES, PostLtFeatures)[1]
return self.__io.get(p_ci.TSI_DPTX_POST_LT_FEATURES, PostLtFeatures)[1]
def __set_post_lt_features(self, config: DisplayPortLinkConfig):
post_lt_features = self.__get_post_lt_features()
@@ -134,10 +137,10 @@ class LinkDisplayPortConfig:
post_lt_features.force_edid_timings = config.force_edid_timings_after_lt
if config.adaptive_sync_auto_enable is not None and self.__caps.adaptive_sync:
post_lt_features.as_auto_enable = config.adaptive_sync_auto_enable
self.__io.set(TSI_DPTX_POST_LT_FEATURES, post_lt_features.value(), c_uint32)
self.__io.set(p_ci.TSI_DPTX_POST_LT_FEATURES, post_lt_features.value(), c_uint32)
def __get_dp2_custom_rates(self) -> list:
rates = self.__io.get(TSI_DP2TX_CUSTOM_RATE_CAPS_R, c_uint32, 32)[1]
rates = self.__io.get(ci.TSI_DP2TX_CUSTOM_RATE_CAPS_R, c_uint32, 32)[1]
custom_rates = []
for i in range(len(rates)):
custom_rates.append(float(rates[i]) * 200000 / 1000000000)
@@ -149,20 +152,20 @@ class LinkDisplayPortConfig:
return
if lane_count not in [1, 2, 4]:
raise ValueError(f"Incorrect lane count number {lane_count}. Must be from list: 1, 2, 4")
self.__io.set(TSI_DPTX_LINK_CFG_LANES, lane_count, c_uint32)
self.__io.set(ci.TSI_DPTX_LINK_CFG_LANES, lane_count, c_uint32)
def __get_lane_count_dp14(self) -> int:
return self.__io.get(TSI_DPTX_LINK_CFG_LANES)[1]
return self.__io.get(ci.TSI_DPTX_LINK_CFG_LANES)[1]
def __set_lane_count_dp21(self, lane_count: Optional[int]):
if lane_count is None:
return
if lane_count not in [1, 2, 4]:
raise ValueError(f"Incorrect lane count number {lane_count}. Must be from list: 1, 2, 4")
self.__io.set(TSI_DP2TX_LT_SLC, lane_count, c_uint32)
self.__io.set(ci.TSI_DP2TX_LT_SLC, lane_count, c_uint32)
def __get_lane_count_dp21(self) -> int:
return self.__io.get(TSI_DP2TX_LT_SLC)[1]
return self.__io.get(ci.TSI_DP2TX_LT_SLC)[1]
def __set_bit_rate_14(self, bit_rate: Optional[float]):
if bit_rate is None:
@@ -170,10 +173,10 @@ class LinkDisplayPortConfig:
if int(round(bit_rate / 0.27)) > self.__caps.max_link_rate:
raise ValueError(f"Following 8b/10b bit rate {bit_rate} is not supported on device. "
f"Max supported link rate {round(self.__caps.max_link_rate * 0.27, 2)}")
self.__io.set(TSI_DPTX_LINK_CFG_BIT_RATE, int(round(bit_rate / 0.27)), c_uint32)
self.__io.set(ci.TSI_DPTX_LINK_CFG_BIT_RATE, int(round(bit_rate / 0.27)), c_uint32)
def __get_bit_rate_14(self) -> float:
return round(self.__io.get(TSI_DPTX_LINK_CFG_BIT_RATE)[1] * 0.27, 2)
return round(self.__io.get(ci.TSI_DPTX_LINK_CFG_BIT_RATE)[1] * 0.27, 2)
def __set_bit_rate_21(self, bit_rate: Optional[Union[float, int]]):
if bit_rate is None:
@@ -182,42 +185,42 @@ class LinkDisplayPortConfig:
if not self.__caps.support_10gbps:
raise ValueError(f"Following bit rate {bit_rate} is not supported on device.")
else:
res = self.__io.get(TSI_DP2TX_CUSTOM_RATE_MAP, c_uint32, 3)[1]
self.__io.set(TSI_DP2TX_CUSTOM_RATE_MAP, (int(bit_rate * 1000000000 / 200000), res[1], res[2]),
res = self.__io.get(ci.TSI_DP2TX_CUSTOM_RATE_MAP, c_uint32, 3)[1]
self.__io.set(ci.TSI_DP2TX_CUSTOM_RATE_MAP, (int(bit_rate * 1000000000 / 200000), res[1], res[2]),
c_uint32, 3)
elif (bit_rate == 10.0 and not self.__caps.support_10gbps) or \
(bit_rate == 13.5 and not self.__caps.support_13_5gbps) or \
(bit_rate == 20.0 and not self.__caps.support_20gbps):
raise ValueError(f"Following bit rate {bit_rate} is not supported on device.")
self.__io.set(TSI_DP2TX_LT_SBR, DP21_LinkRateRev.get(bit_rate), c_uint32)
self.__io.set(ci.TSI_DP2TX_LT_SBR, DP21_LinkRateRev.get(bit_rate), c_uint32)
def __get_bit_rate_21(self) -> float:
return DP21_LinkRate.get(self.__io.get(TSI_DP2TX_LT_SBR)[1])
return DP21_LinkRate.get(self.__io.get(ci.TSI_DP2TX_LT_SBR)[1])
def __support_ssc(self) -> bool:
return (self.__io.get(TSI_DPTX_DOWNSPREAD_STATUS_R, c_uint32)[1] >> 1) & 1 != 0
return (self.__io.get(ci.TSI_DPTX_DOWNSPREAD_STATUS_R, c_uint32)[1] >> 1) & 1 != 0
def __set_config_ssc(self, ssc_conf: Optional[SSCConfig]):
if ssc_conf is None:
return
if not self.__support_ssc():
raise ValueError(f"SSC is not supported on the device.")
self.__io.set(TSI_DPTX_DOWNSPREAD_CONTROL, int(ssc_conf.enabled), c_uint32)
self.__io.set(ci.TSI_DPTX_DOWNSPREAD_CONTROL, int(ssc_conf.enabled), c_uint32)
if ssc_conf.enabled:
if not (1 <= ssc_conf.amplitude <= 50):
raise ValueError(f"Incorrect amplitude value {ssc_conf.amplitude}. Must be from range: 0.1 - 0.5")
self.__io.set(TSI_DPTX_DOWNSPREAD_AMP, ssc_conf.amplitude, c_uint32)
self.__io.set(ci.TSI_DPTX_DOWNSPREAD_AMP, ssc_conf.amplitude, c_uint32)
if not (30000 <= ssc_conf.frequency <= 63000):
raise ValueError(f"Incorrect frequency value {ssc_conf.frequency}. Must be from range: 30000 - 63000")
self.__io.set(TSI_DPTX_DOWNSPREAD_FREQ, ssc_conf.frequency, c_uint32)
self.__io.set(ci.TSI_DPTX_DOWNSPREAD_FREQ, ssc_conf.frequency, c_uint32)
def __get_config_ssc(self) -> SSCConfig:
if not self.__support_ssc():
return None
ssc_conf = SSCConfig()
ssc_conf.enabled = (self.__io.get(TSI_DPTX_DOWNSPREAD_STATUS_R)[1] & 1) != 0
ssc_conf.frequency = self.__io.get(TSI_DPTX_DOWNSPREAD_FREQ)[1]
ssc_conf.amplitude = self.__io.get(TSI_DPTX_DOWNSPREAD_AMP)[1]
ssc_conf.enabled = (self.__io.get(ci.TSI_DPTX_DOWNSPREAD_STATUS_R)[1] & 1) != 0
ssc_conf.frequency = self.__io.get(ci.TSI_DPTX_DOWNSPREAD_FREQ)[1]
ssc_conf.amplitude = self.__io.get(ci.TSI_DPTX_DOWNSPREAD_AMP)[1]
return ssc_conf
def __dp2_support_rates(self) -> bool:
@@ -228,7 +231,7 @@ class LinkDisplayPortConfig:
return
if not self.__dp2_support_rates():
raise ValueError(f"LTTPR is not supported on the device.")
self.__io.set(TSI_DPTX_LTTPR_CONTROL, int(enable))
self.__io.set(ci.TSI_DPTX_LTTPR_CONTROL, int(enable))
def __set_lt_features(self, config: Optional[DisplayPortLinkConfig]):
if config is None:
@@ -270,22 +273,22 @@ class LinkDisplayPortConfig:
else:
raise TypeError("Incorrect DisplayPortLinkConfig format!")
self.__io.set(TSI_DPTX_LT_FEATURES, res.value(), c_uint32)
self.__io.set(ci.TSI_DPTX_LT_FEATURES, res.value(), c_uint32)
def __enable_mst(self, enable: Optional[bool]):
if enable is None:
return
self.__io.set(TSI_DPTX_COMMAND_W, 3 if enable else 4, c_uint32)
self.__io.set(ci.TSI_DPTX_COMMAND_W, 3 if enable else 4, c_uint32)
def __set_mst_channel_count(self, count: Optional[int]):
if count is None:
return
if not (0 <= count <= self.__caps.mst_stream_count):
raise ValueError(f"Incorrect stream count {count}. Available stream count {self.__caps.mst_stream_count}")
self.__io.set(TSI_PG_ENABLED_STREAM_COUNT, count, c_uint32)
self.__io.set(ci.TSI_PG_ENABLED_STREAM_COUNT, count, c_uint32)
def __link_encoding(self) -> DpLinkEncoding:
result, value = self.__io.get(TSI_DPTX_LINK_MODE_R, c_uint)
result, value = self.__io.get(ci.TSI_DPTX_LINK_MODE_R, c_uint)
if value == 0:
return DpLinkEncoding.LE_8b10b
@@ -293,36 +296,36 @@ class LinkDisplayPortConfig:
return DpLinkEncoding.LE_128b132b
def __mst_enabled(self) -> bool:
return (self.__io.get(TSI_DPTX_LINK_STATUS_BITS_R)[1] & (1 << 30)) != 0
return (self.__io.get(ci.TSI_DPTX_LINK_STATUS_BITS_R)[1] & (1 << 30)) != 0
def __mst_stream_count(self) -> int:
result, mst_status = self.__io.get(TSI_DPTX_MST_STATUS_R, c_uint)
result, mst_status = self.__io.get(ci.TSI_DPTX_MST_STATUS_R, c_uint)
return (mst_status >> 8) & 0xFF
def __lttpr_active(self) -> Optional[bool]:
if self.__link_encoding == DpLinkEncoding.LE_128b132b:
return (self.__io.get(TSI_DPTX_LTTPR_CONTROL, c_uint32)[1] & 1) != 0
return (self.__io.get(ci.TSI_DPTX_LTTPR_CONTROL, c_uint32)[1] & 1) != 0
else:
return None
def __check_custom_bit_rate(self) -> float:
res = self.__io.get(TSI_DP2TX_CUSTOM_RATE_MAP, c_uint32, 3)[1]
res = self.__io.get(ci.TSI_DP2TX_CUSTOM_RATE_MAP, c_uint32, 3)[1]
for i in range(3):
if res[i] != 0:
return res[i] * 200000 / 1000000000
return 0
def __try_fec_after_lt(self, enable: bool):
result = self.__io.get(TSI_DPTX_FEC_CTRL, c_int)
result = self.__io.get(ci.TSI_DPTX_FEC_CTRL, c_int)
val = result[1]
if enable:
val |= 0x2
else:
val &= ~0x2
self.__io.set(TSI_DPTX_FEC_CTRL, val)
self.__io.set(ci.TSI_DPTX_FEC_CTRL, val)
def __fec_after_lt_state(self) -> bool:
return (self.__io.get(TSI_DPTX_FEC_CTRL, c_int)[1] & 0x2) != 0
return (self.__io.get(ci.TSI_DPTX_FEC_CTRL, c_int)[1] & 0x2) != 0
def __sdp_control(self, config: Optional[DisplayPortLinkConfig]):
if config is None:
@@ -335,24 +338,24 @@ class LinkDisplayPortConfig:
self.__write_sdp_control(sdp_control)
def __write_sdp_control(self, sdp_control: SdpControl):
self.__io.set(TSI_DPTX_SDP_CTRL, sdp_control.value())
self.__io.set(p_ci.TSI_DPTX_SDP_CTRL, sdp_control.value())
def __read_sdp_control(self) -> SdpControl:
return self.__io.get(TSI_DPTX_SDP_CTRL, SdpControl)[1]
return self.__io.get(p_ci.TSI_DPTX_SDP_CTRL, SdpControl)[1]
def __set_edp_sel_rate(self, rate: float):
if self.__caps.edp and rate in self.__get_edp_caps_rates():
self.__io.set(TSI_DPTX_EDP_LT_SBR, int(rate / 0.0002), c_uint32)
self.__io.set(ci.TSI_DPTX_EDP_LT_SBR, int(rate / 0.0002), c_uint32)
elif not self.__caps.edp:
raise ValueError("EDP is not supported.")
def __get_edp_sel_rate(self) -> int:
if self.__caps.edp:
return self.__io.get(TSI_DPTX_EDP_LT_SBR)[1] * 0.0002
return self.__io.get(ci.TSI_DPTX_EDP_LT_SBR)[1] * 0.0002
def __get_edp_caps_rates(self) -> List[float]:
if self.__caps.edp:
rates = self.__io.get(TSI_DPTX_EXTRA_DP14_RATES, data_type=c_uint32, data_count=8)[1]
rates = self.__io.get(ci.TSI_DPTX_EXTRA_DP14_RATES, data_type=c_uint32, data_count=8)[1]
new_rates = []
for rate in rates:
if rate > 0:

View File

@@ -1,6 +1,6 @@
from typing import Optional, Union, Type
from UniTAP.libs.lib_tsi import PortIO
from UniTAP.libs.lib_tsi.tsi_private_types import *
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
from .link_tx_types import *
from .private_link_tx_types import *
from .link_status_common import *
@@ -62,25 +62,25 @@ class LinkDisplayPortForceConfig:
(bit_rate == 13.5 and not self.__caps.support_13_5gbps) or \
(bit_rate == 20.0 and not self.__caps.support_20gbps):
raise ValueError(f"Following bit rate {bit_rate} is not supported on device.")
self.__io.set(TSI_DP2TX_OUT_BR, DP21_LinkRateRev.get(bit_rate), c_uint32)
self.__io.set(p_ci.TSI_DP2TX_OUT_BR, DP21_LinkRateRev.get(bit_rate), c_uint32)
def __force_get_bit_rate(self) -> float:
return DP21_LinkRate.get(self.__io.get(TSI_DP2TX_OUT_BR)[1])
return DP21_LinkRate.get(self.__io.get(p_ci.TSI_DP2TX_OUT_BR)[1])
def __force_set_lane_count(self, lane_count: Optional[int]):
if lane_count is None:
return
if lane_count not in [1, 2, 4]:
raise ValueError(f"Incorrect lane count number {lane_count}. Must be from list: 1, 2, 4")
self.__io.set(TSI_DP2TX_OUT_LC, lane_count, c_uint32)
self.__io.set(p_ci.TSI_DP2TX_OUT_LC, lane_count, c_uint32)
def __force_get_lane_count(self) -> int:
return self.__io.get(TSI_DP2TX_OUT_LC)[1]
return self.__io.get(p_ci.TSI_DP2TX_OUT_LC)[1]
def __force_set_pattern(self, pattern: Optional[DP128b132bLinkPattern]):
if pattern is None:
return
self.__io.set(TSI_DP2TX_OUT_TEST_PATTERN, pattern.value, c_uint32)
self.__io.set(p_ci.TSI_DP2TX_OUT_TEST_PATTERN, pattern.value, c_uint32)
def __force_get_pattern(self) -> DP128b132bLinkPattern:
return DP128b132bLinkPattern(self.__io.get(TSI_DP2TX_OUT_TEST_PATTERN, c_uint32)[1])
return DP128b132bLinkPattern(self.__io.get(p_ci.TSI_DP2TX_OUT_TEST_PATTERN, c_uint32)[1])

View File

@@ -2,8 +2,7 @@ import warnings
from typing import Optional
from UniTAP.libs.lib_tsi import PortIO
from UniTAP.libs.lib_tsi.tsi_types import *
from .link_tx_types import *
import UniTAP.libs.lib_tsi.tsi_types as ci
from .private_link_tx_types import *
from .link_status_common import *
from .private_link_status_common import *
@@ -47,7 +46,7 @@ class LinkDisplayPortStatusSource:
Returns:
object of int type
"""
result, mst_status = self.__io.get(TSI_DPTX_MST_STATUS_R, c_uint)
result, mst_status = self.__io.get(ci.TSI_DPTX_MST_STATUS_R, c_uint)
return (mst_status >> 8) & 0xFF
@property
@@ -58,7 +57,7 @@ class LinkDisplayPortStatusSource:
Returns:
object of DpLinkEncoding type
"""
result, value = self.__io.get(TSI_DPTX_LINK_MODE_R, c_uint)
result, value = self.__io.get(ci.TSI_DPTX_LINK_MODE_R, c_uint)
if value == 0:
return DpLinkEncoding.LE_8b10b
@@ -77,9 +76,9 @@ class LinkDisplayPortStatusSource:
if self.__check_custom_bit_rate() != 0:
return self.__check_custom_bit_rate()
else:
return DP21_LinkRate.get(self.__io.get(TSI_DP2TX_LT_RATE_R, c_uint)[1])
return DP21_LinkRate.get(self.__io.get(ci.TSI_DP2TX_LT_RATE_R, c_uint)[1])
else:
return round(self.__io.get(TSI_DPTX_LINK_RATE_R, c_uint)[1] * 0.27, 2)
return round(self.__io.get(ci.TSI_DPTX_LINK_RATE_R, c_uint)[1] * 0.27, 2)
@property
def lane_count(self) -> int:
@@ -89,7 +88,7 @@ class LinkDisplayPortStatusSource:
Returns:
object of int type
"""
return self.__io.get(TSI_DPTX_LINK_LANE_COUNT_R, c_int)[1]
return self.__io.get(ci.TSI_DPTX_LINK_LANE_COUNT_R, c_int)[1]
@property
def hpd_asserted(self) -> bool:
@@ -99,7 +98,7 @@ class LinkDisplayPortStatusSource:
Returns:
object of bool type
"""
return (self.__io.get(TSI_DPTX_HPD_STATUS_R, c_int)[1] & 1) != 0
return (self.__io.get(ci.TSI_DPTX_HPD_STATUS_R, c_int)[1] & 1) != 0
@property
def available_link_rate(self) -> float:
@@ -142,8 +141,8 @@ class LinkDisplayPortStatusSource:
raise ValueError(f"Incorrect lane number {lane_number}. Available range: 0-{self.lane_count}")
status = self.__read_link_status()
voltage_swing = self.__io.get(TSI_DPTX_LINK_VOLTAGE_SWING_R, LinkVoltageSwing)[1]
pre_emphasis = self.__io.get(TSI_DPTX_LINK_PRE_EMPHASIS_R, LinkPreEmphasis)[1]
voltage_swing = self.__io.get(ci.TSI_DPTX_LINK_VOLTAGE_SWING_R, LinkVoltageSwing)[1]
pre_emphasis = self.__io.get(ci.TSI_DPTX_LINK_PRE_EMPHASIS_R, LinkPreEmphasis)[1]
error_counters = self.__dpcd.read(0x210, 8).data
lane_status = LaneStatus()
@@ -178,7 +177,7 @@ class LinkDisplayPortStatusSource:
lane_status.error_count = error_counters[6] | ((error_counters[7] & 0x7F) << 8)
if self.link_encoding == DpLinkEncoding.LE_128b132b:
ffe_preset = self.__io.get(TSI_DP2TX_LT_FFE_PRESET_R, c_uint32)[1]
ffe_preset = self.__io.get(ci.TSI_DP2TX_LT_FFE_PRESET_R, c_uint32)[1]
lane_status.ffe_preset = (ffe_preset >> (8 * lane_number)) & 0xFF
else:
lane_status.ffe_preset = 0
@@ -195,7 +194,7 @@ class LinkDisplayPortStatusSource:
object of bool or None type
"""
if self.__caps.dsc or self.__caps.dsc2:
return (self.__io.get(TSI_DPTX_DSC_STATUS_R)[1] & 1) != 0
return (self.__io.get(ci.TSI_DPTX_DSC_STATUS_R)[1] & 1) != 0
else:
return None
@@ -209,7 +208,7 @@ class LinkDisplayPortStatusSource:
object of bool or None type
"""
if self.__caps.mst:
return (self.__io.get(TSI_DPTX_MST_STATUS_R, c_uint32)[1] & 1) != 0
return (self.__io.get(ci.TSI_DPTX_MST_STATUS_R, c_uint32)[1] & 1) != 0
else:
return None
@@ -222,7 +221,7 @@ class LinkDisplayPortStatusSource:
Returns:
object of bool or None type
"""
res = self.__io.get(TSI_DPTX_DOWNSPREAD_STATUS_R)[1]
res = self.__io.get(ci.TSI_DPTX_DOWNSPREAD_STATUS_R)[1]
if ((res >> 1) & 1) != 0:
return (res & 1) != 0
else:
@@ -238,7 +237,7 @@ class LinkDisplayPortStatusSource:
object of bool or None type
"""
if self.__caps.fec or self.__caps.fec2:
return (self.__io.get(TSI_DPTX_FEC_STATUS_R)[1] & 1) != 0
return (self.__io.get(ci.TSI_DPTX_FEC_STATUS_R)[1] & 1) != 0
else:
return None
@@ -272,7 +271,7 @@ class LinkDisplayPortStatusSource:
object of bool or None type
"""
if self.link_encoding == DpLinkEncoding.LE_128b132b:
return (self.__io.get(TSI_DPTX_LTTPR_STATUS_R, c_uint32)[1] & 1) != 0
return (self.__io.get(ci.TSI_DPTX_LTTPR_STATUS_R, c_uint32)[1] & 1) != 0
else:
return None
@@ -327,7 +326,7 @@ class LinkDisplayPortStatusSource:
object of `StreamStatusDP` type
"""
stream_status = StreamStatusDP()
result, msa_info, size = self.__io.get(TSI_DPTX_MSA_INFO_R, DpMsa, 4)
result, msa_info, size = self.__io.get(ci.TSI_DPTX_MSA_INFO_R, DpMsa, 4)
if stream_index < size:
msa_info_private = MSAInfo(msa_info[stream_index])
@@ -336,16 +335,16 @@ class LinkDisplayPortStatusSource:
stream_status.mvid = msa_info_private.m_video
stream_status.nvid = msa_info_private.n_video
result = self.__io.get(TSI_DPTX_CRC_R, DpCrc, self.mst_stream_count)
if result[0] >= TSI_SUCCESS and self.mst_stream_count > 1:
result = self.__io.get(ci.TSI_DPTX_CRC_R, DpCrc, self.mst_stream_count)
if result[0] >= ci.TSI_SUCCESS and self.mst_stream_count > 1:
stream_status.crc = [result[1][stream_index].r, result[1][stream_index].g, result[1][stream_index].b]
elif result[0] >= TSI_SUCCESS and self.mst_stream_count == 1:
elif result[0] >= ci.TSI_SUCCESS and self.mst_stream_count == 1:
stream_status.crc = [result[1].r, result[1].g, result[1].b]
result = self.__io.get(TSI_DPTX_DSC_CRC_R, DpCrc, self.mst_stream_count)
if result[0] >= TSI_SUCCESS and self.mst_stream_count > 1:
result = self.__io.get(ci.TSI_DPTX_DSC_CRC_R, DpCrc, self.mst_stream_count)
if result[0] >= ci.TSI_SUCCESS and self.mst_stream_count > 1:
stream_status.dsc_crc = [result[1][stream_index].r, result[1][stream_index].g, result[1][stream_index].b]
elif result[0] >= TSI_SUCCESS and self.mst_stream_count == 1:
elif result[0] >= ci.TSI_SUCCESS and self.mst_stream_count == 1:
stream_status.dsc_crc = [result[1].r, result[1].g, result[1].b]
else:
raise ValueError(f"Selected stream {stream_index} is not available. "
@@ -368,7 +367,7 @@ class LinkDisplayPortStatusSource:
raise ValueError(f"Selected stream {stream_index} is not available. "
f"Available stream number: {self.mst_stream_count}")
res = self.__io.get(TSI_DPTX_VCP_TABLE_R, VCPTable, 4)[1]
res = self.__io.get(ci.TSI_DPTX_VCP_TABLE_R, VCPTable, 4)[1]
if self.mst_enabled:
status = VCPStatus()
@@ -389,16 +388,16 @@ class LinkDisplayPortStatusSource:
"""
Send ACT command.
"""
self.__io.set(TSI_DPTX_MST_COMMAND_W, 1, c_uint32)
self.__io.set(ci.TSI_DPTX_MST_COMMAND_W, 1, c_uint32)
def __read_lt_features(self) -> LTFeatures:
return self.__io.get(TSI_DPTX_LT_FEATURES, LTFeatures)[1]
return self.__io.get(ci.TSI_DPTX_LT_FEATURES, LTFeatures)[1]
def __read_link_status(self) -> LinkTxStatus:
return self.__io.get(TSI_DPTX_LINK_STATUS_R, LinkTxStatus)[1]
return self.__io.get(ci.TSI_DPTX_LINK_STATUS_R, LinkTxStatus)[1]
def __check_custom_bit_rate(self) -> float:
res = self.__io.get(TSI_DP2TX_CUSTOM_RATE_MAP, c_uint32, 3)[1]
res = self.__io.get(ci.TSI_DP2TX_CUSTOM_RATE_MAP, c_uint32, 3)[1]
for i in range(3):
if res[i] != 0:
return res[i] * 200000 / 1000000000