diff options
Diffstat (limited to 'tools/proxyclient/m1n1/fw/dcp/iboot.py')
| -rw-r--r-- | tools/proxyclient/m1n1/fw/dcp/iboot.py | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/tools/proxyclient/m1n1/fw/dcp/iboot.py b/tools/proxyclient/m1n1/fw/dcp/iboot.py new file mode 100644 index 0000000..8124ca9 --- /dev/null +++ b/tools/proxyclient/m1n1/fw/dcp/iboot.py @@ -0,0 +1,215 @@ +# SPDX-License-Identifier: MIT +from construct import * + +from ...utils import * +from ..asc import StandardASC +from ..afk.epic import * +from .dcpav import * + +EOTF = "EOTF" / Enum(Int32ul, + GAMMA_SDR = 1, + GAMMA_HDR = 2, +) + +Encoding = "Encoding" / Enum(Int32ul, + RGB = 1, + YCBCR_444 = 3, + YCBCR_422 = 4, + YCBCR_420 = 5, +) + +Colorimetry = "Colorimetry" / Enum(Int32ul, + BT601_709 = 1, + BT2020 = 2, + DCIP3 = 3, +) + +Colorspace = "Colorspace" / Enum(Int32ul, + SRGB = 1, + Native = 2, + BT2020 = 3, +) + +SurfaceFormat = "SurfaceFormat" / Enum(Int32ul, + BGRA = 1, + BGRA2 = 2, + RGBA = 3, + w18p = 4, + BGRA3 = 5, + _444v = 6, + _422v = 7, + _420v = 8, + w30r = 9, + w40a = 10, +) + +Transform = "Transform" / Enum(Int8ul, + NONE = 0, + XFLIP = 1, + YFLIP = 2, + ROT_90 = 3, + ROT_180 = 4, + ROT_270 = 5, +) + +AddrFormat = "AddrFormat" / Enum(Int32ul, + PLANAR = 1, + TILED = 2, + AGX = 3 +) + +TimingMode = Struct( + "valid" / Bool(Int32ul), + "width" / Int32ul, + "height" / Int32ul, + "fps_frac" / Int16ul, + "fps_int" / Int16ul, + Padding(8), +) + +TimingModeList = Struct( + "count" / Int32ul, + "list" / GreedyRange(TimingMode), +) + +ColorMode = Struct( + "valid" / Bool(Int32ul), + "colorimetry" / Colorimetry, + "eotf" / EOTF, + "encoding" / Encoding, + "bpp" / Int32ul, + "unk" / Int32ul, +) + +ColorModeList = Struct( + "count" / Int32ul, + "list" / GreedyRange(ColorMode), +) + +SwapInfo = Struct( + "unk1" / Int32ul, + "unk2" / Int32ul, + "unk3" / Int32ul, + "swap_id" / Int32ul, + "unk5" / Int32ul, +) + +IBootPlaneInfo = Struct( + "unk1" / Default(Int32ul, 0), + "addr" / Default(Int64ul, 0), + "tile_size" / Default(Int32ul, 0), + "stride" / Default(Int32ul, 0), + "unk5" / Default(Int32ul, 0), + "unk6" / Default(Int32ul, 0), + "unk7" / Default(Int32ul, 0), + "unk8" / Default(Int32ul, 0), + "addr_format" / Default(AddrFormat, 0), + "unk9" / Default(Int32ul, 0), +) + +IBootLayerInfo = Struct( + "planes" / Array(3, IBootPlaneInfo), + "unk" / Default(Int32ul, 0), + "plane_cnt" / Int32ul, + "width" / Int32ul, + "height" / Int32ul, + "surface_fmt" / SurfaceFormat, + "colorspace" / Colorspace, + "eotf" / EOTF, + "transform" / Transform, + Padding(3) +) + +SwapSetLayer = Struct( + "unk" / Default(Int32ul, 0), + "layer_id" / Int32ul, + "layer_info" / IBootLayerInfo, + "src_w" / Int32ul, + "src_h" / Int32ul, + "src_x" / Int32ul, + "src_y" / Int32ul, + "dst_w" / Int32ul, + "dst_h" / Int32ul, + "dst_x" / Int32ul, + "dst_y" / Int32ul, + "unk2" / Default(Int32ul, 0), +) + +class DCPIBootService(EPICService): + NAME = "disp0-service" + SHORT = "disp0" + + def send_cmd(self, op, data=b'', replen=None): + msg = struct.pack("<IIII", op, 16 + len(data), 0, 0) + data + if replen is not None: + replen += 8 + resp = super().send_cmd(0xc0, msg, replen) + if not resp: + return + rcmd, rlen = struct.unpack("<II", resp[:8]) + return resp[8:rlen] + + def setPower(self, power): + self.send_cmd(2, b"\x01" if power else b"\x00") + + def getModeCount(self): + buf = self.send_cmd(3, b"", 12) + hpd, timing_cnt, color_cnt = struct.unpack("<B3xII", buf) + return bool(hpd), timing_cnt, color_cnt + + def getTimingModes(self): + return TimingModeList.parse(self.send_cmd(4, replen=4096)).list + + def getColorModes(self): + return ColorModeList.parse(self.send_cmd(5, replen=4096)).list + + def setMode(self, timing_mode, color_mode): + data = TimingMode.build(timing_mode) + ColorMode.build(color_mode) + self.send_cmd(6, data) + + def swapBegin(self): + return SwapInfo.parse(self.send_cmd(15, replen=128)) + + def swapSetLayer(self, layer_id, info, src_rect, dst_rect): + data = Container() + data.layer_id = layer_id + data.layer_info = info + data.src_w, data.src_h, data.src_x, data.src_y = src_rect + data.dst_w, data.dst_h, data.dst_x, data.dst_y = dst_rect + return self.send_cmd(16, SwapSetLayer.build(data), replen=128) + + def swapSetTimestamp(self): + pass + # 17 + + def swapEnd(self): + return self.send_cmd(18, b"\x00" * 12, replen=128) + + #def swapWait(self, swap_id): + #buf = struct.pack("<IIII", 1, swap_id, 0, swap_id) + #return self.send_cmd(19, buf, replen=128) + +class DCPIBootEndpoint(EPICEndpoint): + SHORT = "iboot" + + SERVICES = [ + DCPIBootService, + ] + + +class DCPIBootClient(StandardASC): + DVA_OFFSET = 0xf00000000 + + ENDPOINTS = { + 0x20: AFKSystemEndpoint, + 0x23: DCPIBootEndpoint, + 0x24: DCPDPTXEndpoint, + 0x2a: DCPDPTXPortEndpoint, + 0x27: DCPAVDeviceEndpoint, + 0x28: DCPAVServiceEndpoint, + 0x29: DCPAVVideoEndpoint, + } + + def __init__(self, u, asc_base, dart=None, disp_dart=None): + super().__init__(u, asc_base, dart) + self.disp_dart = disp_dart |
