Add TI TMDS1204 HDMI layout as VENDOR/PHY only (2.80.0).

Sink/source ZPCB, skew, length, vias from SLLSF57A Tables 8-6/8-2. Generic hdmi-* TMDS Zdiff stays UNKNOWN. SLLA633 is SIGDET only.
This commit is contained in:
2026-09-22 18:12:23 +02:00
parent 25aa608052
commit 1455e974ac
6 changed files with 1308 additions and 2 deletions
@@ -622,6 +622,15 @@ DOC_HDMI_ADOPTER = (
DOC_HDMI_13 = "High-Definition Multimedia Interface Specification"
REV_HDMI_13 = "Version 1.3, June 22, 2006"
ORG_HDMI = "HDMI Licensing, LLC"
DOC_TMDS1204 = (
"TMDS1204 12Gbps, DC or AC-Coupled to TMDS and FRL HDMI Hybrid Redriver"
)
REV_TMDS1204 = "SLLSF57A AUGUST 2022 REVISED APRIL 2024"
ORG_TI = "Texas Instruments"
DOC_SLLA633 = (
"TMDS_CLOCK/FRL_Data Detection Design in HDMI Sink Applications TMDS1204"
)
REV_SLLA633 = "SLLA633 MAY 2024"
DDR_CHECKS = [
"byte_lane_mapping",
"dq_to_dqs_skew",
@@ -745,6 +754,8 @@ def build_m0_catalog() -> dict[str, Any]:
L("hdmi-2.0", "HDMI 2.0 TMDS", "SERIAL", "HDMI")
L("hdmi-frl", "HDMI FRL mode", "SERIAL", "HDMI",
"FRL is distinct from TMDS. Do not copy TMDS numbers onto FRL.")
L("tmds1204", "TI TMDS1204 HDMI hybrid redriver (vendor PHY)", "SERIAL", "HDMI",
"Vendor PHY implementation. Not HDMI Forum STANDARD. Not generic hdmi-1.4/2.0/FRL.")
L("dvi", "DVI 1.0 TMDS", "SERIAL", "DVI",
"DVI is not HDMI. Numbers from DDWG DVI Revision 1.0 only.")
L("ddr-family", "DDR family (abstract)", "MEMORY", "DDR")
@@ -1553,6 +1564,171 @@ def build_m0_catalog() -> dict[str, Any]:
))
return out
def _tmds1204_cons(pid: str, role: str) -> list[dict[str, Any]]:
"""TI TMDS1204 layout/electrical. VENDOR/PHY only — not HDMI Forum STANDARD."""
kw = dict(
document=DOC_TMDS1204, organization=ORG_TI, revision=REV_TMDS1204,
source_type="PHY", source_class="VENDOR", mandatory="RECOMMENDED",
)
out = [
_c(
pid, p, "PHY_DEPENDENT",
source_type="PHY", source_class="VENDOR", mandatory="RECOMMENDED",
needed_document=(
"TI TMDS1204 datasheet SLLSF57A (vendor PHY). "
"Not HDMI Forum Adopter STANDARD."
),
)
for p in HDMI_CHECKS
if p not in {
"differential_impedance", "intra_pair_skew", "inter_lane_skew",
"data_rate", "vias", "ac_coupling", "crosstalk",
}
]
out.append(_num(
pid, "data_rate", 12.0, "Gbps",
section="5.5", page="10",
conditions=[
"TMDS1204 DR_RX_DATA / DR_RX_CLK maximum",
"chip TMDS1204",
"not HDMI Forum Adopter data-rate table",
],
**kw,
))
if role == "sink":
out.append(_num(
pid, "differential_impedance", 90.0, "ohm",
section="8.3.1", table="Table 8-6", page="63",
conditions=[
"ZPCB_AB and ZPCB_CD min 90 Ω max 110 Ω",
"TMDS1204 sink layout LAB/LCD",
"not HDMI Forum Adopter Zdiff",
"not generic hdmi-* STANDARD",
],
**kw,
))
out.append(_num(
pid, "intra_pair_skew", 2.0, "mil",
section="8.3.1", table="Table 8-6", page="63",
conditions=["LINTRA-AB / LINTRA-CD maximum", "receptacle to TMDS1204 and TMDS1204 to sink"],
**kw,
))
out.append(_num(
pid, "inter_lane_skew", 0.10, "inch",
section="8.3.1", table="Table 8-6", page="63",
conditions=["LINTER-PAIR maximum among D0, D1, D2, CLK"],
**kw,
))
out.append(_num(
pid, "vias", 1.0, "count",
section="8.3.1", table="Table 8-6", page="63",
conditions=["VIAAB maximum between receptacle and TMDS1204"],
**kw,
))
out.append(_num(
pid, "lab_length_max", 2.0, "inch",
section="8.3.1", table="Table 8-6", page="63",
conditions=["LAB PCB trace receptacle to TMDS1204 max (min 0.75 in) at ILPCB"],
**kw,
))
out.append(_num(
pid, "lcd_length_max", 6.0, "inch",
section="8.3.1", table="Table 8-6", page="63",
conditions=["LCD PCB trace TMDS1204 to sink max (min 1 in) at ILPCB"],
**kw,
))
else:
out.append(_num(
pid, "differential_impedance", 75.0, "ohm",
section="8.2.1", table="Table 8-2", page="58",
conditions=[
"ZPCB_AB min 75 Ω max 110 Ω (GPU to TMDS1204)",
"ZPCB_CD is min 90 Ω max 110 Ω (TMDS1204 to receptacle)",
"not HDMI Forum Adopter Zdiff",
"not generic hdmi-* STANDARD",
],
**kw,
))
out.append(_num(
pid, "zpcb_cd_min", 90.0, "ohm",
section="8.2.1", table="Table 8-2", page="58",
conditions=["ZPCB_CD min 90 Ω max 110 Ω", "TMDS1204 source post-channel"],
**kw,
))
out.append(_num(
pid, "intra_pair_skew", 5.0, "mil",
section="8.2.1", table="Table 8-2", page="58",
conditions=["LINTRA-AB / LINTRA-CD maximum"],
**kw,
))
out.append(_num(
pid, "inter_lane_skew", 1.0, "inch",
section="8.2.1", table="Table 8-2", page="58",
conditions=["LINTER-PAIR maximum among D0, D1, D2, CLK"],
**kw,
))
out.append(_num(
pid, "vias", 2.0, "count",
section="8.2.1", table="Table 8-2", page="58",
conditions=["VIAAB maximum between GPU and TMDS1204"],
**kw,
))
out.append(_num(
pid, "lab_length_max", 10.0, "inch",
section="8.2.1", table="Table 8-2", page="58",
conditions=["LAB GPU to TMDS1204 max at 12 Gbps (min 1 in) at ILPCB"],
**kw,
))
out.append(_num(
pid, "lcd_length_max", 2.0, "inch",
section="8.2.1", table="Table 8-2", page="58",
conditions=["LCD TMDS1204 to receptacle max (min 0.75 in) at ILPCB"],
**kw,
))
out.append(_num(
pid, "crosstalk", -24.0, "dB",
section="8.3.1" if role == "sink" else "8.2.1",
table="Table 8-6" if role == "sink" else "Table 8-2",
page="63" if role == "sink" else "58",
conditions=["XTALK maximum, ≤ 3 GHz", "adjacent differential pairs on PCB"],
**kw,
))
out.append(_num(
pid, "rint_min", 90.0, "ohm",
section="5.5", page="10",
conditions=[
"RINT input differential impedance when termination enabled",
"min 90 Ω typ 100 Ω max 110 Ω at 070 °C (wider at 2085 °C)",
"chip pin termination, not PCB trace Zdiff, not HDMI Forum",
],
**kw,
))
out.append(_num(
pid, "ac_coupling", 8.0, "nF",
section="5.5", page="13",
conditions=["CTX_AC required external AC capacitor min 8 nF (typ 10, max 12)"],
**kw,
))
out.append(_num(
pid, "pair_spacing_min_widths", 5.0, "trace_width",
section="8.5.1", page="65",
conditions=[
"distance between differential pairs at least 5× trace width (5W)",
"clock pair 8W or 10W",
"TI layout guideline, not HDMI Forum STANDARD",
],
**kw,
))
out.append(_c(
pid, "sigdet_wakeup", "PHY_DEPENDENT",
source_type="PHY", source_class="VENDOR", mandatory="RECOMMENDED",
needed_document=(
f"{DOC_SLLA633} {REV_SLLA633} §3 p.4 SIGDET_OUT; "
"vendor detection method, not HDMI Forum STANDARD"
),
))
return out
def _dvi_cons(pid: str) -> list[dict[str, Any]]:
out = []
for p in DVI_CHECKS:
@@ -1789,6 +1965,28 @@ def build_m0_catalog() -> dict[str, Any]:
notes="HDMI FRL is distinct from TMDS. Do not apply TMDS rules. UNKNOWN until Adopter spec.",
incomplete=True,
))
physical.append(_iface(
"tmds1204-hdmi-sink", "tmds1204", "SERIAL", "SERIAL_DIFFERENTIAL", "YES",
HDMI_CHECKS, _tmds1204_cons("tmds1204-hdmi-sink", "sink"),
connector="HDMI-A",
hints=["TMDS1204"],
notes=(
"TI TMDS1204 sink redriver layout (Table 8-6). VENDOR/PHY. "
"Not HDMI Forum STANDARD. Do not copy onto generic hdmi-*."
),
incomplete=True,
))
physical.append(_iface(
"tmds1204-hdmi-source", "tmds1204", "SERIAL", "SERIAL_DIFFERENTIAL", "YES",
HDMI_CHECKS, _tmds1204_cons("tmds1204-hdmi-source", "source"),
connector="HDMI-A",
hints=["TMDS1204"],
notes=(
"TI TMDS1204 source redriver layout (Table 8-2). VENDOR/PHY. "
"Not HDMI Forum STANDARD. Do not copy onto generic hdmi-*."
),
incomplete=True,
))
physical.append(_iface(
"dvi-1.0-tmds", "dvi", "SERIAL", "SERIAL_DIFFERENTIAL", "YES",
DVI_CHECKS, _dvi_cons("dvi-1.0-tmds"),
File diff suppressed because it is too large Load Diff
@@ -2,6 +2,13 @@
What's new in Periscope.
## 2.80.0 — 2026-09-22 — TI TMDS1204 HDMI layout as VENDOR/PHY only
TMDS1204 datasheet SLLSF57A fills sink/source PCB layout (ZPCB 90 Ω / 75 Ω ranges, skew, length, vias, XTALK 24 dB, 5W spacing, RINT, AC cap) on physical ids `tmds1204-hdmi-sink` / `tmds1204-hdmi-source`. source_type PHY, source_class VENDOR, RECOMMENDED. Generic `hdmi-*` TMDS/FRL Zdiff stays UNKNOWN. SLLA633 is SIGDET wakeup (PHY_DEPENDENT), no layout ohms. pcbsync.com blog not packed.
- [Changed] `protocol_catalog.py` + `catalog.json`.
- [Changed] pytest `tests/pcb/test_protocol_pdf_pack.py`, `test_protocol_catalog_m0.py`.
## 2.79.0 — 2026-09-22 — HDMI CEC electrical from HDMI Specification 1.3
`CEC_HDMI_Specification.pdf` is High-Definition Multimedia Interface Specification Version 1.3 (22 June 2006), not a CEC-only pamphlet. CEC pull-up 27 kΩ, VOL 0.6 V, VOH 2.5 V, device 200 pF / cable 700 pF, interconnect 5 Ω are packed. TMDS/FRL Zdiff/skew stay UNKNOWN (Adopter spec still required). DDC/HPD not packed.
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "periscope-web",
"version": "2.79.0",
"version": "2.80.0",
"private": true,
"scripts": {
"sync-version": "node scripts/sync-version.mjs",
+1 -1
View File
@@ -25,7 +25,7 @@ from backend.periscopex.protocol_catalog import (
REQUIRED_LOGICAL = {
"usb2-ls-fs", "usb2-ls", "usb2-fs", "usb2-hs", "usb-c", "usb-c-usb2",
"usb3-x", "usb4", "100base-tx", "10base-t", "1000base-t",
"hdmi-1.4", "hdmi-2.0", "hdmi-frl",
"hdmi-1.4", "hdmi-2.0", "hdmi-frl", "tmds1204",
"dvi",
"ddr-family", "ddr4", "lpddr-family", "lpddr4",
"hbm-family", "hbm3", "hyperbus", "qspi", "octal-spi", "emmc", "ufs",
+17
View File
@@ -175,6 +175,23 @@ def test_dvi_not_hdmi_numeric_from_dvi_10():
fz = next(c for c in frl.constraints if c.parameter == "differential_impedance")
assert fz.value_kind == "UNKNOWN"
assert fz.value is None
sink = next(p for p in cat.physical_interfaces if p.id == "tmds1204-hdmi-sink")
assert sink.logical_protocol_id == "tmds1204"
sby = {c.parameter: c for c in sink.constraints}
_cite_ok(sby["differential_impedance"])
assert sby["differential_impedance"].value == 90.0
assert sby["differential_impedance"].source_type == "PHY"
assert sby["differential_impedance"].source_class == "VENDOR"
assert sby["differential_impedance"].mandatory == "RECOMMENDED"
assert sby["differential_impedance"].source.table == "Table 8-6"
assert sby["differential_impedance"].source.organization == "Texas Instruments"
assert "SLLSF57A" in sby["differential_impedance"].source.revision
assert sby["differential_impedance"].source_class != "NORMATIVE"
src = next(p for p in cat.physical_interfaces if p.id == "tmds1204-hdmi-source")
rby = {c.parameter: c for c in src.constraints}
assert rby["differential_impedance"].value == 75.0
assert rby["differential_impedance"].source.table == "Table 8-2"
assert rby["differential_impedance"].source_class == "VENDOR"
g = DesignGraph(
components={
"J3": Component(