Hello
Changelog:
Use VBT information to determine which DDC bus to use for CRTDCC.
Fall back to GPIOA if VBT info is not available.
Reviewed-by: Jesse Barnes <jbar...@virtuousgeek.org>
Signed-off-by: David Müller <d.muel...@elsoft.ch>
diff -dpurN linux-2.6.31-rc8.orig/drivers/gpu/drm/i915/i915_drv.h
linux-2.6.31-rc8.patched/drivers/gpu/drm/i915/i915_drv.h
--- linux-2.6.31-rc8.orig/drivers/gpu/drm/i915/i915_drv.h 2009-08-28
02:59:04.000000000 +0200
+++ linux-2.6.31-rc8.patched/drivers/gpu/drm/i915/i915_drv.h 2009-08-28
09:06:56.000000000 +0200
@@ -222,6 +222,7 @@ typedef struct drm_i915_private {
unsigned int edp_support:1;
int lvds_ssc_freq;
+ int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */
struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
int num_fence_regs; /* 8 on pre-965, 16 otherwise */
diff -dpurN linux-2.6.31-rc8.orig/drivers/gpu/drm/i915/intel_bios.c
linux-2.6.31-rc8.patched/drivers/gpu/drm/i915/intel_bios.c
--- linux-2.6.31-rc8.orig/drivers/gpu/drm/i915/intel_bios.c 2009-08-28
02:59:04.000000000 +0200
+++ linux-2.6.31-rc8.patched/drivers/gpu/drm/i915/intel_bios.c 2009-08-28
09:07:54.000000000 +0200
@@ -59,6 +59,16 @@ find_section(struct bdb_header *bdb, int
return NULL;
}
+static u16
+get_blocksize(void *p)
+{
+ u16 *block_ptr, block_size;
+
+ block_ptr = (u16 *)((char *)p - 2);
+ block_size = *block_ptr;
+ return block_size;
+}
+
static void
fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
struct lvds_dvo_timing *dvo_timing)
@@ -215,6 +225,41 @@ parse_general_features(struct drm_i915_p
}
static void
+parse_general_definitions(struct drm_i915_private *dev_priv,
+ struct bdb_header *bdb)
+{
+ struct bdb_general_definitions *general;
+ const int crt_bus_map_table[] = {
+ GPIOB,
+ GPIOA,
+ GPIOC,
+ GPIOD,
+ GPIOE,
+ GPIOF,
+ };
+
+ /* Set sensible defaults in case we can't find the general block
+ or it is the wrong chipset */
+ dev_priv->crt_ddc_bus = -1;
+
+ general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
+ if (general) {
+ u16 block_size = get_blocksize(general);
+ if (block_size >= sizeof(*general)) {
+ int bus_pin = general->crt_ddc_gmbus_pin;
+ DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin);
+ if ((bus_pin >= 1) && (bus_pin <= 6)) {
+ dev_priv->crt_ddc_bus =
+ crt_bus_map_table[bus_pin-1];
+ }
+ } else {
+ DRM_DEBUG("BDB_GD too small (%d). Invalid.\n",
+ block_size);
+ }
+ }
+}
+
+static void
parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
struct bdb_header *bdb)
{
@@ -222,7 +267,7 @@ parse_sdvo_device_mapping(struct drm_i91
struct bdb_general_definitions *p_defs;
struct child_device_config *p_child;
int i, child_device_num, count;
- u16 block_size, *block_ptr;
+ u16 block_size;
p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
if (!p_defs) {
@@ -240,8 +285,7 @@ parse_sdvo_device_mapping(struct drm_i91
return;
}
/* get the block size of general definitions */
- block_ptr = (u16 *)((char *)p_defs - 2);
- block_size = *block_ptr;
+ block_size = get_blocksize(p_defs);
/* get the number of child device */
child_device_num = (block_size - sizeof(*p_defs)) /
sizeof(*p_child);
@@ -362,6 +406,7 @@ intel_init_bios(struct drm_device *dev)
/* Grab useful general definitions */
parse_general_features(dev_priv, bdb);
+ parse_general_definitions(dev_priv, bdb);
parse_lfp_panel_data(dev_priv, bdb);
parse_sdvo_panel_data(dev_priv, bdb);
parse_sdvo_device_mapping(dev_priv, bdb);
diff -dpurN linux-2.6.31-rc8.orig/drivers/gpu/drm/i915/intel_crt.c
linux-2.6.31-rc8.patched/drivers/gpu/drm/i915/intel_crt.c
--- linux-2.6.31-rc8.orig/drivers/gpu/drm/i915/intel_crt.c 2009-08-28
02:59:04.000000000 +0200
+++ linux-2.6.31-rc8.patched/drivers/gpu/drm/i915/intel_crt.c 2009-08-28
09:06:56.000000000 +0200
@@ -508,6 +508,7 @@ void intel_crt_init(struct drm_device *d
{
struct drm_connector *connector;
struct intel_output *intel_output;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 i2c_reg;
intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
@@ -527,8 +528,12 @@ void intel_crt_init(struct drm_device *d
/* Set up the DDC bus. */
if (IS_IGDNG(dev))
i2c_reg = PCH_GPIOA;
- else
+ else {
i2c_reg = GPIOA;
+ /* Use VBT information for CRT DDC if available */
+ if (dev_priv->crt_ddc_bus != -1)
+ i2c_reg = dev_priv->crt_ddc_bus;
+ }
intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
if (!intel_output->ddc_bus) {
dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel