Blank screen after boot on Radeon Mobility 4670 HD

Description

I'm running Haiku A3 on MSI EX625 laptop, which has Radeon Mobility 4670 HD on board. The PCIID for this card was added to radeon_hd driver listing very recently. I've built radeon_hd driver and the accelerator as of "hrev43937", and put them in places of the original files:/system/add-ons/kernel/drivers/bin/radeon_hd
/system/add-ons/accelerants/radeon_hd.accelerant

With new radeon_hd I'm getting a bright garbage-looking screen on boot (screenshot to be attached). I can boot fine with fail-safe video mode (which forces VESA and disables radeon_hd).

It might be relevant that "connector_read_mode_lvds" sees my native resolution as 1400x900, where the actual screen resolution is 1366x768. However, I get the same white garbage if I try to boot with a forced 1024x768 resolution (via the boot option), which works fine with VESA driver.

Thank you anevilyak. It would be very useful if I could really force the resolution from the boot menu, regardless of the driver used.
Also, the syslog attached is from the VESA-booted system. I'm not able to get the syslog from radeon_hd driven system. Please let me know If there is any way to get it saved.

My mistake: the native resolution detected by "connector_read_mode_lvds" is 1400x1050.
Also, I'm playing with radeon_hd accelerant code, and all the modes above the "native" one (which is not actually native) are marked BAD in the mode list, which is not the case for the original radeon_hd code. Sorry for the confusion.

Thank you anevilyak. It would be very useful if I could really force the resolution from the boot menu, regardless of the driver used.

The reason it doesn't work that way is because it can't really. In the case of VESA the BIOS gives you a list of resolutions to choose based on an index value you pass in, and takes care of all the rest from there since it's all standardized. When using the actual driver, you no longer have the benefit of that, and consequently the driver has to actually compute the modelines, which entails computing constraints based on the monitor, etc., and consequently a lot more information potentially has to be supplied.

The reason it doesn't work that way is because it can't really. In the case of VESA the BIOS gives you a list of resolutions to choose based on an index value you pass in, and takes care of all the rest from there since it's all standardized. When using the actual driver, you no longer have the benefit of that, and consequently the driver has to actually compute the modelines, which entails computing constraints based on the monitor, etc., and consequently a lot more information potentially has to be supplied.

No, of course, we do not want to compute the modelines. The driver generates a list of modes that are valid. All it needs to do is to find a mode in the list that matches the requested mode, if there is any.

building the accelerant and driver and dropping into the folder may not be a good test... a lot has changed in the image since A3. Could you test the latest nightly from an iso or dd'ed onto a usb drive?

That shows AtomBIOS is actually reporting a lvds mode of 1400x1050 for this card. Is 1400x1050 the correct native resolution? We pass that value back to Haiku as the preferred mode if a preferred mode is found.

building the accelerant and driver and dropping into the folder may not be a good test... a lot has changed in the image since A3. Could you test the latest nightly from an iso or dd'ed onto a usb drive?

Sure, I will do that and post in a moment.

That shows AtomBIOS is actually reporting a lvds mode of 1400x1050 for this card. Is 1400x1050 the correct native resolution? We pass that value back to Haiku as the preferred mode if a preferred mode is found.

As was mentioned before (here and on your blog), my native screen resolution is 1366x768. That is what WinXP, Win8, and Linux used to detect, at least. I have no idea why Haiku's LVDS queries give a different result.

It would be great if you could take a look at the AtomBIOS dump I provided...
Also, I assume there are logs from other OSes (like Linux, FreeBSD) that could be useful to investigate the case. If you have anything I can gather in mind, let me know.

1) VESA knows about the native panel mode (1366x768), which is a single mode reported under additional modes section. I have a feeling that these additional (or "detailed") modes should be marked somehow on our end, because they are always relevant (in contrast to ones in the standard mode list).

2) radeon_hd does not even attempt to set the incorrectly detected mode (1400x1050). Instead, it tries to switch to 1024x768. As far as I got, it's the app_server that calls the accelerant to switch to this mode. I have no idea why that happens, and will look into that; however, it's all new to me, so the digging process is very slow :(

Seems like there is some kind of hidden EDID patch (cough hack) in the atombios tables we need to apply over what atombios *just* told us the lvds mode was. Likely not used often as not many people see this issue.

LCDPANEL_CAP_READ_EDID seems like it would be the answer, though the AtomBIOS dump shows ucLCDPanel_SpecialHandlingCap to be 0 :(

-//Definitions for ucLCDPanel_SpecialHandlingCap:
-
-//Once DAL sees this CAP is set, it will read EDID from LCD on its own instead of using sLCDTiming in ATOM_LVDS_INFO_V12.
-//Other entries in ATOM_LVDS_INFO_V12 are still valid/useful to DAL
-#define LCDPANEL_CAP_READ_EDID 0x1
-
-//If a design supports DRR (dynamic refresh rate) on internal panels (LVDS or EDP), this cap is set in ucLCDPanel_SpecialHandlingCap together
-//with multiple supported refresh rates@usSupportedRefreshRate. This cap should not be set when only slow refresh rate is supported (static
-//refresh rate switch by SW. This is only valid from ATOM_LVDS_INFO_V12
-#define LCDPANEL_CAP_DRR_SUPPORTED 0x2
-
-//Use this cap bit for a quick reference whether an embadded panel (LCD1 ) is LVDS or eDP.
-#define LCDPANEL_CAP_eDP 0x4

I'm going to work on a patch that adds the following check box to the fail-safe video modes list in the boot menu:
"Prefer additional VESA mode, if provided", checked by default.

That seems like a fairly hacky hack. Wouldn't it be better to just boot from failsafe (vesa)?

That's what I'm talking about. When booting with VESA as a fallback, people (like me) would still like to use their native resolution, and this resolution is exactly specified in the Additional VESA modes section, as far as I can see.

I'd focus on the drm driver to try and figure out what it is doing different. I've reviewed the code and don't see anything different. Let me ping AMD and see what they think.

We think DRM looks for an EDID from the LVDS panel before going to the LVDS_Into table. That is likely the difference.

21:08 <kallisti5> Good morning. Super quick question. Do you know the case to ignore the AtomBIOS LVDS_Info off the top of your head?
21:09 <AMD> it should always be correct
21:09 <kallisti5> I have a user with a Radeon HD Mobility 4670. usHActive is 1400 and usVActice is 1050. however the native resolution of the lcd is 1366x768
21:09 <kallisti5> hmm
21:10 <AMD> is it a mac?
21:10 <kallisti5> I did see the LVDS patch table, but it doesn't seem to exist in the later table version (1.2)
21:10 <kallisti5> not that i'm aware of... good question though
21:10 <AMD> or did the user hack their system and install a non-standard panel?
21:10 <kallisti5> nope. "MSI EX625 laptop"
21:11 <kallisti5> well.. vesa has the correct perferred mode
21:11 <kallisti5> KERN: Additional Video Mode (1366x768@59Hz):
21:11 <AMD> if the panel has an EDID you can check that first
21:11 <kallisti5> I thought lvds didn't have edid?
21:11 <AMD> usually does
21:11 <AMD> only on really old laptops
21:12 <AMD> does it not
21:12 <AMD> the sbios usually patches the vbios LCDInfo table with the values from the EDID at boot
21:12 <kallisti5> ah. ok. that helps :D We can check for edid, else look for lvds_info
21:12 <AMD> which is how the values get there
21:12 <kallisti5> aah. It maybe a quirk
21:13 <AMD> could be a funky oem bios
21:13 <kallisti5> 99% of the time it's been fine... just this one machine
21:13 <kallisti5> thanks :)
21:13 <AMD> np

So! The logic should be changed. Instead of jumping directly to that table, we should try to bit-bang an EDID from the LVDS gpio pin... if that fails to produce a valid EDID, use the LVDS_Info (if it is an LVDS panel)

I can make the change, it may be a few days though as my free time is short lately.

That's awesome! When you are ready with the fix, please provide binaries as well, because I don't have the dev environment set up at this point. That in case you'd like to test it before submitting... Otherwise, I'll just wait for the nightly build.

A patched system booted into a black screen. As if it wasn't powered on at all. Please see syslog-patched attachment for details. It did try the correct resolution (1366x768), so there must be some other bit missing.

With the second accelerant and an original kernel driver I'm getting the same picture as without patches at all - screen is corrupted. Please see syslog-patched2 attached. I noticed that the pitch is 1376, which doesn't match the width, though I'm not sure if that's the problem.

Confirmed it's still broken on latest. Also, investigated my options on using VESA. Despite the fact EDID reports proper timings for 1366x768, this mode is not a valid VESA mode :(. Hence, we'll have to push radeon_hd into supporting it properly.

Clearly, the framebuffer address is invalid (0x0), and the pitch is totally wrong. Firstly, because it doesn't take into account 4 bytes per pixel. Secondly, because of a smaller alignment (DRM's 5632 = 4 * 1408).