aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authoryakui_zhao <yakui.zhao@intel.com>2009-05-31 05:17:17 -0400
committerEric Anholt <eric@anholt.net>2009-06-05 10:13:05 -0400
commit9b9d172d06b0f2d51cc9431e2c6c3055f0cf10ef (patch)
tree64721f8599a6cb39706cc9c48ce04c17f7377911 /drivers/gpu
parent59a036cfbd29aadf40d2b754cfebee2a96268752 (diff)
drm/i915: parse VBT general definition block to get the SDVO device info
The general definition block contains the child device tables, which include the SDVO device info. For example: device slave address, device dvo port, device type. We will get the info of SDVO device by parsing the general definition blocks. Only when a valid slave address is found, it is regarded as the SDVO device. And the info of DVO port and slave address is recorded. http://bugs.freedesktop.org/show_bug.cgi?id=20429 Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h8
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c86
2 files changed, 93 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ded9e786883e..db81f5513daa 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -126,6 +126,13 @@ struct drm_i915_fence_reg {
126 struct drm_gem_object *obj; 126 struct drm_gem_object *obj;
127}; 127};
128 128
129struct sdvo_device_mapping {
130 u8 dvo_port;
131 u8 slave_addr;
132 u8 dvo_wiring;
133 u8 initialized;
134};
135
129typedef struct drm_i915_private { 136typedef struct drm_i915_private {
130 struct drm_device *dev; 137 struct drm_device *dev;
131 138
@@ -389,6 +396,7 @@ typedef struct drm_i915_private {
389 /* storage for physical objects */ 396 /* storage for physical objects */
390 struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; 397 struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT];
391 } mm; 398 } mm;
399 struct sdvo_device_mapping sdvo_mappings[2];
392} drm_i915_private_t; 400} drm_i915_private_t;
393 401
394/** driver private structure attached to each drm_gem_object */ 402/** driver private structure attached to each drm_gem_object */
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 9d78cff33b24..754dd22fdd77 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -30,6 +30,8 @@
30#include "i915_drv.h" 30#include "i915_drv.h"
31#include "intel_bios.h" 31#include "intel_bios.h"
32 32
33#define SLAVE_ADDR1 0x70
34#define SLAVE_ADDR2 0x72
33 35
34static void * 36static void *
35find_section(struct bdb_header *bdb, int section_id) 37find_section(struct bdb_header *bdb, int section_id)
@@ -193,6 +195,88 @@ parse_general_features(struct drm_i915_private *dev_priv,
193 } 195 }
194} 196}
195 197
198static void
199parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
200 struct bdb_header *bdb)
201{
202 struct sdvo_device_mapping *p_mapping;
203 struct bdb_general_definitions *p_defs;
204 struct child_device_config *p_child;
205 int i, child_device_num, count;
206 u16 block_size, *block_ptr;
207
208 p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
209 if (!p_defs) {
210 DRM_DEBUG("No general definition block is found\n");
211 return;
212 }
213 /* judge whether the size of child device meets the requirements.
214 * If the child device size obtained from general definition block
215 * is different with sizeof(struct child_device_config), skip the
216 * parsing of sdvo device info
217 */
218 if (p_defs->child_dev_size != sizeof(*p_child)) {
219 /* different child dev size . Ignore it */
220 DRM_DEBUG("different child size is found. Invalid.\n");
221 return;
222 }
223 /* get the block size of general definitions */
224 block_ptr = (u16 *)((char *)p_defs - 2);
225 block_size = *block_ptr;
226 /* get the number of child device */
227 child_device_num = (block_size - sizeof(*p_defs)) /
228 sizeof(*p_child);
229 count = 0;
230 for (i = 0; i < child_device_num; i++) {
231 p_child = &(p_defs->devices[i]);
232 if (!p_child->device_type) {
233 /* skip the device block if device type is invalid */
234 continue;
235 }
236 if (p_child->slave_addr != SLAVE_ADDR1 &&
237 p_child->slave_addr != SLAVE_ADDR2) {
238 /*
239 * If the slave address is neither 0x70 nor 0x72,
240 * it is not a SDVO device. Skip it.
241 */
242 continue;
243 }
244 if (p_child->dvo_port != DEVICE_PORT_DVOB &&
245 p_child->dvo_port != DEVICE_PORT_DVOC) {
246 /* skip the incorrect SDVO port */
247 DRM_DEBUG("Incorrect SDVO port. Skip it \n");
248 continue;
249 }
250 DRM_DEBUG("the SDVO device with slave addr %2x is found on "
251 "%s port\n",
252 p_child->slave_addr,
253 (p_child->dvo_port == DEVICE_PORT_DVOB) ?
254 "SDVOB" : "SDVOC");
255 p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]);
256 if (!p_mapping->initialized) {
257 p_mapping->dvo_port = p_child->dvo_port;
258 p_mapping->slave_addr = p_child->slave_addr;
259 p_mapping->dvo_wiring = p_child->dvo_wiring;
260 p_mapping->initialized = 1;
261 } else {
262 DRM_DEBUG("Maybe one SDVO port is shared by "
263 "two SDVO device.\n");
264 }
265 if (p_child->slave2_addr) {
266 /* Maybe this is a SDVO device with multiple inputs */
267 /* And the mapping info is not added */
268 DRM_DEBUG("there exists the slave2_addr. Maybe this "
269 "is a SDVO device with multiple inputs.\n");
270 }
271 count++;
272 }
273
274 if (!count) {
275 /* No SDVO device info is found */
276 DRM_DEBUG("No SDVO device info is found in VBT\n");
277 }
278 return;
279}
196/** 280/**
197 * intel_init_bios - initialize VBIOS settings & find VBT 281 * intel_init_bios - initialize VBIOS settings & find VBT
198 * @dev: DRM device 282 * @dev: DRM device
@@ -242,7 +326,7 @@ intel_init_bios(struct drm_device *dev)
242 parse_general_features(dev_priv, bdb); 326 parse_general_features(dev_priv, bdb);
243 parse_lfp_panel_data(dev_priv, bdb); 327 parse_lfp_panel_data(dev_priv, bdb);
244 parse_sdvo_panel_data(dev_priv, bdb); 328 parse_sdvo_panel_data(dev_priv, bdb);
245 329 parse_sdvo_device_mapping(dev_priv, bdb);
246 pci_unmap_rom(pdev, bios); 330 pci_unmap_rom(pdev, bios);
247 331
248 return 0; 332 return 0;