raspberrypi / rpi-eeprom

Installation scripts and binaries for the Raspberry Pi 4 and Raspberry Pi 5 bootloader EEPROMs
https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#raspberry-pi-boot-eeprom
Other
1.26k stars 200 forks source link

CM4 bootloader does not appear to read or honor EDID #479

Open JinShil opened 1 year ago

JinShil commented 1 year ago

Describe the bug

We have two CM4-based panel PCs. One driving a 7" touchscreen LCD, and the other driving a 10" touchscreen LCD. Both are identical with the exception of the LCD. The LCD is connected to the CM4 via HDMI (HDMI0).

With no OS to boot from (e.g. no OS is installed on the eMMC or SD card), the 7" LCD displays the boot diagnostics screen pictured at https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#boot-diagnostics-on-the-raspberry-pi-4 This is as we expect.

However, with no OS to boot from, the 10" LCD does not display the boot diagnostics screen.

With an OS installed on the eMMC or SD card, both the 7" and 10" panel PCs boot to the desktop and display the Raspberry Pi desktop as expected.

Each panel PC has an EEPROM, connected via I2C (HDMI0_SCL/SDA), which stores the LCD's EDID. When booting from an OS installed on the eMMC or SD Card, this EDID is read from this EEPROM, and both the 7" and 10" LCDs display boot messages and the Raspberry Pi OS desktop as expected. When there is no OS to boot from, only the 7" LCD displays the boot diagnostics screen; the 10" LCD does not.

I hypothesize that the bootloader is not reading the EDID, or the logic for interpreting the EDID is different than that which the OS uses, and that is causing the 10" LCD to not display the boot diagnostics screen. The 7" LCD displays the boot diagnostics screen because the bootloader's default HDMI configuration just happens to match that of the 7" LCD. Is there merit to this hypothesis? If not, please advise.

EDID files for both the 7" and 10" LCDs are attached. EDID.zip

pi@raspberrypi:~ $ vcgencmd bootloader_version
2023/05/11 07:26:03
version 4fd8f1f3f7a05f7756edb1d3f15ffd7e428981f5 (release)
timestamp 1683786363
update-time 1684177011
capabilities 0x0000007f

Steps to reproduce the behaviour

  1. Write EDID to EEPROM
  2. Boot without installing OS to the eMMC or SD Card. Notice that on 7" LCD the boot diagnostics screen appears correctly, but on the 10" LCD it does not.
  3. Install an OS to the eMMC or SD card.
  4. Boot from the OS. Notice that both the 7" and 10" LCDs display correctly. Take note that edid-decode /sys/class/drm/card1-HDMI-A-1/edid shows that the EDID is being read when booting the OS.

Device(s)

Raspberry Pi CM4, Raspberry Pi CM4 Lite

Compute Module IO board.

Custom

RPIBOOT logs

No response

Kernel logs

No response

Device UART logs

No response

timg236 commented 1 year ago

It does read the EDID but will only ever support VGA (default if no edid), 720p (and maybe 1080p)

timg236 commented 1 year ago

Moved to rpi-eeprom repo

JinShil commented 1 year ago

In addition to resolution, what about other settings like pixel clock, back & front porch, etc? We could probably deal with a lower resolution like VGA, but without the right LCD timings, nothing but display artifacts will appear on the screen.

timg236 commented 1 year ago

The bootloader only supports HDMI and DVI. The HDMI compliance tests require VGA support and the bootloader uses the standard timings. If EDID is not available (e.g. short SCL to fake this) then the standard VGA timings will be used

{1,  640,  HDMI_NEGATIVE_SYNC,   16,  96,  48,  480,  HDMI_NEGATIVE_SYNC, 10,  2,  33,    0,    0,       0,       60,  25200000};

typedef struct {
   unsigned short videoID_code;
   unsigned short h_active_pixels;
   HDMI_SYNC_T    h_sync_polarity;
   unsigned short h_front_porch;
   unsigned short h_sync_pulse;
   unsigned short h_back_porch;

   unsigned short v_active_lines;
   HDMI_SYNC_T    v_sync_polarity;
   unsigned short v_front_porch;
   unsigned short v_sync_pulse;
   unsigned short v_back_porch;
   unsigned short v_sync_offset_a;
   unsigned short v_sync_offset_b;

   unsigned short pixel_rep;
   unsigned short frame_rate;
   HDMI_INTERLACED_T interlaced;
   frequency_t pixel_freq;
   HDMI_DISPLAY_TIMINGS_FLAGS_T flags;
} HDMI_DISPLAY_TIMINGS_T;
timg236 commented 1 year ago

I future improvement might be to have an EEPROM config option to force an explicit CEA mode e.g. if the panel / driver-chip can't support VGA 720 / 1080p could be forced. Although, I think the set of modes will be quite limited

JinShil commented 1 year ago

We need to display the bootloader diagnostics screen on our LCDs. Anything that doesn't allow us to do that is not helpful for us. I don't see how forcing a specific mode will help us, if the mode is not compatible with our LCDs.

Why not just read and honor the settings in the EDID like the OS and firmware does? What's the limitation? Is the bootloader EEPROM too small to store the code?

timg236 commented 1 year ago

Do the panels not support VGA / DVI?

The bootloader display driver only supports a small number of specific CEA modes VGA, 720p and 1080p might get added. There's no plans at the moment to support arbitrary timing or a full display stack. I doubt it will ever support DSI/DPI

JinShil commented 1 year ago

Our LCDs have a 40-pin TTL RGB interface or an LVDS interface. We run the HDMI output of the CM4 through a converter IC. The LCD resolutions include 800x480, 1024x600, 1024x768, and 1280x1024.

VGA 640x480 would be better than nothing even if it displayed in the top left corner of the screen or was tiled across the screen, but I don't think we can get anything to appear on the screen if we can't set pixel clocks, front/back porch, etc. Here's an example of what we see without such settings:

image

timg236 commented 1 year ago

Looking at the EDIDs it seems that they don't explicitly declare support for VGA. It may be possible to add support for some common panel resolutions 1024x768 and 800x480 but that's a new feature so can't promise when anyone would be available to look at that. If we were to do that then I would probably add an option similar to hdmi_mode= to force resolutions if EDID is not found since VGA is not necessarily supported by non-HDMI displays.

JinShil commented 12 months ago

If we were to do that then I would probably add an option similar to hdmi_mode= to force resolutions if EDID is not found since VGA is not necessarily supported by non-HDMI displays.

I'm sorry, but I don't understand this. The EDID has the resolution coded in it, so the firmware should just read it and honor it, correct?

Our LCD panels are connected to the compute module through a TFP401A HDMI to TTL RGB converter. So, from the perspective of the compute module it is an HDMI display. I think the firmware just needs to read and transmit the timing settings as pictured below: image Is that possible?

timg236 commented 11 months ago

It's technically feasible, but right now the bootloader HDMI setup is literally just some pre-canned HDMI register setup which was all that was required for 640x480. Marked as enhancement because it seems reasonable but can't say when this might be done.