diff options
Diffstat (limited to 'drivers/gpu/drm/gma500')
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 | # |
4 | ccflags-y += -Iinclude/drm | 4 | ccflags-y += -I$(srctree)/include/drm |
5 | 5 | ||
6 | gma500_gfx-y += gem_glue.o \ | 6 | gma500_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 | |||
86 | static int cdv_brightness; | ||
87 | static struct backlight_device *cdv_backlight_device; | 74 | static struct backlight_device *cdv_backlight_device; |
88 | 75 | ||
89 | static int cdv_get_brightness(struct backlight_device *bd) | 76 | static 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 | 81 | static int cdv_get_brightness(struct backlight_device *bd) | |
98 | static 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 || | 96 | static 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 | ||
132 | static int cdv_set_brightness(struct backlight_device *bd) | 113 | static 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 = { | |||
150 | static int cdv_backlight_init(struct drm_device *dev) | 144 | static 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) | |||
244 | static void cdv_errata(struct drm_device *dev) | 232 | static 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 | ||
559 | const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = { | 559 | static 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 | ||
574 | struct drm_fb_helper_funcs psb_fb_helper_funcs = { | 575 | static 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 | */ |
64 | static u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) | 64 | static 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 | */ |
83 | static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) | 83 | static 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) | |||
126 | static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) | 127 | static 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 | */ |
153 | void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll) | 155 | void 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 | |||
44 | struct 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 */ | ||
56 | struct 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 */ | ||
78 | struct 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 */ | ||
86 | struct 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 | |||
139 | int 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 | |||
172 | int 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 | ||
121 | struct vbt_header { | ||
122 | u32 signature; | ||
123 | u8 revision; | ||
124 | } __packed; | ||
125 | |||
126 | /* The same for r0 and r1 */ | ||
127 | struct vbt_r0 { | ||
128 | struct vbt_header vbt_header; | ||
129 | u8 size; | ||
130 | u8 checksum; | ||
131 | } __packed; | ||
132 | |||
133 | struct 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 | |||
143 | static 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 | |||
157 | static 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 | |||
171 | static 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 | |||
199 | static 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 | |||
227 | static 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; | ||
274 | out: | ||
275 | kfree(gct); | ||
276 | return ret; | ||
277 | } | ||
278 | |||
121 | static void mid_get_vbt_data(struct drm_psb_private *dev_priv) | 279 | static 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 | |||
324 | out: | ||
325 | if (ret) | ||
326 | dev_err(dev->dev, "Unable to read GCT!"); | ||
327 | else | ||
328 | dev_priv->has_gct = true; | ||
254 | } | 329 | } |
255 | 330 | ||
256 | int mid_chip_setup(struct drm_device *dev) | 331 | int 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 | ||
22 | struct 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 | |||
30 | struct oaktrail_timing_info { | 22 | struct 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 | ||
164 | struct oaktrail_gct_v1 { | 156 | struct 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 | ||
181 | struct oaktrail_gct_v2 { | 173 | struct 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 | ||
190 | struct 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 | |||
198 | struct oaktrail_gct_data { | 200 | struct 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) | |||
458 | static int oaktrail_chip_setup(struct drm_device *dev) | 458 | static 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 | ||
475 | static void oaktrail_teardown(struct drm_device *dev) | 475 | static 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 | */ |
251 | static void oaktrail_hdmi_i2c_gpio_fix(void) | 251 | static 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 | |||
47 | struct 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 */ | ||
59 | struct 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 */ | ||
81 | struct opregion_swsci { | ||
82 | /*FIXME: add it later*/ | ||
83 | } __packed; | ||
84 | |||
85 | /* OpRegion mailbox #3: ASLE */ | ||
86 | struct 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 | |||
149 | static 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 | |||
178 | void 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 | |||
205 | void 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 | |||
226 | static struct psb_intel_opregion *system_opregion; | ||
227 | |||
228 | static 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 | |||
249 | static struct notifier_block psb_intel_opregion_notifier = { | ||
250 | .notifier_call = psb_intel_opregion_video_event, | ||
251 | }; | ||
252 | |||
253 | void 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 | |||
276 | void 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 | |||
300 | int 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 | |||
346 | err_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 | |||
25 | extern void psb_intel_opregion_asle_intr(struct drm_device *dev); | ||
26 | extern void psb_intel_opregion_enable_asle(struct drm_device *dev); | ||
27 | extern void psb_intel_opregion_init(struct drm_device *dev); | ||
28 | extern void psb_intel_opregion_fini(struct drm_device *dev); | ||
29 | extern 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 | ||
265 | struct sdvo_device_mapping { | 267 | struct 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 | */ |
191 | static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) | 191 | static 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) |