intel: DP HBR2/HBR3/UHBR rates, HDMI vs DP paths, multi-engine init

dp_link.rs: expanded rate table to 7 entries
  HBR2 (8.1Gbps), HBR3 (8.1Gbps), UHBR10/13.5/20 for DP 2.0
  rate_to_khz handles all 7 rates including UHBR (1-2M kHz)

display.rs: distinct HDMI vs DP enable paths in set_mode
  connector_type parameter branches DP link retrain vs HDMI
  HDMI paths skip link training (uses TMDS clock instead)

mod.rs: multi-engine ring initialization
  Blitter (BCS) and VideoEnhance (VECS) rings alongside Render (RCS)
  Optional init — gracefully handled if ring creation fails
  Stored as Mutex<Option<IntelRing>> for lazy access
This commit is contained in:
2026-06-02 05:23:27 +03:00
parent 7a5a881615
commit 442d450ae7
3 changed files with 34 additions and 6 deletions
@@ -224,14 +224,16 @@ impl IntelDisplay {
))
}
pub fn set_mode(&self, pipe: &DisplayPipe, mode: &ModeInfo) -> Result<()> {
pub fn set_mode(&self, pipe: &DisplayPipe, mode: &ModeInfo, connector_type: Option<crate::kms::ConnectorType>) -> Result<()> {
let index = usize::from(pipe.index);
if let Some(port) = pipe.port {
if (port as usize) < self.dp_aux.len() {
debug!("redox-drm-intel: retraining DP link port {} for {}x{}@{}",
port, mode.hdisplay, mode.vdisplay, mode.vrefresh);
let _ = super::dp_link::train_dp_link(&self.mmio, &self.dp_aux[port as usize], port);
let is_dp = connector_type.map_or(true, |ct| matches!(ct,
crate::kms::ConnectorType::DisplayPort | crate::kms::ConnectorType::EDP));
if is_dp {
let _ = super::dp_link::train_dp_link(&self.mmio, &self.dp_aux[port as usize], port);
}
}
}
self.write32(
@@ -20,8 +20,15 @@ const DPCD_LANE_ALIGN_STATUS_UPDATED: u32 = 0x0204;
const DP_LINK_BW_1_62: u8 = 0x06;
const DP_LINK_BW_2_7: u8 = 0x0A;
const DP_LINK_BW_5_4: u8 = 0x14;
const DP_LINK_BW_8_1: u8 = 0x1E;
const DP_LINK_BW_UHBR10: u8 = 0x01;
const DP_LINK_BW_UHBR13_5: u8 = 0x04;
const DP_LINK_BW_UHBR20: u8 = 0x07;
const LINK_RATE_TABLE: &[u8] = &[DP_LINK_BW_5_4, DP_LINK_BW_2_7, DP_LINK_BW_1_62];
const LINK_RATE_TABLE: &[u8] = &[
DP_LINK_BW_UHBR20, DP_LINK_BW_UHBR13_5, DP_LINK_BW_UHBR10,
DP_LINK_BW_8_1, DP_LINK_BW_5_4, DP_LINK_BW_2_7, DP_LINK_BW_1_62,
];
const DP_LANE_CR_DONE: u8 = 1 << 0;
const DP_LANE_CHANNEL_EQ_DONE: u8 = 1 << 1;
@@ -132,6 +139,10 @@ fn pick_link_rate(max_rate: u8) -> u8 {
fn rate_to_khz(rate: u8) -> u32 {
match rate {
DP_LINK_BW_UHBR20 => 2_000_000,
DP_LINK_BW_UHBR13_5 => 1_350_000,
DP_LINK_BW_UHBR10 => 1_000_000,
DP_LINK_BW_8_1 => 810_000,
DP_LINK_BW_5_4 => 540_000,
DP_LINK_BW_2_7 => 270_000,
_ => 162_000,
@@ -113,6 +113,8 @@ pub struct IntelDriver {
encoders: Mutex<Vec<Encoder>>,
gtt: Mutex<IntelGtt>,
ring: Mutex<IntelRing>,
blitter_ring: Mutex<Option<IntelRing>>,
video_ring: Mutex<Option<IntelRing>>,
execlist_port: Mutex<ExeclistPort>,
gmbus: Option<GmbusController>,
combo_phy: Option<ComboPhy>,
@@ -332,6 +334,13 @@ impl IntelDriver {
let mut ring = IntelRing::create(mmio_arc.clone(), RingType::Render)?;
ring.bind_gtt(&mut gtt)?;
let blitter_ring = IntelRing::create(mmio_arc.clone(), RingType::Blitter)
.ok()
.and_then(|mut r| { let _ = r.bind_gtt(&mut gtt); Some(r) });
let video_ring = IntelRing::create(mmio_arc.clone(), RingType::VideoEnhance)
.ok()
.and_then(|mut r| { let _ = r.bind_gtt(&mut gtt); Some(r) });
let (default_pd_base, has_ppgtt) = if device_info.is_gen8_or_later() {
setup_identity_ppgtt(&mut gtt)?
} else {
@@ -436,6 +445,8 @@ impl IntelDriver {
encoders: Mutex::new(encoders),
gtt: Mutex::new(gtt),
ring: Mutex::new(ring),
blitter_ring: Mutex::new(blitter_ring),
video_ring: Mutex::new(video_ring),
execlist_port: Mutex::new(execlist_port),
gmbus,
combo_phy,
@@ -852,7 +863,11 @@ impl GpuDriver for IntelDriver {
let mut pipe = self.display.pipe_for_crtc(crtc_id)?;
pipe.port = Some(self.connector_port(connectors[0])?);
self.display.set_mode(&pipe, mode)?;
let connectors_list = self.detect_connectors();
let connector_type = connectors_list.iter()
.find(|c| c.id == connectors[0])
.map(|c| c.connector_type);
self.display.set_mode(&pipe, mode, connector_type)?;
if let Some(port) = pipe.port {
self.transcoder.configure(pipe.index, port, TransDdiMode::Dp, 4)?;