| @@ -1,856 +1,858 @@ | | | @@ -1,856 +1,858 @@ |
1 | /* $NetBSD: radeon_acpi.c,v 1.5 2024/04/16 14:34:02 riastradh Exp $ */ | | 1 | /* $NetBSD: radeon_acpi.c,v 1.6 2024/04/18 23:33:15 riastradh Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright 2012 Advanced Micro Devices, Inc. | | 4 | * Copyright 2012 Advanced Micro Devices, Inc. |
5 | * | | 5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a | | 6 | * Permission is hereby granted, free of charge, to any person obtaining a |
7 | * copy of this software and associated documentation files (the "Software"), | | 7 | * copy of this software and associated documentation files (the "Software"), |
8 | * to deal in the Software without restriction, including without limitation | | 8 | * to deal in the Software without restriction, including without limitation |
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | | 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
10 | * and/or sell copies of the Software, and to permit persons to whom the | | 10 | * and/or sell copies of the Software, and to permit persons to whom the |
11 | * Software is furnished to do so, subject to the following conditions: | | 11 | * Software is furnished to do so, subject to the following conditions: |
12 | * | | 12 | * |
13 | * The above copyright notice and this permission notice shall be included in | | 13 | * The above copyright notice and this permission notice shall be included in |
14 | * all copies or substantial portions of the Software. | | 14 | * all copies or substantial portions of the Software. |
15 | * | | 15 | * |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | | 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | | 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
19 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | | 19 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | | 20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | | 21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
22 | * OTHER DEALINGS IN THE SOFTWARE. | | 22 | * OTHER DEALINGS IN THE SOFTWARE. |
23 | * | | 23 | * |
24 | */ | | 24 | */ |
25 | | | 25 | |
26 | #include <sys/cdefs.h> | | 26 | #include <sys/cdefs.h> |
27 | __KERNEL_RCSID(0, "$NetBSD: radeon_acpi.c,v 1.5 2024/04/16 14:34:02 riastradh Exp $"); | | 27 | __KERNEL_RCSID(0, "$NetBSD: radeon_acpi.c,v 1.6 2024/04/18 23:33:15 riastradh Exp $"); |
28 | | | 28 | |
29 | #include <linux/acpi.h> | | 29 | #include <linux/acpi.h> |
30 | #include <linux/pci.h> | | 30 | #include <linux/pci.h> |
31 | #include <linux/pm_runtime.h> | | 31 | #include <linux/pm_runtime.h> |
32 | #include <linux/power_supply.h> | | 32 | #include <linux/power_supply.h> |
33 | #include <linux/slab.h> | | 33 | #include <linux/slab.h> |
34 | | | 34 | |
35 | #include <acpi/acpi_bus.h> | | 35 | #include <acpi/acpi_bus.h> |
36 | #include <acpi/video.h> | | 36 | #include <acpi/video.h> |
37 | | | 37 | |
38 | #include <drm/drm_crtc_helper.h> | | 38 | #include <drm/drm_crtc_helper.h> |
39 | #include <drm/drm_probe_helper.h> | | 39 | #include <drm/drm_probe_helper.h> |
40 | | | 40 | |
41 | #include "atom.h" | | 41 | #include "atom.h" |
42 | #include "radeon.h" | | 42 | #include "radeon.h" |
43 | #include "radeon_acpi.h" | | 43 | #include "radeon_acpi.h" |
44 | | | 44 | |
45 | #ifdef __NetBSD__ | | 45 | #ifdef __NetBSD__ |
46 | #include <dev/acpi/acpi_pci.h> | | 46 | #include <dev/acpi/acpi_pci.h> |
47 | #include <dev/acpi/acpireg.h> | | 47 | #include <dev/acpi/acpireg.h> |
48 | #define _COMPONENT ACPI_DISPLAY_COMPONENT | | 48 | #define _COMPONENT ACPI_DISPLAY_COMPONENT |
49 | ACPI_MODULE_NAME("radeon_acpi") | | 49 | ACPI_MODULE_NAME("radeon_acpi") |
50 | #include <linux/nbsd-namespace-acpi.h> | | 50 | #include <linux/nbsd-namespace-acpi.h> |
51 | #endif | | 51 | #endif |
52 | | | 52 | |
| | | 53 | #ifndef __NetBSD__ /* XXX radeon acpi */ |
53 | #if defined(CONFIG_VGA_SWITCHEROO) | | 54 | #if defined(CONFIG_VGA_SWITCHEROO) |
54 | bool radeon_atpx_dgpu_req_power_for_displays(void); | | 55 | bool radeon_atpx_dgpu_req_power_for_displays(void); |
55 | #else | | 56 | #else |
56 | static inline bool radeon_atpx_dgpu_req_power_for_displays(void) { return false; } | | 57 | static inline bool radeon_atpx_dgpu_req_power_for_displays(void) { return false; } |
57 | #endif | | 58 | #endif |
| | | 59 | #endif |
58 | | | 60 | |
59 | #define ACPI_AC_CLASS "ac_adapter" | | 61 | #define ACPI_AC_CLASS "ac_adapter" |
60 | | | 62 | |
61 | extern void radeon_pm_acpi_event_handler(struct radeon_device *rdev); | | 63 | extern void radeon_pm_acpi_event_handler(struct radeon_device *rdev); |
62 | | | 64 | |
63 | struct atif_verify_interface { | | 65 | struct atif_verify_interface { |
64 | u16 size; /* structure size in bytes (includes size field) */ | | 66 | u16 size; /* structure size in bytes (includes size field) */ |
65 | u16 version; /* version */ | | 67 | u16 version; /* version */ |
66 | u32 notification_mask; /* supported notifications mask */ | | 68 | u32 notification_mask; /* supported notifications mask */ |
67 | u32 function_bits; /* supported functions bit vector */ | | 69 | u32 function_bits; /* supported functions bit vector */ |
68 | } __packed; | | 70 | } __packed; |
69 | | | 71 | |
70 | struct atif_system_params { | | 72 | struct atif_system_params { |
71 | u16 size; /* structure size in bytes (includes size field) */ | | 73 | u16 size; /* structure size in bytes (includes size field) */ |
72 | u32 valid_mask; /* valid flags mask */ | | 74 | u32 valid_mask; /* valid flags mask */ |
73 | u32 flags; /* flags */ | | 75 | u32 flags; /* flags */ |
74 | u8 command_code; /* notify command code */ | | 76 | u8 command_code; /* notify command code */ |
75 | } __packed; | | 77 | } __packed; |
76 | | | 78 | |
77 | struct atif_sbios_requests { | | 79 | struct atif_sbios_requests { |
78 | u16 size; /* structure size in bytes (includes size field) */ | | 80 | u16 size; /* structure size in bytes (includes size field) */ |
79 | u32 pending; /* pending sbios requests */ | | 81 | u32 pending; /* pending sbios requests */ |
80 | u8 panel_exp_mode; /* panel expansion mode */ | | 82 | u8 panel_exp_mode; /* panel expansion mode */ |
81 | u8 thermal_gfx; /* thermal state: target gfx controller */ | | 83 | u8 thermal_gfx; /* thermal state: target gfx controller */ |
82 | u8 thermal_state; /* thermal state: state id (0: exit state, non-0: state) */ | | 84 | u8 thermal_state; /* thermal state: state id (0: exit state, non-0: state) */ |
83 | u8 forced_power_gfx; /* forced power state: target gfx controller */ | | 85 | u8 forced_power_gfx; /* forced power state: target gfx controller */ |
84 | u8 forced_power_state; /* forced power state: state id */ | | 86 | u8 forced_power_state; /* forced power state: state id */ |
85 | u8 system_power_src; /* system power source */ | | 87 | u8 system_power_src; /* system power source */ |
86 | u8 backlight_level; /* panel backlight level (0-255) */ | | 88 | u8 backlight_level; /* panel backlight level (0-255) */ |
87 | } __packed; | | 89 | } __packed; |
88 | | | 90 | |
89 | #define ATIF_NOTIFY_MASK 0x3 | | 91 | #define ATIF_NOTIFY_MASK 0x3 |
90 | #define ATIF_NOTIFY_NONE 0 | | 92 | #define ATIF_NOTIFY_NONE 0 |
91 | #define ATIF_NOTIFY_81 1 | | 93 | #define ATIF_NOTIFY_81 1 |
92 | #define ATIF_NOTIFY_N 2 | | 94 | #define ATIF_NOTIFY_N 2 |
93 | | | 95 | |
94 | struct atcs_verify_interface { | | 96 | struct atcs_verify_interface { |
95 | u16 size; /* structure size in bytes (includes size field) */ | | 97 | u16 size; /* structure size in bytes (includes size field) */ |
96 | u16 version; /* version */ | | 98 | u16 version; /* version */ |
97 | u32 function_bits; /* supported functions bit vector */ | | 99 | u32 function_bits; /* supported functions bit vector */ |
98 | } __packed; | | 100 | } __packed; |
99 | | | 101 | |
100 | #define ATCS_VALID_FLAGS_MASK 0x3 | | 102 | #define ATCS_VALID_FLAGS_MASK 0x3 |
101 | | | 103 | |
102 | struct atcs_pref_req_input { | | 104 | struct atcs_pref_req_input { |
103 | u16 size; /* structure size in bytes (includes size field) */ | | 105 | u16 size; /* structure size in bytes (includes size field) */ |
104 | u16 client_id; /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */ | | 106 | u16 client_id; /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */ |
105 | u16 valid_flags_mask; /* valid flags mask */ | | 107 | u16 valid_flags_mask; /* valid flags mask */ |
106 | u16 flags; /* flags */ | | 108 | u16 flags; /* flags */ |
107 | u8 req_type; /* request type */ | | 109 | u8 req_type; /* request type */ |
108 | u8 perf_req; /* performance request */ | | 110 | u8 perf_req; /* performance request */ |
109 | } __packed; | | 111 | } __packed; |
110 | | | 112 | |
111 | struct atcs_pref_req_output { | | 113 | struct atcs_pref_req_output { |
112 | u16 size; /* structure size in bytes (includes size field) */ | | 114 | u16 size; /* structure size in bytes (includes size field) */ |
113 | u8 ret_val; /* return value */ | | 115 | u8 ret_val; /* return value */ |
114 | } __packed; | | 116 | } __packed; |
115 | | | 117 | |
116 | /* Call the ATIF method | | 118 | /* Call the ATIF method |
117 | */ | | 119 | */ |
118 | /** | | 120 | /** |
119 | * radeon_atif_call - call an ATIF method | | 121 | * radeon_atif_call - call an ATIF method |
120 | * | | 122 | * |
121 | * @handle: acpi handle | | 123 | * @handle: acpi handle |
122 | * @function: the ATIF function to execute | | 124 | * @function: the ATIF function to execute |
123 | * @params: ATIF function params | | 125 | * @params: ATIF function params |
124 | * | | 126 | * |
125 | * Executes the requested ATIF function (all asics). | | 127 | * Executes the requested ATIF function (all asics). |
126 | * Returns a pointer to the acpi output buffer. | | 128 | * Returns a pointer to the acpi output buffer. |
127 | */ | | 129 | */ |
128 | static union acpi_object *radeon_atif_call(acpi_handle handle, int function, | | 130 | static union acpi_object *radeon_atif_call(acpi_handle handle, int function, |
129 | struct acpi_buffer *params) | | 131 | struct acpi_buffer *params) |
130 | { | | 132 | { |
131 | acpi_status status; | | 133 | acpi_status status; |
132 | union acpi_object atif_arg_elements[2]; | | 134 | union acpi_object atif_arg_elements[2]; |
133 | struct acpi_object_list atif_arg; | | 135 | struct acpi_object_list atif_arg; |
134 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | | 136 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
135 | | | 137 | |
136 | atif_arg.count = 2; | | 138 | atif_arg.count = 2; |
137 | atif_arg.pointer = &atif_arg_elements[0]; | | 139 | atif_arg.pointer = &atif_arg_elements[0]; |
138 | | | 140 | |
139 | atif_arg_elements[0].type = ACPI_TYPE_INTEGER; | | 141 | atif_arg_elements[0].type = ACPI_TYPE_INTEGER; |
140 | atif_arg_elements[0].integer.value = function; | | 142 | atif_arg_elements[0].integer.value = function; |
141 | | | 143 | |
142 | if (params) { | | 144 | if (params) { |
143 | atif_arg_elements[1].type = ACPI_TYPE_BUFFER; | | 145 | atif_arg_elements[1].type = ACPI_TYPE_BUFFER; |
144 | atif_arg_elements[1].buffer.length = params->length; | | 146 | atif_arg_elements[1].buffer.length = params->length; |
145 | atif_arg_elements[1].buffer.pointer = params->pointer; | | 147 | atif_arg_elements[1].buffer.pointer = params->pointer; |
146 | } else { | | 148 | } else { |
147 | /* We need a second fake parameter */ | | 149 | /* We need a second fake parameter */ |
148 | atif_arg_elements[1].type = ACPI_TYPE_INTEGER; | | 150 | atif_arg_elements[1].type = ACPI_TYPE_INTEGER; |
149 | atif_arg_elements[1].integer.value = 0; | | 151 | atif_arg_elements[1].integer.value = 0; |
150 | } | | 152 | } |
151 | | | 153 | |
152 | status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer); | | 154 | status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer); |
153 | | | 155 | |
154 | /* Fail only if calling the method fails and ATIF is supported */ | | 156 | /* Fail only if calling the method fails and ATIF is supported */ |
155 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | | 157 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
156 | DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n", | | 158 | DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n", |
157 | acpi_format_exception(status)); | | 159 | acpi_format_exception(status)); |
158 | ACPI_FREE(buffer.pointer); | | 160 | ACPI_FREE(buffer.pointer); |
159 | return NULL; | | 161 | return NULL; |
160 | } | | 162 | } |
161 | | | 163 | |
162 | return buffer.pointer; | | 164 | return buffer.pointer; |
163 | } | | 165 | } |
164 | | | 166 | |
165 | /** | | 167 | /** |
166 | * radeon_atif_parse_notification - parse supported notifications | | 168 | * radeon_atif_parse_notification - parse supported notifications |
167 | * | | 169 | * |
168 | * @n: supported notifications struct | | 170 | * @n: supported notifications struct |
169 | * @mask: supported notifications mask from ATIF | | 171 | * @mask: supported notifications mask from ATIF |
170 | * | | 172 | * |
171 | * Use the supported notifications mask from ATIF function | | 173 | * Use the supported notifications mask from ATIF function |
172 | * ATIF_FUNCTION_VERIFY_INTERFACE to determine what notifications | | 174 | * ATIF_FUNCTION_VERIFY_INTERFACE to determine what notifications |
173 | * are supported (all asics). | | 175 | * are supported (all asics). |
174 | */ | | 176 | */ |
175 | static void radeon_atif_parse_notification(struct radeon_atif_notifications *n, u32 mask) | | 177 | static void radeon_atif_parse_notification(struct radeon_atif_notifications *n, u32 mask) |
176 | { | | 178 | { |
177 | n->display_switch = mask & ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED; | | 179 | n->display_switch = mask & ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED; |
178 | n->expansion_mode_change = mask & ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED; | | 180 | n->expansion_mode_change = mask & ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED; |
179 | n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED; | | 181 | n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED; |
180 | n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED; | | 182 | n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED; |
181 | n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED; | | 183 | n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED; |
182 | n->display_conf_change = mask & ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED; | | 184 | n->display_conf_change = mask & ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED; |
183 | n->px_gfx_switch = mask & ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED; | | 185 | n->px_gfx_switch = mask & ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED; |
184 | n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED; | | 186 | n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED; |
185 | n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED; | | 187 | n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED; |
186 | } | | 188 | } |
187 | | | 189 | |
188 | /** | | 190 | /** |
189 | * radeon_atif_parse_functions - parse supported functions | | 191 | * radeon_atif_parse_functions - parse supported functions |
190 | * | | 192 | * |
191 | * @f: supported functions struct | | 193 | * @f: supported functions struct |
192 | * @mask: supported functions mask from ATIF | | 194 | * @mask: supported functions mask from ATIF |
193 | * | | 195 | * |
194 | * Use the supported functions mask from ATIF function | | 196 | * Use the supported functions mask from ATIF function |
195 | * ATIF_FUNCTION_VERIFY_INTERFACE to determine what functions | | 197 | * ATIF_FUNCTION_VERIFY_INTERFACE to determine what functions |
196 | * are supported (all asics). | | 198 | * are supported (all asics). |
197 | */ | | 199 | */ |
198 | static void radeon_atif_parse_functions(struct radeon_atif_functions *f, u32 mask) | | 200 | static void radeon_atif_parse_functions(struct radeon_atif_functions *f, u32 mask) |
199 | { | | 201 | { |
200 | f->system_params = mask & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED; | | 202 | f->system_params = mask & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED; |
201 | f->sbios_requests = mask & ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED; | | 203 | f->sbios_requests = mask & ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED; |
202 | f->select_active_disp = mask & ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED; | | 204 | f->select_active_disp = mask & ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED; |
203 | f->lid_state = mask & ATIF_GET_LID_STATE_SUPPORTED; | | 205 | f->lid_state = mask & ATIF_GET_LID_STATE_SUPPORTED; |
204 | f->get_tv_standard = mask & ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED; | | 206 | f->get_tv_standard = mask & ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED; |
205 | f->set_tv_standard = mask & ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED; | | 207 | f->set_tv_standard = mask & ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED; |
206 | f->get_panel_expansion_mode = mask & ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED; | | 208 | f->get_panel_expansion_mode = mask & ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED; |
207 | f->set_panel_expansion_mode = mask & ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED; | | 209 | f->set_panel_expansion_mode = mask & ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED; |
208 | f->temperature_change = mask & ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED; | | 210 | f->temperature_change = mask & ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED; |
209 | f->graphics_device_types = mask & ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED; | | 211 | f->graphics_device_types = mask & ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED; |
210 | } | | 212 | } |
211 | | | 213 | |
212 | /** | | 214 | /** |
213 | * radeon_atif_verify_interface - verify ATIF | | 215 | * radeon_atif_verify_interface - verify ATIF |
214 | * | | 216 | * |
215 | * @handle: acpi handle | | 217 | * @handle: acpi handle |
216 | * @atif: radeon atif struct | | 218 | * @atif: radeon atif struct |
217 | * | | 219 | * |
218 | * Execute the ATIF_FUNCTION_VERIFY_INTERFACE ATIF function | | 220 | * Execute the ATIF_FUNCTION_VERIFY_INTERFACE ATIF function |
219 | * to initialize ATIF and determine what features are supported | | 221 | * to initialize ATIF and determine what features are supported |
220 | * (all asics). | | 222 | * (all asics). |
221 | * returns 0 on success, error on failure. | | 223 | * returns 0 on success, error on failure. |
222 | */ | | 224 | */ |
223 | static int radeon_atif_verify_interface(acpi_handle handle, | | 225 | static int radeon_atif_verify_interface(acpi_handle handle, |
224 | struct radeon_atif *atif) | | 226 | struct radeon_atif *atif) |
225 | { | | 227 | { |
226 | union acpi_object *info; | | 228 | union acpi_object *info; |
227 | struct atif_verify_interface output; | | 229 | struct atif_verify_interface output; |
228 | size_t size; | | 230 | size_t size; |
229 | int err = 0; | | 231 | int err = 0; |
230 | | | 232 | |
231 | info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); | | 233 | info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); |
232 | if (!info) | | 234 | if (!info) |
233 | return -EIO; | | 235 | return -EIO; |
234 | | | 236 | |
235 | memset(&output, 0, sizeof(output)); | | 237 | memset(&output, 0, sizeof(output)); |
236 | | | 238 | |
237 | size = *(u16 *) info->buffer.pointer; | | 239 | size = *(u16 *) info->buffer.pointer; |
238 | if (size < 12) { | | 240 | if (size < 12) { |
239 | DRM_INFO("ATIF buffer is too small: %zu\n", size); | | 241 | DRM_INFO("ATIF buffer is too small: %zu\n", size); |
240 | err = -EINVAL; | | 242 | err = -EINVAL; |
241 | goto out; | | 243 | goto out; |
242 | } | | 244 | } |
243 | size = min(sizeof(output), size); | | 245 | size = min(sizeof(output), size); |
244 | | | 246 | |
245 | memcpy(&output, info->buffer.pointer, size); | | 247 | memcpy(&output, info->buffer.pointer, size); |
246 | | | 248 | |
247 | /* TODO: check version? */ | | 249 | /* TODO: check version? */ |
248 | DRM_DEBUG_DRIVER("ATIF version %u\n", output.version); | | 250 | DRM_DEBUG_DRIVER("ATIF version %u\n", output.version); |
249 | | | 251 | |
250 | radeon_atif_parse_notification(&atif->notifications, output.notification_mask); | | 252 | radeon_atif_parse_notification(&atif->notifications, output.notification_mask); |
251 | radeon_atif_parse_functions(&atif->functions, output.function_bits); | | 253 | radeon_atif_parse_functions(&atif->functions, output.function_bits); |
252 | | | 254 | |
253 | out: | | 255 | out: |
254 | ACPI_FREE(info); | | 256 | ACPI_FREE(info); |
255 | return err; | | 257 | return err; |
256 | } | | 258 | } |
257 | | | 259 | |
258 | /** | | 260 | /** |
259 | * radeon_atif_get_notification_params - determine notify configuration | | 261 | * radeon_atif_get_notification_params - determine notify configuration |
260 | * | | 262 | * |
261 | * @handle: acpi handle | | 263 | * @handle: acpi handle |
262 | * @n: atif notification configuration struct | | 264 | * @n: atif notification configuration struct |
263 | * | | 265 | * |
264 | * Execute the ATIF_FUNCTION_GET_SYSTEM_PARAMETERS ATIF function | | 266 | * Execute the ATIF_FUNCTION_GET_SYSTEM_PARAMETERS ATIF function |
265 | * to determine if a notifier is used and if so which one | | 267 | * to determine if a notifier is used and if so which one |
266 | * (all asics). This is either Notify(VGA, 0x81) or Notify(VGA, n) | | 268 | * (all asics). This is either Notify(VGA, 0x81) or Notify(VGA, n) |
267 | * where n is specified in the result if a notifier is used. | | 269 | * where n is specified in the result if a notifier is used. |
268 | * Returns 0 on success, error on failure. | | 270 | * Returns 0 on success, error on failure. |
269 | */ | | 271 | */ |
270 | static int radeon_atif_get_notification_params(acpi_handle handle, | | 272 | static int radeon_atif_get_notification_params(acpi_handle handle, |
271 | struct radeon_atif_notification_cfg *n) | | 273 | struct radeon_atif_notification_cfg *n) |
272 | { | | 274 | { |
273 | union acpi_object *info; | | 275 | union acpi_object *info; |
274 | struct atif_system_params params; | | 276 | struct atif_system_params params; |
275 | size_t size; | | 277 | size_t size; |
276 | int err = 0; | | 278 | int err = 0; |
277 | | | 279 | |
278 | info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL); | | 280 | info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL); |
279 | if (!info) { | | 281 | if (!info) { |
280 | err = -EIO; | | 282 | err = -EIO; |
281 | goto out; | | 283 | goto out; |
282 | } | | 284 | } |
283 | | | 285 | |
284 | size = *(u16 *) info->buffer.pointer; | | 286 | size = *(u16 *) info->buffer.pointer; |
285 | if (size < 10) { | | 287 | if (size < 10) { |
286 | err = -EINVAL; | | 288 | err = -EINVAL; |
287 | goto out; | | 289 | goto out; |
288 | } | | 290 | } |
289 | | | 291 | |
290 | memset(¶ms, 0, sizeof(params)); | | 292 | memset(¶ms, 0, sizeof(params)); |
291 | size = min(sizeof(params), size); | | 293 | size = min(sizeof(params), size); |
292 | memcpy(¶ms, info->buffer.pointer, size); | | 294 | memcpy(¶ms, info->buffer.pointer, size); |
293 | | | 295 | |
294 | DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n", | | 296 | DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n", |
295 | params.flags, params.valid_mask); | | 297 | params.flags, params.valid_mask); |
296 | params.flags = params.flags & params.valid_mask; | | 298 | params.flags = params.flags & params.valid_mask; |
297 | | | 299 | |
298 | if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) { | | 300 | if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) { |
299 | n->enabled = false; | | 301 | n->enabled = false; |
300 | n->command_code = 0; | | 302 | n->command_code = 0; |
301 | } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) { | | 303 | } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) { |
302 | n->enabled = true; | | 304 | n->enabled = true; |
303 | n->command_code = 0x81; | | 305 | n->command_code = 0x81; |
304 | } else { | | 306 | } else { |
305 | if (size < 11) { | | 307 | if (size < 11) { |
306 | err = -EINVAL; | | 308 | err = -EINVAL; |
307 | goto out; | | 309 | goto out; |
308 | } | | 310 | } |
309 | n->enabled = true; | | 311 | n->enabled = true; |
310 | n->command_code = params.command_code; | | 312 | n->command_code = params.command_code; |
311 | } | | 313 | } |
312 | | | 314 | |
313 | out: | | 315 | out: |
314 | DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n", | | 316 | DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n", |
315 | (n->enabled ? "enabled" : "disabled"), | | 317 | (n->enabled ? "enabled" : "disabled"), |
316 | n->command_code); | | 318 | n->command_code); |
317 | ACPI_FREE(info); | | 319 | ACPI_FREE(info); |
318 | return err; | | 320 | return err; |
319 | } | | 321 | } |
320 | | | 322 | |
321 | #ifndef __NetBSD__ /* XXX radeon acpi */ | | 323 | #ifndef __NetBSD__ /* XXX radeon acpi */ |
322 | | | 324 | |
323 | /** | | 325 | /** |
324 | * radeon_atif_get_sbios_requests - get requested sbios event | | 326 | * radeon_atif_get_sbios_requests - get requested sbios event |
325 | * | | 327 | * |
326 | * @handle: acpi handle | | 328 | * @handle: acpi handle |
327 | * @req: atif sbios request struct | | 329 | * @req: atif sbios request struct |
328 | * | | 330 | * |
329 | * Execute the ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS ATIF function | | 331 | * Execute the ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS ATIF function |
330 | * to determine what requests the sbios is making to the driver | | 332 | * to determine what requests the sbios is making to the driver |
331 | * (all asics). | | 333 | * (all asics). |
332 | * Returns 0 on success, error on failure. | | 334 | * Returns 0 on success, error on failure. |
333 | */ | | 335 | */ |
334 | static int radeon_atif_get_sbios_requests(acpi_handle handle, | | 336 | static int radeon_atif_get_sbios_requests(acpi_handle handle, |
335 | struct atif_sbios_requests *req) | | 337 | struct atif_sbios_requests *req) |
336 | { | | 338 | { |
337 | union acpi_object *info; | | 339 | union acpi_object *info; |
338 | size_t size; | | 340 | size_t size; |
339 | int count = 0; | | 341 | int count = 0; |
340 | | | 342 | |
341 | info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL); | | 343 | info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL); |
342 | if (!info) | | 344 | if (!info) |
343 | return -EIO; | | 345 | return -EIO; |
344 | | | 346 | |
345 | size = *(u16 *)info->buffer.pointer; | | 347 | size = *(u16 *)info->buffer.pointer; |
346 | if (size < 0xd) { | | 348 | if (size < 0xd) { |
347 | count = -EINVAL; | | 349 | count = -EINVAL; |
348 | goto out; | | 350 | goto out; |
349 | } | | 351 | } |
350 | memset(req, 0, sizeof(*req)); | | 352 | memset(req, 0, sizeof(*req)); |
351 | | | 353 | |
352 | size = min(sizeof(*req), size); | | 354 | size = min(sizeof(*req), size); |
353 | memcpy(req, info->buffer.pointer, size); | | 355 | memcpy(req, info->buffer.pointer, size); |
354 | DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending); | | 356 | DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending); |
355 | | | 357 | |
356 | count = hweight32(req->pending); | | 358 | count = hweight32(req->pending); |
357 | | | 359 | |
358 | out: | | 360 | out: |
359 | ACPI_FREE(info); | | 361 | ACPI_FREE(info); |
360 | return count; | | 362 | return count; |
361 | } | | 363 | } |
362 | | | 364 | |
363 | /** | | 365 | /** |
364 | * radeon_atif_handler - handle ATIF notify requests | | 366 | * radeon_atif_handler - handle ATIF notify requests |
365 | * | | 367 | * |
366 | * @rdev: radeon_device pointer | | 368 | * @rdev: radeon_device pointer |
367 | * @event: atif sbios request struct | | 369 | * @event: atif sbios request struct |
368 | * | | 370 | * |
369 | * Checks the acpi event and if it matches an atif event, | | 371 | * Checks the acpi event and if it matches an atif event, |
370 | * handles it. | | 372 | * handles it. |
371 | * Returns NOTIFY code | | 373 | * Returns NOTIFY code |
372 | */ | | 374 | */ |
373 | static int radeon_atif_handler(struct radeon_device *rdev, | | 375 | static int radeon_atif_handler(struct radeon_device *rdev, |
374 | struct acpi_bus_event *event) | | 376 | struct acpi_bus_event *event) |
375 | { | | 377 | { |
376 | struct radeon_atif *atif = &rdev->atif; | | 378 | struct radeon_atif *atif = &rdev->atif; |
377 | struct atif_sbios_requests req; | | 379 | struct atif_sbios_requests req; |
378 | acpi_handle handle; | | 380 | acpi_handle handle; |
379 | int count; | | 381 | int count; |
380 | | | 382 | |
381 | DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n", | | 383 | DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n", |
382 | event->device_class, event->type); | | 384 | event->device_class, event->type); |
383 | | | 385 | |
384 | if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0) | | 386 | if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0) |
385 | return NOTIFY_DONE; | | 387 | return NOTIFY_DONE; |
386 | | | 388 | |
387 | if (!atif->notification_cfg.enabled || | | 389 | if (!atif->notification_cfg.enabled || |
388 | event->type != atif->notification_cfg.command_code) | | 390 | event->type != atif->notification_cfg.command_code) |
389 | /* Not our event */ | | 391 | /* Not our event */ |
390 | return NOTIFY_DONE; | | 392 | return NOTIFY_DONE; |
391 | | | 393 | |
392 | /* Check pending SBIOS requests */ | | 394 | /* Check pending SBIOS requests */ |
393 | handle = ACPI_HANDLE(&rdev->pdev->dev); | | 395 | handle = ACPI_HANDLE(&rdev->pdev->dev); |
394 | count = radeon_atif_get_sbios_requests(handle, &req); | | 396 | count = radeon_atif_get_sbios_requests(handle, &req); |
395 | | | 397 | |
396 | if (count <= 0) | | 398 | if (count <= 0) |
397 | return NOTIFY_DONE; | | 399 | return NOTIFY_DONE; |
398 | | | 400 | |
399 | DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count); | | 401 | DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count); |
400 | | | 402 | |
401 | if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) { | | 403 | if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) { |
402 | struct radeon_encoder *enc = atif->encoder_for_bl; | | 404 | struct radeon_encoder *enc = atif->encoder_for_bl; |
403 | | | 405 | |
404 | if (enc) { | | 406 | if (enc) { |
405 | DRM_DEBUG_DRIVER("Changing brightness to %d\n", | | 407 | DRM_DEBUG_DRIVER("Changing brightness to %d\n", |
406 | req.backlight_level); | | 408 | req.backlight_level); |
407 | | | 409 | |
408 | radeon_set_backlight_level(rdev, enc, req.backlight_level); | | 410 | radeon_set_backlight_level(rdev, enc, req.backlight_level); |
409 | | | 411 | |
410 | #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) | | 412 | #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) |
411 | if (rdev->is_atom_bios) { | | 413 | if (rdev->is_atom_bios) { |
412 | struct radeon_encoder_atom_dig *dig = enc->enc_priv; | | 414 | struct radeon_encoder_atom_dig *dig = enc->enc_priv; |
413 | backlight_force_update(dig->bl_dev, | | 415 | backlight_force_update(dig->bl_dev, |
414 | BACKLIGHT_UPDATE_HOTKEY); | | 416 | BACKLIGHT_UPDATE_HOTKEY); |
415 | } else { | | 417 | } else { |
416 | struct radeon_encoder_lvds *dig = enc->enc_priv; | | 418 | struct radeon_encoder_lvds *dig = enc->enc_priv; |
417 | backlight_force_update(dig->bl_dev, | | 419 | backlight_force_update(dig->bl_dev, |
418 | BACKLIGHT_UPDATE_HOTKEY); | | 420 | BACKLIGHT_UPDATE_HOTKEY); |
419 | } | | 421 | } |
420 | #endif | | 422 | #endif |
421 | } | | 423 | } |
422 | } | | 424 | } |
423 | if (req.pending & ATIF_DGPU_DISPLAY_EVENT) { | | 425 | if (req.pending & ATIF_DGPU_DISPLAY_EVENT) { |
424 | if ((rdev->flags & RADEON_IS_PX) && | | 426 | if ((rdev->flags & RADEON_IS_PX) && |
425 | radeon_atpx_dgpu_req_power_for_displays()) { | | 427 | radeon_atpx_dgpu_req_power_for_displays()) { |
426 | pm_runtime_get_sync(rdev->ddev->dev); | | 428 | pm_runtime_get_sync(rdev->ddev->dev); |
427 | /* Just fire off a uevent and let userspace tell us what to do */ | | 429 | /* Just fire off a uevent and let userspace tell us what to do */ |
428 | drm_helper_hpd_irq_event(rdev->ddev); | | 430 | drm_helper_hpd_irq_event(rdev->ddev); |
429 | pm_runtime_mark_last_busy(rdev->ddev->dev); | | 431 | pm_runtime_mark_last_busy(rdev->ddev->dev); |
430 | pm_runtime_put_autosuspend(rdev->ddev->dev); | | 432 | pm_runtime_put_autosuspend(rdev->ddev->dev); |
431 | } | | 433 | } |
432 | } | | 434 | } |
433 | /* TODO: check other events */ | | 435 | /* TODO: check other events */ |
434 | | | 436 | |
435 | /* We've handled the event, stop the notifier chain. The ACPI interface | | 437 | /* We've handled the event, stop the notifier chain. The ACPI interface |
436 | * overloads ACPI_VIDEO_NOTIFY_PROBE, we don't want to send that to | | 438 | * overloads ACPI_VIDEO_NOTIFY_PROBE, we don't want to send that to |
437 | * userspace if the event was generated only to signal a SBIOS | | 439 | * userspace if the event was generated only to signal a SBIOS |
438 | * request. | | 440 | * request. |
439 | */ | | 441 | */ |
440 | return NOTIFY_BAD; | | 442 | return NOTIFY_BAD; |
441 | } | | 443 | } |
442 | | | 444 | |
443 | #endif /* __NetBSD__ */ | | 445 | #endif /* __NetBSD__ */ |
444 | | | 446 | |
445 | /* Call the ATCS method | | 447 | /* Call the ATCS method |
446 | */ | | 448 | */ |
447 | /** | | 449 | /** |
448 | * radeon_atcs_call - call an ATCS method | | 450 | * radeon_atcs_call - call an ATCS method |
449 | * | | 451 | * |
450 | * @handle: acpi handle | | 452 | * @handle: acpi handle |
451 | * @function: the ATCS function to execute | | 453 | * @function: the ATCS function to execute |
452 | * @params: ATCS function params | | 454 | * @params: ATCS function params |
453 | * | | 455 | * |
454 | * Executes the requested ATCS function (all asics). | | 456 | * Executes the requested ATCS function (all asics). |
455 | * Returns a pointer to the acpi output buffer. | | 457 | * Returns a pointer to the acpi output buffer. |
456 | */ | | 458 | */ |
457 | static union acpi_object *radeon_atcs_call(acpi_handle handle, int function, | | 459 | static union acpi_object *radeon_atcs_call(acpi_handle handle, int function, |
458 | struct acpi_buffer *params) | | 460 | struct acpi_buffer *params) |
459 | { | | 461 | { |
460 | acpi_status status; | | 462 | acpi_status status; |
461 | union acpi_object atcs_arg_elements[2]; | | 463 | union acpi_object atcs_arg_elements[2]; |
462 | struct acpi_object_list atcs_arg; | | 464 | struct acpi_object_list atcs_arg; |
463 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | | 465 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
464 | | | 466 | |
465 | atcs_arg.count = 2; | | 467 | atcs_arg.count = 2; |
466 | atcs_arg.pointer = &atcs_arg_elements[0]; | | 468 | atcs_arg.pointer = &atcs_arg_elements[0]; |
467 | | | 469 | |
468 | atcs_arg_elements[0].type = ACPI_TYPE_INTEGER; | | 470 | atcs_arg_elements[0].type = ACPI_TYPE_INTEGER; |
469 | atcs_arg_elements[0].integer.value = function; | | 471 | atcs_arg_elements[0].integer.value = function; |
470 | | | 472 | |
471 | if (params) { | | 473 | if (params) { |
472 | atcs_arg_elements[1].type = ACPI_TYPE_BUFFER; | | 474 | atcs_arg_elements[1].type = ACPI_TYPE_BUFFER; |
473 | atcs_arg_elements[1].buffer.length = params->length; | | 475 | atcs_arg_elements[1].buffer.length = params->length; |
474 | atcs_arg_elements[1].buffer.pointer = params->pointer; | | 476 | atcs_arg_elements[1].buffer.pointer = params->pointer; |
475 | } else { | | 477 | } else { |
476 | /* We need a second fake parameter */ | | 478 | /* We need a second fake parameter */ |
477 | atcs_arg_elements[1].type = ACPI_TYPE_INTEGER; | | 479 | atcs_arg_elements[1].type = ACPI_TYPE_INTEGER; |
478 | atcs_arg_elements[1].integer.value = 0; | | 480 | atcs_arg_elements[1].integer.value = 0; |
479 | } | | 481 | } |
480 | | | 482 | |
481 | status = acpi_evaluate_object(handle, "ATCS", &atcs_arg, &buffer); | | 483 | status = acpi_evaluate_object(handle, "ATCS", &atcs_arg, &buffer); |
482 | | | 484 | |
483 | /* Fail only if calling the method fails and ATIF is supported */ | | 485 | /* Fail only if calling the method fails and ATIF is supported */ |
484 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | | 486 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
485 | DRM_DEBUG_DRIVER("failed to evaluate ATCS got %s\n", | | 487 | DRM_DEBUG_DRIVER("failed to evaluate ATCS got %s\n", |
486 | acpi_format_exception(status)); | | 488 | acpi_format_exception(status)); |
487 | ACPI_FREE(buffer.pointer); | | 489 | ACPI_FREE(buffer.pointer); |
488 | return NULL; | | 490 | return NULL; |
489 | } | | 491 | } |
490 | | | 492 | |
491 | return buffer.pointer; | | 493 | return buffer.pointer; |
492 | } | | 494 | } |
493 | | | 495 | |
494 | /** | | 496 | /** |
495 | * radeon_atcs_parse_functions - parse supported functions | | 497 | * radeon_atcs_parse_functions - parse supported functions |
496 | * | | 498 | * |
497 | * @f: supported functions struct | | 499 | * @f: supported functions struct |
498 | * @mask: supported functions mask from ATCS | | 500 | * @mask: supported functions mask from ATCS |
499 | * | | 501 | * |
500 | * Use the supported functions mask from ATCS function | | 502 | * Use the supported functions mask from ATCS function |
501 | * ATCS_FUNCTION_VERIFY_INTERFACE to determine what functions | | 503 | * ATCS_FUNCTION_VERIFY_INTERFACE to determine what functions |
502 | * are supported (all asics). | | 504 | * are supported (all asics). |
503 | */ | | 505 | */ |
504 | static void radeon_atcs_parse_functions(struct radeon_atcs_functions *f, u32 mask) | | 506 | static void radeon_atcs_parse_functions(struct radeon_atcs_functions *f, u32 mask) |
505 | { | | 507 | { |
506 | f->get_ext_state = mask & ATCS_GET_EXTERNAL_STATE_SUPPORTED; | | 508 | f->get_ext_state = mask & ATCS_GET_EXTERNAL_STATE_SUPPORTED; |
507 | f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED; | | 509 | f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED; |
508 | f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED; | | 510 | f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED; |
509 | f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED; | | 511 | f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED; |
510 | } | | 512 | } |
511 | | | 513 | |
512 | /** | | 514 | /** |
513 | * radeon_atcs_verify_interface - verify ATCS | | 515 | * radeon_atcs_verify_interface - verify ATCS |
514 | * | | 516 | * |
515 | * @handle: acpi handle | | 517 | * @handle: acpi handle |
516 | * @atcs: radeon atcs struct | | 518 | * @atcs: radeon atcs struct |
517 | * | | 519 | * |
518 | * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function | | 520 | * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function |
519 | * to initialize ATCS and determine what features are supported | | 521 | * to initialize ATCS and determine what features are supported |
520 | * (all asics). | | 522 | * (all asics). |
521 | * returns 0 on success, error on failure. | | 523 | * returns 0 on success, error on failure. |
522 | */ | | 524 | */ |
523 | static int radeon_atcs_verify_interface(acpi_handle handle, | | 525 | static int radeon_atcs_verify_interface(acpi_handle handle, |
524 | struct radeon_atcs *atcs) | | 526 | struct radeon_atcs *atcs) |
525 | { | | 527 | { |
526 | union acpi_object *info; | | 528 | union acpi_object *info; |
527 | struct atcs_verify_interface output; | | 529 | struct atcs_verify_interface output; |
528 | size_t size; | | 530 | size_t size; |
529 | int err = 0; | | 531 | int err = 0; |
530 | | | 532 | |
531 | info = radeon_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL); | | 533 | info = radeon_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL); |
532 | if (!info) | | 534 | if (!info) |
533 | return -EIO; | | 535 | return -EIO; |
534 | | | 536 | |
535 | memset(&output, 0, sizeof(output)); | | 537 | memset(&output, 0, sizeof(output)); |
536 | | | 538 | |
537 | size = *(u16 *) info->buffer.pointer; | | 539 | size = *(u16 *) info->buffer.pointer; |
538 | if (size < 8) { | | 540 | if (size < 8) { |
539 | DRM_INFO("ATCS buffer is too small: %zu\n", size); | | 541 | DRM_INFO("ATCS buffer is too small: %zu\n", size); |
540 | err = -EINVAL; | | 542 | err = -EINVAL; |
541 | goto out; | | 543 | goto out; |
542 | } | | 544 | } |
543 | size = min(sizeof(output), size); | | 545 | size = min(sizeof(output), size); |
544 | | | 546 | |
545 | memcpy(&output, info->buffer.pointer, size); | | 547 | memcpy(&output, info->buffer.pointer, size); |
546 | | | 548 | |
547 | /* TODO: check version? */ | | 549 | /* TODO: check version? */ |
548 | DRM_DEBUG_DRIVER("ATCS version %u\n", output.version); | | 550 | DRM_DEBUG_DRIVER("ATCS version %u\n", output.version); |
549 | | | 551 | |
550 | radeon_atcs_parse_functions(&atcs->functions, output.function_bits); | | 552 | radeon_atcs_parse_functions(&atcs->functions, output.function_bits); |
551 | | | 553 | |
552 | out: | | 554 | out: |
553 | ACPI_FREE(info); | | 555 | ACPI_FREE(info); |
554 | return err; | | 556 | return err; |
555 | } | | 557 | } |
556 | | | 558 | |
557 | /** | | 559 | /** |
558 | * radeon_acpi_is_pcie_performance_request_supported | | 560 | * radeon_acpi_is_pcie_performance_request_supported |
559 | * | | 561 | * |
560 | * @rdev: radeon_device pointer | | 562 | * @rdev: radeon_device pointer |
561 | * | | 563 | * |
562 | * Check if the ATCS pcie_perf_req and pcie_dev_rdy methods | | 564 | * Check if the ATCS pcie_perf_req and pcie_dev_rdy methods |
563 | * are supported (all asics). | | 565 | * are supported (all asics). |
564 | * returns true if supported, false if not. | | 566 | * returns true if supported, false if not. |
565 | */ | | 567 | */ |
566 | bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev) | | 568 | bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev) |
567 | { | | 569 | { |
568 | struct radeon_atcs *atcs = &rdev->atcs; | | 570 | struct radeon_atcs *atcs = &rdev->atcs; |
569 | | | 571 | |
570 | if (atcs->functions.pcie_perf_req && atcs->functions.pcie_dev_rdy) | | 572 | if (atcs->functions.pcie_perf_req && atcs->functions.pcie_dev_rdy) |
571 | return true; | | 573 | return true; |
572 | | | 574 | |
573 | return false; | | 575 | return false; |
574 | } | | 576 | } |
575 | | | 577 | |
576 | /** | | 578 | /** |
577 | * radeon_acpi_pcie_notify_device_ready | | 579 | * radeon_acpi_pcie_notify_device_ready |
578 | * | | 580 | * |
579 | * @rdev: radeon_device pointer | | 581 | * @rdev: radeon_device pointer |
580 | * | | 582 | * |
581 | * Executes the PCIE_DEVICE_READY_NOTIFICATION method | | 583 | * Executes the PCIE_DEVICE_READY_NOTIFICATION method |
582 | * (all asics). | | 584 | * (all asics). |
583 | * returns 0 on success, error on failure. | | 585 | * returns 0 on success, error on failure. |
584 | */ | | 586 | */ |
585 | int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev) | | 587 | int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev) |
586 | { | | 588 | { |
587 | acpi_handle handle; | | 589 | acpi_handle handle; |
588 | union acpi_object *info; | | 590 | union acpi_object *info; |
589 | struct radeon_atcs *atcs = &rdev->atcs; | | 591 | struct radeon_atcs *atcs = &rdev->atcs; |
590 | | | 592 | |
591 | /* Get the device handle */ | | 593 | /* Get the device handle */ |
592 | #ifdef __NetBSD__ | | 594 | #ifdef __NetBSD__ |
593 | const struct pci_attach_args *pa = &rdev->pdev->pd_pa; | | 595 | const struct pci_attach_args *pa = &rdev->pdev->pd_pa; |
594 | struct acpi_devnode *const d = | | 596 | struct acpi_devnode *const d = |
595 | acpi_pcidev_find(pci_get_segment(pa->pa_pc), | | 597 | acpi_pcidev_find(pci_get_segment(pa->pa_pc), |
596 | pa->pa_bus, pa->pa_device, pa->pa_function); | | 598 | pa->pa_bus, pa->pa_device, pa->pa_function); |
597 | if (d == NULL) | | 599 | if (d == NULL) |
598 | return -EINVAL; | | 600 | return -EINVAL; |
599 | handle = d->ad_handle; | | 601 | handle = d->ad_handle; |
600 | #else | | 602 | #else |
601 | handle = ACPI_HANDLE(&rdev->pdev->dev); | | 603 | handle = ACPI_HANDLE(&rdev->pdev->dev); |
602 | #endif | | 604 | #endif |
603 | if (!handle) | | 605 | if (!handle) |
604 | return -EINVAL; | | 606 | return -EINVAL; |
605 | | | 607 | |
606 | if (!atcs->functions.pcie_dev_rdy) | | 608 | if (!atcs->functions.pcie_dev_rdy) |
607 | return -EINVAL; | | 609 | return -EINVAL; |
608 | | | 610 | |
609 | info = radeon_atcs_call(handle, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, NULL); | | 611 | info = radeon_atcs_call(handle, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, NULL); |
610 | if (!info) | | 612 | if (!info) |
611 | return -EIO; | | 613 | return -EIO; |
612 | | | 614 | |
613 | ACPI_FREE(info); | | 615 | ACPI_FREE(info); |
614 | | | 616 | |
615 | return 0; | | 617 | return 0; |
616 | } | | 618 | } |
617 | | | 619 | |
618 | /** | | 620 | /** |
619 | * radeon_acpi_pcie_performance_request | | 621 | * radeon_acpi_pcie_performance_request |
620 | * | | 622 | * |
621 | * @rdev: radeon_device pointer | | 623 | * @rdev: radeon_device pointer |
622 | * @perf_req: requested perf level (pcie gen speed) | | 624 | * @perf_req: requested perf level (pcie gen speed) |
623 | * @advertise: set advertise caps flag if set | | 625 | * @advertise: set advertise caps flag if set |
624 | * | | 626 | * |
625 | * Executes the PCIE_PERFORMANCE_REQUEST method to | | 627 | * Executes the PCIE_PERFORMANCE_REQUEST method to |
626 | * change the pcie gen speed (all asics). | | 628 | * change the pcie gen speed (all asics). |
627 | * returns 0 on success, error on failure. | | 629 | * returns 0 on success, error on failure. |
628 | */ | | 630 | */ |
629 | int radeon_acpi_pcie_performance_request(struct radeon_device *rdev, | | 631 | int radeon_acpi_pcie_performance_request(struct radeon_device *rdev, |
630 | u8 perf_req, bool advertise) | | 632 | u8 perf_req, bool advertise) |
631 | { | | 633 | { |
632 | acpi_handle handle; | | 634 | acpi_handle handle; |
633 | union acpi_object *info; | | 635 | union acpi_object *info; |
634 | struct radeon_atcs *atcs = &rdev->atcs; | | 636 | struct radeon_atcs *atcs = &rdev->atcs; |
635 | struct atcs_pref_req_input atcs_input; | | 637 | struct atcs_pref_req_input atcs_input; |
636 | struct atcs_pref_req_output atcs_output; | | 638 | struct atcs_pref_req_output atcs_output; |
637 | struct acpi_buffer params; | | 639 | struct acpi_buffer params; |
638 | size_t size; | | 640 | size_t size; |
639 | u32 retry = 3; | | 641 | u32 retry = 3; |
640 | | | 642 | |
641 | /* Get the device handle */ | | 643 | /* Get the device handle */ |
642 | #ifdef __NetBSD__ | | 644 | #ifdef __NetBSD__ |
643 | const struct pci_attach_args *pa = &rdev->pdev->pd_pa; | | 645 | const struct pci_attach_args *pa = &rdev->pdev->pd_pa; |
644 | struct acpi_devnode *const d = | | 646 | struct acpi_devnode *const d = |
645 | acpi_pcidev_find(pci_get_segment(pa->pa_pc), | | 647 | acpi_pcidev_find(pci_get_segment(pa->pa_pc), |
646 | pa->pa_bus, pa->pa_device, pa->pa_function); | | 648 | pa->pa_bus, pa->pa_device, pa->pa_function); |
647 | if (d == NULL) | | 649 | if (d == NULL) |
648 | return -EINVAL; | | 650 | return -EINVAL; |
649 | handle = d->ad_handle; | | 651 | handle = d->ad_handle; |
650 | #else | | 652 | #else |
651 | handle = ACPI_HANDLE(&rdev->pdev->dev); | | 653 | handle = ACPI_HANDLE(&rdev->pdev->dev); |
652 | #endif | | 654 | #endif |
653 | if (!handle) | | 655 | if (!handle) |
654 | return -EINVAL; | | 656 | return -EINVAL; |
655 | | | 657 | |
656 | if (!atcs->functions.pcie_perf_req) | | 658 | if (!atcs->functions.pcie_perf_req) |
657 | return -EINVAL; | | 659 | return -EINVAL; |
658 | | | 660 | |
659 | atcs_input.size = sizeof(struct atcs_pref_req_input); | | 661 | atcs_input.size = sizeof(struct atcs_pref_req_input); |
660 | /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */ | | 662 | /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */ |
661 | atcs_input.client_id = rdev->pdev->devfn | (rdev->pdev->bus->number << 8); | | 663 | atcs_input.client_id = rdev->pdev->devfn | (rdev->pdev->bus->number << 8); |
662 | atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK; | | 664 | atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK; |
663 | atcs_input.flags = ATCS_WAIT_FOR_COMPLETION; | | 665 | atcs_input.flags = ATCS_WAIT_FOR_COMPLETION; |
664 | if (advertise) | | 666 | if (advertise) |
665 | atcs_input.flags |= ATCS_ADVERTISE_CAPS; | | 667 | atcs_input.flags |= ATCS_ADVERTISE_CAPS; |
666 | atcs_input.req_type = ATCS_PCIE_LINK_SPEED; | | 668 | atcs_input.req_type = ATCS_PCIE_LINK_SPEED; |
667 | atcs_input.perf_req = perf_req; | | 669 | atcs_input.perf_req = perf_req; |
668 | | | 670 | |
669 | params.length = sizeof(struct atcs_pref_req_input); | | 671 | params.length = sizeof(struct atcs_pref_req_input); |
670 | params.pointer = &atcs_input; | | 672 | params.pointer = &atcs_input; |
671 | | | 673 | |
672 | while (retry--) { | | 674 | while (retry--) { |
673 | info = radeon_atcs_call(handle, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, ¶ms); | | 675 | info = radeon_atcs_call(handle, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, ¶ms); |
674 | if (!info) | | 676 | if (!info) |
675 | return -EIO; | | 677 | return -EIO; |
676 | | | 678 | |
677 | memset(&atcs_output, 0, sizeof(atcs_output)); | | 679 | memset(&atcs_output, 0, sizeof(atcs_output)); |
678 | | | 680 | |
679 | size = *(u16 *) info->buffer.pointer; | | 681 | size = *(u16 *) info->buffer.pointer; |
680 | if (size < 3) { | | 682 | if (size < 3) { |
681 | DRM_INFO("ATCS buffer is too small: %zu\n", size); | | 683 | DRM_INFO("ATCS buffer is too small: %zu\n", size); |
682 | ACPI_FREE(info); | | 684 | ACPI_FREE(info); |
683 | return -EINVAL; | | 685 | return -EINVAL; |
684 | } | | 686 | } |
685 | size = min(sizeof(atcs_output), size); | | 687 | size = min(sizeof(atcs_output), size); |
686 | | | 688 | |
687 | memcpy(&atcs_output, info->buffer.pointer, size); | | 689 | memcpy(&atcs_output, info->buffer.pointer, size); |
688 | | | 690 | |
689 | ACPI_FREE(info); | | 691 | ACPI_FREE(info); |
690 | | | 692 | |
691 | switch (atcs_output.ret_val) { | | 693 | switch (atcs_output.ret_val) { |
692 | case ATCS_REQUEST_REFUSED: | | 694 | case ATCS_REQUEST_REFUSED: |
693 | default: | | 695 | default: |
694 | return -EINVAL; | | 696 | return -EINVAL; |
695 | case ATCS_REQUEST_COMPLETE: | | 697 | case ATCS_REQUEST_COMPLETE: |
696 | return 0; | | 698 | return 0; |
697 | case ATCS_REQUEST_IN_PROGRESS: | | 699 | case ATCS_REQUEST_IN_PROGRESS: |
698 | udelay(10); | | 700 | udelay(10); |
699 | break; | | 701 | break; |
700 | } | | 702 | } |
701 | } | | 703 | } |
702 | | | 704 | |
703 | return 0; | | 705 | return 0; |
704 | } | | 706 | } |
705 | | | 707 | |
706 | /** | | 708 | /** |
707 | * radeon_acpi_event - handle notify events | | 709 | * radeon_acpi_event - handle notify events |
708 | * | | 710 | * |
709 | * @nb: notifier block | | 711 | * @nb: notifier block |
710 | * @val: val | | 712 | * @val: val |
711 | * @data: acpi event | | 713 | * @data: acpi event |
712 | * | | 714 | * |
713 | * Calls relevant radeon functions in response to various | | 715 | * Calls relevant radeon functions in response to various |
714 | * acpi events. | | 716 | * acpi events. |
715 | * Returns NOTIFY code | | 717 | * Returns NOTIFY code |
716 | */ | | 718 | */ |
717 | #ifndef __NetBSD__ /* XXX radeon acpi */ | | 719 | #ifndef __NetBSD__ /* XXX radeon acpi */ |
718 | static int radeon_acpi_event(struct notifier_block *nb, | | 720 | static int radeon_acpi_event(struct notifier_block *nb, |
719 | unsigned long val, | | 721 | unsigned long val, |
720 | void *data) | | 722 | void *data) |
721 | { | | 723 | { |
722 | struct radeon_device *rdev = container_of(nb, struct radeon_device, acpi_nb); | | 724 | struct radeon_device *rdev = container_of(nb, struct radeon_device, acpi_nb); |
723 | struct acpi_bus_event *entry = (struct acpi_bus_event *)data; | | 725 | struct acpi_bus_event *entry = (struct acpi_bus_event *)data; |
724 | | | 726 | |
725 | if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) { | | 727 | if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) { |
726 | if (power_supply_is_system_supplied() > 0) | | 728 | if (power_supply_is_system_supplied() > 0) |
727 | DRM_DEBUG_DRIVER("pm: AC\n"); | | 729 | DRM_DEBUG_DRIVER("pm: AC\n"); |
728 | else | | 730 | else |
729 | DRM_DEBUG_DRIVER("pm: DC\n"); | | 731 | DRM_DEBUG_DRIVER("pm: DC\n"); |
730 | | | 732 | |
731 | radeon_pm_acpi_event_handler(rdev); | | 733 | radeon_pm_acpi_event_handler(rdev); |
732 | } | | 734 | } |
733 | | | 735 | |
734 | /* Check for pending SBIOS requests */ | | 736 | /* Check for pending SBIOS requests */ |
735 | return radeon_atif_handler(rdev, entry); | | 737 | return radeon_atif_handler(rdev, entry); |
736 | } | | 738 | } |
737 | #endif | | 739 | #endif |
738 | | | 740 | |
739 | /* Call all ACPI methods here */ | | 741 | /* Call all ACPI methods here */ |
740 | /** | | 742 | /** |
741 | * radeon_acpi_init - init driver acpi support | | 743 | * radeon_acpi_init - init driver acpi support |
742 | * | | 744 | * |
743 | * @rdev: radeon_device pointer | | 745 | * @rdev: radeon_device pointer |
744 | * | | 746 | * |
745 | * Verifies the AMD ACPI interfaces and registers with the acpi | | 747 | * Verifies the AMD ACPI interfaces and registers with the acpi |
746 | * notifier chain (all asics). | | 748 | * notifier chain (all asics). |
747 | * Returns 0 on success, error on failure. | | 749 | * Returns 0 on success, error on failure. |
748 | */ | | 750 | */ |
749 | int radeon_acpi_init(struct radeon_device *rdev) | | 751 | int radeon_acpi_init(struct radeon_device *rdev) |
750 | { | | 752 | { |
751 | acpi_handle handle; | | 753 | acpi_handle handle; |
752 | struct radeon_atif *atif = &rdev->atif; | | 754 | struct radeon_atif *atif = &rdev->atif; |
753 | struct radeon_atcs *atcs = &rdev->atcs; | | 755 | struct radeon_atcs *atcs = &rdev->atcs; |
754 | int ret; | | 756 | int ret; |
755 | | | 757 | |
756 | /* Get the device handle */ | | 758 | /* Get the device handle */ |
757 | #ifdef __NetBSD__ | | 759 | #ifdef __NetBSD__ |
758 | const struct pci_attach_args *pa = &rdev->pdev->pd_pa; | | 760 | const struct pci_attach_args *pa = &rdev->pdev->pd_pa; |
759 | struct acpi_devnode *const d = | | 761 | struct acpi_devnode *const d = |
760 | acpi_pcidev_find(pci_get_segment(pa->pa_pc), | | 762 | acpi_pcidev_find(pci_get_segment(pa->pa_pc), |
761 | pa->pa_bus, pa->pa_device, pa->pa_function); | | 763 | pa->pa_bus, pa->pa_device, pa->pa_function); |
762 | if (d == NULL) | | 764 | if (d == NULL) |
763 | return -EINVAL; | | 765 | return -EINVAL; |
764 | handle = d->ad_handle; | | 766 | handle = d->ad_handle; |
765 | #else | | 767 | #else |
766 | handle = ACPI_HANDLE(&rdev->pdev->dev); | | 768 | handle = ACPI_HANDLE(&rdev->pdev->dev); |
767 | #endif | | 769 | #endif |
768 | | | 770 | |
769 | /* No need to proceed if we're sure that ATIF is not supported */ | | 771 | /* No need to proceed if we're sure that ATIF is not supported */ |
770 | if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle) | | 772 | if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle) |
771 | return 0; | | 773 | return 0; |
772 | | | 774 | |
773 | /* Call the ATCS method */ | | 775 | /* Call the ATCS method */ |
774 | ret = radeon_atcs_verify_interface(handle, atcs); | | 776 | ret = radeon_atcs_verify_interface(handle, atcs); |
775 | if (ret) { | | 777 | if (ret) { |
776 | DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret); | | 778 | DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret); |
777 | } | | 779 | } |
778 | | | 780 | |
779 | /* Call the ATIF method */ | | 781 | /* Call the ATIF method */ |
780 | ret = radeon_atif_verify_interface(handle, atif); | | 782 | ret = radeon_atif_verify_interface(handle, atif); |
781 | if (ret) { | | 783 | if (ret) { |
782 | DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret); | | 784 | DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret); |
783 | goto out; | | 785 | goto out; |
784 | } | | 786 | } |
785 | | | 787 | |
786 | if (atif->notifications.brightness_change) { | | 788 | if (atif->notifications.brightness_change) { |
787 | struct drm_encoder *tmp; | | 789 | struct drm_encoder *tmp; |
788 | struct radeon_encoder *target = NULL; | | 790 | struct radeon_encoder *target = NULL; |
789 | | | 791 | |
790 | /* Find the encoder controlling the brightness */ | | 792 | /* Find the encoder controlling the brightness */ |
791 | list_for_each_entry(tmp, &rdev->ddev->mode_config.encoder_list, | | 793 | list_for_each_entry(tmp, &rdev->ddev->mode_config.encoder_list, |
792 | head) { | | 794 | head) { |
793 | struct radeon_encoder *enc = to_radeon_encoder(tmp); | | 795 | struct radeon_encoder *enc = to_radeon_encoder(tmp); |
794 | | | 796 | |
795 | if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) && | | 797 | if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) && |
796 | enc->enc_priv) { | | 798 | enc->enc_priv) { |
797 | if (rdev->is_atom_bios) { | | 799 | if (rdev->is_atom_bios) { |
798 | struct radeon_encoder_atom_dig *dig = enc->enc_priv; | | 800 | struct radeon_encoder_atom_dig *dig = enc->enc_priv; |
799 | if (dig->bl_dev) { | | 801 | if (dig->bl_dev) { |
800 | target = enc; | | 802 | target = enc; |
801 | break; | | 803 | break; |
802 | } | | 804 | } |
803 | } else { | | 805 | } else { |
804 | struct radeon_encoder_lvds *dig = enc->enc_priv; | | 806 | struct radeon_encoder_lvds *dig = enc->enc_priv; |
805 | if (dig->bl_dev) { | | 807 | if (dig->bl_dev) { |
806 | target = enc; | | 808 | target = enc; |
807 | break; | | 809 | break; |
808 | } | | 810 | } |
809 | } | | 811 | } |
810 | } | | 812 | } |
811 | } | | 813 | } |
812 | | | 814 | |
813 | atif->encoder_for_bl = target; | | 815 | atif->encoder_for_bl = target; |
814 | } | | 816 | } |
815 | | | 817 | |
816 | if (atif->functions.sbios_requests && !atif->functions.system_params) { | | 818 | if (atif->functions.sbios_requests && !atif->functions.system_params) { |
817 | /* XXX check this workraround, if sbios request function is | | 819 | /* XXX check this workraround, if sbios request function is |
818 | * present we have to see how it's configured in the system | | 820 | * present we have to see how it's configured in the system |
819 | * params | | 821 | * params |
820 | */ | | 822 | */ |
821 | atif->functions.system_params = true; | | 823 | atif->functions.system_params = true; |
822 | } | | 824 | } |
823 | | | 825 | |
824 | if (atif->functions.system_params) { | | 826 | if (atif->functions.system_params) { |
825 | ret = radeon_atif_get_notification_params(handle, | | 827 | ret = radeon_atif_get_notification_params(handle, |
826 | &atif->notification_cfg); | | 828 | &atif->notification_cfg); |
827 | if (ret) { | | 829 | if (ret) { |
828 | DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n", | | 830 | DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n", |
829 | ret); | | 831 | ret); |
830 | /* Disable notification */ | | 832 | /* Disable notification */ |
831 | atif->notification_cfg.enabled = false; | | 833 | atif->notification_cfg.enabled = false; |
832 | } | | 834 | } |
833 | } | | 835 | } |
834 | | | 836 | |
835 | out: | | 837 | out: |
836 | #ifndef __NetBSD__ /* XXX radeon acpi */ | | 838 | #ifndef __NetBSD__ /* XXX radeon acpi */ |
837 | rdev->acpi_nb.notifier_call = radeon_acpi_event; | | 839 | rdev->acpi_nb.notifier_call = radeon_acpi_event; |
838 | register_acpi_notifier(&rdev->acpi_nb); | | 840 | register_acpi_notifier(&rdev->acpi_nb); |
839 | #endif | | 841 | #endif |
840 | | | 842 | |
841 | return ret; | | 843 | return ret; |
842 | } | | 844 | } |
843 | | | 845 | |
844 | /** | | 846 | /** |
845 | * radeon_acpi_fini - tear down driver acpi support | | 847 | * radeon_acpi_fini - tear down driver acpi support |
846 | * | | 848 | * |
847 | * @rdev: radeon_device pointer | | 849 | * @rdev: radeon_device pointer |
848 | * | | 850 | * |
849 | * Unregisters with the acpi notifier chain (all asics). | | 851 | * Unregisters with the acpi notifier chain (all asics). |
850 | */ | | 852 | */ |
851 | void radeon_acpi_fini(struct radeon_device *rdev) | | 853 | void radeon_acpi_fini(struct radeon_device *rdev) |
852 | { | | 854 | { |
853 | #ifndef __NetBSD__ /* XXX radeon acpi */ | | 855 | #ifndef __NetBSD__ /* XXX radeon acpi */ |
854 | unregister_acpi_notifier(&rdev->acpi_nb); | | 856 | unregister_acpi_notifier(&rdev->acpi_nb); |
855 | #endif | | 857 | #endif |
856 | } | | 858 | } |