>From eae41c519d9e3dd948fa965a16f0ef6586386ca1 Mon Sep 17 00:00:00 2001
From: Alex Deucher <[email protected]>
Date: Fri, 5 Feb 2010 04:21:19 -0500
Subject: [PATCH] drm/radeon/kms: add support for hardcoded edids in rom

Some servers hardcode an edid in rom so that they will
work properly with KVMs.  This is a port of the relevant
code from the ddx.

Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/radeon/radeon.h         |    1 +
 drivers/gpu/drm/radeon/radeon_combios.c |   21 +++++++++++++++++++++
 drivers/gpu/drm/radeon/radeon_display.c |   15 ++++++++++++++-
 drivers/gpu/drm/radeon/radeon_mode.h    |    2 ++
 4 files changed, 38 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 584b206..ede3e91 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -826,6 +826,7 @@ struct radeon_device {
        struct workqueue_struct *wq;
        struct work_struct hotplug_work;
        int num_crtc; /* number of crtcs */
+       bool edid_in_rom; /* hardcoded edid in rom */

        /* audio stuff */
        struct timer_list       audio_timer;
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c
b/drivers/gpu/drm/radeon/radeon_combios.c
index 24a485a..e75edd9 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -443,6 +443,27 @@ static uint16_t combios_get_table_offset(struct
drm_device *dev,

 }

+struct edid *
+radeon_combios_get_hardcoded_edid(struct radeon_device *rdev)
+{
+       struct drm_device *dev = rdev->ddev;
+       u16 edid_info;
+       struct edid *edid = NULL;
+
+       edid_info = combios_get_table_offset(dev, COMBIOS_HARDCODED_EDID_TABLE);
+       if (edid_info) {
+               if (RBIOS8(edid_info) == 0xff) {
+                       edid = kmalloc(EDID_LENGTH * (4 /*MAX_EDID_EXT_NUM*/ + 
1),
+                                      GFP_KERNEL);
+                       if (edid == NULL)
+                               return NULL;
+                       memcpy((unsigned char *)edid,
+                              (unsigned char *)(rdev->bios + edid_info), 
EDID_LENGTH);
+               }
+       }
+       return edid;
+}
+
 static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct
radeon_device *rdev,
                                                       int ddc_line)
 {
diff --git a/drivers/gpu/drm/radeon/radeon_display.c
b/drivers/gpu/drm/radeon/radeon_display.c
index 42f1def..7beefb3 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -384,6 +384,8 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)

 int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
 {
+       struct drm_device *dev = radeon_connector->base.dev;
+       struct radeon_device *rdev = dev->dev_private;
        int ret = 0;

        if ((radeon_connector->base.connector_type ==
DRM_MODE_CONNECTOR_DisplayPort) ||
@@ -400,7 +402,9 @@ int radeon_ddc_get_modes(struct radeon_connector
*radeon_connector)
                radeon_connector->edid = drm_get_edid(&radeon_connector->base,
&radeon_connector->ddc_bus->adapter);
                radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
        }
-
+       /* some servers provide a hardcoded edid in rom for KVMs */
+       if ((!radeon_connector->edid) && rdev->edid_in_rom)
+               radeon_connector->edid = 
radeon_combios_get_hardcoded_edid(rdev);
        if (radeon_connector->edid) {
                drm_mode_connector_update_edid_property(&radeon_connector->base,
radeon_connector->edid);
                ret = drm_add_edid_modes(&radeon_connector->base, 
radeon_connector->edid);
@@ -863,6 +867,7 @@ static int radeon_modeset_create_props(struct
radeon_device *rdev)

 int radeon_modeset_init(struct radeon_device *rdev)
 {
+       struct drm_device *dev = rdev->ddev;
        int i;
        int ret;

@@ -886,6 +891,14 @@ int radeon_modeset_init(struct radeon_device *rdev)
                return ret;
        }

+       /* add quirks -- is there a better place for this? */
+       rdev->edid_in_rom = false;
+       if (ASIC_IS_RN50(rdev)) {
+               if ((dev->pdev->subsystem_vendor == 0x108e /* SUN */) &&
+                   ((dev->pdev->subsystem_device == 0x016c)))
+                       rdev->edid_in_rom = true;
+       }
+
        if (rdev->flags & RADEON_SINGLE_CRTC)
                rdev->num_crtc = 1;
        else {
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h
b/drivers/gpu/drm/radeon/radeon_mode.h
index 81bfc5b..184e44b 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -479,6 +479,8 @@ extern int radeon_crtc_cursor_set(struct drm_crtc *crtc,
 extern int radeon_crtc_cursor_move(struct drm_crtc *crtc,
                                   int x, int y);

+extern struct edid *
+radeon_combios_get_hardcoded_edid(struct radeon_device *rdev);
 extern bool radeon_atom_get_clock_info(struct drm_device *dev);
 extern bool radeon_combios_get_clock_info(struct drm_device *dev);
 extern struct radeon_encoder_atom_dig *
-- 
1.5.6.3

Attachment: 0001-drm-radeon-kms-add-support-for-hardcoded-edids-in-r.patch
Description: application/mbox

------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
--
_______________________________________________
Dri-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to