aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2012-08-16 11:13:43 -0400
committerAlex Deucher <alexander.deucher@amd.com>2012-09-20 13:10:37 -0400
commite3a1592085988c60a2207eb492b89493573a0303 (patch)
tree15fe7eb1e2dd281ff0a03dd576145734efe4424a /drivers
parent82e029357d4726bbfb31b4169f82dcaea5fa3eba (diff)
drm/radeon: add initial support for ATCS ACPI methods
Just verify the interface and track what functions are supported. Not actually used yet. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h12
-rw-r--r--drivers/gpu/drm/radeon/radeon_acpi.c127
2 files changed, 138 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index b5b16878f0cf..99a5c8445014 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1464,6 +1464,17 @@ struct radeon_atif {
1464 struct radeon_encoder *backlight_ctl; 1464 struct radeon_encoder *backlight_ctl;
1465}; 1465};
1466 1466
1467struct radeon_atcs_functions {
1468 bool get_ext_state;
1469 bool pcie_perf_req;
1470 bool pcie_dev_rdy;
1471 bool pcie_bus_width;
1472};
1473
1474struct radeon_atcs {
1475 struct radeon_atcs_functions functions;
1476};
1477
1467/* 1478/*
1468 * Core structure, functions and helpers. 1479 * Core structure, functions and helpers.
1469 */ 1480 */
@@ -1557,6 +1568,7 @@ struct radeon_device {
1557 struct mutex gpu_clock_mutex; 1568 struct mutex gpu_clock_mutex;
1558 /* ACPI interface */ 1569 /* ACPI interface */
1559 struct radeon_atif atif; 1570 struct radeon_atif atif;
1571 struct radeon_atcs atcs;
1560}; 1572};
1561 1573
1562int radeon_device_init(struct radeon_device *rdev, 1574int radeon_device_init(struct radeon_device *rdev,
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 49a7d64be9e3..cae895ba8e2f 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -74,6 +74,12 @@ struct atif_sbios_requests {
74#define ATIF_NOTIFY_81 1 74#define ATIF_NOTIFY_81 1
75#define ATIF_NOTIFY_N 2 75#define ATIF_NOTIFY_N 2
76 76
77struct atcs_verify_interface {
78 u16 size; /* structure size in bytes (includes size field) */
79 u16 version; /* version */
80 u32 function_bits; /* supported functions bit vector */
81} __packed;
82
77/* Call the ATIF method 83/* Call the ATIF method
78 */ 84 */
79/** 85/**
@@ -383,6 +389,118 @@ int radeon_atif_handler(struct radeon_device *rdev,
383 return NOTIFY_BAD; 389 return NOTIFY_BAD;
384} 390}
385 391
392/* Call the ATCS method
393 */
394/**
395 * radeon_atcs_call - call an ATCS method
396 *
397 * @handle: acpi handle
398 * @function: the ATCS function to execute
399 * @params: ATCS function params
400 *
401 * Executes the requested ATCS function (all asics).
402 * Returns a pointer to the acpi output buffer.
403 */
404static union acpi_object *radeon_atcs_call(acpi_handle handle, int function,
405 struct acpi_buffer *params)
406{
407 acpi_status status;
408 union acpi_object atcs_arg_elements[2];
409 struct acpi_object_list atcs_arg;
410 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
411
412 atcs_arg.count = 2;
413 atcs_arg.pointer = &atcs_arg_elements[0];
414
415 atcs_arg_elements[0].type = ACPI_TYPE_INTEGER;
416 atcs_arg_elements[0].integer.value = function;
417
418 if (params) {
419 atcs_arg_elements[1].type = ACPI_TYPE_BUFFER;
420 atcs_arg_elements[1].buffer.length = params->length;
421 atcs_arg_elements[1].buffer.pointer = params->pointer;
422 } else {
423 /* We need a second fake parameter */
424 atcs_arg_elements[1].type = ACPI_TYPE_INTEGER;
425 atcs_arg_elements[1].integer.value = 0;
426 }
427
428 status = acpi_evaluate_object(handle, "ATCS", &atcs_arg, &buffer);
429
430 /* Fail only if calling the method fails and ATIF is supported */
431 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
432 DRM_DEBUG_DRIVER("failed to evaluate ATCS got %s\n",
433 acpi_format_exception(status));
434 kfree(buffer.pointer);
435 return NULL;
436 }
437
438 return buffer.pointer;
439}
440
441/**
442 * radeon_atcs_parse_functions - parse supported functions
443 *
444 * @f: supported functions struct
445 * @mask: supported functions mask from ATCS
446 *
447 * Use the supported functions mask from ATCS function
448 * ATCS_FUNCTION_VERIFY_INTERFACE to determine what functions
449 * are supported (all asics).
450 */
451static void radeon_atcs_parse_functions(struct radeon_atcs_functions *f, u32 mask)
452{
453 f->get_ext_state = mask & ATCS_GET_EXTERNAL_STATE_SUPPORTED;
454 f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED;
455 f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED;
456 f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED;
457}
458
459/**
460 * radeon_atcs_verify_interface - verify ATCS
461 *
462 * @handle: acpi handle
463 * @atcs: radeon atcs struct
464 *
465 * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function
466 * to initialize ATCS and determine what features are supported
467 * (all asics).
468 * returns 0 on success, error on failure.
469 */
470static int radeon_atcs_verify_interface(acpi_handle handle,
471 struct radeon_atcs *atcs)
472{
473 union acpi_object *info;
474 struct atcs_verify_interface output;
475 size_t size;
476 int err = 0;
477
478 info = radeon_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL);
479 if (!info)
480 return -EIO;
481
482 memset(&output, 0, sizeof(output));
483
484 size = *(u16 *) info->buffer.pointer;
485 if (size < 8) {
486 DRM_INFO("ATCS buffer is too small: %lu\n", size);
487 err = -EINVAL;
488 goto out;
489 }
490 size = min(sizeof(output), size);
491
492 memcpy(&output, info->buffer.pointer, size);
493
494 /* TODO: check version? */
495 DRM_DEBUG_DRIVER("ATCS version %u\n", output.version);
496
497 radeon_atcs_parse_functions(&atcs->functions, output.function_bits);
498
499out:
500 kfree(info);
501 return err;
502}
503
386/** 504/**
387 * radeon_acpi_event - handle notify events 505 * radeon_acpi_event - handle notify events
388 * 506 *
@@ -428,6 +546,7 @@ int radeon_acpi_init(struct radeon_device *rdev)
428{ 546{
429 acpi_handle handle; 547 acpi_handle handle;
430 struct radeon_atif *atif = &rdev->atif; 548 struct radeon_atif *atif = &rdev->atif;
549 struct radeon_atcs *atcs = &rdev->atcs;
431 int ret; 550 int ret;
432 551
433 /* Get the device handle */ 552 /* Get the device handle */
@@ -437,10 +556,16 @@ int radeon_acpi_init(struct radeon_device *rdev)
437 if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle) 556 if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle)
438 return 0; 557 return 0;
439 558
559 /* Call the ATCS method */
560 ret = radeon_atcs_verify_interface(handle, atcs);
561 if (ret) {
562 DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret);
563 }
564
440 /* Call the ATIF method */ 565 /* Call the ATIF method */
441 ret = radeon_atif_verify_interface(handle, atif); 566 ret = radeon_atif_verify_interface(handle, atif);
442 if (ret) { 567 if (ret) {
443 DRM_DEBUG_DRIVER("Call to verify_interface failed: %d\n", ret); 568 DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret);
444 goto out; 569 goto out;
445 } 570 }
446 571