From: Luca Tettamanti <kronos.it@gmail.com>
To: Alex Deucher <alexdeucher@gmail.com>
Cc: Alex Deucher <alexander.deucher@amd.com>, joeyli <jlee@suse.com>,
dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] drm/radeon: add new AMD ACPI header and update relevant code
Date: Tue, 31 Jul 2012 22:05:20 +0200 [thread overview]
Message-ID: <20120731200520.GA5425@growl> (raw)
In-Reply-To: <CADnq5_NN8OcmyKDemO=Mv0as-02sYEHxxbn2G4XtSmpzEsnR0w@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 952 bytes --]
On Tue, Jul 31, 2012 at 09:58:04AM -0400, Alex Deucher wrote:
> On Tue, Jul 31, 2012 at 5:16 AM, Luca Tettamanti <kronos.it@gmail.com> wrote:
> > On Mon, Jul 30, 2012 at 10:45 PM, Alex Deucher <alexdeucher@gmail.com> wrote:
> >> Regarding patches 3 and 4, it might be easier to just store a pointer
> >> to the relevant encoder when you verify ATIF rather than walking the
> >> encoder list every time.
Done.
> > Makes sense, I was unsure about the lifetime of the encoders, but
> > AFAICS they're destroyed only when the module in unloaded.
>
> They are present for the life of the driver.
I had to move to call to radeon_acpi_init after radeon_modeset_init,
otherwise the encoders are not present yet (the tear down code path is
correct, acpi first, then modeset).
Latest and greatest version is attached; I fixed notifications when
using custom command codes (tested by Pali Rohár) and implemented your
suggestion.
Luca
[-- Attachment #2: 0001-drm-radeon-refactor-radeon_atif_call.patch --]
[-- Type: text/plain, Size: 2875 bytes --]
>From f0f8699eabee0d47b93fba14f8126b821cc106a5 Mon Sep 17 00:00:00 2001
From: Luca Tettamanti <kronos.it@gmail.com>
Date: Sun, 29 Jul 2012 17:04:43 +0200
Subject: [PATCH 1/4] drm/radeon: refactor radeon_atif_call
Don't hard-code function number, this will allow to reuse the function.
v2: add support for the 2nd parameter (from Lee, Chun-Yi
<jlee@suse.com>).
Signed-off-by: Luca Tettamanti <kronos.it@gmail.com>
---
drivers/gpu/drm/radeon/radeon_acpi.c | 38 ++++++++++++++++++++--------------
1 file changed, 23 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 5b32e49..158e514 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -14,23 +14,30 @@
#include <linux/vga_switcheroo.h>
/* Call the ATIF method
- *
- * Note: currently we discard the output
*/
-static int radeon_atif_call(acpi_handle handle)
+static union acpi_object *radeon_atif_call(acpi_handle handle, int function,
+ struct acpi_buffer *params)
{
acpi_status status;
union acpi_object atif_arg_elements[2];
struct acpi_object_list atif_arg;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
atif_arg.count = 2;
atif_arg.pointer = &atif_arg_elements[0];
atif_arg_elements[0].type = ACPI_TYPE_INTEGER;
- atif_arg_elements[0].integer.value = ATIF_FUNCTION_VERIFY_INTERFACE;
- atif_arg_elements[1].type = ACPI_TYPE_INTEGER;
- atif_arg_elements[1].integer.value = 0;
+ atif_arg_elements[0].integer.value = function;
+
+ if (params) {
+ atif_arg_elements[1].type = ACPI_TYPE_BUFFER;
+ atif_arg_elements[1].buffer.length = params->length;
+ atif_arg_elements[1].buffer.pointer = params->pointer;
+ } else {
+ /* We need a second fake parameter */
+ atif_arg_elements[1].type = ACPI_TYPE_INTEGER;
+ atif_arg_elements[1].integer.value = 0;
+ }
status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer);
@@ -39,18 +46,18 @@ static int radeon_atif_call(acpi_handle handle)
DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
acpi_format_exception(status));
kfree(buffer.pointer);
- return 1;
+ return NULL;
}
- kfree(buffer.pointer);
- return 0;
+ return buffer.pointer;
}
/* Call all ACPI methods here */
int radeon_acpi_init(struct radeon_device *rdev)
{
acpi_handle handle;
- int ret;
+ union acpi_object *info;
+ int ret = 0;
/* Get the device handle */
handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
@@ -60,10 +67,11 @@ int radeon_acpi_init(struct radeon_device *rdev)
return 0;
/* Call the ATIF method */
- ret = radeon_atif_call(handle);
- if (ret)
- return ret;
+ info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
+ if (!info)
+ ret = -EIO;
- return 0;
+ kfree(info);
+ return ret;
}
--
1.7.10.4
[-- Attachment #3: 0002-drm-radeon-implement-radeon_atif_verify_interface.patch --]
[-- Type: text/plain, Size: 5884 bytes --]
>From 427002ddf653b0abd0fb820b09322bf2a0b281af Mon Sep 17 00:00:00 2001
From: Luca Tettamanti <kronos.it@gmail.com>
Date: Mon, 30 Jul 2012 21:11:58 +0200
Subject: [PATCH 2/4] drm/radeon: implement radeon_atif_verify_interface
Wrap the call to VERIFY_INTERFACE and add the parsing of the support
vectors.
v2: use a packed struct for handling the output of ACPI calls, hides
ugly pointer arithmetics (Lee, Chun-Yi <jlee@suse.com>).
Signed-off-by: Luca Tettamanti <kronos.it@gmail.com>
---
drivers/gpu/drm/radeon/radeon.h | 40 +++++++++++++++++
drivers/gpu/drm/radeon/radeon_acpi.c | 79 +++++++++++++++++++++++++++++++---
2 files changed, 113 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index fefcca5..0db98eb 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1456,6 +1456,44 @@ struct r600_vram_scratch {
u64 gpu_addr;
};
+/*
+ * ACPI
+ */
+struct radeon_atif_notification_cfg {
+ bool enabled;
+ int command_code;
+};
+
+struct radeon_atif_notifications {
+ bool display_switch;
+ bool expansion_mode_change;
+ bool thermal_state;
+ bool forced_power_state;
+ bool system_power_state;
+ bool display_conf_change;
+ bool px_gfx_switch;
+ bool brightness_change;
+ bool dgpu_display_event;
+};
+
+struct radeon_atif_functions {
+ bool system_params;
+ bool sbios_requests;
+ bool select_active_disp;
+ bool lid_state;
+ bool get_tv_standard;
+ bool set_tv_standard;
+ bool get_panel_expansion_mode;
+ bool set_panel_expansion_mode;
+ bool temperature_change;
+ bool graphics_device_types;
+};
+
+struct radeon_atif {
+ struct radeon_atif_notifications notifications;
+ struct radeon_atif_functions functions;
+ struct radeon_atif_notification_cfg notification_cfg;
+};
/*
* Core structure, functions and helpers.
@@ -1548,6 +1586,8 @@ struct radeon_device {
unsigned debugfs_count;
/* virtual memory */
struct radeon_vm_manager vm_manager;
+ /* ACPI interface */
+ struct radeon_atif atif;
};
int 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 158e514..53c519d 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -13,6 +13,13 @@
#include <linux/vga_switcheroo.h>
+struct atif_verify_interface {
+ u16 size; /* structure size in bytes (includes size field) */
+ u16 version; /* version */
+ u32 notification_mask; /* supported notifications mask */
+ u32 function_bits; /* supported functions bit vector */
+} __packed;
+
/* Call the ATIF method
*/
static union acpi_object *radeon_atif_call(acpi_handle handle, int function,
@@ -52,12 +59,73 @@ static union acpi_object *radeon_atif_call(acpi_handle handle, int function,
return buffer.pointer;
}
+static void radeon_atif_parse_notification(struct radeon_atif_notifications *n, u32 mask)
+{
+ n->display_switch = mask & ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED;
+ n->expansion_mode_change = mask & ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED;
+ n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED;
+ n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED;
+ n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED;
+ n->display_conf_change = mask & ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED;
+ n->px_gfx_switch = mask & ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED;
+ n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED;
+ n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED;
+}
+
+static void radeon_atif_parse_functions(struct radeon_atif_functions *f, u32 mask)
+{
+ f->system_params = ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED;
+ f->sbios_requests = ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED;
+ f->select_active_disp = ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED;
+ f->lid_state = ATIF_GET_LID_STATE_SUPPORTED;
+ f->get_tv_standard = ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED;
+ f->set_tv_standard = ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED;
+ f->get_panel_expansion_mode = ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED;
+ f->set_panel_expansion_mode = ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED;
+ f->temperature_change = ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED;
+ f->graphics_device_types = ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED;
+}
+
+static int radeon_atif_verify_interface(acpi_handle handle,
+ struct radeon_atif *atif)
+{
+ union acpi_object *info;
+ struct atif_verify_interface output;
+ size_t size;
+ int err = 0;
+
+ info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
+ if (!info)
+ return -EIO;
+
+ memset(&output, 0, sizeof(output));
+
+ size = *(u16 *) info->buffer.pointer;
+ if (size < 12) {
+ DRM_INFO("ATIF buffer is too small: %lu\n", size);
+ err = -EINVAL;
+ goto out;
+ }
+ size = min(sizeof(output), size);
+
+ memcpy(&output, info->buffer.pointer, size);
+
+ /* TODO: check version? */
+ DRM_DEBUG_DRIVER("ATIF version %u\n", output.version);
+
+ radeon_atif_parse_notification(&atif->notifications, output.notification_mask);
+ radeon_atif_parse_functions(&atif->functions, output.function_bits);
+
+out:
+ kfree(info);
+ return err;
+}
+
/* Call all ACPI methods here */
int radeon_acpi_init(struct radeon_device *rdev)
{
acpi_handle handle;
- union acpi_object *info;
- int ret = 0;
+ int ret;
/* Get the device handle */
handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
@@ -67,11 +135,10 @@ int radeon_acpi_init(struct radeon_device *rdev)
return 0;
/* Call the ATIF method */
- info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
- if (!info)
- ret = -EIO;
+ ret = radeon_atif_verify_interface(handle, &rdev->atif);
+ if (ret)
+ DRM_DEBUG_DRIVER("Call to verify_interface failed: %d\n", ret);
- kfree(info);
return ret;
}
--
1.7.10.4
[-- Attachment #4: 0003-drm-radeon-implement-wrapper-for-GET_SYSTEM_PARAMS.patch --]
[-- Type: text/plain, Size: 3383 bytes --]
>From e83d04d1b60c5cf46611f6afc9680024e1dad73b Mon Sep 17 00:00:00 2001
From: Luca Tettamanti <kronos.it@gmail.com>
Date: Mon, 30 Jul 2012 21:16:06 +0200
Subject: [PATCH 3/4] drm/radeon: implement wrapper for GET_SYSTEM_PARAMS
Use GET_SYSTEM_PARAMS for retrieving the configuration for the system
BIOS notifications.
v2: packed struct (Lee, Chun-Yi <jlee@suse.com>)
Signed-off-by: Luca Tettamanti <kronos.it@gmail.com>
---
drivers/gpu/drm/radeon/radeon_acpi.c | 84 +++++++++++++++++++++++++++++++++-
1 file changed, 82 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 53c519d..3d025dd 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -20,6 +20,18 @@ struct atif_verify_interface {
u32 function_bits; /* supported functions bit vector */
} __packed;
+struct atif_system_params {
+ u16 size;
+ u32 valid_mask;
+ u32 flags;
+ u8 command_code;
+} __packed;
+
+#define ATIF_NOTIFY_MASK 0x3
+#define ATIF_NOTIFY_NONE 0
+#define ATIF_NOTIFY_81 1
+#define ATIF_NOTIFY_N 2
+
/* Call the ATIF method
*/
static union acpi_object *radeon_atif_call(acpi_handle handle, int function,
@@ -121,10 +133,56 @@ out:
return err;
}
+static int radeon_atif_get_notification_params(acpi_handle handle,
+ struct radeon_atif_notification_cfg *n)
+{
+ union acpi_object *info;
+ struct atif_system_params params;
+ size_t size;
+ int err = 0;
+
+ info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL);
+ if (!info) {
+ err = -EIO;
+ goto out;
+ }
+
+ size = *(u16 *) info->buffer.pointer;
+ if (size < 10) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ memset(¶ms, 0, sizeof(params));
+ size = min(sizeof(params), size);
+ memcpy(¶ms, info->buffer.pointer, size);
+
+ params.flags = params.flags & params.valid_mask;
+
+ if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) {
+ n->enabled = false;
+ n->command_code = 0;
+ } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) {
+ n->enabled = true;
+ n->command_code = 0x81;
+ } else {
+ if (size < 11) {
+ err = -EINVAL;
+ goto out;
+ }
+ n->command_code = params.command_code;
+ }
+
+out:
+ kfree(info);
+ return err;
+}
+
/* Call all ACPI methods here */
int radeon_acpi_init(struct radeon_device *rdev)
{
acpi_handle handle;
+ struct radeon_atif *atif = &rdev->atif;
int ret;
/* Get the device handle */
@@ -135,10 +193,32 @@ int radeon_acpi_init(struct radeon_device *rdev)
return 0;
/* Call the ATIF method */
- ret = radeon_atif_verify_interface(handle, &rdev->atif);
- if (ret)
+ ret = radeon_atif_verify_interface(handle, atif);
+ if (ret) {
DRM_DEBUG_DRIVER("Call to verify_interface failed: %d\n", ret);
+ goto out;
+ }
+
+ if (atif->functions.sbios_requests && !atif->functions.system_params) {
+ /* XXX check this workraround, if sbios request function is
+ * present we have to see how it's configured in the system
+ * params
+ */
+ atif->functions.system_params = true;
+ }
+
+ if (atif->functions.system_params) {
+ ret = radeon_atif_get_notification_params(handle,
+ &atif->notification_cfg);
+ if (ret) {
+ DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",
+ ret);
+ /* Disable notification */
+ atif->notification_cfg.enabled = false;
+ }
+ }
+out:
return ret;
}
--
1.7.10.4
[-- Attachment #5: 0004-drm-radeon-implement-handler-for-ACPI-event.patch --]
[-- Type: text/plain, Size: 10417 bytes --]
>From 88a3e35a0495cfff7d1a8ea23b779c621b3e1faa Mon Sep 17 00:00:00 2001
From: Luca Tettamanti <kronos.it@gmail.com>
Date: Mon, 30 Jul 2012 21:20:35 +0200
Subject: [PATCH 4/4] drm/radeon: implement handler for ACPI event
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Set up an handler for ACPI events and respond to brightness change
requests from the system BIOS.
v2: fix notification when using device-specific command codes
(tested by Pali Rohár <pali.rohar@gmail.com>); cache the encoder
controlling the backlight during the initialization to avoid searching
it every time (suggested by Alex Deucher).
Signed-off-by: Luca Tettamanti <kronos.it@gmail.com>
---
drivers/gpu/drm/radeon/atombios_encoders.c | 2 +-
drivers/gpu/drm/radeon/radeon.h | 1 +
drivers/gpu/drm/radeon/radeon_acpi.c | 132 +++++++++++++++++++++++++++-
drivers/gpu/drm/radeon/radeon_acpi.h | 6 ++
drivers/gpu/drm/radeon/radeon_kms.c | 16 ++--
drivers/gpu/drm/radeon/radeon_mode.h | 2 +
drivers/gpu/drm/radeon/radeon_pm.c | 4 +-
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 c2d3552..e4152d6 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,
WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch);
}
-static void
+void
atombios_set_panel_brightness(struct radeon_encoder *radeon_encoder)
{
struct drm_encoder *encoder = &radeon_encoder->base;
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 0db98eb..a57795b 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1493,6 +1493,7 @@ struct radeon_atif {
struct radeon_atif_notifications notifications;
struct radeon_atif_functions functions;
struct radeon_atif_notification_cfg notification_cfg;
+ struct radeon_encoder *backlight_ctl;
};
/*
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 3d025dd..9a97914 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -3,6 +3,7 @@
#include <linux/slab.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
+#include <acpi/video.h>
#include "drmP.h"
#include "drm.h"
@@ -10,6 +11,7 @@
#include "drm_crtc_helper.h"
#include "radeon.h"
#include "radeon_acpi.h"
+#include "atom.h"
#include <linux/vga_switcheroo.h>
@@ -21,10 +23,22 @@ struct atif_verify_interface {
} __packed;
struct atif_system_params {
- u16 size;
- u32 valid_mask;
- u32 flags;
- u8 command_code;
+ u16 size; /* structure size in bytes (includes size field) */
+ u32 valid_mask; /* valid flags mask */
+ u32 flags; /* flags */
+ u8 command_code; /* notify command code */
+} __packed;
+
+struct atif_sbios_requests {
+ u16 size; /* structure size in bytes (includes size field) */
+ u32 pending; /* pending sbios requests */
+ u8 panel_exp_mode; /* panel expansion mode */
+ u8 thermal_gfx; /* thermal state: target gfx controller */
+ u8 thermal_state; /* thermal state: state id (0: exit state, non-0: state) */
+ u8 forced_power_gfx; /* forced power state: target gfx controller */
+ u8 forced_power_state; /* forced power state: state id */
+ u8 system_power_src; /* system power source */
+ u8 backlight_level; /* panel backlight level (0-255) */
} __packed;
#define ATIF_NOTIFY_MASK 0x3
@@ -157,6 +171,8 @@ static int radeon_atif_get_notification_params(acpi_handle handle,
size = min(sizeof(params), size);
memcpy(¶ms, info->buffer.pointer, size);
+ DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n",
+ params.flags, params.valid_mask);
params.flags = params.flags & params.valid_mask;
if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) {
@@ -174,10 +190,91 @@ static int radeon_atif_get_notification_params(acpi_handle handle,
}
out:
+ DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n",
+ (n->enabled ? "enabled" : "disabled"),
+ n->command_code);
kfree(info);
return err;
}
+static int radeon_atif_get_sbios_requests(acpi_handle handle,
+ struct atif_sbios_requests *req)
+{
+ union acpi_object *info;
+ size_t size;
+ int count = 0;
+
+ info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL);
+ if (!info)
+ return -EIO;
+
+ size = *(u16 *)info->buffer.pointer;
+ if (size < 0xd) {
+ count = -EINVAL;
+ goto out;
+ }
+ memset(req, 0, sizeof(*req));
+
+ size = min(sizeof(*req), size);
+ memcpy(req, info->buffer.pointer, size);
+ DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending);
+
+ count = hweight32(req->pending);
+
+out:
+ kfree(info);
+ return count;
+}
+
+int radeon_atif_handler(struct radeon_device *rdev,
+ struct acpi_bus_event *event)
+{
+ struct radeon_atif *atif = &rdev->atif;
+ struct atif_sbios_requests req;
+ acpi_handle handle;
+ int count;
+
+ DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n",
+ event->device_class, event->type);
+
+ if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
+ return NOTIFY_DONE;
+
+ if (!atif->notification_cfg.enabled ||
+ event->type != atif->notification_cfg.command_code)
+ /* Not our event */
+ return NOTIFY_DONE;
+
+ /* Check pending SBIOS requests */
+ handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
+ count = radeon_atif_get_sbios_requests(handle, &req);
+
+ if (count <= 0)
+ return NOTIFY_DONE;
+
+ DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);
+
+ if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) {
+ struct radeon_encoder *enc = atif->backlight_ctl;
+
+ if (enc) {
+ struct radeon_encoder_atom_dig *dig = enc->enc_priv;
+ dig->backlight_level = req.backlight_level;
+
+ DRM_DEBUG_DRIVER("Changing brightness to %d\n",
+ req.backlight_level);
+
+ atombios_set_panel_brightness(enc);
+
+ backlight_force_update(dig->bl_dev,
+ BACKLIGHT_UPDATE_HOTKEY);
+ }
+ }
+ /* TODO: check other events */
+
+ return NOTIFY_OK;
+}
+
/* Call all ACPI methods here */
int radeon_acpi_init(struct radeon_device *rdev)
{
@@ -199,6 +296,33 @@ int radeon_acpi_init(struct radeon_device *rdev)
goto out;
}
+ if (atif->notifications.brightness_change) {
+ struct drm_encoder *tmp;
+ struct radeon_encoder *target = NULL;
+
+ /* Find the encoder controlling the brightness */
+ list_for_each_entry(tmp, &rdev->ddev->mode_config.encoder_list,
+ head) {
+ struct radeon_encoder *enc = to_radeon_encoder(tmp);
+ struct radeon_encoder_atom_dig *dig = enc->enc_priv;
+
+ if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
+ dig->bl_dev != NULL) {
+ target = enc;
+ break;
+ }
+ }
+
+ atif->backlight_ctl = target;
+ if (!target) {
+ /* Brightness change notification is enabled, but we
+ * didn't find a backlight controller, this should
+ * never happen.
+ */
+ DRM_ERROR("Cannot find a backlight controller\n");
+ }
+ }
+
if (atif->functions.sbios_requests && !atif->functions.system_params) {
/* XXX check this workraround, if sbios request function is
* 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 a42288d..df1f162 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.h
+++ b/drivers/gpu/drm/radeon/radeon_acpi.h
@@ -24,6 +24,12 @@
#ifndef RADEON_ACPI_H
#define RADEON_ACPI_H
+struct radeon_device;
+struct acpi_bus_event;
+
+int radeon_atif_handler(struct radeon_device *rdev,
+ struct acpi_bus_event *event);
+
/* AMD hw uses four ACPI control methods:
* 1. ATIF
* ARG0: (ACPI_INTEGER) function code
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 5c58d7d..a13b2eb 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -78,11 +78,6 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
goto out;
}
- /* Call ACPI methods */
- acpi_status = radeon_acpi_init(rdev);
- if (acpi_status)
- dev_dbg(&dev->pdev->dev, "Error during ACPI methods call\n");
-
/* Again modeset_init should fail only on fatal error
* otherwise it should provide enough functionalities
* for shadowfb to run
@@ -90,6 +85,17 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
r = radeon_modeset_init(rdev);
if (r)
dev_err(&dev->pdev->dev, "Fatal error during modeset init\n");
+
+ /* Call ACPI methods: require modeset init
+ * but failure is not fatal
+ */
+ if (!r) {
+ acpi_status = radeon_acpi_init(rdev);
+ if (acpi_status)
+ dev_dbg(&dev->pdev->dev,
+ "Error during ACPI methods call\n");
+ }
+
out:
if (r)
radeon_driver_unload_kms(dev);
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 129ed8e..ce91d62 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -697,6 +697,8 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode);
void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc);
+void atombios_set_panel_brightness(struct radeon_encoder *radeon_encoder);
+
/* legacy tv */
void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder,
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 5b37e28..8621748 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -22,6 +22,7 @@
*/
#include "drmP.h"
#include "radeon.h"
+#include "radeon_acpi.h"
#include "avivod.h"
#include "atom.h"
#ifdef CONFIG_ACPI
@@ -95,7 +96,8 @@ static int radeon_acpi_event(struct notifier_block *nb,
}
}
- return NOTIFY_OK;
+ /* Check for pending SBIOS requests */
+ return radeon_atif_handler(rdev, entry);
}
#endif
--
1.7.10.4
[-- Attachment #6: Type: text/plain, Size: 159 bytes --]
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2012-07-31 20:05 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-25 17:38 [PATCH] drm/radeon: add new AMD ACPI header and update relevant code alexdeucher
2012-07-26 12:58 ` Luca Tettamanti
2012-07-26 15:35 ` Alex Deucher
2012-07-26 19:33 ` Luca Tettamanti
2012-07-26 19:42 ` Alex Deucher
2012-07-26 19:58 ` Alex Deucher
2012-07-28 14:56 ` Luca Tettamanti
2012-07-28 21:29 ` Alex Deucher
2012-07-29 13:06 ` Luca Tettamanti
2012-07-30 14:20 ` Alex Deucher
2012-07-30 20:24 ` Luca Tettamanti
2012-07-30 20:30 ` Alex Deucher
2012-07-30 20:36 ` Luca Tettamanti
2012-07-30 20:45 ` Alex Deucher
2012-07-31 9:16 ` Luca Tettamanti
2012-07-31 13:58 ` Alex Deucher
2012-07-31 20:05 ` Luca Tettamanti [this message]
2012-07-31 21:33 ` Alex Deucher
2012-08-01 8:57 ` Luca Tettamanti
2012-08-01 13:56 ` Alex Deucher
2012-08-02 15:03 ` Alex Deucher
2012-08-02 16:31 ` Luca Tettamanti
2012-08-02 16:33 ` Alex Deucher
2012-08-02 20:54 ` Alex Deucher
2012-08-01 13:49 ` [PATCH/RFC] drm/radeon: ACPI: veto the keypress on ATIF events Luca Tettamanti
2012-08-01 14:02 ` Alex Deucher
2012-08-01 14:50 ` joeyli
2012-08-02 0:45 ` Zhang Rui
2012-08-02 13:46 ` Luca Tettamanti
2012-08-03 1:40 ` Zhang Rui
2012-08-03 1:45 ` Alex Deucher
2012-08-03 2:06 ` Zhang Rui
2012-07-29 19:33 ` [PATCH] drm/radeon: add new AMD ACPI header and update relevant code Luca Tettamanti
2012-07-30 14:29 ` Alex Deucher
2012-07-29 3:51 ` joeyli
2012-07-29 13:10 ` Luca Tettamanti
2012-07-30 8:32 ` joeyli
2012-07-30 14:16 ` Luca Tettamanti
2012-07-28 14:39 ` Pali Rohár
2012-07-27 2:50 ` joeyli
2012-07-27 3:31 ` Alex Deucher
2012-07-27 4:46 ` joeyli
2012-07-27 9:02 ` Luca Tettamanti
2012-07-27 13:21 ` Alex Deucher
2012-07-27 15:32 ` joeyli
2012-07-27 15:36 ` joeyli
2012-07-27 16:31 ` Alex Deucher
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120731200520.GA5425@growl \
--to=kronos.it@gmail.com \
--cc=alexander.deucher@amd.com \
--cc=alexdeucher@gmail.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=jlee@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.