Found out what the HDMI chip is on 5D2 "TDA19989AET/" data sheet below
https://media.digikey.com/pdf/Data%20Sheets/NXP%20PDFs/TDA19989.pdf
This is interesting; the HDMI chip is definitely I2C. Checking the address (that should be the first character from the I2C messages):
- the log has I2C_Read: 0x70, 7a, a few 72 and 7c, and I2C_Write: 70, 7a, a few 72 and 7e.
- HDMI core address (from datasheet): 0x70
- CEC core address (from datasheet): 0x34
Running with -d debugmsg,io in QEMU, after changing the HDMI CONNECT GPIO to 1, gives these messages, but the low-level I/O activity doesn't make much sense to me. The debug messages say I2C, but the communication looks more like SPI, with some unusual encoding of the address and data. There's probably a small controller between the DIGIC and the HDMI chip, which talks to the former via SPI and to the latter via I2C.
A good initial step would be to replay the I2C data from the logs in QEMU, hopefully initializing the HDMI display in the emulator. This is quite difficult for a beginner (it's not straightforward for me either), but I'm pretty sure it's doable.
I2C_Write:
If data size is 1, the following int32 is written to SPI: (addr << 20) | (sub << 11) | (data << 2) | 0x80402.
Cross-check: I2C_Write : 0x70, 0x98, len = 1, data = 0x11 => 0x70CC446 written to SIO1 TX register (visible with -d debugmsg,io in qemu).
Otherwise, (addr << 19) | (sub << 10) | (data[0] << 1) | 0x40201 (everything shifted by 1 bit to the right), followed by N-2 bytes encoded as (x<<1)+1, followed by the last byte encoded as (x<<2)+2. Guess: this SPI to I2C bridge is some logic function, and this weird encoding was chosen to reduce the number of logic gates.
Cross-check: I2C_Write : 0x70, 0x98, len = 3, data = 0x57; I2C : 57, 80, 03 => 0x38662AF, 0x101, 0xE written to TX register.
I2C_Read:
First, (addr << 11) | (sub << 2) | 0x403 is written to TX, regardless of data size.
If data size (known in advance) is 1, (addr << 11) | 0xFFE is written to SIO1 TX; the response is expected on RX, shifted by 1: out = *sio1_rx >> 1.
Cross-check (returning random values): I2C_Read : 0x70, 0x95, len = 1, data = 0xa0 => 0x38657 and 0x38FFE to TX, 0x677C8741 from RX.
Otherwise, (addr << 9) | 0x3FF is written to TX, and the response is bit-shifted: first read from the RX register gives the most significant 7 bits of the first response char (mask 0xFE, data shifted by 1), second read gives the least significant bit from the first char (mask 1<<8 ) and the most significant 7 bits from the second char (mask 0xFE after shifting left by 1), and so on. The last RX has LSB for char n-1 with mask 1<<10, and all 8 bits for the last char shifted by 1.
Cross-check:
[ HDMI:ff9aed94 ] (88:02) I2C_Read : 0x7c, 0xc0, len = 64, data = 0x91
[ HDMI:ff9aee1c ] (88:03) I2C : 91, e4, 71, c7, 95, 85, de, 8e, 7d, 60, 66, 2c, 9f, 19, 28, 35
[ HDMI:ff9aee1c ] (88:03) I2C : 54, 7a, a4, 31, 46, a5, ed, 25, 5a, 29, 1c, 5c, dc, a1, 7e, bd
[ HDMI:ff9aee1c ] (88:03) I2C : f1, 96, 78, ce, 7b, e4, a6, d1, 8d, c2, 4f, 67, 94, 2f, dd, e5
[ HDMI:ff9aee1c ] (88:03) I2C : 23, 62, 40, 5b, a5, 24, 47, 4b, ee, 7d, 2c, 68, ea, d5, 84, e5
=> 0x3E703, 0xFBFF to TX.
Random values were sent to RX to get the above numbers:
0x3D666748 -> 0x90 (shl 1, mask 0xFE)
0x352FF5A6 -> 0x91 (mask 0x100, shr 8)
0xEA1E5F2 -> 0xE4 (shl 1, mask 0xFE) [ same register read twice, but... random didn't know that ]
...
0x283B642 -> 0x84
0x75FDEBDC -> 0 (mask 0x400?)
0x7EF1AFCA -> 0xE5 (shl 1, mask 0xFF?)