Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
radeon_acpi.c
Go to the documentation of this file.
1 /*
2  * Copyright 2012 Advanced Micro Devices, Inc.
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 shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23 
24 #include <linux/pci.h>
25 #include <linux/acpi.h>
26 #include <linux/slab.h>
27 #include <linux/power_supply.h>
28 #include <acpi/acpi_drivers.h>
29 #include <acpi/acpi_bus.h>
30 #include <acpi/video.h>
31 
32 #include <drm/drmP.h>
33 #include <drm/drm_crtc_helper.h>
34 #include "radeon.h"
35 #include "radeon_acpi.h"
36 #include "atom.h"
37 
38 #include <linux/vga_switcheroo.h>
39 
40 #define ACPI_AC_CLASS "ac_adapter"
41 
43 
45  u16 size; /* structure size in bytes (includes size field) */
46  u16 version; /* version */
47  u32 notification_mask; /* supported notifications mask */
48  u32 function_bits; /* supported functions bit vector */
49 } __packed;
50 
52  u16 size; /* structure size in bytes (includes size field) */
53  u32 valid_mask; /* valid flags mask */
54  u32 flags; /* flags */
55  u8 command_code; /* notify command code */
56 } __packed;
57 
59  u16 size; /* structure size in bytes (includes size field) */
60  u32 pending; /* pending sbios requests */
61  u8 panel_exp_mode; /* panel expansion mode */
62  u8 thermal_gfx; /* thermal state: target gfx controller */
63  u8 thermal_state; /* thermal state: state id (0: exit state, non-0: state) */
64  u8 forced_power_gfx; /* forced power state: target gfx controller */
65  u8 forced_power_state; /* forced power state: state id */
66  u8 system_power_src; /* system power source */
67  u8 backlight_level; /* panel backlight level (0-255) */
68 } __packed;
69 
70 #define ATIF_NOTIFY_MASK 0x3
71 #define ATIF_NOTIFY_NONE 0
72 #define ATIF_NOTIFY_81 1
73 #define ATIF_NOTIFY_N 2
74 
76  u16 size; /* structure size in bytes (includes size field) */
77  u16 version; /* version */
78  u32 function_bits; /* supported functions bit vector */
79 } __packed;
80 
81 /* Call the ATIF method
82  */
93 static union acpi_object *radeon_atif_call(acpi_handle handle, int function,
94  struct acpi_buffer *params)
95 {
97  union acpi_object atif_arg_elements[2];
98  struct acpi_object_list atif_arg;
99  struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
100 
101  atif_arg.count = 2;
102  atif_arg.pointer = &atif_arg_elements[0];
103 
104  atif_arg_elements[0].type = ACPI_TYPE_INTEGER;
105  atif_arg_elements[0].integer.value = function;
106 
107  if (params) {
108  atif_arg_elements[1].type = ACPI_TYPE_BUFFER;
109  atif_arg_elements[1].buffer.length = params->length;
110  atif_arg_elements[1].buffer.pointer = params->pointer;
111  } else {
112  /* We need a second fake parameter */
113  atif_arg_elements[1].type = ACPI_TYPE_INTEGER;
114  atif_arg_elements[1].integer.value = 0;
115  }
116 
117  status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer);
118 
119  /* Fail only if calling the method fails and ATIF is supported */
120  if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
121  DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
122  acpi_format_exception(status));
123  kfree(buffer.pointer);
124  return NULL;
125  }
126 
127  return buffer.pointer;
128 }
129 
140 static void radeon_atif_parse_notification(struct radeon_atif_notifications *n, u32 mask)
141 {
151 }
152 
163 static void radeon_atif_parse_functions(struct radeon_atif_functions *f, u32 mask)
164 {
175 }
176 
188 static int radeon_atif_verify_interface(acpi_handle handle,
189  struct radeon_atif *atif)
190 {
191  union acpi_object *info;
193  size_t size;
194  int err = 0;
195 
196  info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
197  if (!info)
198  return -EIO;
199 
200  memset(&output, 0, sizeof(output));
201 
202  size = *(u16 *) info->buffer.pointer;
203  if (size < 12) {
204  DRM_INFO("ATIF buffer is too small: %zu\n", size);
205  err = -EINVAL;
206  goto out;
207  }
208  size = min(sizeof(output), size);
209 
210  memcpy(&output, info->buffer.pointer, size);
211 
212  /* TODO: check version? */
213  DRM_DEBUG_DRIVER("ATIF version %u\n", output.version);
214 
215  radeon_atif_parse_notification(&atif->notifications, output.notification_mask);
216  radeon_atif_parse_functions(&atif->functions, output.function_bits);
217 
218 out:
219  kfree(info);
220  return err;
221 }
222 
235 static int radeon_atif_get_notification_params(acpi_handle handle,
237 {
238  union acpi_object *info;
239  struct atif_system_params params;
240  size_t size;
241  int err = 0;
242 
243  info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL);
244  if (!info) {
245  err = -EIO;
246  goto out;
247  }
248 
249  size = *(u16 *) info->buffer.pointer;
250  if (size < 10) {
251  err = -EINVAL;
252  goto out;
253  }
254 
255  memset(&params, 0, sizeof(params));
256  size = min(sizeof(params), size);
257  memcpy(&params, info->buffer.pointer, size);
258 
259  DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n",
260  params.flags, params.valid_mask);
261  params.flags = params.flags & params.valid_mask;
262 
263  if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) {
264  n->enabled = false;
265  n->command_code = 0;
266  } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) {
267  n->enabled = true;
268  n->command_code = 0x81;
269  } else {
270  if (size < 11) {
271  err = -EINVAL;
272  goto out;
273  }
274  n->enabled = true;
275  n->command_code = params.command_code;
276  }
277 
278 out:
279  DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n",
280  (n->enabled ? "enabled" : "disabled"),
281  n->command_code);
282  kfree(info);
283  return err;
284 }
285 
297 static int radeon_atif_get_sbios_requests(acpi_handle handle,
298  struct atif_sbios_requests *req)
299 {
300  union acpi_object *info;
301  size_t size;
302  int count = 0;
303 
304  info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL);
305  if (!info)
306  return -EIO;
307 
308  size = *(u16 *)info->buffer.pointer;
309  if (size < 0xd) {
310  count = -EINVAL;
311  goto out;
312  }
313  memset(req, 0, sizeof(*req));
314 
315  size = min(sizeof(*req), size);
316  memcpy(req, info->buffer.pointer, size);
317  DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending);
318 
319  count = hweight32(req->pending);
320 
321 out:
322  kfree(info);
323  return count;
324 }
325 
337  struct acpi_bus_event *event)
338 {
339  struct radeon_atif *atif = &rdev->atif;
340  struct atif_sbios_requests req;
342  int count;
343 
344  DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n",
345  event->device_class, event->type);
346 
347  if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
348  return NOTIFY_DONE;
349 
350  if (!atif->notification_cfg.enabled ||
351  event->type != atif->notification_cfg.command_code)
352  /* Not our event */
353  return NOTIFY_DONE;
354 
355  /* Check pending SBIOS requests */
356  handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
357  count = radeon_atif_get_sbios_requests(handle, &req);
358 
359  if (count <= 0)
360  return NOTIFY_DONE;
361 
362  DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);
363 
365  struct radeon_encoder *enc = atif->encoder_for_bl;
366 
367  if (enc) {
368  DRM_DEBUG_DRIVER("Changing brightness to %d\n",
369  req.backlight_level);
370 
372 
373 #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
374  if (rdev->is_atom_bios) {
375  struct radeon_encoder_atom_dig *dig = enc->enc_priv;
378  } else {
379  struct radeon_encoder_lvds *dig = enc->enc_priv;
382  }
383 #endif
384  }
385  }
386  /* TODO: check other events */
387 
388  /* We've handled the event, stop the notifier chain. The ACPI interface
389  * overloads ACPI_VIDEO_NOTIFY_PROBE, we don't want to send that to
390  * userspace if the event was generated only to signal a SBIOS
391  * request.
392  */
393  return NOTIFY_BAD;
394 }
395 
396 /* Call the ATCS method
397  */
408 static union acpi_object *radeon_atcs_call(acpi_handle handle, int function,
409  struct acpi_buffer *params)
410 {
412  union acpi_object atcs_arg_elements[2];
413  struct acpi_object_list atcs_arg;
414  struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
415 
416  atcs_arg.count = 2;
417  atcs_arg.pointer = &atcs_arg_elements[0];
418 
419  atcs_arg_elements[0].type = ACPI_TYPE_INTEGER;
420  atcs_arg_elements[0].integer.value = function;
421 
422  if (params) {
423  atcs_arg_elements[1].type = ACPI_TYPE_BUFFER;
424  atcs_arg_elements[1].buffer.length = params->length;
425  atcs_arg_elements[1].buffer.pointer = params->pointer;
426  } else {
427  /* We need a second fake parameter */
428  atcs_arg_elements[1].type = ACPI_TYPE_INTEGER;
429  atcs_arg_elements[1].integer.value = 0;
430  }
431 
432  status = acpi_evaluate_object(handle, "ATCS", &atcs_arg, &buffer);
433 
434  /* Fail only if calling the method fails and ATIF is supported */
435  if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
436  DRM_DEBUG_DRIVER("failed to evaluate ATCS got %s\n",
437  acpi_format_exception(status));
438  kfree(buffer.pointer);
439  return NULL;
440  }
441 
442  return buffer.pointer;
443 }
444 
455 static void radeon_atcs_parse_functions(struct radeon_atcs_functions *f, u32 mask)
456 {
461 }
462 
474 static int radeon_atcs_verify_interface(acpi_handle handle,
475  struct radeon_atcs *atcs)
476 {
477  union acpi_object *info;
479  size_t size;
480  int err = 0;
481 
482  info = radeon_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL);
483  if (!info)
484  return -EIO;
485 
486  memset(&output, 0, sizeof(output));
487 
488  size = *(u16 *) info->buffer.pointer;
489  if (size < 8) {
490  DRM_INFO("ATCS buffer is too small: %zu\n", size);
491  err = -EINVAL;
492  goto out;
493  }
494  size = min(sizeof(output), size);
495 
496  memcpy(&output, info->buffer.pointer, size);
497 
498  /* TODO: check version? */
499  DRM_DEBUG_DRIVER("ATCS version %u\n", output.version);
500 
501  radeon_atcs_parse_functions(&atcs->functions, output.function_bits);
502 
503 out:
504  kfree(info);
505  return err;
506 }
507 
519 static int radeon_acpi_event(struct notifier_block *nb,
520  unsigned long val,
521  void *data)
522 {
523  struct radeon_device *rdev = container_of(nb, struct radeon_device, acpi_nb);
524  struct acpi_bus_event *entry = (struct acpi_bus_event *)data;
525 
526  if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) {
528  DRM_DEBUG_DRIVER("pm: AC\n");
529  else
530  DRM_DEBUG_DRIVER("pm: DC\n");
531 
533  }
534 
535  /* Check for pending SBIOS requests */
536  return radeon_atif_handler(rdev, entry);
537 }
538 
539 /* Call all ACPI methods here */
550 {
552  struct radeon_atif *atif = &rdev->atif;
553  struct radeon_atcs *atcs = &rdev->atcs;
554  int ret;
555 
556  /* Get the device handle */
557  handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
558 
559  /* No need to proceed if we're sure that ATIF is not supported */
560  if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle)
561  return 0;
562 
563  /* Call the ATCS method */
564  ret = radeon_atcs_verify_interface(handle, atcs);
565  if (ret) {
566  DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret);
567  }
568 
569  /* Call the ATIF method */
570  ret = radeon_atif_verify_interface(handle, atif);
571  if (ret) {
572  DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret);
573  goto out;
574  }
575 
576  if (atif->notifications.brightness_change) {
577  struct drm_encoder *tmp;
578  struct radeon_encoder *target = NULL;
579 
580  /* Find the encoder controlling the brightness */
581  list_for_each_entry(tmp, &rdev->ddev->mode_config.encoder_list,
582  head) {
583  struct radeon_encoder *enc = to_radeon_encoder(tmp);
584 
585  if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
586  enc->enc_priv) {
587  if (rdev->is_atom_bios) {
588  struct radeon_encoder_atom_dig *dig = enc->enc_priv;
589  if (dig->bl_dev) {
590  target = enc;
591  break;
592  }
593  } else {
594  struct radeon_encoder_lvds *dig = enc->enc_priv;
595  if (dig->bl_dev) {
596  target = enc;
597  break;
598  }
599  }
600  }
601  }
602 
603  atif->encoder_for_bl = target;
604  if (!target) {
605  /* Brightness change notification is enabled, but we
606  * didn't find a backlight controller, this should
607  * never happen.
608  */
609  DRM_ERROR("Cannot find a backlight controller\n");
610  }
611  }
612 
613  if (atif->functions.sbios_requests && !atif->functions.system_params) {
614  /* XXX check this workraround, if sbios request function is
615  * present we have to see how it's configured in the system
616  * params
617  */
618  atif->functions.system_params = true;
619  }
620 
621  if (atif->functions.system_params) {
622  ret = radeon_atif_get_notification_params(handle,
623  &atif->notification_cfg);
624  if (ret) {
625  DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",
626  ret);
627  /* Disable notification */
628  atif->notification_cfg.enabled = false;
629  }
630  }
631 
632 out:
633  rdev->acpi_nb.notifier_call = radeon_acpi_event;
635 
636  return ret;
637 }
638 
646 void radeon_acpi_fini(struct radeon_device *rdev)
647 {
649 }