aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/gma500/opregion.c1
-rw-r--r--drivers/gpu/drm/i915/Makefile3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h3
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c2
-rw-r--r--drivers/gpu/drm/i915/intel_acpi.c146
-rw-r--r--drivers/gpu/drm/i915/intel_display.c19
-rw-r--r--drivers/gpu/drm/i915/intel_opregion.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/core/subdev.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nvc0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/fb.h5
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/init.c14
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mxm/base.c48
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_acpi.c138
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_acpi.c6
18 files changed, 123 insertions, 276 deletions
diff --git a/drivers/gpu/drm/gma500/opregion.c b/drivers/gpu/drm/gma500/opregion.c
index ad0d6de938f3..13ec6283bf59 100644
--- a/drivers/gpu/drm/gma500/opregion.c
+++ b/drivers/gpu/drm/gma500/opregion.c
@@ -22,7 +22,6 @@
22 * 22 *
23 */ 23 */
24#include <linux/acpi.h> 24#include <linux/acpi.h>
25#include <linux/acpi_io.h>
26#include "psb_drv.h" 25#include "psb_drv.h"
27#include "psb_intel_reg.h" 26#include "psb_intel_reg.h"
28 27
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 41838eaa799c..d4ae48b04cf2 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -38,7 +38,6 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
38 intel_ringbuffer.o \ 38 intel_ringbuffer.o \
39 intel_overlay.o \ 39 intel_overlay.o \
40 intel_sprite.o \ 40 intel_sprite.o \
41 intel_opregion.o \
42 intel_sideband.o \ 41 intel_sideband.o \
43 intel_uncore.o \ 42 intel_uncore.o \
44 dvo_ch7xxx.o \ 43 dvo_ch7xxx.o \
@@ -51,7 +50,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
51 50
52i915-$(CONFIG_COMPAT) += i915_ioc32.o 51i915-$(CONFIG_COMPAT) += i915_ioc32.o
53 52
54i915-$(CONFIG_ACPI) += intel_acpi.o 53i915-$(CONFIG_ACPI) += intel_acpi.o intel_opregion.o
55 54
56i915-$(CONFIG_DRM_I915_FBDEV) += intel_fbdev.o 55i915-$(CONFIG_DRM_I915_FBDEV) += intel_fbdev.o
57 56
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 90fcccba17b0..1caa5e34fbe3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2339,8 +2339,8 @@ extern void intel_i2c_reset(struct drm_device *dev);
2339 2339
2340/* intel_opregion.c */ 2340/* intel_opregion.c */
2341struct intel_encoder; 2341struct intel_encoder;
2342extern int intel_opregion_setup(struct drm_device *dev);
2343#ifdef CONFIG_ACPI 2342#ifdef CONFIG_ACPI
2343extern int intel_opregion_setup(struct drm_device *dev);
2344extern void intel_opregion_init(struct drm_device *dev); 2344extern void intel_opregion_init(struct drm_device *dev);
2345extern void intel_opregion_fini(struct drm_device *dev); 2345extern void intel_opregion_fini(struct drm_device *dev);
2346extern void intel_opregion_asle_intr(struct drm_device *dev); 2346extern void intel_opregion_asle_intr(struct drm_device *dev);
@@ -2349,6 +2349,7 @@ extern int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
2349extern int intel_opregion_notify_adapter(struct drm_device *dev, 2349extern int intel_opregion_notify_adapter(struct drm_device *dev,
2350 pci_power_t state); 2350 pci_power_t state);
2351#else 2351#else
2352static inline int intel_opregion_setup(struct drm_device *dev) { return 0; }
2352static inline void intel_opregion_init(struct drm_device *dev) { return; } 2353static inline void intel_opregion_init(struct drm_device *dev) { return; }
2353static inline void intel_opregion_fini(struct drm_device *dev) { return; } 2354static inline void intel_opregion_fini(struct drm_device *dev) { return; }
2354static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; } 2355static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; }
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index c79dd2b1f70e..d3c3b5b15824 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -906,14 +906,12 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
906 WARN_ON(readq(&gtt_entries[i-1]) 906 WARN_ON(readq(&gtt_entries[i-1])
907 != gen8_pte_encode(addr, level, true)); 907 != gen8_pte_encode(addr, level, true));
908 908
909#if 0 /* TODO: Still needed on GEN8? */
910 /* This next bit makes the above posting read even more important. We 909 /* This next bit makes the above posting read even more important. We
911 * want to flush the TLBs only after we're certain all the PTE updates 910 * want to flush the TLBs only after we're certain all the PTE updates
912 * have finished. 911 * have finished.
913 */ 912 */
914 I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); 913 I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
915 POSTING_READ(GFX_FLSH_CNTL_GEN6); 914 POSTING_READ(GFX_FLSH_CNTL_GEN6);
916#endif
917} 915}
918 916
919/* 917/*
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c
index dfff0907f70e..d96eee1ae9c5 100644
--- a/drivers/gpu/drm/i915/intel_acpi.c
+++ b/drivers/gpu/drm/i915/intel_acpi.c
@@ -6,14 +6,10 @@
6#include <linux/pci.h> 6#include <linux/pci.h>
7#include <linux/acpi.h> 7#include <linux/acpi.h>
8#include <linux/vga_switcheroo.h> 8#include <linux/vga_switcheroo.h>
9#include <acpi/acpi_drivers.h>
10
11#include <drm/drmP.h> 9#include <drm/drmP.h>
12#include "i915_drv.h" 10#include "i915_drv.h"
13 11
14#define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */ 12#define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */
15
16#define INTEL_DSM_FN_SUPPORTED_FUNCTIONS 0 /* No args */
17#define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */ 13#define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */
18 14
19static struct intel_dsm_priv { 15static struct intel_dsm_priv {
@@ -28,61 +24,6 @@ static const u8 intel_dsm_guid[] = {
28 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c 24 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c
29}; 25};
30 26
31static int intel_dsm(acpi_handle handle, int func)
32{
33 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
34 struct acpi_object_list input;
35 union acpi_object params[4];
36 union acpi_object *obj;
37 u32 result;
38 int ret = 0;
39
40 input.count = 4;
41 input.pointer = params;
42 params[0].type = ACPI_TYPE_BUFFER;
43 params[0].buffer.length = sizeof(intel_dsm_guid);
44 params[0].buffer.pointer = (char *)intel_dsm_guid;
45 params[1].type = ACPI_TYPE_INTEGER;
46 params[1].integer.value = INTEL_DSM_REVISION_ID;
47 params[2].type = ACPI_TYPE_INTEGER;
48 params[2].integer.value = func;
49 params[3].type = ACPI_TYPE_PACKAGE;
50 params[3].package.count = 0;
51 params[3].package.elements = NULL;
52
53 ret = acpi_evaluate_object(handle, "_DSM", &input, &output);
54 if (ret) {
55 DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret);
56 return ret;
57 }
58
59 obj = (union acpi_object *)output.pointer;
60
61 result = 0;
62 switch (obj->type) {
63 case ACPI_TYPE_INTEGER:
64 result = obj->integer.value;
65 break;
66
67 case ACPI_TYPE_BUFFER:
68 if (obj->buffer.length == 4) {
69 result = (obj->buffer.pointer[0] |
70 (obj->buffer.pointer[1] << 8) |
71 (obj->buffer.pointer[2] << 16) |
72 (obj->buffer.pointer[3] << 24));
73 break;
74 }
75 default:
76 ret = -EINVAL;
77 break;
78 }
79 if (result == 0x80000002)
80 ret = -ENODEV;
81
82 kfree(output.pointer);
83 return ret;
84}
85
86static char *intel_dsm_port_name(u8 id) 27static char *intel_dsm_port_name(u8 id)
87{ 28{
88 switch (id) { 29 switch (id) {
@@ -137,83 +78,56 @@ static char *intel_dsm_mux_type(u8 type)
137 78
138static void intel_dsm_platform_mux_info(void) 79static void intel_dsm_platform_mux_info(void)
139{ 80{
140 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 81 int i;
141 struct acpi_object_list input; 82 union acpi_object *pkg, *connector_count;
142 union acpi_object params[4]; 83
143 union acpi_object *pkg; 84 pkg = acpi_evaluate_dsm_typed(intel_dsm_priv.dhandle, intel_dsm_guid,
144 int i, ret; 85 INTEL_DSM_REVISION_ID, INTEL_DSM_FN_PLATFORM_MUX_INFO,
145 86 NULL, ACPI_TYPE_PACKAGE);
146 input.count = 4; 87 if (!pkg) {
147 input.pointer = params; 88 DRM_DEBUG_DRIVER("failed to evaluate _DSM\n");
148 params[0].type = ACPI_TYPE_BUFFER; 89 return;
149 params[0].buffer.length = sizeof(intel_dsm_guid);
150 params[0].buffer.pointer = (char *)intel_dsm_guid;
151 params[1].type = ACPI_TYPE_INTEGER;
152 params[1].integer.value = INTEL_DSM_REVISION_ID;
153 params[2].type = ACPI_TYPE_INTEGER;
154 params[2].integer.value = INTEL_DSM_FN_PLATFORM_MUX_INFO;
155 params[3].type = ACPI_TYPE_PACKAGE;
156 params[3].package.count = 0;
157 params[3].package.elements = NULL;
158
159 ret = acpi_evaluate_object(intel_dsm_priv.dhandle, "_DSM", &input,
160 &output);
161 if (ret) {
162 DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret);
163 goto out;
164 } 90 }
165 91
166 pkg = (union acpi_object *)output.pointer; 92 connector_count = &pkg->package.elements[0];
167 93 DRM_DEBUG_DRIVER("MUX info connectors: %lld\n",
168 if (pkg->type == ACPI_TYPE_PACKAGE) { 94 (unsigned long long)connector_count->integer.value);
169 union acpi_object *connector_count = &pkg->package.elements[0]; 95 for (i = 1; i < pkg->package.count; i++) {
170 DRM_DEBUG_DRIVER("MUX info connectors: %lld\n", 96 union acpi_object *obj = &pkg->package.elements[i];
171 (unsigned long long)connector_count->integer.value); 97 union acpi_object *connector_id = &obj->package.elements[0];
172 for (i = 1; i < pkg->package.count; i++) { 98 union acpi_object *info = &obj->package.elements[1];
173 union acpi_object *obj = &pkg->package.elements[i]; 99 DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n",
174 union acpi_object *connector_id = 100 (unsigned long long)connector_id->integer.value);
175 &obj->package.elements[0]; 101 DRM_DEBUG_DRIVER(" port id: %s\n",
176 union acpi_object *info = &obj->package.elements[1]; 102 intel_dsm_port_name(info->buffer.pointer[0]));
177 DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n", 103 DRM_DEBUG_DRIVER(" display mux info: %s\n",
178 (unsigned long long)connector_id->integer.value); 104 intel_dsm_mux_type(info->buffer.pointer[1]));
179 DRM_DEBUG_DRIVER(" port id: %s\n", 105 DRM_DEBUG_DRIVER(" aux/dc mux info: %s\n",
180 intel_dsm_port_name(info->buffer.pointer[0])); 106 intel_dsm_mux_type(info->buffer.pointer[2]));
181 DRM_DEBUG_DRIVER(" display mux info: %s\n", 107 DRM_DEBUG_DRIVER(" hpd mux info: %s\n",
182 intel_dsm_mux_type(info->buffer.pointer[1])); 108 intel_dsm_mux_type(info->buffer.pointer[3]));
183 DRM_DEBUG_DRIVER(" aux/dc mux info: %s\n",
184 intel_dsm_mux_type(info->buffer.pointer[2]));
185 DRM_DEBUG_DRIVER(" hpd mux info: %s\n",
186 intel_dsm_mux_type(info->buffer.pointer[3]));
187 }
188 } 109 }
189 110
190out: 111 ACPI_FREE(pkg);
191 kfree(output.pointer);
192} 112}
193 113
194static bool intel_dsm_pci_probe(struct pci_dev *pdev) 114static bool intel_dsm_pci_probe(struct pci_dev *pdev)
195{ 115{
196 acpi_handle dhandle; 116 acpi_handle dhandle;
197 int ret;
198 117
199 dhandle = ACPI_HANDLE(&pdev->dev); 118 dhandle = ACPI_HANDLE(&pdev->dev);
200 if (!dhandle) 119 if (!dhandle)
201 return false; 120 return false;
202 121
203 if (!acpi_has_method(dhandle, "_DSM")) { 122 if (!acpi_check_dsm(dhandle, intel_dsm_guid, INTEL_DSM_REVISION_ID,
123 1 << INTEL_DSM_FN_PLATFORM_MUX_INFO)) {
204 DRM_DEBUG_KMS("no _DSM method for intel device\n"); 124 DRM_DEBUG_KMS("no _DSM method for intel device\n");
205 return false; 125 return false;
206 } 126 }
207 127
208 ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS);
209 if (ret < 0) {
210 DRM_DEBUG_KMS("failed to get supported _DSM functions\n");
211 return false;
212 }
213
214 intel_dsm_priv.dhandle = dhandle; 128 intel_dsm_priv.dhandle = dhandle;
215
216 intel_dsm_platform_mux_info(); 129 intel_dsm_platform_mux_info();
130
217 return true; 131 return true;
218} 132}
219 133
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 54e82a80cf50..769b864465a9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10541,11 +10541,20 @@ static struct intel_quirk intel_quirks[] = {
10541 /* Sony Vaio Y cannot use SSC on LVDS */ 10541 /* Sony Vaio Y cannot use SSC on LVDS */
10542 { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable }, 10542 { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable },
10543 10543
10544 /* 10544 /* Acer Aspire 5734Z must invert backlight brightness */
10545 * All GM45 Acer (and its brands eMachines and Packard Bell) laptops 10545 { 0x2a42, 0x1025, 0x0459, quirk_invert_brightness },
10546 * seem to use inverted backlight PWM. 10546
10547 */ 10547 /* Acer/eMachines G725 */
10548 { 0x2a42, 0x1025, PCI_ANY_ID, quirk_invert_brightness }, 10548 { 0x2a42, 0x1025, 0x0210, quirk_invert_brightness },
10549
10550 /* Acer/eMachines e725 */
10551 { 0x2a42, 0x1025, 0x0212, quirk_invert_brightness },
10552
10553 /* Acer/Packard Bell NCL20 */
10554 { 0x2a42, 0x1025, 0x034b, quirk_invert_brightness },
10555
10556 /* Acer Aspire 4736Z */
10557 { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness },
10549 10558
10550 /* Dell XPS13 HD Sandy Bridge */ 10559 /* Dell XPS13 HD Sandy Bridge */
10551 { 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable }, 10560 { 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable },
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index 6d69a9bad865..9a8804bee5cd 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -28,7 +28,6 @@
28#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 28#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
29 29
30#include <linux/acpi.h> 30#include <linux/acpi.h>
31#include <linux/acpi_io.h>
32#include <acpi/video.h> 31#include <acpi/video.h>
33 32
34#include <drm/drmP.h> 33#include <drm/drmP.h>
diff --git a/drivers/gpu/drm/nouveau/core/core/subdev.c b/drivers/gpu/drm/nouveau/core/core/subdev.c
index 48f06378d3f9..2ea5568b6cf5 100644
--- a/drivers/gpu/drm/nouveau/core/core/subdev.c
+++ b/drivers/gpu/drm/nouveau/core/core/subdev.c
@@ -104,11 +104,8 @@ nouveau_subdev_create_(struct nouveau_object *parent,
104 104
105 if (parent) { 105 if (parent) {
106 struct nouveau_device *device = nv_device(parent); 106 struct nouveau_device *device = nv_device(parent);
107 int subidx = nv_hclass(subdev) & 0xff;
108
109 subdev->debug = nouveau_dbgopt(device->dbgopt, subname); 107 subdev->debug = nouveau_dbgopt(device->dbgopt, subname);
110 subdev->mmio = nv_subdev(device)->mmio; 108 subdev->mmio = nv_subdev(device)->mmio;
111 device->subdev[subidx] = *pobject;
112 } 109 }
113 110
114 return 0; 111 return 0;
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c
index 9135b25a29d0..dd01c6c435d6 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c
@@ -268,6 +268,8 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
268 if (ret) 268 if (ret)
269 return ret; 269 return ret;
270 270
271 device->subdev[i] = devobj->subdev[i];
272
271 /* note: can't init *any* subdevs until devinit has been run 273 /* note: can't init *any* subdevs until devinit has been run
272 * due to not knowing exactly what the vbios init tables will 274 * due to not knowing exactly what the vbios init tables will
273 * mess with. devinit also can't be run until all of its 275 * mess with. devinit also can't be run until all of its
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
index 8d06eef2b9ee..dbc5e33de94f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
@@ -161,7 +161,7 @@ nvc0_identify(struct nouveau_device *device)
161 device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; 161 device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
162 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; 162 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
163 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; 163 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
164 device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; 164 device->oclass[NVDEV_SUBDEV_MC ] = nvc0_mc_oclass;
165 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; 165 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
166 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 166 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
167 device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; 167 device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
index 434bb4b0fa2e..5c8a63dc506a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
@@ -334,7 +334,7 @@ nvc0_graph_mthd(struct nvc0_graph_priv *priv, struct nvc0_graph_mthd *mthds)
334 while ((mthd = &mthds[i++]) && (init = mthd->init)) { 334 while ((mthd = &mthds[i++]) && (init = mthd->init)) {
335 u32 addr = 0x80000000 | mthd->oclass; 335 u32 addr = 0x80000000 | mthd->oclass;
336 for (data = 0; init->count; init++) { 336 for (data = 0; init->count; init++) {
337 if (data != init->data) { 337 if (init == mthd->init || data != init->data) {
338 nv_wr32(priv, 0x40448c, init->data); 338 nv_wr32(priv, 0x40448c, init->data);
339 data = init->data; 339 data = init->data;
340 } 340 }
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
index 8541aa382ff2..d89dbdf39b0d 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
@@ -75,6 +75,11 @@ struct nouveau_fb {
75static inline struct nouveau_fb * 75static inline struct nouveau_fb *
76nouveau_fb(void *obj) 76nouveau_fb(void *obj)
77{ 77{
78 /* fbram uses this before device subdev pointer is valid */
79 if (nv_iclass(obj, NV_SUBDEV_CLASS) &&
80 nv_subidx(obj) == NVDEV_SUBDEV_FB)
81 return obj;
82
78 return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB]; 83 return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB];
79} 84}
80 85
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
index 420908cb82b6..df1b1b423093 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
@@ -365,13 +365,13 @@ static u16
365init_script(struct nouveau_bios *bios, int index) 365init_script(struct nouveau_bios *bios, int index)
366{ 366{
367 struct nvbios_init init = { .bios = bios }; 367 struct nvbios_init init = { .bios = bios };
368 u16 data; 368 u16 bmp_ver = bmp_version(bios), data;
369 369
370 if (bmp_version(bios) && bmp_version(bios) < 0x0510) { 370 if (bmp_ver && bmp_ver < 0x0510) {
371 if (index > 1) 371 if (index > 1 || bmp_ver < 0x0100)
372 return 0x0000; 372 return 0x0000;
373 373
374 data = bios->bmp_offset + (bios->version.major < 2 ? 14 : 18); 374 data = bios->bmp_offset + (bmp_ver < 0x0200 ? 14 : 18);
375 return nv_ro16(bios, data + (index * 2)); 375 return nv_ro16(bios, data + (index * 2));
376 } 376 }
377 377
@@ -1294,7 +1294,11 @@ init_jump(struct nvbios_init *init)
1294 u16 offset = nv_ro16(bios, init->offset + 1); 1294 u16 offset = nv_ro16(bios, init->offset + 1);
1295 1295
1296 trace("JUMP\t0x%04x\n", offset); 1296 trace("JUMP\t0x%04x\n", offset);
1297 init->offset = offset; 1297
1298 if (init_exec(init))
1299 init->offset = offset;
1300 else
1301 init->offset += 3;
1298} 1302}
1299 1303
1300/** 1304/**
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
index 129120473f6c..13c5af88a601 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
@@ -87,55 +87,39 @@ mxm_shadow_dsm(struct nouveau_mxm *mxm, u8 version)
87 0xB8, 0x9C, 0x79, 0xB6, 0x2F, 0xD5, 0x56, 0x65 87 0xB8, 0x9C, 0x79, 0xB6, 0x2F, 0xD5, 0x56, 0x65
88 }; 88 };
89 u32 mxms_args[] = { 0x00000000 }; 89 u32 mxms_args[] = { 0x00000000 };
90 union acpi_object args[4] = { 90 union acpi_object argv4 = {
91 /* _DSM MUID */ 91 .buffer.type = ACPI_TYPE_BUFFER,
92 { .buffer.type = 3, 92 .buffer.length = sizeof(mxms_args),
93 .buffer.length = sizeof(muid), 93 .buffer.pointer = (char *)mxms_args,
94 .buffer.pointer = muid,
95 },
96 /* spec says this can be zero to mean "highest revision", but
97 * of course there's at least one bios out there which fails
98 * unless you pass in exactly the version it supports..
99 */
100 { .integer.type = ACPI_TYPE_INTEGER,
101 .integer.value = (version & 0xf0) << 4 | (version & 0x0f),
102 },
103 /* MXMS function */
104 { .integer.type = ACPI_TYPE_INTEGER,
105 .integer.value = 0x00000010,
106 },
107 /* Pointer to MXMS arguments */
108 { .buffer.type = ACPI_TYPE_BUFFER,
109 .buffer.length = sizeof(mxms_args),
110 .buffer.pointer = (char *)mxms_args,
111 },
112 }; 94 };
113 struct acpi_object_list list = { ARRAY_SIZE(args), args };
114 struct acpi_buffer retn = { ACPI_ALLOCATE_BUFFER, NULL };
115 union acpi_object *obj; 95 union acpi_object *obj;
116 acpi_handle handle; 96 acpi_handle handle;
117 int ret; 97 int rev;
118 98
119 handle = ACPI_HANDLE(&device->pdev->dev); 99 handle = ACPI_HANDLE(&device->pdev->dev);
120 if (!handle) 100 if (!handle)
121 return false; 101 return false;
122 102
123 ret = acpi_evaluate_object(handle, "_DSM", &list, &retn); 103 /*
124 if (ret) { 104 * spec says this can be zero to mean "highest revision", but
125 nv_debug(mxm, "DSM MXMS failed: %d\n", ret); 105 * of course there's at least one bios out there which fails
106 * unless you pass in exactly the version it supports..
107 */
108 rev = (version & 0xf0) << 4 | (version & 0x0f);
109 obj = acpi_evaluate_dsm(handle, muid, rev, 0x00000010, &argv4);
110 if (!obj) {
111 nv_debug(mxm, "DSM MXMS failed\n");
126 return false; 112 return false;
127 } 113 }
128 114
129 obj = retn.pointer;
130 if (obj->type == ACPI_TYPE_BUFFER) { 115 if (obj->type == ACPI_TYPE_BUFFER) {
131 mxm->mxms = kmemdup(obj->buffer.pointer, 116 mxm->mxms = kmemdup(obj->buffer.pointer,
132 obj->buffer.length, GFP_KERNEL); 117 obj->buffer.length, GFP_KERNEL);
133 } else 118 } else if (obj->type == ACPI_TYPE_INTEGER) {
134 if (obj->type == ACPI_TYPE_INTEGER) {
135 nv_debug(mxm, "DSM MXMS returned 0x%llx\n", obj->integer.value); 119 nv_debug(mxm, "DSM MXMS returned 0x%llx\n", obj->integer.value);
136 } 120 }
137 121
138 kfree(obj); 122 ACPI_FREE(obj);
139 return mxm->mxms != NULL; 123 return mxm->mxms != NULL;
140} 124}
141#endif 125#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c
index 6828d81ed7b9..900fae01793e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -447,6 +447,8 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
447 if (ret) 447 if (ret)
448 goto done; 448 goto done;
449 449
450 info->offset = ntfy->node->offset;
451
450done: 452done:
451 if (ret) 453 if (ret)
452 nouveau_abi16_ntfy_fini(chan, ntfy); 454 nouveau_abi16_ntfy_fini(chan, ntfy);
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index ba0183fb84f3..3c149617cfcb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -1,15 +1,10 @@
1#include <linux/pci.h> 1#include <linux/pci.h>
2#include <linux/acpi.h> 2#include <linux/acpi.h>
3#include <linux/slab.h> 3#include <linux/slab.h>
4#include <acpi/acpi_drivers.h>
5#include <acpi/acpi_bus.h>
6#include <acpi/video.h>
7#include <acpi/acpi.h>
8#include <linux/mxm-wmi.h> 4#include <linux/mxm-wmi.h>
9
10#include <linux/vga_switcheroo.h> 5#include <linux/vga_switcheroo.h>
11
12#include <drm/drm_edid.h> 6#include <drm/drm_edid.h>
7#include <acpi/video.h>
13 8
14#include "nouveau_drm.h" 9#include "nouveau_drm.h"
15#include "nouveau_acpi.h" 10#include "nouveau_acpi.h"
@@ -78,124 +73,66 @@ static const char nouveau_op_dsm_muid[] = {
78 73
79static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *result) 74static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
80{ 75{
81 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 76 int i;
82 struct acpi_object_list input;
83 union acpi_object params[4];
84 union acpi_object *obj; 77 union acpi_object *obj;
85 int i, err;
86 char args_buff[4]; 78 char args_buff[4];
79 union acpi_object argv4 = {
80 .buffer.type = ACPI_TYPE_BUFFER,
81 .buffer.length = 4,
82 .buffer.pointer = args_buff
83 };
87 84
88 input.count = 4;
89 input.pointer = params;
90 params[0].type = ACPI_TYPE_BUFFER;
91 params[0].buffer.length = sizeof(nouveau_op_dsm_muid);
92 params[0].buffer.pointer = (char *)nouveau_op_dsm_muid;
93 params[1].type = ACPI_TYPE_INTEGER;
94 params[1].integer.value = 0x00000100;
95 params[2].type = ACPI_TYPE_INTEGER;
96 params[2].integer.value = func;
97 params[3].type = ACPI_TYPE_BUFFER;
98 params[3].buffer.length = 4;
99 /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */ 85 /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */
100 for (i = 0; i < 4; i++) 86 for (i = 0; i < 4; i++)
101 args_buff[i] = (arg >> i * 8) & 0xFF; 87 args_buff[i] = (arg >> i * 8) & 0xFF;
102 params[3].buffer.pointer = args_buff;
103
104 err = acpi_evaluate_object(handle, "_DSM", &input, &output);
105 if (err) {
106 printk(KERN_INFO "failed to evaluate _DSM: %d\n", err);
107 return err;
108 }
109
110 obj = (union acpi_object *)output.pointer;
111 88
112 if (obj->type == ACPI_TYPE_INTEGER) 89 *result = 0;
113 if (obj->integer.value == 0x80000002) { 90 obj = acpi_evaluate_dsm_typed(handle, nouveau_op_dsm_muid, 0x00000100,
114 return -ENODEV; 91 func, &argv4, ACPI_TYPE_BUFFER);
115 } 92 if (!obj) {
116 93 acpi_handle_info(handle, "failed to evaluate _DSM\n");
117 if (obj->type == ACPI_TYPE_BUFFER) { 94 return AE_ERROR;
118 if (obj->buffer.length == 4 && result) { 95 } else {
119 *result = 0; 96 if (obj->buffer.length == 4) {
120 *result |= obj->buffer.pointer[0]; 97 *result |= obj->buffer.pointer[0];
121 *result |= (obj->buffer.pointer[1] << 8); 98 *result |= (obj->buffer.pointer[1] << 8);
122 *result |= (obj->buffer.pointer[2] << 16); 99 *result |= (obj->buffer.pointer[2] << 16);
123 *result |= (obj->buffer.pointer[3] << 24); 100 *result |= (obj->buffer.pointer[3] << 24);
124 } 101 }
102 ACPI_FREE(obj);
125 } 103 }
126 104
127 kfree(output.pointer);
128 return 0; 105 return 0;
129} 106}
130 107
131static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result) 108static int nouveau_dsm(acpi_handle handle, int func, int arg)
132{ 109{
133 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 110 int ret = 0;
134 struct acpi_object_list input;
135 union acpi_object params[4];
136 union acpi_object *obj; 111 union acpi_object *obj;
137 int err; 112 union acpi_object argv4 = {
138 113 .integer.type = ACPI_TYPE_INTEGER,
139 input.count = 4; 114 .integer.value = arg,
140 input.pointer = params; 115 };
141 params[0].type = ACPI_TYPE_BUFFER; 116
142 params[0].buffer.length = sizeof(nouveau_dsm_muid); 117 obj = acpi_evaluate_dsm_typed(handle, nouveau_dsm_muid, 0x00000102,
143 params[0].buffer.pointer = (char *)nouveau_dsm_muid; 118 func, &argv4, ACPI_TYPE_INTEGER);
144 params[1].type = ACPI_TYPE_INTEGER; 119 if (!obj) {
145 params[1].integer.value = 0x00000102; 120 acpi_handle_info(handle, "failed to evaluate _DSM\n");
146 params[2].type = ACPI_TYPE_INTEGER; 121 return AE_ERROR;
147 params[2].integer.value = func; 122 } else {
148 params[3].type = ACPI_TYPE_INTEGER;
149 params[3].integer.value = arg;
150
151 err = acpi_evaluate_object(handle, "_DSM", &input, &output);
152 if (err) {
153 printk(KERN_INFO "failed to evaluate _DSM: %d\n", err);
154 return err;
155 }
156
157 obj = (union acpi_object *)output.pointer;
158
159 if (obj->type == ACPI_TYPE_INTEGER)
160 if (obj->integer.value == 0x80000002) 123 if (obj->integer.value == 0x80000002)
161 return -ENODEV; 124 ret = -ENODEV;
162 125 ACPI_FREE(obj);
163 if (obj->type == ACPI_TYPE_BUFFER) {
164 if (obj->buffer.length == 4 && result) {
165 *result = 0;
166 *result |= obj->buffer.pointer[0];
167 *result |= (obj->buffer.pointer[1] << 8);
168 *result |= (obj->buffer.pointer[2] << 16);
169 *result |= (obj->buffer.pointer[3] << 24);
170 }
171 } 126 }
172 127
173 kfree(output.pointer); 128 return ret;
174 return 0;
175}
176
177/* Returns 1 if a DSM function is usable and 0 otherwise */
178static int nouveau_test_dsm(acpi_handle test_handle,
179 int (*dsm_func)(acpi_handle, int, int, uint32_t *),
180 int sfnc)
181{
182 u32 result = 0;
183
184 /* Function 0 returns a Buffer containing available functions. The args
185 * parameter is ignored for function 0, so just put 0 in it */
186 if (dsm_func(test_handle, 0, 0, &result))
187 return 0;
188
189 /* ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. If
190 * the n-th bit is enabled, function n is supported */
191 return result & 1 && result & (1 << sfnc);
192} 129}
193 130
194static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id) 131static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id)
195{ 132{
196 mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); 133 mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0);
197 mxm_wmi_call_mxds(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); 134 mxm_wmi_call_mxds(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0);
198 return nouveau_dsm(handle, NOUVEAU_DSM_LED, mux_id, NULL); 135 return nouveau_dsm(handle, NOUVEAU_DSM_LED, mux_id);
199} 136}
200 137
201static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switcheroo_state state) 138static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switcheroo_state state)
@@ -205,7 +142,7 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero
205 arg = NOUVEAU_DSM_POWER_SPEED; 142 arg = NOUVEAU_DSM_POWER_SPEED;
206 else 143 else
207 arg = NOUVEAU_DSM_POWER_STAMINA; 144 arg = NOUVEAU_DSM_POWER_STAMINA;
208 nouveau_dsm(handle, NOUVEAU_DSM_POWER, arg, NULL); 145 nouveau_dsm(handle, NOUVEAU_DSM_POWER, arg);
209 return 0; 146 return 0;
210} 147}
211 148
@@ -265,11 +202,12 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
265 nouveau_dsm_priv.other_handle = dhandle; 202 nouveau_dsm_priv.other_handle = dhandle;
266 return false; 203 return false;
267 } 204 }
268 if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER)) 205 if (acpi_check_dsm(dhandle, nouveau_dsm_muid, 0x00000102,
206 1 << NOUVEAU_DSM_POWER))
269 retval |= NOUVEAU_DSM_HAS_MUX; 207 retval |= NOUVEAU_DSM_HAS_MUX;
270 208
271 if (nouveau_test_dsm(dhandle, nouveau_optimus_dsm, 209 if (acpi_check_dsm(dhandle, nouveau_op_dsm_muid, 0x00000100,
272 NOUVEAU_DSM_OPTIMUS_CAPS)) 210 1 << NOUVEAU_DSM_OPTIMUS_CAPS))
273 retval |= NOUVEAU_DSM_HAS_OPT; 211 retval |= NOUVEAU_DSM_HAS_OPT;
274 212
275 if (retval & NOUVEAU_DSM_HAS_OPT) { 213 if (retval & NOUVEAU_DSM_HAS_OPT) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 29c3efdfc7dd..25ea82f8def3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -610,7 +610,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
610 ret = nouveau_fence_sync(fence, chan); 610 ret = nouveau_fence_sync(fence, chan);
611 nouveau_fence_unref(&fence); 611 nouveau_fence_unref(&fence);
612 if (ret) 612 if (ret)
613 return ret; 613 goto fail_free;
614 614
615 if (new_bo != old_bo) { 615 if (new_bo != old_bo) {
616 ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM); 616 ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM);
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 98a9074b306b..77e9d07c55b6 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -25,18 +25,14 @@
25#include <linux/acpi.h> 25#include <linux/acpi.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/power_supply.h> 27#include <linux/power_supply.h>
28#include <acpi/acpi_drivers.h> 28#include <linux/vga_switcheroo.h>
29#include <acpi/acpi_bus.h>
30#include <acpi/video.h> 29#include <acpi/video.h>
31
32#include <drm/drmP.h> 30#include <drm/drmP.h>
33#include <drm/drm_crtc_helper.h> 31#include <drm/drm_crtc_helper.h>
34#include "radeon.h" 32#include "radeon.h"
35#include "radeon_acpi.h" 33#include "radeon_acpi.h"
36#include "atom.h" 34#include "atom.h"
37 35
38#include <linux/vga_switcheroo.h>
39
40#define ACPI_AC_CLASS "ac_adapter" 36#define ACPI_AC_CLASS "ac_adapter"
41 37
42extern void radeon_pm_acpi_event_handler(struct radeon_device *rdev); 38extern void radeon_pm_acpi_event_handler(struct radeon_device *rdev);