aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_bios.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_bios.c')
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c86
1 files changed, 85 insertions, 1 deletions
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;