aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/gma500/intel_bios.c232
-rw-r--r--drivers/gpu/drm/gma500/intel_bios.h122
-rw-r--r--drivers/gpu/drm/gma500/intel_opregion.c117
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h4
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
30static void *find_section(struct bdb_header *bdb, int section_id) 32static 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
57static u16
58get_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
55static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, 67static 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
220static void 242static void
243parse_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
333static void
221parse_driver_features(struct drm_psb_private *dev_priv, 334parse_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
350static void
351parse_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
194struct 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
133struct bdb_general_definitions { 217struct 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
156struct bdb_lvds_options { 245struct 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
28struct opregion_header { 44struct 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
39struct opregion_apci { 55/* OpRegion mailbox #1: public ACPI methods */
40 /*FIXME: add it later*/ 56struct 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 */
43struct opregion_swsci { 78struct 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
47struct opregion_acpi { 85/* OpRegion mailbox #3: ASLE */
48 /*FIXME: add it later*/ 86struct 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
51int gma_intel_opregion_init(struct drm_device *dev) 139int 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
75int gma_intel_opregion_exit(struct drm_device *dev) 172int 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;
494struct drm_psb_private { 495struct 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