- B9A: read-only audit of stock LK/DT: the panel is an ST7735S 128x128 on SPI (BLSP1 QUP4, 16 MHz, mode 3, D/C GPIO116, RESET GPIO118), backlight = PM8916 MPP4 current sink 40 mA. - B9B: upstream panel-mipi-dbi with the stock init sequence as firmware; MPP4 sink via pinctrl + gpio-backlight; first light with correct colours/orientation/offsets. - B9C: fbcon (6x8, 21x16) on tty1 + getty, UART console kept, aurora-display service; cache B9C b9ce13c9 written and verified, cold boots with LTE + Wi-Fi + display. - B9L (RAM only): lk2nd second stage with an msm8916 SPI panel port shows a picture before Linux. - Sanitizer: whitelist for b8/ and b9/.
45 lines
2.2 KiB
Python
45 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
"""B9A read-only: decode the ST7735S init sequence from (a) stock LK lk.bin command table and
|
|
(b) stock dtb_01 qcom,mdss-spi-on-command, and compare them byte-for-byte.
|
|
LK table (gcdb mdss_spi_cmd, 16 B each): u32 size, u32 payload_ptr, u32 wait_ms, u8 cmds_post_tg.
|
|
DT format (msm-3.10 mdss_spi_panel): repeated [wait_ms, len, cmd, params...]; wait applies after the command.
|
|
usage: decode-panel.py lk.bin dtb_01.dts"""
|
|
import re, struct, sys
|
|
|
|
BASE = 0x8f600000
|
|
lk = open(sys.argv[1], 'rb').read()
|
|
dts = open(sys.argv[2]).read()
|
|
|
|
NAMES = {0x01: 'SWRESET', 0x11: 'SLPOUT', 0x20: 'INVOFF', 0x21: 'INVON', 0x28: 'DISPOFF', 0x29: 'DISPON',
|
|
0x2a: 'CASET', 0x2b: 'RASET', 0x2c: 'RAMWR', 0x36: 'MADCTL', 0x3a: 'COLMOD', 0xb1: 'FRMCTR1',
|
|
0xb2: 'FRMCTR2', 0xb3: 'FRMCTR3', 0xb4: 'INVCTR', 0xc0: 'PWCTR1', 0xc1: 'PWCTR2', 0xc2: 'PWCTR3',
|
|
0xc3: 'PWCTR4', 0xc4: 'PWCTR5', 0xc5: 'VMCTR1', 0xe0: 'GMCTRP1', 0xe1: 'GMCTRN1', 0x10: 'SLPIN'}
|
|
|
|
def lk_cmds(table, n):
|
|
out = []
|
|
for i in range(n):
|
|
size, ptr, wait, post = struct.unpack_from('<IIIB', lk, table - BASE + 16 * i)
|
|
out.append((bytes(lk[ptr - BASE:ptr - BASE + size]), wait))
|
|
return out
|
|
|
|
def dt_cmds(node, prop):
|
|
m = re.search(re.escape(node) + r' \{.*?' + re.escape(prop) + r' = \[([0-9a-f ]+)\];', dts, re.S)
|
|
b = bytes.fromhex(m.group(1)); out = []; i = 0
|
|
while i < len(b):
|
|
wait, ln = b[i], b[i + 1]; out.append((b[i + 2:i + 2 + ln], wait)); i += 2 + ln
|
|
return out
|
|
|
|
def show(title, cmds):
|
|
print(f'== {title}: {len(cmds)} commands')
|
|
for i, (p, w) in enumerate(cmds):
|
|
print(f' {i:2d} {p[0]:02x} {NAMES.get(p[0], "?"):8s} {p[1:].hex(" "):48s} wait={w} ms')
|
|
|
|
lkc = lk_cmds(0x8f64849c, 19) # st7735s table, count 19 (pinfo+0xf4/+0xf0, panel_id 1 branch)
|
|
dtc = dt_cmds('qcom,mdss_spi_st7735s_wx144_128x128_cmd', 'qcom,mdss-spi-on-command')
|
|
show('stock LK st7735s (0x8f64849c)', lkc)
|
|
show('stock dtb_01 st7735s on-command', dtc)
|
|
print('LK == DT (payload+wait):', lkc == dtc)
|
|
for i, (a, b) in enumerate(zip(lkc, dtc)):
|
|
if a != b:
|
|
print(' diff at', i, a, b)
|
|
show('stock dtb_01 st7735s off-command', dt_cmds('qcom,mdss_spi_st7735s_wx144_128x128_cmd', 'qcom,mdss-spi-off-command'))
|