aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/gma500
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/gma500')
-rw-r--r--drivers/gpu/drm/gma500/Makefile4
-rw-r--r--drivers/gpu/drm/gma500/cdv_device.c117
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_lvds.c2
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c7
-rw-r--r--drivers/gpu/drm/gma500/gtt.c14
-rw-r--r--drivers/gpu/drm/gma500/intel_opregion.c178
-rw-r--r--drivers/gpu/drm/gma500/mdfld_device.c4
-rw-r--r--drivers/gpu/drm/gma500/mdfld_dsi_dpi.c1
-rw-r--r--drivers/gpu/drm/gma500/mdfld_dsi_output.h1
-rw-r--r--drivers/gpu/drm/gma500/mid_bios.c295
-rw-r--r--drivers/gpu/drm/gma500/oaktrail.h25
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_device.c11
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c2
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_lvds.c4
-rw-r--r--drivers/gpu/drm/gma500/opregion.c350
-rw-r--r--drivers/gpu/drm/gma500/opregion.h29
-rw-r--r--drivers/gpu/drm/gma500/psb_device.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c8
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h15
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_reg.h1
-rw-r--r--drivers/gpu/drm/gma500/psb_irq.c6
-rw-r--r--drivers/gpu/drm/gma500/psb_lid.c2
22 files changed, 674 insertions, 404 deletions
diff --git a/drivers/gpu/drm/gma500/Makefile b/drivers/gpu/drm/gma500/Makefile
index 1583982917ce..dd7d6b57996f 100644
--- a/drivers/gpu/drm/gma500/Makefile
+++ b/drivers/gpu/drm/gma500/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# KMS driver for the GMA500 2# KMS driver for the GMA500
3# 3#
4ccflags-y += -Iinclude/drm 4ccflags-y += -I$(srctree)/include/drm
5 5
6gma500_gfx-y += gem_glue.o \ 6gma500_gfx-y += gem_glue.o \
7 accel_2d.o \ 7 accel_2d.o \
@@ -12,8 +12,8 @@ gma500_gfx-y += gem_glue.o \
12 intel_bios.o \ 12 intel_bios.o \
13 intel_i2c.o \ 13 intel_i2c.o \
14 intel_gmbus.o \ 14 intel_gmbus.o \
15 intel_opregion.o \
16 mmu.o \ 15 mmu.o \
16 opregion.o \
17 power.o \ 17 power.o \
18 psb_drv.o \ 18 psb_drv.o \
19 psb_intel_display.o \ 19 psb_intel_display.o \
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c
index 62f9b735459b..c10f02068d11 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -57,8 +57,7 @@ static int cdv_output_init(struct drm_device *dev)
57 cdv_intel_crt_init(dev, &dev_priv->mode_dev); 57 cdv_intel_crt_init(dev, &dev_priv->mode_dev);
58 cdv_intel_lvds_init(dev, &dev_priv->mode_dev); 58 cdv_intel_lvds_init(dev, &dev_priv->mode_dev);
59 59
60 /* These bits indicate HDMI not SDVO on CDV, but we don't yet support 60 /* These bits indicate HDMI not SDVO on CDV */
61 the HDMI interface */
62 if (REG_READ(SDVOB) & SDVO_DETECTED) 61 if (REG_READ(SDVOB) & SDVO_DETECTED)
63 cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB); 62 cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB);
64 if (REG_READ(SDVOC) & SDVO_DETECTED) 63 if (REG_READ(SDVOC) & SDVO_DETECTED)
@@ -69,76 +68,71 @@ static int cdv_output_init(struct drm_device *dev)
69#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 68#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
70 69
71/* 70/*
72 * Poulsbo Backlight Interfaces 71 * Cedartrail Backlght Interfaces
73 */ 72 */
74 73
75#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */
76#define BLC_PWM_FREQ_CALC_CONSTANT 32
77#define MHz 1000000
78
79#define PSB_BLC_PWM_PRECISION_FACTOR 10
80#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE
81#define PSB_BLC_MIN_PWM_REG_FREQ 0x2
82
83#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
84#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16)
85
86static int cdv_brightness;
87static struct backlight_device *cdv_backlight_device; 74static struct backlight_device *cdv_backlight_device;
88 75
89static int cdv_get_brightness(struct backlight_device *bd) 76static int cdv_backlight_combination_mode(struct drm_device *dev)
90{ 77{
91 /* return locally cached var instead of HW read (due to DPST etc.) */ 78 return REG_READ(BLC_PWM_CTL2) & PWM_LEGACY_MODE;
92 /* FIXME: ideally return actual value in case firmware fiddled with
93 it */
94 return cdv_brightness;
95} 79}
96 80
97 81static int cdv_get_brightness(struct backlight_device *bd)
98static int cdv_backlight_setup(struct drm_device *dev)
99{ 82{
100 struct drm_psb_private *dev_priv = dev->dev_private; 83 struct drm_device *dev = bl_get_data(bd);
101 unsigned long core_clock; 84 u32 val = REG_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
102 /* u32 bl_max_freq; */
103 /* unsigned long value; */
104 u16 bl_max_freq;
105 uint32_t value;
106 uint32_t blc_pwm_precision_factor;
107
108 /* get bl_max_freq and pol from dev_priv*/
109 if (!dev_priv->lvds_bl) {
110 dev_err(dev->dev, "Has no valid LVDS backlight info\n");
111 return -ENOENT;
112 }
113 bl_max_freq = dev_priv->lvds_bl->freq;
114 blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
115 85
116 core_clock = dev_priv->core_freq; 86 if (cdv_backlight_combination_mode(dev)) {
87 u8 lbpc;
117 88
118 value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; 89 val &= ~1;
119 value *= blc_pwm_precision_factor; 90 pci_read_config_byte(dev->pdev, 0xF4, &lbpc);
120 value /= bl_max_freq; 91 val *= lbpc;
121 value /= blc_pwm_precision_factor; 92 }
93 return val;
94}
122 95
123 if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ || 96static u32 cdv_get_max_backlight(struct drm_device *dev)
124 value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ) 97{
125 return -ERANGE; 98 u32 max = REG_READ(BLC_PWM_CTL);
126 else { 99
127 /* FIXME */ 100 if (max == 0) {
101 DRM_DEBUG_KMS("LVDS Panel PWM value is 0!\n");
102 /* i915 does this, I believe which means that we should not
103 * smash PWM control as firmware will take control of it. */
104 return 1;
128 } 105 }
129 return 0; 106
107 max >>= 16;
108 if (cdv_backlight_combination_mode(dev))
109 max *= 0xff;
110 return max;
130} 111}
131 112
132static int cdv_set_brightness(struct backlight_device *bd) 113static int cdv_set_brightness(struct backlight_device *bd)
133{ 114{
115 struct drm_device *dev = bl_get_data(bd);
134 int level = bd->props.brightness; 116 int level = bd->props.brightness;
117 u32 blc_pwm_ctl;
135 118
136 /* Percentage 1-100% being valid */ 119 /* Percentage 1-100% being valid */
137 if (level < 1) 120 if (level < 1)
138 level = 1; 121 level = 1;
139 122
140 /*cdv_intel_lvds_set_brightness(dev, level); FIXME */ 123 if (cdv_backlight_combination_mode(dev)) {
141 cdv_brightness = level; 124 u32 max = cdv_get_max_backlight(dev);
125 u8 lbpc;
126
127 lbpc = level * 0xfe / max + 1;
128 level /= lbpc;
129
130 pci_write_config_byte(dev->pdev, 0xF4, lbpc);
131 }
132
133 blc_pwm_ctl = REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
134 REG_WRITE(BLC_PWM_CTL, (blc_pwm_ctl |
135 (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
142 return 0; 136 return 0;
143} 137}
144 138
@@ -150,7 +144,6 @@ static const struct backlight_ops cdv_ops = {
150static int cdv_backlight_init(struct drm_device *dev) 144static int cdv_backlight_init(struct drm_device *dev)
151{ 145{
152 struct drm_psb_private *dev_priv = dev->dev_private; 146 struct drm_psb_private *dev_priv = dev->dev_private;
153 int ret;
154 struct backlight_properties props; 147 struct backlight_properties props;
155 148
156 memset(&props, 0, sizeof(struct backlight_properties)); 149 memset(&props, 0, sizeof(struct backlight_properties));
@@ -162,14 +155,9 @@ static int cdv_backlight_init(struct drm_device *dev)
162 if (IS_ERR(cdv_backlight_device)) 155 if (IS_ERR(cdv_backlight_device))
163 return PTR_ERR(cdv_backlight_device); 156 return PTR_ERR(cdv_backlight_device);
164 157
165 ret = cdv_backlight_setup(dev); 158 cdv_backlight_device->props.brightness =
166 if (ret < 0) { 159 cdv_get_brightness(cdv_backlight_device);
167 backlight_device_unregister(cdv_backlight_device); 160 cdv_backlight_device->props.max_brightness = cdv_get_max_backlight(dev);
168 cdv_backlight_device = NULL;
169 return ret;
170 }
171 cdv_backlight_device->props.brightness = 100;
172 cdv_backlight_device->props.max_brightness = 100;
173 backlight_update_status(cdv_backlight_device); 161 backlight_update_status(cdv_backlight_device);
174 dev_priv->backlight_device = cdv_backlight_device; 162 dev_priv->backlight_device = cdv_backlight_device;
175 return 0; 163 return 0;
@@ -244,11 +232,12 @@ static void cdv_init_pm(struct drm_device *dev)
244static void cdv_errata(struct drm_device *dev) 232static void cdv_errata(struct drm_device *dev)
245{ 233{
246 /* Disable bonus launch. 234 /* Disable bonus launch.
247 * CPU and GPU competes for memory and display misses updates and flickers. 235 * CPU and GPU competes for memory and display misses updates and
248 * Worst with dual core, dual displays. 236 * flickers. Worst with dual core, dual displays.
249 * 237 *
250 * Fixes were done to Win 7 gfx driver to disable a feature called Bonus 238 * Fixes were done to Win 7 gfx driver to disable a feature called
251 * Launch to work around the issue, by degrading performance. 239 * Bonus Launch to work around the issue, by degrading
240 * performance.
252 */ 241 */
253 CDV_MSG_WRITE32(3, 0x30, 0x08027108); 242 CDV_MSG_WRITE32(3, 0x30, 0x08027108);
254} 243}
@@ -501,7 +490,7 @@ static int cdv_chip_setup(struct drm_device *dev)
501 struct drm_psb_private *dev_priv = dev->dev_private; 490 struct drm_psb_private *dev_priv = dev->dev_private;
502 INIT_WORK(&dev_priv->hotplug_work, cdv_hotplug_work_func); 491 INIT_WORK(&dev_priv->hotplug_work, cdv_hotplug_work_func);
503 cdv_get_core_freq(dev); 492 cdv_get_core_freq(dev);
504 gma_intel_opregion_init(dev); 493 psb_intel_opregion_init(dev);
505 psb_intel_init_bios(dev); 494 psb_intel_init_bios(dev);
506 cdv_hotplug_enable(dev, false); 495 cdv_hotplug_enable(dev, false);
507 return 0; 496 return 0;
diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
index 44a8353d92bf..ff5b58eb878c 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
@@ -556,7 +556,7 @@ static void cdv_intel_lvds_enc_destroy(struct drm_encoder *encoder)
556 drm_encoder_cleanup(encoder); 556 drm_encoder_cleanup(encoder);
557} 557}
558 558
559const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = { 559static const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = {
560 .destroy = cdv_intel_lvds_enc_destroy, 560 .destroy = cdv_intel_lvds_enc_destroy,
561}; 561};
562 562
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index c9fe4bdeb681..f47f883ff9ef 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -408,6 +408,8 @@ static int psbfb_create(struct psb_fbdev *fbdev,
408 return -ENOMEM; 408 return -ENOMEM;
409 } 409 }
410 410
411 memset(dev_priv->vram_addr + backing->offset, 0, size);
412
411 mutex_lock(&dev->struct_mutex); 413 mutex_lock(&dev->struct_mutex);
412 414
413 info = framebuffer_alloc(0, device); 415 info = framebuffer_alloc(0, device);
@@ -453,8 +455,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,
453 info->fix.ypanstep = 0; 455 info->fix.ypanstep = 0;
454 456
455 /* Accessed stolen memory directly */ 457 /* Accessed stolen memory directly */
456 info->screen_base = (char *)dev_priv->vram_addr + 458 info->screen_base = dev_priv->vram_addr + backing->offset;
457 backing->offset;
458 info->screen_size = size; 459 info->screen_size = size;
459 460
460 if (dev_priv->gtt.stolen_size) { 461 if (dev_priv->gtt.stolen_size) {
@@ -571,7 +572,7 @@ static int psbfb_probe(struct drm_fb_helper *helper,
571 return new_fb; 572 return new_fb;
572} 573}
573 574
574struct drm_fb_helper_funcs psb_fb_helper_funcs = { 575static struct drm_fb_helper_funcs psb_fb_helper_funcs = {
575 .gamma_set = psbfb_gamma_set, 576 .gamma_set = psbfb_gamma_set,
576 .gamma_get = psbfb_gamma_get, 577 .gamma_get = psbfb_gamma_get,
577 .fb_probe = psbfb_probe, 578 .fb_probe = psbfb_probe,
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index 54e5c9e1e6fa..4cd33df5f93c 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -61,7 +61,7 @@ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
61 * Given a gtt_range object return the GTT offset of the page table 61 * Given a gtt_range object return the GTT offset of the page table
62 * entries for this gtt_range 62 * entries for this gtt_range
63 */ 63 */
64static u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) 64static u32 __iomem *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
65{ 65{
66 struct drm_psb_private *dev_priv = dev->dev_private; 66 struct drm_psb_private *dev_priv = dev->dev_private;
67 unsigned long offset; 67 unsigned long offset;
@@ -82,7 +82,8 @@ static u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
82 */ 82 */
83static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) 83static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
84{ 84{
85 u32 *gtt_slot, pte; 85 u32 __iomem *gtt_slot;
86 u32 pte;
86 struct page **pages; 87 struct page **pages;
87 int i; 88 int i;
88 89
@@ -126,7 +127,8 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
126static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) 127static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
127{ 128{
128 struct drm_psb_private *dev_priv = dev->dev_private; 129 struct drm_psb_private *dev_priv = dev->dev_private;
129 u32 *gtt_slot, pte; 130 u32 __iomem *gtt_slot;
131 u32 pte;
130 int i; 132 int i;
131 133
132 WARN_ON(r->stolen); 134 WARN_ON(r->stolen);
@@ -152,7 +154,8 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
152 */ 154 */
153void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll) 155void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll)
154{ 156{
155 u32 *gtt_slot, pte; 157 u32 __iomem *gtt_slot;
158 u32 pte;
156 int i; 159 int i;
157 160
158 if (roll >= r->npage) { 161 if (roll >= r->npage) {
@@ -413,7 +416,6 @@ int psb_gtt_init(struct drm_device *dev, int resume)
413 unsigned long stolen_size, vram_stolen_size; 416 unsigned long stolen_size, vram_stolen_size;
414 unsigned i, num_pages; 417 unsigned i, num_pages;
415 unsigned pfn_base; 418 unsigned pfn_base;
416 uint32_t vram_pages;
417 uint32_t dvmt_mode = 0; 419 uint32_t dvmt_mode = 0;
418 struct psb_gtt *pg; 420 struct psb_gtt *pg;
419 421
@@ -529,7 +531,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)
529 */ 531 */
530 532
531 pfn_base = dev_priv->stolen_base >> PAGE_SHIFT; 533 pfn_base = dev_priv->stolen_base >> PAGE_SHIFT;
532 vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT; 534 num_pages = vram_stolen_size >> PAGE_SHIFT;
533 printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n", 535 printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
534 num_pages, pfn_base << PAGE_SHIFT, 0); 536 num_pages, pfn_base << PAGE_SHIFT, 0);
535 for (i = 0; i < num_pages; ++i) { 537 for (i = 0; i < num_pages; ++i) {
diff --git a/drivers/gpu/drm/gma500/intel_opregion.c b/drivers/gpu/drm/gma500/intel_opregion.c
deleted file mode 100644
index 7041f40affff..000000000000
--- a/drivers/gpu/drm/gma500/intel_opregion.c
+++ /dev/null
@@ -1,178 +0,0 @@
1/*
2 * Copyright 2010 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * FIXME: resolve with the i915 version
24 */
25
26#include "psb_drv.h"
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
44struct opregion_header {
45 u8 signature[16];
46 u32 size;
47 u32 opregion_ver;
48 u8 bios_ver[32];
49 u8 vbios_ver[16];
50 u8 driver_ver[16];
51 u32 mboxes;
52 u8 reserved[164];
53} __packed;
54
55/* OpRegion mailbox #1: public ACPI methods */
56struct opregion_acpi {
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));
76
77/* OpRegion mailbox #2: SWSCI */
78struct opregion_swsci {
79 u32 scic; /* SWSCI command|status|data */
80 u32 parm; /* command parameters */
81 u32 dslp; /* driver sleep time-out */
82 u8 rsvd[244];
83} __attribute__((packed));
84
85/* OpRegion mailbox #3: ASLE */
86struct opregion_asle {
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)
138
139int gma_intel_opregion_init(struct drm_device *dev)
140{
141 struct drm_psb_private *dev_priv = dev->dev_private;
142 struct psb_intel_opregion *opregion = &dev_priv->opregion;
143 u32 opregion_phy;
144 void *base;
145 u32 *lid_state;
146
147 dev_priv->lid_state = NULL;
148
149 pci_read_config_dword(dev->pdev, 0xfc, &opregion_phy);
150 if (opregion_phy == 0)
151 return -ENOTSUPP;
152
153 base = ioremap(opregion_phy, 8*1024);
154 if (!base)
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 }
162
163 lid_state = base + 0x01ac;
164
165 dev_priv->lid_state = lid_state;
166 dev_priv->lid_last_state = readl(lid_state);
167 opregion->header = base;
168 opregion->vbt = base + OPREGION_VBT_OFFSET;
169 return 0;
170}
171
172int gma_intel_opregion_exit(struct drm_device *dev)
173{
174 struct drm_psb_private *dev_priv = dev->dev_private;
175 if (dev_priv->opregion.header)
176 iounmap(dev_priv->opregion.header);
177 return 0;
178}
diff --git a/drivers/gpu/drm/gma500/mdfld_device.c b/drivers/gpu/drm/gma500/mdfld_device.c
index a0bd48cd92f4..717f4db28c3c 100644
--- a/drivers/gpu/drm/gma500/mdfld_device.c
+++ b/drivers/gpu/drm/gma500/mdfld_device.c
@@ -672,8 +672,8 @@ const struct psb_ops mdfld_chip_ops = {
672 .accel_2d = 0, 672 .accel_2d = 0,
673 .pipes = 3, 673 .pipes = 3,
674 .crtcs = 3, 674 .crtcs = 3,
675 .lvds_mask = (1 << 1); 675 .lvds_mask = (1 << 1),
676 .hdmi_mask = (1 << 1); 676 .hdmi_mask = (1 << 1),
677 .sgx_offset = MRST_SGX_OFFSET, 677 .sgx_offset = MRST_SGX_OFFSET,
678 678
679 .chip_setup = mid_chip_setup, 679 .chip_setup = mid_chip_setup,
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c b/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c
index d52358b744a0..b34ff097b979 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c
@@ -869,7 +869,6 @@ void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
869 mdfld_set_pipe_timing(dsi_config, pipe); 869 mdfld_set_pipe_timing(dsi_config, pipe);
870 870
871 REG_WRITE(DSPABASE, 0x00); 871 REG_WRITE(DSPABASE, 0x00);
872 REG_WRITE(DSPASTRIDE, (mode->hdisplay * 4));
873 REG_WRITE(DSPASIZE, 872 REG_WRITE(DSPASIZE,
874 ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); 873 ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
875 874
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.h b/drivers/gpu/drm/gma500/mdfld_dsi_output.h
index 21071cef92a4..36eb0744841c 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_output.h
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.h
@@ -29,7 +29,6 @@
29#define __MDFLD_DSI_OUTPUT_H__ 29#define __MDFLD_DSI_OUTPUT_H__
30 30
31#include <linux/backlight.h> 31#include <linux/backlight.h>
32#include <linux/version.h>
33#include <drm/drmP.h> 32#include <drm/drmP.h>
34#include <drm/drm.h> 33#include <drm/drm.h>
35#include <drm/drm_crtc.h> 34#include <drm/drm_crtc.h>
diff --git a/drivers/gpu/drm/gma500/mid_bios.c b/drivers/gpu/drm/gma500/mid_bios.c
index 5eee9ad80da4..b2a790bd9899 100644
--- a/drivers/gpu/drm/gma500/mid_bios.c
+++ b/drivers/gpu/drm/gma500/mid_bios.c
@@ -118,139 +118,214 @@ static void mid_get_pci_revID(struct drm_psb_private *dev_priv)
118 dev_priv->platform_rev_id); 118 dev_priv->platform_rev_id);
119} 119}
120 120
121struct vbt_header {
122 u32 signature;
123 u8 revision;
124} __packed;
125
126/* The same for r0 and r1 */
127struct vbt_r0 {
128 struct vbt_header vbt_header;
129 u8 size;
130 u8 checksum;
131} __packed;
132
133struct vbt_r10 {
134 struct vbt_header vbt_header;
135 u8 checksum;
136 u16 size;
137 u8 panel_count;
138 u8 primary_panel_idx;
139 u8 secondary_panel_idx;
140 u8 __reserved[5];
141} __packed;
142
143static int read_vbt_r0(u32 addr, struct vbt_r0 *vbt)
144{
145 void __iomem *vbt_virtual;
146
147 vbt_virtual = ioremap(addr, sizeof(*vbt));
148 if (vbt_virtual == NULL)
149 return -1;
150
151 memcpy_fromio(vbt, vbt_virtual, sizeof(*vbt));
152 iounmap(vbt_virtual);
153
154 return 0;
155}
156
157static int read_vbt_r10(u32 addr, struct vbt_r10 *vbt)
158{
159 void __iomem *vbt_virtual;
160
161 vbt_virtual = ioremap(addr, sizeof(*vbt));
162 if (!vbt_virtual)
163 return -1;
164
165 memcpy_fromio(vbt, vbt_virtual, sizeof(*vbt));
166 iounmap(vbt_virtual);
167
168 return 0;
169}
170
171static int mid_get_vbt_data_r0(struct drm_psb_private *dev_priv, u32 addr)
172{
173 struct vbt_r0 vbt;
174 void __iomem *gct_virtual;
175 struct gct_r0 gct;
176 u8 bpi;
177
178 if (read_vbt_r0(addr, &vbt))
179 return -1;
180
181 gct_virtual = ioremap(addr + sizeof(vbt), vbt.size - sizeof(vbt));
182 if (!gct_virtual)
183 return -1;
184 memcpy_fromio(&gct, gct_virtual, sizeof(gct));
185 iounmap(gct_virtual);
186
187 bpi = gct.PD.BootPanelIndex;
188 dev_priv->gct_data.bpi = bpi;
189 dev_priv->gct_data.pt = gct.PD.PanelType;
190 dev_priv->gct_data.DTD = gct.panel[bpi].DTD;
191 dev_priv->gct_data.Panel_Port_Control =
192 gct.panel[bpi].Panel_Port_Control;
193 dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
194 gct.panel[bpi].Panel_MIPI_Display_Descriptor;
195
196 return 0;
197}
198
199static int mid_get_vbt_data_r1(struct drm_psb_private *dev_priv, u32 addr)
200{
201 struct vbt_r0 vbt;
202 void __iomem *gct_virtual;
203 struct gct_r1 gct;
204 u8 bpi;
205
206 if (read_vbt_r0(addr, &vbt))
207 return -1;
208
209 gct_virtual = ioremap(addr + sizeof(vbt), vbt.size - sizeof(vbt));
210 if (!gct_virtual)
211 return -1;
212 memcpy_fromio(&gct, gct_virtual, sizeof(gct));
213 iounmap(gct_virtual);
214
215 bpi = gct.PD.BootPanelIndex;
216 dev_priv->gct_data.bpi = bpi;
217 dev_priv->gct_data.pt = gct.PD.PanelType;
218 dev_priv->gct_data.DTD = gct.panel[bpi].DTD;
219 dev_priv->gct_data.Panel_Port_Control =
220 gct.panel[bpi].Panel_Port_Control;
221 dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
222 gct.panel[bpi].Panel_MIPI_Display_Descriptor;
223
224 return 0;
225}
226
227static int mid_get_vbt_data_r10(struct drm_psb_private *dev_priv, u32 addr)
228{
229 struct vbt_r10 vbt;
230 void __iomem *gct_virtual;
231 struct gct_r10 *gct;
232 struct oaktrail_timing_info *dp_ti = &dev_priv->gct_data.DTD;
233 struct gct_r10_timing_info *ti;
234 int ret = -1;
235
236 if (read_vbt_r10(addr, &vbt))
237 return -1;
238
239 gct = kmalloc(sizeof(*gct) * vbt.panel_count, GFP_KERNEL);
240 if (!gct)
241 return -1;
242
243 gct_virtual = ioremap(addr + sizeof(vbt),
244 sizeof(*gct) * vbt.panel_count);
245 if (!gct_virtual)
246 goto out;
247 memcpy_fromio(gct, gct_virtual, sizeof(*gct));
248 iounmap(gct_virtual);
249
250 dev_priv->gct_data.bpi = vbt.primary_panel_idx;
251 dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
252 gct[vbt.primary_panel_idx].Panel_MIPI_Display_Descriptor;
253
254 ti = &gct[vbt.primary_panel_idx].DTD;
255 dp_ti->pixel_clock = ti->pixel_clock;
256 dp_ti->hactive_hi = ti->hactive_hi;
257 dp_ti->hactive_lo = ti->hactive_lo;
258 dp_ti->hblank_hi = ti->hblank_hi;
259 dp_ti->hblank_lo = ti->hblank_lo;
260 dp_ti->hsync_offset_hi = ti->hsync_offset_hi;
261 dp_ti->hsync_offset_lo = ti->hsync_offset_lo;
262 dp_ti->hsync_pulse_width_hi = ti->hsync_pulse_width_hi;
263 dp_ti->hsync_pulse_width_lo = ti->hsync_pulse_width_lo;
264 dp_ti->vactive_hi = ti->vactive_hi;
265 dp_ti->vactive_lo = ti->vactive_lo;
266 dp_ti->vblank_hi = ti->vblank_hi;
267 dp_ti->vblank_lo = ti->vblank_lo;
268 dp_ti->vsync_offset_hi = ti->vsync_offset_hi;
269 dp_ti->vsync_offset_lo = ti->vsync_offset_lo;
270 dp_ti->vsync_pulse_width_hi = ti->vsync_pulse_width_hi;
271 dp_ti->vsync_pulse_width_lo = ti->vsync_pulse_width_lo;
272
273 ret = 0;
274out:
275 kfree(gct);
276 return ret;
277}
278
121static void mid_get_vbt_data(struct drm_psb_private *dev_priv) 279static void mid_get_vbt_data(struct drm_psb_private *dev_priv)
122{ 280{
123 struct drm_device *dev = dev_priv->dev; 281 struct drm_device *dev = dev_priv->dev;
124 struct oaktrail_vbt *vbt = &dev_priv->vbt_data;
125 u32 addr; 282 u32 addr;
126 u16 new_size; 283 u8 __iomem *vbt_virtual;
127 u8 *vbt_virtual; 284 struct vbt_header vbt_header;
128 u8 bpi;
129 u8 number_desc = 0;
130 struct oaktrail_timing_info *dp_ti = &dev_priv->gct_data.DTD;
131 struct gct_r10_timing_info ti;
132 void *pGCT;
133 struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); 285 struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
286 int ret = -1;
134 287
135 /* Get the address of the platform config vbt, B0:D2:F0;0xFC */ 288 /* Get the address of the platform config vbt */
136 pci_read_config_dword(pci_gfx_root, 0xFC, &addr); 289 pci_read_config_dword(pci_gfx_root, 0xFC, &addr);
137 pci_dev_put(pci_gfx_root); 290 pci_dev_put(pci_gfx_root);
138 291
139 dev_dbg(dev->dev, "drm platform config address is %x\n", addr); 292 dev_dbg(dev->dev, "drm platform config address is %x\n", addr);
140 293
141 /* check for platform config address == 0. */ 294 if (!addr)
142 /* this means fw doesn't support vbt */ 295 goto out;
143
144 if (addr == 0) {
145 vbt->size = 0;
146 return;
147 }
148 296
149 /* get the virtual address of the vbt */ 297 /* get the virtual address of the vbt */
150 vbt_virtual = ioremap(addr, sizeof(*vbt)); 298 vbt_virtual = ioremap(addr, sizeof(vbt_header));
151 if (vbt_virtual == NULL) { 299 if (!vbt_virtual)
152 vbt->size = 0; 300 goto out;
153 return;
154 }
155 301
156 memcpy(vbt, vbt_virtual, sizeof(*vbt)); 302 memcpy_fromio(&vbt_header, vbt_virtual, sizeof(vbt_header));
157 iounmap(vbt_virtual); /* Free virtual address space */ 303 iounmap(vbt_virtual);
158 304
159 /* No matching signature don't process the data */ 305 if (memcmp(&vbt_header.signature, "$GCT", 4))
160 if (memcmp(vbt->signature, "$GCT", 4)) { 306 goto out;
161 vbt->size = 0; 307
162 return; 308 dev_dbg(dev->dev, "GCT revision is %02x\n", vbt_header.revision);
163 }
164 309
165 dev_dbg(dev->dev, "GCT revision is %x\n", vbt->revision); 310 switch (vbt_header.revision) {
166 311 case 0x00:
167 switch (vbt->revision) { 312 ret = mid_get_vbt_data_r0(dev_priv, addr);
168 case 0:
169 vbt->oaktrail_gct = ioremap(addr + sizeof(*vbt) - 4,
170 vbt->size - sizeof(*vbt) + 4);
171 pGCT = vbt->oaktrail_gct;
172 bpi = ((struct oaktrail_gct_v1 *)pGCT)->PD.BootPanelIndex;
173 dev_priv->gct_data.bpi = bpi;
174 dev_priv->gct_data.pt =
175 ((struct oaktrail_gct_v1 *)pGCT)->PD.PanelType;
176 memcpy(&dev_priv->gct_data.DTD,
177 &((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].DTD,
178 sizeof(struct oaktrail_timing_info));
179 dev_priv->gct_data.Panel_Port_Control =
180 ((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control;
181 dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
182 ((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
183 break; 313 break;
184 case 1: 314 case 0x01:
185 vbt->oaktrail_gct = ioremap(addr + sizeof(*vbt) - 4, 315 ret = mid_get_vbt_data_r1(dev_priv, addr);
186 vbt->size - sizeof(*vbt) + 4);
187 pGCT = vbt->oaktrail_gct;
188 bpi = ((struct oaktrail_gct_v2 *)pGCT)->PD.BootPanelIndex;
189 dev_priv->gct_data.bpi = bpi;
190 dev_priv->gct_data.pt =
191 ((struct oaktrail_gct_v2 *)pGCT)->PD.PanelType;
192 memcpy(&dev_priv->gct_data.DTD,
193 &((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].DTD,
194 sizeof(struct oaktrail_timing_info));
195 dev_priv->gct_data.Panel_Port_Control =
196 ((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control;
197 dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
198 ((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
199 break; 316 break;
200 case 0x10: 317 case 0x10:
201 /*header definition changed from rev 01 (v2) to rev 10h. */ 318 ret = mid_get_vbt_data_r10(dev_priv, addr);
202 /*so, some values have changed location*/
203 new_size = vbt->checksum; /*checksum contains lo size byte*/
204 /*LSB of oaktrail_gct contains hi size byte*/
205 new_size |= ((0xff & (unsigned int)(long)vbt->oaktrail_gct)) << 8;
206
207 vbt->checksum = vbt->size; /*size contains the checksum*/
208 if (new_size > 0xff)
209 vbt->size = 0xff; /*restrict size to 255*/
210 else
211 vbt->size = new_size;
212
213 /* number of descriptors defined in the GCT */
214 number_desc = ((0xff00 & (unsigned int)(long)vbt->oaktrail_gct)) >> 8;
215 bpi = ((0xff0000 & (unsigned int)(long)vbt->oaktrail_gct)) >> 16;
216 vbt->oaktrail_gct = ioremap(addr + GCT_R10_HEADER_SIZE,
217 GCT_R10_DISPLAY_DESC_SIZE * number_desc);
218 pGCT = vbt->oaktrail_gct;
219 pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE);
220 dev_priv->gct_data.bpi = bpi; /*save boot panel id*/
221
222 /*copy the GCT display timings into a temp structure*/
223 memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info));
224
225 /*now copy the temp struct into the dev_priv->gct_data*/
226 dp_ti->pixel_clock = ti.pixel_clock;
227 dp_ti->hactive_hi = ti.hactive_hi;
228 dp_ti->hactive_lo = ti.hactive_lo;
229 dp_ti->hblank_hi = ti.hblank_hi;
230 dp_ti->hblank_lo = ti.hblank_lo;
231 dp_ti->hsync_offset_hi = ti.hsync_offset_hi;
232 dp_ti->hsync_offset_lo = ti.hsync_offset_lo;
233 dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi;
234 dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo;
235 dp_ti->vactive_hi = ti.vactive_hi;
236 dp_ti->vactive_lo = ti.vactive_lo;
237 dp_ti->vblank_hi = ti.vblank_hi;
238 dp_ti->vblank_lo = ti.vblank_lo;
239 dp_ti->vsync_offset_hi = ti.vsync_offset_hi;
240 dp_ti->vsync_offset_lo = ti.vsync_offset_lo;
241 dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi;
242 dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo;
243
244 /* Move the MIPI_Display_Descriptor data from GCT to dev priv */
245 dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
246 *((u8 *)pGCT + 0x0d);
247 dev_priv->gct_data.Panel_MIPI_Display_Descriptor |=
248 (*((u8 *)pGCT + 0x0e)) << 8;
249 break; 319 break;
250 default: 320 default:
251 dev_err(dev->dev, "Unknown revision of GCT!\n"); 321 dev_err(dev->dev, "Unknown revision of GCT!\n");
252 vbt->size = 0;
253 } 322 }
323
324out:
325 if (ret)
326 dev_err(dev->dev, "Unable to read GCT!");
327 else
328 dev_priv->has_gct = true;
254} 329}
255 330
256int mid_chip_setup(struct drm_device *dev) 331int mid_chip_setup(struct drm_device *dev)
diff --git a/drivers/gpu/drm/gma500/oaktrail.h b/drivers/gpu/drm/gma500/oaktrail.h
index 2da1f368f14e..f2f9f38a5362 100644
--- a/drivers/gpu/drm/gma500/oaktrail.h
+++ b/drivers/gpu/drm/gma500/oaktrail.h
@@ -19,14 +19,6 @@
19 19
20/* MID device specific descriptors */ 20/* MID device specific descriptors */
21 21
22struct oaktrail_vbt {
23 s8 signature[4]; /*4 bytes,"$GCT" */
24 u8 revision;
25 u8 size;
26 u8 checksum;
27 void *oaktrail_gct;
28} __packed;
29
30struct oaktrail_timing_info { 22struct oaktrail_timing_info {
31 u16 pixel_clock; 23 u16 pixel_clock;
32 u8 hactive_lo; 24 u8 hactive_lo;
@@ -161,7 +153,7 @@ union oaktrail_panel_rx {
161 u16 panel_receiver; 153 u16 panel_receiver;
162} __packed; 154} __packed;
163 155
164struct oaktrail_gct_v1 { 156struct gct_r0 {
165 union { /*8 bits,Defined as follows: */ 157 union { /*8 bits,Defined as follows: */
166 struct { 158 struct {
167 u8 PanelType:4; /*4 bits, Bit field for panels*/ 159 u8 PanelType:4; /*4 bits, Bit field for panels*/
@@ -178,7 +170,7 @@ struct oaktrail_gct_v1 {
178 union oaktrail_panel_rx panelrx[4]; /* panel receivers*/ 170 union oaktrail_panel_rx panelrx[4]; /* panel receivers*/
179} __packed; 171} __packed;
180 172
181struct oaktrail_gct_v2 { 173struct gct_r1 {
182 union { /*8 bits,Defined as follows: */ 174 union { /*8 bits,Defined as follows: */
183 struct { 175 struct {
184 u8 PanelType:4; /*4 bits, Bit field for panels*/ 176 u8 PanelType:4; /*4 bits, Bit field for panels*/
@@ -195,6 +187,16 @@ struct oaktrail_gct_v2 {
195 union oaktrail_panel_rx panelrx[4]; /* panel receivers*/ 187 union oaktrail_panel_rx panelrx[4]; /* panel receivers*/
196} __packed; 188} __packed;
197 189
190struct gct_r10 {
191 struct gct_r10_timing_info DTD;
192 u16 Panel_MIPI_Display_Descriptor;
193 u16 Panel_MIPI_Receiver_Descriptor;
194 u16 Panel_Backlight_Inverter_Descriptor;
195 u8 Panel_Initial_Brightness;
196 u32 MIPI_Ctlr_Init_ptr;
197 u32 MIPI_Panel_Init_ptr;
198} __packed;
199
198struct oaktrail_gct_data { 200struct oaktrail_gct_data {
199 u8 bpi; /* boot panel index, number of panel used during boot */ 201 u8 bpi; /* boot panel index, number of panel used during boot */
200 u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */ 202 u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */
@@ -213,9 +215,6 @@ struct oaktrail_gct_data {
213#define MODE_SETTING_IN_DSR 0x4 215#define MODE_SETTING_IN_DSR 0x4
214#define MODE_SETTING_ENCODER_DONE 0x8 216#define MODE_SETTING_ENCODER_DONE 0x8
215 217
216#define GCT_R10_HEADER_SIZE 16
217#define GCT_R10_DISPLAY_DESC_SIZE 28
218
219/* 218/*
220 * Moorestown HDMI interfaces 219 * Moorestown HDMI interfaces
221 */ 220 */
diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c
index 4c5a1864adf4..0bb74cc3ecf8 100644
--- a/drivers/gpu/drm/gma500/oaktrail_device.c
+++ b/drivers/gpu/drm/gma500/oaktrail_device.c
@@ -458,27 +458,26 @@ static int oaktrail_power_up(struct drm_device *dev)
458static int oaktrail_chip_setup(struct drm_device *dev) 458static int oaktrail_chip_setup(struct drm_device *dev)
459{ 459{
460 struct drm_psb_private *dev_priv = dev->dev_private; 460 struct drm_psb_private *dev_priv = dev->dev_private;
461 struct oaktrail_vbt *vbt = &dev_priv->vbt_data;
462 int ret; 461 int ret;
463 462
464 ret = mid_chip_setup(dev); 463 ret = mid_chip_setup(dev);
465 if (ret < 0) 464 if (ret < 0)
466 return ret; 465 return ret;
467 if (vbt->size == 0) { 466 if (!dev_priv->has_gct) {
468 /* Now pull the BIOS data */ 467 /* Now pull the BIOS data */
469 gma_intel_opregion_init(dev); 468 psb_intel_opregion_init(dev);
470 psb_intel_init_bios(dev); 469 psb_intel_init_bios(dev);
471 } 470 }
471 oaktrail_hdmi_setup(dev);
472 return 0; 472 return 0;
473} 473}
474 474
475static void oaktrail_teardown(struct drm_device *dev) 475static void oaktrail_teardown(struct drm_device *dev)
476{ 476{
477 struct drm_psb_private *dev_priv = dev->dev_private; 477 struct drm_psb_private *dev_priv = dev->dev_private;
478 struct oaktrail_vbt *vbt = &dev_priv->vbt_data;
479 478
480 oaktrail_hdmi_teardown(dev); 479 oaktrail_hdmi_teardown(dev);
481 if (vbt->size == 0) 480 if (!dev_priv->has_gct)
482 psb_intel_destroy_bios(dev); 481 psb_intel_destroy_bios(dev);
483} 482}
484 483
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
index 5e84fbde749b..88627e3ba1e3 100644
--- a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
@@ -250,7 +250,7 @@ static irqreturn_t oaktrail_hdmi_i2c_handler(int this_irq, void *dev)
250 */ 250 */
251static void oaktrail_hdmi_i2c_gpio_fix(void) 251static void oaktrail_hdmi_i2c_gpio_fix(void)
252{ 252{
253 void *base; 253 void __iomem *base;
254 unsigned int gpio_base = 0xff12c000; 254 unsigned int gpio_base = 0xff12c000;
255 int gpio_len = 0x1000; 255 int gpio_len = 0x1000;
256 u32 temp; 256 u32 temp;
diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c b/drivers/gpu/drm/gma500/oaktrail_lvds.c
index 654f32b22b21..558c77fb55ec 100644
--- a/drivers/gpu/drm/gma500/oaktrail_lvds.c
+++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c
@@ -257,7 +257,7 @@ static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev,
257 mode_dev->panel_fixed_mode = NULL; 257 mode_dev->panel_fixed_mode = NULL;
258 258
259 /* Use the firmware provided data on Moorestown */ 259 /* Use the firmware provided data on Moorestown */
260 if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/ 260 if (dev_priv->has_gct) {
261 mode = kzalloc(sizeof(*mode), GFP_KERNEL); 261 mode = kzalloc(sizeof(*mode), GFP_KERNEL);
262 if (!mode) 262 if (!mode)
263 return; 263 return;
@@ -371,7 +371,7 @@ void oaktrail_lvds_init(struct drm_device *dev,
371 BRIGHTNESS_MAX_LEVEL); 371 BRIGHTNESS_MAX_LEVEL);
372 372
373 mode_dev->panel_wants_dither = false; 373 mode_dev->panel_wants_dither = false;
374 if (dev_priv->vbt_data.size != 0x00) 374 if (dev_priv->has_gct)
375 mode_dev->panel_wants_dither = (dev_priv->gct_data. 375 mode_dev->panel_wants_dither = (dev_priv->gct_data.
376 Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE); 376 Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE);
377 if (dev_priv->lvds_dither) 377 if (dev_priv->lvds_dither)
diff --git a/drivers/gpu/drm/gma500/opregion.c b/drivers/gpu/drm/gma500/opregion.c
new file mode 100644
index 000000000000..05661bfeac75
--- /dev/null
+++ b/drivers/gpu/drm/gma500/opregion.c
@@ -0,0 +1,350 @@
1/*
2 * Copyright 2011 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 */
24#ifdef CONFIG_ACPI
25#include <linux/acpi.h>
26#include <linux/acpi_io.h>
27#endif
28#include "psb_drv.h"
29#include "psb_intel_reg.h"
30
31#define PCI_ASLE 0xe4
32#define PCI_ASLS 0xfc
33
34#define OPREGION_HEADER_OFFSET 0
35#define OPREGION_ACPI_OFFSET 0x100
36#define ACPI_CLID 0x01ac /* current lid state indicator */
37#define ACPI_CDCK 0x01b0 /* current docking state indicator */
38#define OPREGION_SWSCI_OFFSET 0x200
39#define OPREGION_ASLE_OFFSET 0x300
40#define OPREGION_VBT_OFFSET 0x400
41
42#define OPREGION_SIGNATURE "IntelGraphicsMem"
43#define MBOX_ACPI (1<<0)
44#define MBOX_SWSCI (1<<1)
45#define MBOX_ASLE (1<<2)
46
47struct opregion_header {
48 u8 signature[16];
49 u32 size;
50 u32 opregion_ver;
51 u8 bios_ver[32];
52 u8 vbios_ver[16];
53 u8 driver_ver[16];
54 u32 mboxes;
55 u8 reserved[164];
56} __packed;
57
58/* OpRegion mailbox #1: public ACPI methods */
59struct opregion_acpi {
60 u32 drdy; /* driver readiness */
61 u32 csts; /* notification status */
62 u32 cevt; /* current event */
63 u8 rsvd1[20];
64 u32 didl[8]; /* supported display devices ID list */
65 u32 cpdl[8]; /* currently presented display list */
66 u32 cadl[8]; /* currently active display list */
67 u32 nadl[8]; /* next active devices list */
68 u32 aslp; /* ASL sleep time-out */
69 u32 tidx; /* toggle table index */
70 u32 chpd; /* current hotplug enable indicator */
71 u32 clid; /* current lid state*/
72 u32 cdck; /* current docking state */
73 u32 sxsw; /* Sx state resume */
74 u32 evts; /* ASL supported events */
75 u32 cnot; /* current OS notification */
76 u32 nrdy; /* driver status */
77 u8 rsvd2[60];
78} __packed;
79
80/* OpRegion mailbox #2: SWSCI */
81struct opregion_swsci {
82 /*FIXME: add it later*/
83} __packed;
84
85/* OpRegion mailbox #3: ASLE */
86struct opregion_asle {
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} __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/* response bits of ASLE irq request */
126#define ASLE_ALS_ILLUM_FAILED (1<<10)
127#define ASLE_BACKLIGHT_FAILED (1<<12)
128#define ASLE_PFIT_FAILED (1<<14)
129#define ASLE_PWM_FREQ_FAILED (1<<16)
130
131/* ASLE backlight brightness to set */
132#define ASLE_BCLP_VALID (1<<31)
133#define ASLE_BCLP_MSK (~(1<<31))
134
135/* ASLE panel fitting request */
136#define ASLE_PFIT_VALID (1<<31)
137#define ASLE_PFIT_CENTER (1<<0)
138#define ASLE_PFIT_STRETCH_TEXT (1<<1)
139#define ASLE_PFIT_STRETCH_GFX (1<<2)
140
141/* PWM frequency and minimum brightness */
142#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
143#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
144#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
145#define ASLE_PFMB_PWM_VALID (1<<31)
146
147#define ASLE_CBLV_VALID (1<<31)
148
149static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
150{
151 struct drm_psb_private *dev_priv = dev->dev_private;
152 struct opregion_asle *asle = dev_priv->opregion.asle;
153 struct backlight_device *bd = dev_priv->backlight_device;
154 u32 max;
155
156 DRM_DEBUG_DRIVER("asle set backlight %x\n", bclp);
157
158 if (!(bclp & ASLE_BCLP_VALID))
159 return ASLE_BACKLIGHT_FAILED;
160
161 if (bd == NULL)
162 return ASLE_BACKLIGHT_FAILED;
163
164 bclp &= ASLE_BCLP_MSK;
165 if (bclp > 255)
166 return ASLE_BACKLIGHT_FAILED;
167
168#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
169 max = bd->props.max_brightness;
170 bd->props.brightness = bclp * max / 255;
171 backlight_update_status(bd);
172#endif
173 asle->cblv = (bclp * 0x64) / 0xff | ASLE_CBLV_VALID;
174
175 return 0;
176}
177
178void psb_intel_opregion_asle_intr(struct drm_device *dev)
179{
180 struct drm_psb_private *dev_priv = dev->dev_private;
181 struct opregion_asle *asle = dev_priv->opregion.asle;
182 u32 asle_stat = 0;
183 u32 asle_req;
184
185 if (!asle)
186 return;
187
188 asle_req = asle->aslc & ASLE_REQ_MSK;
189 if (!asle_req) {
190 DRM_DEBUG_DRIVER("non asle set request??\n");
191 return;
192 }
193
194 if (asle_req & ASLE_SET_BACKLIGHT)
195 asle_stat |= asle_set_backlight(dev, asle->bclp);
196
197 asle->aslc = asle_stat;
198}
199
200#define ASLE_ALS_EN (1<<0)
201#define ASLE_BLC_EN (1<<1)
202#define ASLE_PFIT_EN (1<<2)
203#define ASLE_PFMB_EN (1<<3)
204
205void psb_intel_opregion_enable_asle(struct drm_device *dev)
206{
207 struct drm_psb_private *dev_priv = dev->dev_private;
208 struct opregion_asle *asle = dev_priv->opregion.asle;
209
210 if (asle) {
211 /* Don't do this on Medfield or other non PC like devices, they
212 use the bit for something different altogether */
213 psb_enable_pipestat(dev_priv, 0, PIPE_LEGACY_BLC_EVENT_ENABLE);
214 psb_enable_pipestat(dev_priv, 1, PIPE_LEGACY_BLC_EVENT_ENABLE);
215
216 asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN
217 | ASLE_PFMB_EN;
218 asle->ardy = 1;
219 }
220}
221
222#define ACPI_EV_DISPLAY_SWITCH (1<<0)
223#define ACPI_EV_LID (1<<1)
224#define ACPI_EV_DOCK (1<<2)
225
226static struct psb_intel_opregion *system_opregion;
227
228static int psb_intel_opregion_video_event(struct notifier_block *nb,
229 unsigned long val, void *data)
230{
231 /* The only video events relevant to opregion are 0x80. These indicate
232 either a docking event, lid switch or display switch request. In
233 Linux, these are handled by the dock, button and video drivers.
234 We might want to fix the video driver to be opregion-aware in
235 future, but right now we just indicate to the firmware that the
236 request has been handled */
237
238 struct opregion_acpi *acpi;
239
240 if (!system_opregion)
241 return NOTIFY_DONE;
242
243 acpi = system_opregion->acpi;
244 acpi->csts = 0;
245
246 return NOTIFY_OK;
247}
248
249static struct notifier_block psb_intel_opregion_notifier = {
250 .notifier_call = psb_intel_opregion_video_event,
251};
252
253void psb_intel_opregion_init(struct drm_device *dev)
254{
255 struct drm_psb_private *dev_priv = dev->dev_private;
256 struct psb_intel_opregion *opregion = &dev_priv->opregion;
257
258 if (!opregion->header)
259 return;
260
261 if (opregion->acpi) {
262 /* Notify BIOS we are ready to handle ACPI video ext notifs.
263 * Right now, all the events are handled by the ACPI video
264 * module. We don't actually need to do anything with them. */
265 opregion->acpi->csts = 0;
266 opregion->acpi->drdy = 1;
267
268 system_opregion = opregion;
269 register_acpi_notifier(&psb_intel_opregion_notifier);
270 }
271
272 if (opregion->asle)
273 psb_intel_opregion_enable_asle(dev);
274}
275
276void psb_intel_opregion_fini(struct drm_device *dev)
277{
278 struct drm_psb_private *dev_priv = dev->dev_private;
279 struct psb_intel_opregion *opregion = &dev_priv->opregion;
280
281 if (!opregion->header)
282 return;
283
284 if (opregion->acpi) {
285 opregion->acpi->drdy = 0;
286
287 system_opregion = NULL;
288 unregister_acpi_notifier(&psb_intel_opregion_notifier);
289 }
290
291 /* just clear all opregion memory pointers now */
292 iounmap(opregion->header);
293 opregion->header = NULL;
294 opregion->acpi = NULL;
295 opregion->swsci = NULL;
296 opregion->asle = NULL;
297 opregion->vbt = NULL;
298}
299
300int psb_intel_opregion_setup(struct drm_device *dev)
301{
302 struct drm_psb_private *dev_priv = dev->dev_private;
303 struct psb_intel_opregion *opregion = &dev_priv->opregion;
304 u32 opregion_phy, mboxes;
305 void __iomem *base;
306 int err = 0;
307
308 pci_read_config_dword(dev->pdev, PCI_ASLS, &opregion_phy);
309 if (opregion_phy == 0) {
310 DRM_DEBUG_DRIVER("ACPI Opregion not supported\n");
311 return -ENOTSUPP;
312 }
313 DRM_DEBUG("OpRegion detected at 0x%8x\n", opregion_phy);
314#ifdef CONFIG_ACPI
315 base = acpi_os_ioremap(opregion_phy, 8*1024);
316#else
317 base = ioremap(opregion_phy, 8*1024);
318#endif
319 if (!base)
320 return -ENOMEM;
321
322 if (memcmp(base, OPREGION_SIGNATURE, 16)) {
323 DRM_DEBUG_DRIVER("opregion signature mismatch\n");
324 err = -EINVAL;
325 goto err_out;
326 }
327
328 opregion->header = base;
329 opregion->vbt = base + OPREGION_VBT_OFFSET;
330
331 opregion->lid_state = base + ACPI_CLID;
332
333 mboxes = opregion->header->mboxes;
334 if (mboxes & MBOX_ACPI) {
335 DRM_DEBUG_DRIVER("Public ACPI methods supported\n");
336 opregion->acpi = base + OPREGION_ACPI_OFFSET;
337 }
338
339 if (mboxes & MBOX_ASLE) {
340 DRM_DEBUG_DRIVER("ASLE supported\n");
341 opregion->asle = base + OPREGION_ASLE_OFFSET;
342 }
343
344 return 0;
345
346err_out:
347 iounmap(base);
348 return err;
349}
350
diff --git a/drivers/gpu/drm/gma500/opregion.h b/drivers/gpu/drm/gma500/opregion.h
new file mode 100644
index 000000000000..a392ea8908b7
--- /dev/null
+++ b/drivers/gpu/drm/gma500/opregion.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright 2012 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 */
24
25extern void psb_intel_opregion_asle_intr(struct drm_device *dev);
26extern void psb_intel_opregion_enable_asle(struct drm_device *dev);
27extern void psb_intel_opregion_init(struct drm_device *dev);
28extern void psb_intel_opregion_fini(struct drm_device *dev);
29extern int psb_intel_opregion_setup(struct drm_device *dev);
diff --git a/drivers/gpu/drm/gma500/psb_device.c b/drivers/gpu/drm/gma500/psb_device.c
index 34e6866a73b2..e95cddbceb60 100644
--- a/drivers/gpu/drm/gma500/psb_device.c
+++ b/drivers/gpu/drm/gma500/psb_device.c
@@ -293,7 +293,7 @@ static int psb_chip_setup(struct drm_device *dev)
293{ 293{
294 psb_get_core_freq(dev); 294 psb_get_core_freq(dev);
295 gma_intel_setup_gmbus(dev); 295 gma_intel_setup_gmbus(dev);
296 gma_intel_opregion_init(dev); 296 psb_intel_opregion_init(dev);
297 psb_intel_init_bios(dev); 297 psb_intel_init_bios(dev);
298 return 0; 298 return 0;
299} 299}
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index d5a6eab8227e..0e85978877e8 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -215,12 +215,11 @@ static int psb_driver_unload(struct drm_device *dev)
215 /* Kill vblank etc here */ 215 /* Kill vblank etc here */
216 216
217 gma_backlight_exit(dev); 217 gma_backlight_exit(dev);
218
219 psb_modeset_cleanup(dev); 218 psb_modeset_cleanup(dev);
220 219
221 if (dev_priv) { 220 if (dev_priv) {
221 psb_intel_opregion_fini(dev);
222 psb_lid_timer_takedown(dev_priv); 222 psb_lid_timer_takedown(dev_priv);
223 gma_intel_opregion_exit(dev);
224 223
225 if (dev_priv->ops->chip_teardown) 224 if (dev_priv->ops->chip_teardown)
226 dev_priv->ops->chip_teardown(dev); 225 dev_priv->ops->chip_teardown(dev);
@@ -310,6 +309,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
310 if (!dev_priv->sgx_reg) 309 if (!dev_priv->sgx_reg)
311 goto out_err; 310 goto out_err;
312 311
312 psb_intel_opregion_setup(dev);
313
313 ret = dev_priv->ops->chip_setup(dev); 314 ret = dev_priv->ops->chip_setup(dev);
314 if (ret) 315 if (ret)
315 goto out_err; 316 goto out_err;
@@ -349,9 +350,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
349 PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE); 350 PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE);
350 PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE); 351 PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE);
351 352
352/* igd_opregion_init(&dev_priv->opregion_dev); */
353 acpi_video_register(); 353 acpi_video_register();
354 if (dev_priv->lid_state) 354 if (dev_priv->opregion.lid_state)
355 psb_lid_timer_init(dev_priv); 355 psb_lid_timer_init(dev_priv);
356 356
357 ret = drm_vblank_init(dev, dev_priv->num_pipe); 357 ret = drm_vblank_init(dev, dev_priv->num_pipe);
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index d3528a694206..270a27bc936a 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -30,6 +30,7 @@
30#include "psb_intel_drv.h" 30#include "psb_intel_drv.h"
31#include "gtt.h" 31#include "gtt.h"
32#include "power.h" 32#include "power.h"
33#include "opregion.h"
33#include "oaktrail.h" 34#include "oaktrail.h"
34 35
35/* Append new drm mode definition here, align with libdrm definition */ 36/* Append new drm mode definition here, align with libdrm definition */
@@ -120,6 +121,7 @@ enum {
120#define PSB_HWSTAM 0x2098 121#define PSB_HWSTAM 0x2098
121#define PSB_INSTPM 0x20C0 122#define PSB_INSTPM 0x20C0
122#define PSB_INT_IDENTITY_R 0x20A4 123#define PSB_INT_IDENTITY_R 0x20A4
124#define _PSB_IRQ_ASLE (1<<0)
123#define _MDFLD_PIPEC_EVENT_FLAG (1<<2) 125#define _MDFLD_PIPEC_EVENT_FLAG (1<<2)
124#define _MDFLD_PIPEC_VBLANK_FLAG (1<<3) 126#define _MDFLD_PIPEC_VBLANK_FLAG (1<<3)
125#define _PSB_DPST_PIPEB_FLAG (1<<4) 127#define _PSB_DPST_PIPEB_FLAG (1<<4)
@@ -259,7 +261,7 @@ struct psb_intel_opregion {
259 struct opregion_swsci *swsci; 261 struct opregion_swsci *swsci;
260 struct opregion_asle *asle; 262 struct opregion_asle *asle;
261 void *vbt; 263 void *vbt;
262 int enabled; 264 u32 __iomem *lid_state;
263}; 265};
264 266
265struct sdvo_device_mapping { 267struct sdvo_device_mapping {
@@ -505,9 +507,9 @@ struct drm_psb_private {
505 /* GTT Memory manager */ 507 /* GTT Memory manager */
506 struct psb_gtt_mm *gtt_mm; 508 struct psb_gtt_mm *gtt_mm;
507 struct page *scratch_page; 509 struct page *scratch_page;
508 u32 *gtt_map; 510 u32 __iomem *gtt_map;
509 uint32_t stolen_base; 511 uint32_t stolen_base;
510 void *vram_addr; 512 u8 __iomem *vram_addr;
511 unsigned long vram_stolen_size; 513 unsigned long vram_stolen_size;
512 int gtt_initialized; 514 int gtt_initialized;
513 u16 gmch_ctrl; /* Saved GTT setup */ 515 u16 gmch_ctrl; /* Saved GTT setup */
@@ -523,8 +525,8 @@ struct drm_psb_private {
523 * Register base 525 * Register base
524 */ 526 */
525 527
526 uint8_t *sgx_reg; 528 uint8_t __iomem *sgx_reg;
527 uint8_t *vdc_reg; 529 uint8_t __iomem *vdc_reg;
528 uint32_t gatt_free_offset; 530 uint32_t gatt_free_offset;
529 531
530 /* 532 /*
@@ -610,7 +612,7 @@ struct drm_psb_private {
610 int rpm_enabled; 612 int rpm_enabled;
611 613
612 /* MID specific */ 614 /* MID specific */
613 struct oaktrail_vbt vbt_data; 615 bool has_gct;
614 struct oaktrail_gct_data gct_data; 616 struct oaktrail_gct_data gct_data;
615 617
616 /* Oaktrail HDMI state */ 618 /* Oaktrail HDMI state */
@@ -638,7 +640,6 @@ struct drm_psb_private {
638 spinlock_t lid_lock; 640 spinlock_t lid_lock;
639 struct timer_list lid_timer; 641 struct timer_list lid_timer;
640 struct psb_intel_opregion opregion; 642 struct psb_intel_opregion opregion;
641 u32 *lid_state;
642 u32 lid_last_state; 643 u32 lid_last_state;
643 644
644 /* 645 /*
diff --git a/drivers/gpu/drm/gma500/psb_intel_reg.h b/drivers/gpu/drm/gma500/psb_intel_reg.h
index 519a9cd9ffbc..8e8c8efb0a89 100644
--- a/drivers/gpu/drm/gma500/psb_intel_reg.h
+++ b/drivers/gpu/drm/gma500/psb_intel_reg.h
@@ -507,6 +507,7 @@
507#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL << 17) 507#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL << 17)
508#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL << 18) 508#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL << 18)
509#define PIPE_TE_ENABLE (1UL << 22) 509#define PIPE_TE_ENABLE (1UL << 22)
510#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL << 22)
510#define PIPE_DPST_EVENT_ENABLE (1UL << 23) 511#define PIPE_DPST_EVENT_ENABLE (1UL << 23)
511#define PIPE_VSYNC_ENABL (1UL << 25) 512#define PIPE_VSYNC_ENABL (1UL << 25)
512#define PIPE_HDMI_AUDIO_UNDERRUN (1UL << 26) 513#define PIPE_HDMI_AUDIO_UNDERRUN (1UL << 26)
diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c
index 2fcdffdc9063..8652cdf3f03f 100644
--- a/drivers/gpu/drm/gma500/psb_irq.c
+++ b/drivers/gpu/drm/gma500/psb_irq.c
@@ -190,6 +190,9 @@ static void mid_pipe_event_handler(struct drm_device *dev, int pipe)
190 */ 190 */
191static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) 191static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)
192{ 192{
193 if (vdc_stat & _PSB_IRQ_ASLE)
194 psb_intel_opregion_asle_intr(dev);
195
193 if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG) 196 if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)
194 mid_pipe_event_handler(dev, 0); 197 mid_pipe_event_handler(dev, 0);
195 198
@@ -283,6 +286,7 @@ void psb_irq_preinstall(struct drm_device *dev)
283 /* Revisit this area - want per device masks ? */ 286 /* Revisit this area - want per device masks ? */
284 if (dev_priv->ops->hotplug) 287 if (dev_priv->ops->hotplug)
285 dev_priv->vdc_irq_mask |= _PSB_IRQ_DISP_HOTSYNC; 288 dev_priv->vdc_irq_mask |= _PSB_IRQ_DISP_HOTSYNC;
289 dev_priv->vdc_irq_mask |= _PSB_IRQ_ASLE;
286 290
287 /* This register is safe even if display island is off */ 291 /* This register is safe even if display island is off */
288 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); 292 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
@@ -422,7 +426,7 @@ void psb_irq_turn_off_dpst(struct drm_device *dev)
422 psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); 426 psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);
423 427
424 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); 428 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
425 PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE), 429 PSB_WVDC32(pwm_reg & ~PWM_PHASEIN_INT_ENABLE,
426 PWM_CONTROL_LOGIC); 430 PWM_CONTROL_LOGIC);
427 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); 431 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
428 432
diff --git a/drivers/gpu/drm/gma500/psb_lid.c b/drivers/gpu/drm/gma500/psb_lid.c
index b867aabe6bf3..7ff8bb2bdc23 100644
--- a/drivers/gpu/drm/gma500/psb_lid.c
+++ b/drivers/gpu/drm/gma500/psb_lid.c
@@ -29,7 +29,7 @@ static void psb_lid_timer_func(unsigned long data)
29 struct drm_device *dev = (struct drm_device *)dev_priv->dev; 29 struct drm_device *dev = (struct drm_device *)dev_priv->dev;
30 struct timer_list *lid_timer = &dev_priv->lid_timer; 30 struct timer_list *lid_timer = &dev_priv->lid_timer;
31 unsigned long irq_flags; 31 unsigned long irq_flags;
32 u32 *lid_state = dev_priv->lid_state; 32 u32 __iomem *lid_state = dev_priv->opregion.lid_state;
33 u32 pp_status; 33 u32 pp_status;
34 34
35 if (readl(lid_state) == dev_priv->lid_last_state) 35 if (readl(lid_state) == dev_priv->lid_last_state)