diff options
author | Luca Tettamanti <kronos.it@gmail.com> | 2012-08-16 11:11:18 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2012-09-20 13:10:35 -0400 |
commit | fd64ca8a9d9d7e92fc81fe0b23dcf324246fd356 (patch) | |
tree | 7b381a32ab4f034b7583be4aa2b1c3b58ae32b96 /drivers/gpu/drm | |
parent | 86504672f7d79986a8ef618fb120044220e3d1eb (diff) |
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>).
v3: fix radeon_atif_parse_functions handling (Alex Deucher)
Signed-off-by: Luca Tettamanti <kronos.it@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 40 | ||||
-rw-r--r-- | 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 5dbd591818fe..763f3333776e 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1424,6 +1424,44 @@ struct r600_vram_scratch { | |||
1424 | u64 gpu_addr; | 1424 | u64 gpu_addr; |
1425 | }; | 1425 | }; |
1426 | 1426 | ||
1427 | /* | ||
1428 | * ACPI | ||
1429 | */ | ||
1430 | struct radeon_atif_notification_cfg { | ||
1431 | bool enabled; | ||
1432 | int command_code; | ||
1433 | }; | ||
1434 | |||
1435 | struct radeon_atif_notifications { | ||
1436 | bool display_switch; | ||
1437 | bool expansion_mode_change; | ||
1438 | bool thermal_state; | ||
1439 | bool forced_power_state; | ||
1440 | bool system_power_state; | ||
1441 | bool display_conf_change; | ||
1442 | bool px_gfx_switch; | ||
1443 | bool brightness_change; | ||
1444 | bool dgpu_display_event; | ||
1445 | }; | ||
1446 | |||
1447 | struct radeon_atif_functions { | ||
1448 | bool system_params; | ||
1449 | bool sbios_requests; | ||
1450 | bool select_active_disp; | ||
1451 | bool lid_state; | ||
1452 | bool get_tv_standard; | ||
1453 | bool set_tv_standard; | ||
1454 | bool get_panel_expansion_mode; | ||
1455 | bool set_panel_expansion_mode; | ||
1456 | bool temperature_change; | ||
1457 | bool graphics_device_types; | ||
1458 | }; | ||
1459 | |||
1460 | struct radeon_atif { | ||
1461 | struct radeon_atif_notifications notifications; | ||
1462 | struct radeon_atif_functions functions; | ||
1463 | struct radeon_atif_notification_cfg notification_cfg; | ||
1464 | }; | ||
1427 | 1465 | ||
1428 | /* | 1466 | /* |
1429 | * Core structure, functions and helpers. | 1467 | * Core structure, functions and helpers. |
@@ -1516,6 +1554,8 @@ struct radeon_device { | |||
1516 | /* virtual memory */ | 1554 | /* virtual memory */ |
1517 | struct radeon_vm_manager vm_manager; | 1555 | struct radeon_vm_manager vm_manager; |
1518 | struct mutex gpu_clock_mutex; | 1556 | struct mutex gpu_clock_mutex; |
1557 | /* ACPI interface */ | ||
1558 | struct radeon_atif atif; | ||
1519 | }; | 1559 | }; |
1520 | 1560 | ||
1521 | int radeon_device_init(struct radeon_device *rdev, | 1561 | 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 f7b511dcba30..2f6cef2acadc 100644 --- a/drivers/gpu/drm/radeon/radeon_acpi.c +++ b/drivers/gpu/drm/radeon/radeon_acpi.c | |||
@@ -36,6 +36,13 @@ | |||
36 | 36 | ||
37 | #include <linux/vga_switcheroo.h> | 37 | #include <linux/vga_switcheroo.h> |
38 | 38 | ||
39 | struct atif_verify_interface { | ||
40 | u16 size; /* structure size in bytes (includes size field) */ | ||
41 | u16 version; /* version */ | ||
42 | u32 notification_mask; /* supported notifications mask */ | ||
43 | u32 function_bits; /* supported functions bit vector */ | ||
44 | } __packed; | ||
45 | |||
39 | /* Call the ATIF method | 46 | /* Call the ATIF method |
40 | */ | 47 | */ |
41 | static union acpi_object *radeon_atif_call(acpi_handle handle, int function, | 48 | static union acpi_object *radeon_atif_call(acpi_handle handle, int function, |
@@ -75,12 +82,73 @@ static union acpi_object *radeon_atif_call(acpi_handle handle, int function, | |||
75 | return buffer.pointer; | 82 | return buffer.pointer; |
76 | } | 83 | } |
77 | 84 | ||
85 | static void radeon_atif_parse_notification(struct radeon_atif_notifications *n, u32 mask) | ||
86 | { | ||
87 | n->display_switch = mask & ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED; | ||
88 | n->expansion_mode_change = mask & ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED; | ||
89 | n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED; | ||
90 | n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED; | ||
91 | n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED; | ||
92 | n->display_conf_change = mask & ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED; | ||
93 | n->px_gfx_switch = mask & ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED; | ||
94 | n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED; | ||
95 | n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED; | ||
96 | } | ||
97 | |||
98 | static void radeon_atif_parse_functions(struct radeon_atif_functions *f, u32 mask) | ||
99 | { | ||
100 | f->system_params = mask & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED; | ||
101 | f->sbios_requests = mask & ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED; | ||
102 | f->select_active_disp = mask & ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED; | ||
103 | f->lid_state = mask & ATIF_GET_LID_STATE_SUPPORTED; | ||
104 | f->get_tv_standard = mask & ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED; | ||
105 | f->set_tv_standard = mask & ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED; | ||
106 | f->get_panel_expansion_mode = mask & ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED; | ||
107 | f->set_panel_expansion_mode = mask & ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED; | ||
108 | f->temperature_change = mask & ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED; | ||
109 | f->graphics_device_types = mask & ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED; | ||
110 | } | ||
111 | |||
112 | static int radeon_atif_verify_interface(acpi_handle handle, | ||
113 | struct radeon_atif *atif) | ||
114 | { | ||
115 | union acpi_object *info; | ||
116 | struct atif_verify_interface output; | ||
117 | size_t size; | ||
118 | int err = 0; | ||
119 | |||
120 | info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); | ||
121 | if (!info) | ||
122 | return -EIO; | ||
123 | |||
124 | memset(&output, 0, sizeof(output)); | ||
125 | |||
126 | size = *(u16 *) info->buffer.pointer; | ||
127 | if (size < 12) { | ||
128 | DRM_INFO("ATIF buffer is too small: %lu\n", size); | ||
129 | err = -EINVAL; | ||
130 | goto out; | ||
131 | } | ||
132 | size = min(sizeof(output), size); | ||
133 | |||
134 | memcpy(&output, info->buffer.pointer, size); | ||
135 | |||
136 | /* TODO: check version? */ | ||
137 | DRM_DEBUG_DRIVER("ATIF version %u\n", output.version); | ||
138 | |||
139 | radeon_atif_parse_notification(&atif->notifications, output.notification_mask); | ||
140 | radeon_atif_parse_functions(&atif->functions, output.function_bits); | ||
141 | |||
142 | out: | ||
143 | kfree(info); | ||
144 | return err; | ||
145 | } | ||
146 | |||
78 | /* Call all ACPI methods here */ | 147 | /* Call all ACPI methods here */ |
79 | int radeon_acpi_init(struct radeon_device *rdev) | 148 | int radeon_acpi_init(struct radeon_device *rdev) |
80 | { | 149 | { |
81 | acpi_handle handle; | 150 | acpi_handle handle; |
82 | union acpi_object *info; | 151 | int ret; |
83 | int ret = 0; | ||
84 | 152 | ||
85 | /* Get the device handle */ | 153 | /* Get the device handle */ |
86 | handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); | 154 | handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); |
@@ -90,11 +158,10 @@ int radeon_acpi_init(struct radeon_device *rdev) | |||
90 | return 0; | 158 | return 0; |
91 | 159 | ||
92 | /* Call the ATIF method */ | 160 | /* Call the ATIF method */ |
93 | info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); | 161 | ret = radeon_atif_verify_interface(handle, &rdev->atif); |
94 | if (!info) | 162 | if (ret) |
95 | ret = -EIO; | 163 | DRM_DEBUG_DRIVER("Call to verify_interface failed: %d\n", ret); |
96 | 164 | ||
97 | kfree(info); | ||
98 | return ret; | 165 | return ret; |
99 | } | 166 | } |
100 | 167 | ||