From: joeyli <jlee@suse.com>
To: Luca Tettamanti <kronos.it@gmail.com>
Cc: Alex Deucher <alexander.deucher@amd.com>,
dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] drm/radeon: add new AMD ACPI header and update relevant code
Date: Mon, 30 Jul 2012 16:32:47 +0800 [thread overview]
Message-ID: <1343637167.6341.76.camel@linux-s257.site> (raw)
In-Reply-To: <20120729131058.GB12378@growl>
於 日,2012-07-29 於 15:10 +0200,Luca Tettamanti 提到:
> On Sun, Jul 29, 2012 at 11:51:48AM +0800, joeyli wrote:
> > Hi Luca,
> >
> > 於 六,2012-07-28 於 16:56 +0200,Luca Tettamanti 提到:
> > > I just found the first problem (probably a BIOS bug):
> > > ATIF_FUNCTION_GET_SYSTEM_PARAMETERS is implemented in the DSDT, but the
> > > corresponding bit ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED is not set :(
> > > I intended to use the method to set up the notification handler but now
> > > my BIOS says that it's not there even if it is...
> > > Can I assume some default values (e.g. notifications are enabled and will
> > > use 0x81 unless ATIF_FUNCTION_GET_SYSTEM_PARAMETERS says something
> > > different)?
> > >
> >
> > Did you check your DSDT for there have some "Notify (VGA, 0x81)"
> > statement in AFN0..AFN15?
> > If YES, I think that means your machine in case the 0x81 is for ATI used
> > by default.
>
> Yes, my point is that the nofication is there, but since
> GET_SYSTEM_PARAMETERS is not announced I have not way to check it.
> IOW, what is implemented in the DSDT does not match what is announced by
> VERIFY_INTERFACE.
> For reference this is the DSDT: http://pastebin.com/KKS7ZsTt
>
> Luca
>
Yes, saw the problem in your DSDT:
Method (AF00, 0, NotSerialized)
{
CreateWordField (ATIB, Zero, SSZE)
...
Store (0x80, NMSK)
Store (0x02, SFUN) <=== 10b, bit 0 is 0
Return (ATIB)
}
But, AF01 still supported in ATIF on this machine, maybe we should still
try GET_SYSTEM_PARAMETERS even the function vector set to 0?
No idea...
On the other hand,
My patch to avoid 0x81 event conflict with acpi/video driver like below.
This patch woks on my notebook. Your patches do much more things then
mine, so I think my patch just for reference.
There have a problem is:
If we want use acpi_notifier_call_chain to check does event consume by
any notifier in acpi's blocking notifier chain, then we need return
NOTIFY_BAD in radeon_acpi but not NOTIFY_OK.
So, I suggest radeon_acpi should register to acpi notifier chain by
itself but not append on radeon_acpi_event in radeon_pm.
And,
suggest also check the device class is ACPI_VIDEO_CLASS like following:
+static int radeon_acpi_video_event(struct notifier_block *nb,
...
+ if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
+ return NOTIFY_DONE;
+
Thanks a lot!
Joey Lee
>From 9c0c42ab8f37dafd3b512ca395b64bf39819d26b Mon Sep 17 00:00:00 2001
From: Lee, Chun-Yi <jlee@suse.com>
Date: Mon, 30 Jul 2012 16:17:05 +0800
Subject: [PATCH] drm/radeon avoid 0x81 acpi event conflict with acpi video
driver
drm/radeon avoid 0x81 acpi event conflict with acpi video driver
Signed-off-by: Lee, Chun-Yi <jlee@suse.com>
---
drivers/acpi/video.c | 6 +-
drivers/gpu/drm/radeon/radeon_acpi.c | 150 ++++++++++++++++++++++++++++++----
2 files changed, 139 insertions(+), 17 deletions(-)
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 1e0a9e1..e32492d 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -1457,7 +1457,8 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
acpi_video_device_enumerate(video);
acpi_video_device_rebind(video);
acpi_bus_generate_proc_event(device, event, 0);
- keycode = KEY_SWITCHVIDEOMODE;
+ if (!acpi_notifier_call_chain(device, event, 0))
+ keycode = KEY_SWITCHVIDEOMODE;
break;
case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */
@@ -1479,7 +1480,8 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
break;
}
- if (event != ACPI_VIDEO_NOTIFY_SWITCH)
+ if (event != ACPI_VIDEO_NOTIFY_SWITCH ||
+ event != ACPI_VIDEO_NOTIFY_PROBE)
acpi_notifier_call_chain(device, event, 0);
if (keycode) {
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 5b32e49..37ed5e1 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"
@@ -13,36 +14,150 @@
#include <linux/vga_switcheroo.h>
+struct atif_verify_output {
+ u16 size; /* structure size in bytes (includes size field) */
+ u16 version; /* version */
+ u32 notif_mask; /* supported notifications mask */
+ u32 func_bits; /* supported functions bit vector */
+} __attribute__((packed));
+
+static struct atif_verify_output *verify_output;
+
+struct atif_get_sysparams_output {
+ u16 size; /* structure size in bytes (includes size field) */
+ u32 valid_flags_mask; /* valid flags mask */
+ u32 flags; /* flags */
+ u8 notify_code; /* notify command code */
+} __attribute__((packed));
+
+static u8 notify_code;
+
/* Call the ATIF method
*
* Note: currently we discard the output
*/
-static int radeon_atif_call(acpi_handle handle)
+static int radeon_atif_call(acpi_handle handle, int function, struct acpi_buffer *params, struct acpi_buffer *output)
{
acpi_status status;
union acpi_object atif_arg_elements[2];
struct acpi_object_list atif_arg;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
+ union acpi_object *obj;
- atif_arg.count = 2;
+ atif_arg.count = 1;
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;
- status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer);
+ if (params) {
+ atif_arg.count = 2;
+ atif_arg_elements[1].type = ACPI_TYPE_BUFFER;
+ atif_arg_elements[1].buffer.length = params->length;
+ atif_arg_elements[1].buffer.pointer = params->pointer;
+ }
- /* Fail only if calling the method fails and ATIF is supported */
- if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
- DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
- acpi_format_exception(status));
- kfree(buffer.pointer);
+ status = acpi_evaluate_object(handle, "ATIF", &atif_arg, output);
+ if (ACPI_FAILURE(status))
return 1;
+
+ obj = (union acpi_object *) output->pointer;
+ if (!obj)
+ return 1;
+ else if (obj->type != ACPI_TYPE_BUFFER) {
+ kfree(obj);
+ return 1;
+ } else if (obj->buffer.length != 256) {
+ DRM_DEBUG_DRIVER("Unknown ATIF output buffer length %d\n", obj->buffer.length);
+ kfree(obj);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int radeon_atif_verify(acpi_handle handle)
+{
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct atif_verify_output *voutput;
+ union acpi_object *obj;
+ int ret;
+
+ /* evaluate the ATIF verify function */
+ ret = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL, &output);
+ if (ret) {
+ kfree(output.pointer);
+ return ret;
+ }
+
+ obj = (union acpi_object *) output.pointer;
+
+ voutput = (struct atif_verify_output *) obj->buffer.pointer;
+ verify_output = kzalloc(sizeof(struct atif_verify_output), GFP_KERNEL); /* TODO: kfree */
+ verify_output->size = voutput->size;
+ verify_output->version = voutput->version;
+ verify_output->notif_mask = voutput->notif_mask;
+ verify_output->func_bits = voutput->func_bits;
+
+ kfree(output.pointer);
+ return 0;
+}
+
+static int radeon_acpi_video_event(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ /* The only video events relevant to opregion are 0x81 or n. These indicate
+ either a docking event, lid switch or display switch request. In
+ Linux, these are handled by the dock, button and video drivers.
+ */
+
+ struct acpi_bus_event *event = data;
+ int ret = NOTIFY_BAD; /* Question: for fill acpi's blocking notifier chains */
+
+ if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
+ return NOTIFY_DONE;
+
+ if (event->type != notify_code)
+ return NOTIFY_DONE;
+
+ /* TODO: run anything should take care by radeon */
+
+ return ret;
+}
+
+static struct notifier_block radeon_acpi_notifier = {
+ .notifier_call = radeon_acpi_video_event,
+};
+
+static int radeon_atif_get_system_param(acpi_handle handle)
+{
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct atif_get_sysparams_output *params_output;
+ union acpi_object *obj;
+ u32 flags;
+ int ret;
+
+ /* evaluate the ATIF get system parameters function */
+ ret = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL, &output);
+ if (ret) {
+ kfree(output.pointer);
+ return ret;
}
- kfree(buffer.pointer);
+ obj = (union acpi_object *) output.pointer;
+
+ params_output = (struct atif_get_sysparams_output *) obj->buffer.pointer;
+ flags = params_output->flags;
+
+ if (flags) {
+ if (flags == 1)
+ notify_code = 0x81;
+ else if (flags == 2)
+ notify_code = params_output->notify_code;
+
+ register_acpi_notifier(&radeon_acpi_notifier);
+ }
+
+ kfree(output.pointer);
return 0;
}
@@ -59,11 +174,16 @@ int radeon_acpi_init(struct radeon_device *rdev)
if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle)
return 0;
- /* Call the ATIF method */
- ret = radeon_atif_call(handle);
+ /* Call the ATIF verify function */
+ ret = radeon_atif_verify(handle);
if (ret)
return ret;
+ if (verify_output->func_bits & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED)
+ ret = radeon_atif_get_system_param(handle);
+ if (ret)
+ return ret;
+
return 0;
}
--
1.7.7
_______________________________________________
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-30 8:35 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
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 [this message]
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=1343637167.6341.76.camel@linux-s257.site \
--to=jlee@suse.com \
--cc=alexander.deucher@amd.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=kronos.it@gmail.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.