We have two sources of information about panel capabilities on mobile radeon - the BIOS, which gives us a native mode, and the panel's preferred mode. In theory these two will always match, but there's some corner cases where the BIOS hasn't been fully initialised and so the native mode in it ends up with default values. However, if we get a panel with reasonable EDID, it's probably the case that the panel's preferred mode does actually represent the panel capabilities. This patch handles that case by replacing the native mode with the panel's preferred mode if the resolutions don't match. Systems without a valid internal panel EDID will still use the BIOS native mode.
Signed-off-by: Matthew Garrett mjg@redhat.com --- drivers/gpu/drm/radeon/radeon_connectors.c | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 6d6b5f1..3248738 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -474,11 +474,19 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct drm_display_mode *native_mode = &radeon_encoder->native_mode; + struct drm_display_mode *t, *mode; + + /* If the EDID preferred mode doesn't match the native mode, use it */ + list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { + if (mode->type & DRM_MODE_TYPE_PREFERRED) { + if (mode->hdisplay != native_mode->hdisplay || + mode->vdisplay != native_mode->vdisplay) + memcpy(native_mode, mode, sizeof(*mode)); + } + }
/* Try to get native mode details from EDID if necessary */ if (!native_mode->clock) { - struct drm_display_mode *t, *mode; - list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { if (mode->hdisplay == native_mode->hdisplay && mode->vdisplay == native_mode->vdisplay) { @@ -489,6 +497,7 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, } } } + if (!native_mode->clock) { DRM_DEBUG_KMS("No LVDS native mode details, disabling RMX\n"); radeon_encoder->rmx_type = RMX_OFF;
At least some Apples program the GPU into a state that wedges the engine once userspace starts trying to perform accelerated operations. Executing the Atom init scripts gets the hardware back into a working state. The same hardware works fine when booted via BIOS emulation, so let's just execute the init scripts on Apples when we're using EFI.
Signed-off-by: Matthew Garrett mjg@redhat.com --- drivers/gpu/drm/radeon/radeon_device.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 440e6ec..a3b011b 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -32,6 +32,7 @@ #include <drm/radeon_drm.h> #include <linux/vgaarb.h> #include <linux/vga_switcheroo.h> +#include <linux/efi.h> #include "radeon_reg.h" #include "radeon.h" #include "atom.h" @@ -348,6 +349,9 @@ bool radeon_card_posted(struct radeon_device *rdev) { uint32_t reg;
+ if (efi_enabled && rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) + return false; + /* first check CRTCs */ if (ASIC_IS_DCE41(rdev)) { reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
On Mon, Aug 8, 2011 at 12:21 PM, Matthew Garrett mjg@redhat.com wrote:
At least some Apples program the GPU into a state that wedges the engine once userspace starts trying to perform accelerated operations. Executing the Atom init scripts gets the hardware back into a working state. The same hardware works fine when booted via BIOS emulation, so let's just execute the init scripts on Apples when we're using EFI.
Signed-off-by: Matthew Garrett mjg@redhat.com
Reviewed-by: Alex Deucher alexander.deucher@amd.com
drivers/gpu/drm/radeon/radeon_device.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 440e6ec..a3b011b 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -32,6 +32,7 @@ #include <drm/radeon_drm.h> #include <linux/vgaarb.h> #include <linux/vga_switcheroo.h> +#include <linux/efi.h> #include "radeon_reg.h" #include "radeon.h" #include "atom.h" @@ -348,6 +349,9 @@ bool radeon_card_posted(struct radeon_device *rdev) { uint32_t reg;
- if (efi_enabled && rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE)
- return false;
/* first check CRTCs */ if (ASIC_IS_DCE41(rdev)) { reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | -- 1.7.6
On Mon, Aug 8, 2011 at 12:21 PM, Matthew Garrett mjg@redhat.com wrote:
We have two sources of information about panel capabilities on mobile radeon - the BIOS, which gives us a native mode, and the panel's preferred mode. In theory these two will always match, but there's some corner cases where the BIOS hasn't been fully initialised and so the native mode in it ends up with default values. However, if we get a panel with reasonable EDID, it's probably the case that the panel's preferred mode does actually represent the panel capabilities. This patch handles that case by replacing the native mode with the panel's preferred mode if the resolutions don't match. Systems without a valid internal panel EDID will still use the BIOS native mode.
Signed-off-by: Matthew Garrett mjg@redhat.com
Reviewed-by: Alex Deucher alexander.deucher@amd.com
drivers/gpu/drm/radeon/radeon_connectors.c | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 6d6b5f1..3248738 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -474,11 +474,19 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
- struct drm_display_mode *t, *mode;
- /* If the EDID preferred mode doesn't match the native mode, use it */
- list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
- if (mode->type & DRM_MODE_TYPE_PREFERRED) {
- if (mode->hdisplay != native_mode->hdisplay ||
- mode->vdisplay != native_mode->vdisplay)
- memcpy(native_mode, mode, sizeof(*mode));
- }
- }
/* Try to get native mode details from EDID if necessary */ if (!native_mode->clock) {
- struct drm_display_mode *t, *mode;
list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { if (mode->hdisplay == native_mode->hdisplay && mode->vdisplay == native_mode->vdisplay) { @@ -489,6 +497,7 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, } } }
if (!native_mode->clock) { DRM_DEBUG_KMS("No LVDS native mode details, disabling RMX\n"); radeon_encoder->rmx_type = RMX_OFF; -- 1.7.6
dri-devel@lists.freedesktop.org