aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/radeon/atombios_encoders.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_acpi.c132
-rw-r--r--drivers/gpu/drm/radeon/radeon_acpi.h6
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c16
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c4
7 files changed, 152 insertions, 11 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
index f3645e15ef11..370b2c4a7c86 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -72,7 +72,7 @@ radeon_atom_set_backlight_level_to_reg(struct radeon_device *rdev,
72 WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch); 72 WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch);
73} 73}
74 74
75static void 75void
76atombios_set_panel_brightness(struct radeon_encoder *radeon_encoder) 76atombios_set_panel_brightness(struct radeon_encoder *radeon_encoder)
77{ 77{
78 struct drm_encoder *encoder = &radeon_encoder->base; 78 struct drm_encoder *encoder = &radeon_encoder->base;
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 763f3333776e..dea5f08bd23b 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1461,6 +1461,7 @@ struct radeon_atif {
1461 struct radeon_atif_notifications notifications; 1461 struct radeon_atif_notifications notifications;
1462 struct radeon_atif_functions functions; 1462 struct radeon_atif_functions functions;
1463 struct radeon_atif_notification_cfg notification_cfg; 1463 struct radeon_atif_notification_cfg notification_cfg;
1464 struct radeon_encoder *backlight_ctl;
1464}; 1465};
1465 1466
1466/* 1467/*
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 0454eccc9c03..b052a556db79 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -26,6 +26,7 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <acpi/acpi_drivers.h> 27#include <acpi/acpi_drivers.h>
28#include <acpi/acpi_bus.h> 28#include <acpi/acpi_bus.h>
29#include <acpi/video.h>
29 30
30#include "drmP.h" 31#include "drmP.h"
31#include "drm.h" 32#include "drm.h"
@@ -33,6 +34,7 @@
33#include "drm_crtc_helper.h" 34#include "drm_crtc_helper.h"
34#include "radeon.h" 35#include "radeon.h"
35#include "radeon_acpi.h" 36#include "radeon_acpi.h"
37#include "atom.h"
36 38
37#include <linux/vga_switcheroo.h> 39#include <linux/vga_switcheroo.h>
38 40
@@ -44,10 +46,22 @@ struct atif_verify_interface {
44} __packed; 46} __packed;
45 47
46struct atif_system_params { 48struct atif_system_params {
47 u16 size; 49 u16 size; /* structure size in bytes (includes size field) */
48 u32 valid_mask; 50 u32 valid_mask; /* valid flags mask */
49 u32 flags; 51 u32 flags; /* flags */
50 u8 command_code; 52 u8 command_code; /* notify command code */
53} __packed;
54
55struct atif_sbios_requests {
56 u16 size; /* structure size in bytes (includes size field) */
57 u32 pending; /* pending sbios requests */
58 u8 panel_exp_mode; /* panel expansion mode */
59 u8 thermal_gfx; /* thermal state: target gfx controller */
60 u8 thermal_state; /* thermal state: state id (0: exit state, non-0: state) */
61 u8 forced_power_gfx; /* forced power state: target gfx controller */
62 u8 forced_power_state; /* forced power state: state id */
63 u8 system_power_src; /* system power source */
64 u8 backlight_level; /* panel backlight level (0-255) */
51} __packed; 65} __packed;
52 66
53#define ATIF_NOTIFY_MASK 0x3 67#define ATIF_NOTIFY_MASK 0x3
@@ -180,6 +194,8 @@ static int radeon_atif_get_notification_params(acpi_handle handle,
180 size = min(sizeof(params), size); 194 size = min(sizeof(params), size);
181 memcpy(&params, info->buffer.pointer, size); 195 memcpy(&params, info->buffer.pointer, size);
182 196
197 DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n",
198 params.flags, params.valid_mask);
183 params.flags = params.flags & params.valid_mask; 199 params.flags = params.flags & params.valid_mask;
184 200
185 if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) { 201 if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) {
@@ -198,10 +214,91 @@ static int radeon_atif_get_notification_params(acpi_handle handle,
198 } 214 }
199 215
200out: 216out:
217 DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n",
218 (n->enabled ? "enabled" : "disabled"),
219 n->command_code);
201 kfree(info); 220 kfree(info);
202 return err; 221 return err;
203} 222}
204 223
224static int radeon_atif_get_sbios_requests(acpi_handle handle,
225 struct atif_sbios_requests *req)
226{
227 union acpi_object *info;
228 size_t size;
229 int count = 0;
230
231 info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL);
232 if (!info)
233 return -EIO;
234
235 size = *(u16 *)info->buffer.pointer;
236 if (size < 0xd) {
237 count = -EINVAL;
238 goto out;
239 }
240 memset(req, 0, sizeof(*req));
241
242 size = min(sizeof(*req), size);
243 memcpy(req, info->buffer.pointer, size);
244 DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending);
245
246 count = hweight32(req->pending);
247
248out:
249 kfree(info);
250 return count;
251}
252
253int radeon_atif_handler(struct radeon_device *rdev,
254 struct acpi_bus_event *event)
255{
256 struct radeon_atif *atif = &rdev->atif;
257 struct atif_sbios_requests req;
258 acpi_handle handle;
259 int count;
260
261 DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n",
262 event->device_class, event->type);
263
264 if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
265 return NOTIFY_DONE;
266
267 if (!atif->notification_cfg.enabled ||
268 event->type != atif->notification_cfg.command_code)
269 /* Not our event */
270 return NOTIFY_DONE;
271
272 /* Check pending SBIOS requests */
273 handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
274 count = radeon_atif_get_sbios_requests(handle, &req);
275
276 if (count <= 0)
277 return NOTIFY_DONE;
278
279 DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);
280
281 if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) {
282 struct radeon_encoder *enc = atif->backlight_ctl;
283
284 if (enc) {
285 struct radeon_encoder_atom_dig *dig = enc->enc_priv;
286 dig->backlight_level = req.backlight_level;
287
288 DRM_DEBUG_DRIVER("Changing brightness to %d\n",
289 req.backlight_level);
290
291 atombios_set_panel_brightness(enc);
292
293 backlight_force_update(dig->bl_dev,
294 BACKLIGHT_UPDATE_HOTKEY);
295 }
296 }
297 /* TODO: check other events */
298
299 return NOTIFY_OK;
300}
301
205/* Call all ACPI methods here */ 302/* Call all ACPI methods here */
206int radeon_acpi_init(struct radeon_device *rdev) 303int radeon_acpi_init(struct radeon_device *rdev)
207{ 304{
@@ -223,6 +320,33 @@ int radeon_acpi_init(struct radeon_device *rdev)
223 goto out; 320 goto out;
224 } 321 }
225 322
323 if (atif->notifications.brightness_change) {
324 struct drm_encoder *tmp;
325 struct radeon_encoder *target = NULL;
326
327 /* Find the encoder controlling the brightness */
328 list_for_each_entry(tmp, &rdev->ddev->mode_config.encoder_list,
329 head) {
330 struct radeon_encoder *enc = to_radeon_encoder(tmp);
331 struct radeon_encoder_atom_dig *dig = enc->enc_priv;
332
333 if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
334 dig->bl_dev != NULL) {
335 target = enc;
336 break;
337 }
338 }
339
340 atif->backlight_ctl = target;
341 if (!target) {
342 /* Brightness change notification is enabled, but we
343 * didn't find a backlight controller, this should
344 * never happen.
345 */
346 DRM_ERROR("Cannot find a backlight controller\n");
347 }
348 }
349
226 if (atif->functions.sbios_requests && !atif->functions.system_params) { 350 if (atif->functions.sbios_requests && !atif->functions.system_params) {
227 /* XXX check this workraround, if sbios request function is 351 /* XXX check this workraround, if sbios request function is
228 * present we have to see how it's configured in the system 352 * present we have to see how it's configured in the system
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.h b/drivers/gpu/drm/radeon/radeon_acpi.h
index 642aa4719454..be4af76f213d 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.h
+++ b/drivers/gpu/drm/radeon/radeon_acpi.h
@@ -24,6 +24,12 @@
24#ifndef RADEON_ACPI_H 24#ifndef RADEON_ACPI_H
25#define RADEON_ACPI_H 25#define RADEON_ACPI_H
26 26
27struct radeon_device;
28struct acpi_bus_event;
29
30int radeon_atif_handler(struct radeon_device *rdev,
31 struct acpi_bus_event *event);
32
27/* AMD hw uses four ACPI control methods: 33/* AMD hw uses four ACPI control methods:
28 * 1. ATIF 34 * 1. ATIF
29 * ARG0: (ACPI_INTEGER) function code 35 * ARG0: (ACPI_INTEGER) function code
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 414b4acf6947..8c2471854cd7 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -103,11 +103,6 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
103 goto out; 103 goto out;
104 } 104 }
105 105
106 /* Call ACPI methods */
107 acpi_status = radeon_acpi_init(rdev);
108 if (acpi_status)
109 dev_dbg(&dev->pdev->dev, "Error during ACPI methods call\n");
110
111 /* Again modeset_init should fail only on fatal error 106 /* Again modeset_init should fail only on fatal error
112 * otherwise it should provide enough functionalities 107 * otherwise it should provide enough functionalities
113 * for shadowfb to run 108 * for shadowfb to run
@@ -115,6 +110,17 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
115 r = radeon_modeset_init(rdev); 110 r = radeon_modeset_init(rdev);
116 if (r) 111 if (r)
117 dev_err(&dev->pdev->dev, "Fatal error during modeset init\n"); 112 dev_err(&dev->pdev->dev, "Fatal error during modeset init\n");
113
114 /* Call ACPI methods: require modeset init
115 * but failure is not fatal
116 */
117 if (!r) {
118 acpi_status = radeon_acpi_init(rdev);
119 if (acpi_status)
120 dev_dbg(&dev->pdev->dev,
121 "Error during ACPI methods call\n");
122 }
123
118out: 124out:
119 if (r) 125 if (r)
120 radeon_driver_unload_kms(dev); 126 radeon_driver_unload_kms(dev);
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 5005057974b1..1f411c2609d8 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -698,6 +698,8 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder,
698 struct drm_display_mode *adjusted_mode); 698 struct drm_display_mode *adjusted_mode);
699void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc); 699void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc);
700 700
701void atombios_set_panel_brightness(struct radeon_encoder *radeon_encoder);
702
701/* legacy tv */ 703/* legacy tv */
702void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder, 704void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder,
703 uint32_t *h_total_disp, uint32_t *h_sync_strt_wid, 705 uint32_t *h_total_disp, uint32_t *h_sync_strt_wid,
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 2c2c901226f4..14e544e0eb31 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -22,6 +22,7 @@
22 */ 22 */
23#include "drmP.h" 23#include "drmP.h"
24#include "radeon.h" 24#include "radeon.h"
25#include "radeon_acpi.h"
25#include "avivod.h" 26#include "avivod.h"
26#include "atom.h" 27#include "atom.h"
27#ifdef CONFIG_ACPI 28#ifdef CONFIG_ACPI
@@ -94,7 +95,8 @@ static int radeon_acpi_event(struct notifier_block *nb,
94 } 95 }
95 } 96 }
96 97
97 return NOTIFY_OK; 98 /* Check for pending SBIOS requests */
99 return radeon_atif_handler(rdev, entry);
98} 100}
99#endif 101#endif
100 102