diff options
-rw-r--r-- | drivers/gpu/drm/gma500/intel_bios.c | 232 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/intel_bios.h | 122 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/intel_opregion.c | 117 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_drv.h | 4 |
4 files changed, 438 insertions, 37 deletions
diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c index 51ea6df125f2..479e4497d26c 100644 --- a/drivers/gpu/drm/gma500/intel_bios.c +++ b/drivers/gpu/drm/gma500/intel_bios.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include "psb_intel_reg.h" | 26 | #include "psb_intel_reg.h" |
27 | #include "intel_bios.h" | 27 | #include "intel_bios.h" |
28 | 28 | ||
29 | #define SLAVE_ADDR1 0x70 | ||
30 | #define SLAVE_ADDR2 0x72 | ||
29 | 31 | ||
30 | static void *find_section(struct bdb_header *bdb, int section_id) | 32 | static void *find_section(struct bdb_header *bdb, int section_id) |
31 | { | 33 | { |
@@ -52,6 +54,16 @@ static void *find_section(struct bdb_header *bdb, int section_id) | |||
52 | return NULL; | 54 | return NULL; |
53 | } | 55 | } |
54 | 56 | ||
57 | static u16 | ||
58 | get_blocksize(void *p) | ||
59 | { | ||
60 | u16 *block_ptr, block_size; | ||
61 | |||
62 | block_ptr = (u16 *)((char *)p - 2); | ||
63 | block_size = *block_ptr; | ||
64 | return block_size; | ||
65 | } | ||
66 | |||
55 | static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, | 67 | static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, |
56 | struct lvds_dvo_timing *dvo_timing) | 68 | struct lvds_dvo_timing *dvo_timing) |
57 | { | 69 | { |
@@ -75,6 +87,16 @@ static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, | |||
75 | panel_fixed_mode->clock = dvo_timing->clock * 10; | 87 | panel_fixed_mode->clock = dvo_timing->clock * 10; |
76 | panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; | 88 | panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; |
77 | 89 | ||
90 | if (dvo_timing->hsync_positive) | ||
91 | panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC; | ||
92 | else | ||
93 | panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
94 | |||
95 | if (dvo_timing->vsync_positive) | ||
96 | panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC; | ||
97 | else | ||
98 | panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC; | ||
99 | |||
78 | /* Some VBTs have bogus h/vtotal values */ | 100 | /* Some VBTs have bogus h/vtotal values */ |
79 | if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) | 101 | if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) |
80 | panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; | 102 | panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; |
@@ -218,6 +240,97 @@ static void parse_general_features(struct drm_psb_private *dev_priv, | |||
218 | } | 240 | } |
219 | 241 | ||
220 | static void | 242 | static void |
243 | parse_sdvo_device_mapping(struct drm_psb_private *dev_priv, | ||
244 | struct bdb_header *bdb) | ||
245 | { | ||
246 | struct sdvo_device_mapping *p_mapping; | ||
247 | struct bdb_general_definitions *p_defs; | ||
248 | struct child_device_config *p_child; | ||
249 | int i, child_device_num, count; | ||
250 | u16 block_size; | ||
251 | |||
252 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | ||
253 | if (!p_defs) { | ||
254 | DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n"); | ||
255 | return; | ||
256 | } | ||
257 | /* judge whether the size of child device meets the requirements. | ||
258 | * If the child device size obtained from general definition block | ||
259 | * is different with sizeof(struct child_device_config), skip the | ||
260 | * parsing of sdvo device info | ||
261 | */ | ||
262 | if (p_defs->child_dev_size != sizeof(*p_child)) { | ||
263 | /* different child dev size . Ignore it */ | ||
264 | DRM_DEBUG_KMS("different child size is found. Invalid.\n"); | ||
265 | return; | ||
266 | } | ||
267 | /* get the block size of general definitions */ | ||
268 | block_size = get_blocksize(p_defs); | ||
269 | /* get the number of child device */ | ||
270 | child_device_num = (block_size - sizeof(*p_defs)) / | ||
271 | sizeof(*p_child); | ||
272 | count = 0; | ||
273 | for (i = 0; i < child_device_num; i++) { | ||
274 | p_child = &(p_defs->devices[i]); | ||
275 | if (!p_child->device_type) { | ||
276 | /* skip the device block if device type is invalid */ | ||
277 | continue; | ||
278 | } | ||
279 | if (p_child->slave_addr != SLAVE_ADDR1 && | ||
280 | p_child->slave_addr != SLAVE_ADDR2) { | ||
281 | /* | ||
282 | * If the slave address is neither 0x70 nor 0x72, | ||
283 | * it is not a SDVO device. Skip it. | ||
284 | */ | ||
285 | continue; | ||
286 | } | ||
287 | if (p_child->dvo_port != DEVICE_PORT_DVOB && | ||
288 | p_child->dvo_port != DEVICE_PORT_DVOC) { | ||
289 | /* skip the incorrect SDVO port */ | ||
290 | DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n"); | ||
291 | continue; | ||
292 | } | ||
293 | DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on" | ||
294 | " %s port\n", | ||
295 | p_child->slave_addr, | ||
296 | (p_child->dvo_port == DEVICE_PORT_DVOB) ? | ||
297 | "SDVOB" : "SDVOC"); | ||
298 | p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]); | ||
299 | if (!p_mapping->initialized) { | ||
300 | p_mapping->dvo_port = p_child->dvo_port; | ||
301 | p_mapping->slave_addr = p_child->slave_addr; | ||
302 | p_mapping->dvo_wiring = p_child->dvo_wiring; | ||
303 | p_mapping->ddc_pin = p_child->ddc_pin; | ||
304 | p_mapping->i2c_pin = p_child->i2c_pin; | ||
305 | p_mapping->initialized = 1; | ||
306 | DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n", | ||
307 | p_mapping->dvo_port, | ||
308 | p_mapping->slave_addr, | ||
309 | p_mapping->dvo_wiring, | ||
310 | p_mapping->ddc_pin, | ||
311 | p_mapping->i2c_pin); | ||
312 | } else { | ||
313 | DRM_DEBUG_KMS("Maybe one SDVO port is shared by " | ||
314 | "two SDVO device.\n"); | ||
315 | } | ||
316 | if (p_child->slave2_addr) { | ||
317 | /* Maybe this is a SDVO device with multiple inputs */ | ||
318 | /* And the mapping info is not added */ | ||
319 | DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this" | ||
320 | " is a SDVO device with multiple inputs.\n"); | ||
321 | } | ||
322 | count++; | ||
323 | } | ||
324 | |||
325 | if (!count) { | ||
326 | /* No SDVO device info is found */ | ||
327 | DRM_DEBUG_KMS("No SDVO device info is found in VBT\n"); | ||
328 | } | ||
329 | return; | ||
330 | } | ||
331 | |||
332 | |||
333 | static void | ||
221 | parse_driver_features(struct drm_psb_private *dev_priv, | 334 | parse_driver_features(struct drm_psb_private *dev_priv, |
222 | struct bdb_header *bdb) | 335 | struct bdb_header *bdb) |
223 | { | 336 | { |
@@ -234,6 +347,72 @@ parse_driver_features(struct drm_psb_private *dev_priv, | |||
234 | dev_priv->dplla_96mhz = false; | 347 | dev_priv->dplla_96mhz = false; |
235 | } | 348 | } |
236 | 349 | ||
350 | static void | ||
351 | parse_device_mapping(struct drm_psb_private *dev_priv, | ||
352 | struct bdb_header *bdb) | ||
353 | { | ||
354 | struct bdb_general_definitions *p_defs; | ||
355 | struct child_device_config *p_child, *child_dev_ptr; | ||
356 | int i, child_device_num, count; | ||
357 | u16 block_size; | ||
358 | |||
359 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | ||
360 | if (!p_defs) { | ||
361 | DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); | ||
362 | return; | ||
363 | } | ||
364 | /* judge whether the size of child device meets the requirements. | ||
365 | * If the child device size obtained from general definition block | ||
366 | * is different with sizeof(struct child_device_config), skip the | ||
367 | * parsing of sdvo device info | ||
368 | */ | ||
369 | if (p_defs->child_dev_size != sizeof(*p_child)) { | ||
370 | /* different child dev size . Ignore it */ | ||
371 | DRM_DEBUG_KMS("different child size is found. Invalid.\n"); | ||
372 | return; | ||
373 | } | ||
374 | /* get the block size of general definitions */ | ||
375 | block_size = get_blocksize(p_defs); | ||
376 | /* get the number of child device */ | ||
377 | child_device_num = (block_size - sizeof(*p_defs)) / | ||
378 | sizeof(*p_child); | ||
379 | count = 0; | ||
380 | /* get the number of child devices that are present */ | ||
381 | for (i = 0; i < child_device_num; i++) { | ||
382 | p_child = &(p_defs->devices[i]); | ||
383 | if (!p_child->device_type) { | ||
384 | /* skip the device block if device type is invalid */ | ||
385 | continue; | ||
386 | } | ||
387 | count++; | ||
388 | } | ||
389 | if (!count) { | ||
390 | DRM_DEBUG_KMS("no child dev is parsed from VBT\n"); | ||
391 | return; | ||
392 | } | ||
393 | dev_priv->child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL); | ||
394 | if (!dev_priv->child_dev) { | ||
395 | DRM_DEBUG_KMS("No memory space for child devices\n"); | ||
396 | return; | ||
397 | } | ||
398 | |||
399 | dev_priv->child_dev_num = count; | ||
400 | count = 0; | ||
401 | for (i = 0; i < child_device_num; i++) { | ||
402 | p_child = &(p_defs->devices[i]); | ||
403 | if (!p_child->device_type) { | ||
404 | /* skip the device block if device type is invalid */ | ||
405 | continue; | ||
406 | } | ||
407 | child_dev_ptr = dev_priv->child_dev + count; | ||
408 | count++; | ||
409 | memcpy((void *)child_dev_ptr, (void *)p_child, | ||
410 | sizeof(*p_child)); | ||
411 | } | ||
412 | return; | ||
413 | } | ||
414 | |||
415 | |||
237 | /** | 416 | /** |
238 | * psb_intel_init_bios - initialize VBIOS settings & find VBT | 417 | * psb_intel_init_bios - initialize VBIOS settings & find VBT |
239 | * @dev: DRM device | 418 | * @dev: DRM device |
@@ -253,39 +432,54 @@ bool psb_intel_init_bios(struct drm_device *dev) | |||
253 | struct drm_psb_private *dev_priv = dev->dev_private; | 432 | struct drm_psb_private *dev_priv = dev->dev_private; |
254 | struct pci_dev *pdev = dev->pdev; | 433 | struct pci_dev *pdev = dev->pdev; |
255 | struct vbt_header *vbt = NULL; | 434 | struct vbt_header *vbt = NULL; |
256 | struct bdb_header *bdb; | 435 | struct bdb_header *bdb = NULL; |
257 | u8 __iomem *bios; | 436 | u8 __iomem *bios = NULL; |
258 | size_t size; | 437 | size_t size; |
259 | int i; | 438 | int i; |
260 | 439 | ||
261 | bios = pci_map_rom(pdev, &size); | 440 | /* XXX Should this validation be moved to intel_opregion.c? */ |
262 | if (!bios) | 441 | if (dev_priv->opregion.vbt) { |
263 | return -1; | 442 | struct vbt_header *vbt = dev_priv->opregion.vbt; |
443 | if (memcmp(vbt->signature, "$VBT", 4) == 0) { | ||
444 | DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n", | ||
445 | vbt->signature); | ||
446 | bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset); | ||
447 | } else | ||
448 | dev_priv->opregion.vbt = NULL; | ||
449 | } | ||
264 | 450 | ||
265 | /* Scour memory looking for the VBT signature */ | 451 | if (bdb == NULL) { |
266 | for (i = 0; i + 4 < size; i++) { | 452 | bios = pci_map_rom(pdev, &size); |
267 | if (!memcmp(bios + i, "$VBT", 4)) { | 453 | if (!bios) |
268 | vbt = (struct vbt_header *)(bios + i); | 454 | return -1; |
269 | break; | 455 | |
456 | /* Scour memory looking for the VBT signature */ | ||
457 | for (i = 0; i + 4 < size; i++) { | ||
458 | if (!memcmp(bios + i, "$VBT", 4)) { | ||
459 | vbt = (struct vbt_header *)(bios + i); | ||
460 | break; | ||
461 | } | ||
270 | } | 462 | } |
271 | } | ||
272 | 463 | ||
273 | if (!vbt) { | 464 | if (!vbt) { |
274 | dev_err(dev->dev, "VBT signature missing\n"); | 465 | dev_err(dev->dev, "VBT signature missing\n"); |
275 | pci_unmap_rom(pdev, bios); | 466 | pci_unmap_rom(pdev, bios); |
276 | return -1; | 467 | return -1; |
468 | } | ||
469 | bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); | ||
277 | } | 470 | } |
278 | 471 | ||
279 | bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); | 472 | /* Grab useful general dxefinitions */ |
280 | |||
281 | /* Grab useful general definitions */ | ||
282 | parse_general_features(dev_priv, bdb); | 473 | parse_general_features(dev_priv, bdb); |
283 | parse_driver_features(dev_priv, bdb); | 474 | parse_driver_features(dev_priv, bdb); |
284 | parse_lfp_panel_data(dev_priv, bdb); | 475 | parse_lfp_panel_data(dev_priv, bdb); |
285 | parse_sdvo_panel_data(dev_priv, bdb); | 476 | parse_sdvo_panel_data(dev_priv, bdb); |
477 | parse_sdvo_device_mapping(dev_priv, bdb); | ||
478 | parse_device_mapping(dev_priv, bdb); | ||
286 | parse_backlight_data(dev_priv, bdb); | 479 | parse_backlight_data(dev_priv, bdb); |
287 | 480 | ||
288 | pci_unmap_rom(pdev, bios); | 481 | if (bios) |
482 | pci_unmap_rom(pdev, bios); | ||
289 | 483 | ||
290 | return 0; | 484 | return 0; |
291 | } | 485 | } |
diff --git a/drivers/gpu/drm/gma500/intel_bios.h b/drivers/gpu/drm/gma500/intel_bios.h index c67979ef6f0a..0a738663eb5a 100644 --- a/drivers/gpu/drm/gma500/intel_bios.h +++ b/drivers/gpu/drm/gma500/intel_bios.h | |||
@@ -127,9 +127,93 @@ struct bdb_general_features { | |||
127 | /* bits 5 */ | 127 | /* bits 5 */ |
128 | u8 int_crt_support:1; | 128 | u8 int_crt_support:1; |
129 | u8 int_tv_support:1; | 129 | u8 int_tv_support:1; |
130 | u8 rsvd11:6; /* finish byte */ | 130 | u8 int_efp_support:1; |
131 | u8 dp_ssc_enb:1; /* PCH attached eDP supports SSC */ | ||
132 | u8 dp_ssc_freq:1; /* SSC freq for PCH attached eDP */ | ||
133 | u8 rsvd11:3; /* finish byte */ | ||
131 | } __attribute__((packed)); | 134 | } __attribute__((packed)); |
132 | 135 | ||
136 | /* pre-915 */ | ||
137 | #define GPIO_PIN_DVI_LVDS 0x03 /* "DVI/LVDS DDC GPIO pins" */ | ||
138 | #define GPIO_PIN_ADD_I2C 0x05 /* "ADDCARD I2C GPIO pins" */ | ||
139 | #define GPIO_PIN_ADD_DDC 0x04 /* "ADDCARD DDC GPIO pins" */ | ||
140 | #define GPIO_PIN_ADD_DDC_I2C 0x06 /* "ADDCARD DDC/I2C GPIO pins" */ | ||
141 | |||
142 | /* Pre 915 */ | ||
143 | #define DEVICE_TYPE_NONE 0x00 | ||
144 | #define DEVICE_TYPE_CRT 0x01 | ||
145 | #define DEVICE_TYPE_TV 0x09 | ||
146 | #define DEVICE_TYPE_EFP 0x12 | ||
147 | #define DEVICE_TYPE_LFP 0x22 | ||
148 | /* On 915+ */ | ||
149 | #define DEVICE_TYPE_CRT_DPMS 0x6001 | ||
150 | #define DEVICE_TYPE_CRT_DPMS_HOTPLUG 0x4001 | ||
151 | #define DEVICE_TYPE_TV_COMPOSITE 0x0209 | ||
152 | #define DEVICE_TYPE_TV_MACROVISION 0x0289 | ||
153 | #define DEVICE_TYPE_TV_RF_COMPOSITE 0x020c | ||
154 | #define DEVICE_TYPE_TV_SVIDEO_COMPOSITE 0x0609 | ||
155 | #define DEVICE_TYPE_TV_SCART 0x0209 | ||
156 | #define DEVICE_TYPE_TV_CODEC_HOTPLUG_PWR 0x6009 | ||
157 | #define DEVICE_TYPE_EFP_HOTPLUG_PWR 0x6012 | ||
158 | #define DEVICE_TYPE_EFP_DVI_HOTPLUG_PWR 0x6052 | ||
159 | #define DEVICE_TYPE_EFP_DVI_I 0x6053 | ||
160 | #define DEVICE_TYPE_EFP_DVI_D_DUAL 0x6152 | ||
161 | #define DEVICE_TYPE_EFP_DVI_D_HDCP 0x60d2 | ||
162 | #define DEVICE_TYPE_OPENLDI_HOTPLUG_PWR 0x6062 | ||
163 | #define DEVICE_TYPE_OPENLDI_DUALPIX 0x6162 | ||
164 | #define DEVICE_TYPE_LFP_PANELLINK 0x5012 | ||
165 | #define DEVICE_TYPE_LFP_CMOS_PWR 0x5042 | ||
166 | #define DEVICE_TYPE_LFP_LVDS_PWR 0x5062 | ||
167 | #define DEVICE_TYPE_LFP_LVDS_DUAL 0x5162 | ||
168 | #define DEVICE_TYPE_LFP_LVDS_DUAL_HDCP 0x51e2 | ||
169 | |||
170 | #define DEVICE_CFG_NONE 0x00 | ||
171 | #define DEVICE_CFG_12BIT_DVOB 0x01 | ||
172 | #define DEVICE_CFG_12BIT_DVOC 0x02 | ||
173 | #define DEVICE_CFG_24BIT_DVOBC 0x09 | ||
174 | #define DEVICE_CFG_24BIT_DVOCB 0x0a | ||
175 | #define DEVICE_CFG_DUAL_DVOB 0x11 | ||
176 | #define DEVICE_CFG_DUAL_DVOC 0x12 | ||
177 | #define DEVICE_CFG_DUAL_DVOBC 0x13 | ||
178 | #define DEVICE_CFG_DUAL_LINK_DVOBC 0x19 | ||
179 | #define DEVICE_CFG_DUAL_LINK_DVOCB 0x1a | ||
180 | |||
181 | #define DEVICE_WIRE_NONE 0x00 | ||
182 | #define DEVICE_WIRE_DVOB 0x01 | ||
183 | #define DEVICE_WIRE_DVOC 0x02 | ||
184 | #define DEVICE_WIRE_DVOBC 0x03 | ||
185 | #define DEVICE_WIRE_DVOBB 0x05 | ||
186 | #define DEVICE_WIRE_DVOCC 0x06 | ||
187 | #define DEVICE_WIRE_DVOB_MASTER 0x0d | ||
188 | #define DEVICE_WIRE_DVOC_MASTER 0x0e | ||
189 | |||
190 | #define DEVICE_PORT_DVOA 0x00 /* none on 845+ */ | ||
191 | #define DEVICE_PORT_DVOB 0x01 | ||
192 | #define DEVICE_PORT_DVOC 0x02 | ||
193 | |||
194 | struct child_device_config { | ||
195 | u16 handle; | ||
196 | u16 device_type; | ||
197 | u8 device_id[10]; /* ascii string */ | ||
198 | u16 addin_offset; | ||
199 | u8 dvo_port; /* See Device_PORT_* above */ | ||
200 | u8 i2c_pin; | ||
201 | u8 slave_addr; | ||
202 | u8 ddc_pin; | ||
203 | u16 edid_ptr; | ||
204 | u8 dvo_cfg; /* See DEVICE_CFG_* above */ | ||
205 | u8 dvo2_port; | ||
206 | u8 i2c2_pin; | ||
207 | u8 slave2_addr; | ||
208 | u8 ddc2_pin; | ||
209 | u8 capabilities; | ||
210 | u8 dvo_wiring;/* See DEVICE_WIRE_* above */ | ||
211 | u8 dvo2_wiring; | ||
212 | u16 extended_type; | ||
213 | u8 dvo_function; | ||
214 | } __attribute__((packed)); | ||
215 | |||
216 | |||
133 | struct bdb_general_definitions { | 217 | struct bdb_general_definitions { |
134 | /* DDC GPIO */ | 218 | /* DDC GPIO */ |
135 | u8 crt_ddc_gmbus_pin; | 219 | u8 crt_ddc_gmbus_pin; |
@@ -144,13 +228,18 @@ struct bdb_general_definitions { | |||
144 | u8 boot_display[2]; | 228 | u8 boot_display[2]; |
145 | u8 child_dev_size; | 229 | u8 child_dev_size; |
146 | 230 | ||
147 | /* device info */ | 231 | /* |
148 | u8 tv_or_lvds_info[33]; | 232 | * Device info: |
149 | u8 dev1[33]; | 233 | * If TV is present, it'll be at devices[0]. |
150 | u8 dev2[33]; | 234 | * LVDS will be next, either devices[0] or [1], if present. |
151 | u8 dev3[33]; | 235 | * On some platforms the number of device is 6. But could be as few as |
152 | u8 dev4[33]; | 236 | * 4 if both TV and LVDS are missing. |
153 | /* may be another device block here on some platforms */ | 237 | * And the device num is related with the size of general definition |
238 | * block. It is obtained by using the following formula: | ||
239 | * number = (block_size - sizeof(bdb_general_definitions))/ | ||
240 | * sizeof(child_device_config); | ||
241 | */ | ||
242 | struct child_device_config devices[0]; | ||
154 | }; | 243 | }; |
155 | 244 | ||
156 | struct bdb_lvds_options { | 245 | struct bdb_lvds_options { |
@@ -466,4 +555,21 @@ extern void psb_intel_destroy_bios(struct drm_device *dev); | |||
466 | #define SWF14_APM_STANDBY 0x1 | 555 | #define SWF14_APM_STANDBY 0x1 |
467 | #define SWF14_APM_RESTORE 0x0 | 556 | #define SWF14_APM_RESTORE 0x0 |
468 | 557 | ||
558 | /* Add the device class for LFP, TV, HDMI */ | ||
559 | #define DEVICE_TYPE_INT_LFP 0x1022 | ||
560 | #define DEVICE_TYPE_INT_TV 0x1009 | ||
561 | #define DEVICE_TYPE_HDMI 0x60D2 | ||
562 | #define DEVICE_TYPE_DP 0x68C6 | ||
563 | #define DEVICE_TYPE_eDP 0x78C6 | ||
564 | |||
565 | /* define the DVO port for HDMI output type */ | ||
566 | #define DVO_B 1 | ||
567 | #define DVO_C 2 | ||
568 | #define DVO_D 3 | ||
569 | |||
570 | /* define the PORT for DP output type */ | ||
571 | #define PORT_IDPB 7 | ||
572 | #define PORT_IDPC 8 | ||
573 | #define PORT_IDPD 9 | ||
574 | |||
469 | #endif /* _I830_BIOS_H_ */ | 575 | #endif /* _I830_BIOS_H_ */ |
diff --git a/drivers/gpu/drm/gma500/intel_opregion.c b/drivers/gpu/drm/gma500/intel_opregion.c index d946bc1b17bf..7041f40affff 100644 --- a/drivers/gpu/drm/gma500/intel_opregion.c +++ b/drivers/gpu/drm/gma500/intel_opregion.c | |||
@@ -25,6 +25,22 @@ | |||
25 | 25 | ||
26 | #include "psb_drv.h" | 26 | #include "psb_drv.h" |
27 | 27 | ||
28 | #define PCI_ASLE 0xe4 | ||
29 | #define PCI_ASLS 0xfc | ||
30 | |||
31 | #define OPREGION_HEADER_OFFSET 0 | ||
32 | #define OPREGION_ACPI_OFFSET 0x100 | ||
33 | #define ACPI_CLID 0x01ac /* current lid state indicator */ | ||
34 | #define ACPI_CDCK 0x01b0 /* current docking state indicator */ | ||
35 | #define OPREGION_SWSCI_OFFSET 0x200 | ||
36 | #define OPREGION_ASLE_OFFSET 0x300 | ||
37 | #define OPREGION_VBT_OFFSET 0x400 | ||
38 | |||
39 | #define OPREGION_SIGNATURE "IntelGraphicsMem" | ||
40 | #define MBOX_ACPI (1<<0) | ||
41 | #define MBOX_SWSCI (1<<1) | ||
42 | #define MBOX_ASLE (1<<2) | ||
43 | |||
28 | struct opregion_header { | 44 | struct opregion_header { |
29 | u8 signature[16]; | 45 | u8 signature[16]; |
30 | u32 size; | 46 | u32 size; |
@@ -36,21 +52,94 @@ struct opregion_header { | |||
36 | u8 reserved[164]; | 52 | u8 reserved[164]; |
37 | } __packed; | 53 | } __packed; |
38 | 54 | ||
39 | struct opregion_apci { | 55 | /* OpRegion mailbox #1: public ACPI methods */ |
40 | /*FIXME: add it later*/ | 56 | struct opregion_acpi { |
41 | } __packed; | 57 | u32 drdy; /* driver readiness */ |
58 | u32 csts; /* notification status */ | ||
59 | u32 cevt; /* current event */ | ||
60 | u8 rsvd1[20]; | ||
61 | u32 didl[8]; /* supported display devices ID list */ | ||
62 | u32 cpdl[8]; /* currently presented display list */ | ||
63 | u32 cadl[8]; /* currently active display list */ | ||
64 | u32 nadl[8]; /* next active devices list */ | ||
65 | u32 aslp; /* ASL sleep time-out */ | ||
66 | u32 tidx; /* toggle table index */ | ||
67 | u32 chpd; /* current hotplug enable indicator */ | ||
68 | u32 clid; /* current lid state*/ | ||
69 | u32 cdck; /* current docking state */ | ||
70 | u32 sxsw; /* Sx state resume */ | ||
71 | u32 evts; /* ASL supported events */ | ||
72 | u32 cnot; /* current OS notification */ | ||
73 | u32 nrdy; /* driver status */ | ||
74 | u8 rsvd2[60]; | ||
75 | } __attribute__((packed)); | ||
42 | 76 | ||
77 | /* OpRegion mailbox #2: SWSCI */ | ||
43 | struct opregion_swsci { | 78 | struct opregion_swsci { |
44 | /*FIXME: add it later*/ | 79 | u32 scic; /* SWSCI command|status|data */ |
45 | } __packed; | 80 | u32 parm; /* command parameters */ |
81 | u32 dslp; /* driver sleep time-out */ | ||
82 | u8 rsvd[244]; | ||
83 | } __attribute__((packed)); | ||
46 | 84 | ||
47 | struct opregion_acpi { | 85 | /* OpRegion mailbox #3: ASLE */ |
48 | /*FIXME: add it later*/ | 86 | struct opregion_asle { |
49 | } __packed; | 87 | u32 ardy; /* driver readiness */ |
88 | u32 aslc; /* ASLE interrupt command */ | ||
89 | u32 tche; /* technology enabled indicator */ | ||
90 | u32 alsi; /* current ALS illuminance reading */ | ||
91 | u32 bclp; /* backlight brightness to set */ | ||
92 | u32 pfit; /* panel fitting state */ | ||
93 | u32 cblv; /* current brightness level */ | ||
94 | u16 bclm[20]; /* backlight level duty cycle mapping table */ | ||
95 | u32 cpfm; /* current panel fitting mode */ | ||
96 | u32 epfm; /* enabled panel fitting modes */ | ||
97 | u8 plut[74]; /* panel LUT and identifier */ | ||
98 | u32 pfmb; /* PWM freq and min brightness */ | ||
99 | u8 rsvd[102]; | ||
100 | } __attribute__((packed)); | ||
101 | |||
102 | /* ASLE irq request bits */ | ||
103 | #define ASLE_SET_ALS_ILLUM (1 << 0) | ||
104 | #define ASLE_SET_BACKLIGHT (1 << 1) | ||
105 | #define ASLE_SET_PFIT (1 << 2) | ||
106 | #define ASLE_SET_PWM_FREQ (1 << 3) | ||
107 | #define ASLE_REQ_MSK 0xf | ||
108 | |||
109 | /* response bits of ASLE irq request */ | ||
110 | #define ASLE_ALS_ILLUM_FAILED (1<<10) | ||
111 | #define ASLE_BACKLIGHT_FAILED (1<<12) | ||
112 | #define ASLE_PFIT_FAILED (1<<14) | ||
113 | #define ASLE_PWM_FREQ_FAILED (1<<16) | ||
114 | |||
115 | /* ASLE backlight brightness to set */ | ||
116 | #define ASLE_BCLP_VALID (1<<31) | ||
117 | #define ASLE_BCLP_MSK (~(1<<31)) | ||
118 | |||
119 | /* ASLE panel fitting request */ | ||
120 | #define ASLE_PFIT_VALID (1<<31) | ||
121 | #define ASLE_PFIT_CENTER (1<<0) | ||
122 | #define ASLE_PFIT_STRETCH_TEXT (1<<1) | ||
123 | #define ASLE_PFIT_STRETCH_GFX (1<<2) | ||
124 | |||
125 | /* PWM frequency and minimum brightness */ | ||
126 | #define ASLE_PFMB_BRIGHTNESS_MASK (0xff) | ||
127 | #define ASLE_PFMB_BRIGHTNESS_VALID (1<<8) | ||
128 | #define ASLE_PFMB_PWM_MASK (0x7ffffe00) | ||
129 | #define ASLE_PFMB_PWM_VALID (1<<31) | ||
130 | |||
131 | #define ASLE_CBLV_VALID (1<<31) | ||
132 | |||
133 | #define ACPI_OTHER_OUTPUT (0<<8) | ||
134 | #define ACPI_VGA_OUTPUT (1<<8) | ||
135 | #define ACPI_TV_OUTPUT (2<<8) | ||
136 | #define ACPI_DIGITAL_OUTPUT (3<<8) | ||
137 | #define ACPI_LVDS_OUTPUT (4<<8) | ||
50 | 138 | ||
51 | int gma_intel_opregion_init(struct drm_device *dev) | 139 | int gma_intel_opregion_init(struct drm_device *dev) |
52 | { | 140 | { |
53 | struct drm_psb_private *dev_priv = dev->dev_private; | 141 | struct drm_psb_private *dev_priv = dev->dev_private; |
142 | struct psb_intel_opregion *opregion = &dev_priv->opregion; | ||
54 | u32 opregion_phy; | 143 | u32 opregion_phy; |
55 | void *base; | 144 | void *base; |
56 | u32 *lid_state; | 145 | u32 *lid_state; |
@@ -64,18 +153,26 @@ int gma_intel_opregion_init(struct drm_device *dev) | |||
64 | base = ioremap(opregion_phy, 8*1024); | 153 | base = ioremap(opregion_phy, 8*1024); |
65 | if (!base) | 154 | if (!base) |
66 | return -ENOMEM; | 155 | return -ENOMEM; |
156 | /* FIXME: should use _io ops - ditto on i915 */ | ||
157 | if (memcmp(base, OPREGION_SIGNATURE, 16)) { | ||
158 | DRM_ERROR("opregion signature mismatch\n"); | ||
159 | iounmap(base); | ||
160 | return -EINVAL; | ||
161 | } | ||
67 | 162 | ||
68 | lid_state = base + 0x01ac; | 163 | lid_state = base + 0x01ac; |
69 | 164 | ||
70 | dev_priv->lid_state = lid_state; | 165 | dev_priv->lid_state = lid_state; |
71 | dev_priv->lid_last_state = readl(lid_state); | 166 | dev_priv->lid_last_state = readl(lid_state); |
167 | opregion->header = base; | ||
168 | opregion->vbt = base + OPREGION_VBT_OFFSET; | ||
72 | return 0; | 169 | return 0; |
73 | } | 170 | } |
74 | 171 | ||
75 | int gma_intel_opregion_exit(struct drm_device *dev) | 172 | int gma_intel_opregion_exit(struct drm_device *dev) |
76 | { | 173 | { |
77 | struct drm_psb_private *dev_priv = dev->dev_private; | 174 | struct drm_psb_private *dev_priv = dev->dev_private; |
78 | if (dev_priv->lid_state) | 175 | if (dev_priv->opregion.header) |
79 | iounmap(dev_priv->lid_state); | 176 | iounmap(dev_priv->opregion.header); |
80 | return 0; | 177 | return 0; |
81 | } | 178 | } |
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 4c50969fd193..64de248558b2 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h | |||
@@ -257,6 +257,7 @@ struct psb_intel_opregion { | |||
257 | struct opregion_acpi *acpi; | 257 | struct opregion_acpi *acpi; |
258 | struct opregion_swsci *swsci; | 258 | struct opregion_swsci *swsci; |
259 | struct opregion_asle *asle; | 259 | struct opregion_asle *asle; |
260 | void *vbt; | ||
260 | int enabled; | 261 | int enabled; |
261 | }; | 262 | }; |
262 | 263 | ||
@@ -494,6 +495,9 @@ struct psb_ops; | |||
494 | struct drm_psb_private { | 495 | struct drm_psb_private { |
495 | struct drm_device *dev; | 496 | struct drm_device *dev; |
496 | const struct psb_ops *ops; | 497 | const struct psb_ops *ops; |
498 | |||
499 | struct child_device_config *child_dev; | ||
500 | int child_dev_num; | ||
497 | 501 | ||
498 | struct psb_gtt gtt; | 502 | struct psb_gtt gtt; |
499 | 503 | ||