6996b316d5c5fc4eab39eddefc48fa03071ef2f6
[cascardo/linux.git] / drivers / gpu / drm / radeon / radeon_atpx_handler.c
1 /*
2  * Copyright (c) 2010 Red Hat Inc.
3  * Author : Dave Airlie <airlied@redhat.com>
4  *
5  * Licensed under GPLv2
6  *
7  * ATPX support for both Intel/ATI
8  */
9 #include <linux/vga_switcheroo.h>
10 #include <linux/slab.h>
11 #include <linux/acpi.h>
12 #include <linux/pci.h>
13 #include <linux/delay.h>
14
15 #include "radeon_acpi.h"
16
17 struct radeon_atpx_functions {
18         bool px_params;
19         bool power_cntl;
20         bool disp_mux_cntl;
21         bool i2c_mux_cntl;
22         bool switch_start;
23         bool switch_end;
24         bool disp_connectors_mapping;
25         bool disp_detetion_ports;
26 };
27
28 struct radeon_atpx {
29         acpi_handle handle;
30         struct radeon_atpx_functions functions;
31 };
32
33 static struct radeon_atpx_priv {
34         bool atpx_detected;
35         /* handle for device - and atpx */
36         acpi_handle dhandle;
37         struct radeon_atpx atpx;
38 } radeon_atpx_priv;
39
40 struct atpx_verify_interface {
41         u16 size;               /* structure size in bytes (includes size field) */
42         u16 version;            /* version */
43         u32 function_bits;      /* supported functions bit vector */
44 } __packed;
45
46 struct atpx_px_params {
47         u16 size;               /* structure size in bytes (includes size field) */
48         u32 valid_flags;        /* which flags are valid */
49         u32 flags;              /* flags */
50 } __packed;
51
52 struct atpx_power_control {
53         u16 size;
54         u8 dgpu_state;
55 } __packed;
56
57 struct atpx_mux {
58         u16 size;
59         u16 mux;
60 } __packed;
61
62 bool radeon_has_atpx(void) {
63         return radeon_atpx_priv.atpx_detected;
64 }
65
66 bool radeon_has_atpx_dgpu_power_cntl(void) {
67         return radeon_atpx_priv.atpx.functions.power_cntl;
68 }
69
70 /**
71  * radeon_atpx_call - call an ATPX method
72  *
73  * @handle: acpi handle
74  * @function: the ATPX function to execute
75  * @params: ATPX function params
76  *
77  * Executes the requested ATPX function (all asics).
78  * Returns a pointer to the acpi output buffer.
79  */
80 static union acpi_object *radeon_atpx_call(acpi_handle handle, int function,
81                                            struct acpi_buffer *params)
82 {
83         acpi_status status;
84         union acpi_object atpx_arg_elements[2];
85         struct acpi_object_list atpx_arg;
86         struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
87
88         atpx_arg.count = 2;
89         atpx_arg.pointer = &atpx_arg_elements[0];
90
91         atpx_arg_elements[0].type = ACPI_TYPE_INTEGER;
92         atpx_arg_elements[0].integer.value = function;
93
94         if (params) {
95                 atpx_arg_elements[1].type = ACPI_TYPE_BUFFER;
96                 atpx_arg_elements[1].buffer.length = params->length;
97                 atpx_arg_elements[1].buffer.pointer = params->pointer;
98         } else {
99                 /* We need a second fake parameter */
100                 atpx_arg_elements[1].type = ACPI_TYPE_INTEGER;
101                 atpx_arg_elements[1].integer.value = 0;
102         }
103
104         status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
105
106         /* Fail only if calling the method fails and ATPX is supported */
107         if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
108                 printk("failed to evaluate ATPX got %s\n",
109                        acpi_format_exception(status));
110                 kfree(buffer.pointer);
111                 return NULL;
112         }
113
114         return buffer.pointer;
115 }
116
117 /**
118  * radeon_atpx_parse_functions - parse supported functions
119  *
120  * @f: supported functions struct
121  * @mask: supported functions mask from ATPX
122  *
123  * Use the supported functions mask from ATPX function
124  * ATPX_FUNCTION_VERIFY_INTERFACE to determine what functions
125  * are supported (all asics).
126  */
127 static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mask)
128 {
129         f->px_params = mask & ATPX_GET_PX_PARAMETERS_SUPPORTED;
130         f->power_cntl = mask & ATPX_POWER_CONTROL_SUPPORTED;
131         f->disp_mux_cntl = mask & ATPX_DISPLAY_MUX_CONTROL_SUPPORTED;
132         f->i2c_mux_cntl = mask & ATPX_I2C_MUX_CONTROL_SUPPORTED;
133         f->switch_start = mask & ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED;
134         f->switch_end = mask & ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED;
135         f->disp_connectors_mapping = mask & ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED;
136         f->disp_detetion_ports = mask & ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED;
137 }
138
139 /**
140  * radeon_atpx_validate_functions - validate ATPX functions
141  *
142  * @atpx: radeon atpx struct
143  *
144  * Validate that required functions are enabled (all asics).
145  * returns 0 on success, error on failure.
146  */
147 static int radeon_atpx_validate(struct radeon_atpx *atpx)
148 {
149         u32 valid_bits = 0;
150
151         if (atpx->functions.px_params) {
152                 union acpi_object *info;
153                 struct atpx_px_params output;
154                 size_t size;
155
156                 info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL);
157                 if (!info)
158                         return -EIO;
159
160                 memset(&output, 0, sizeof(output));
161
162                 size = *(u16 *) info->buffer.pointer;
163                 if (size < 10) {
164                         printk("ATPX buffer is too small: %zu\n", size);
165                         kfree(info);
166                         return -EINVAL;
167                 }
168                 size = min(sizeof(output), size);
169
170                 memcpy(&output, info->buffer.pointer, size);
171
172                 valid_bits = output.flags & output.valid_flags;
173
174                 kfree(info);
175         }
176
177         /* if separate mux flag is set, mux controls are required */
178         if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) {
179                 atpx->functions.i2c_mux_cntl = true;
180                 atpx->functions.disp_mux_cntl = true;
181         }
182         /* if any outputs are muxed, mux controls are required */
183         if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED |
184                           ATPX_TV_SIGNAL_MUXED |
185                           ATPX_DFP_SIGNAL_MUXED))
186                 atpx->functions.disp_mux_cntl = true;
187
188         /* some bioses set these bits rather than flagging power_cntl as supported */
189         if (valid_bits & (ATPX_DYNAMIC_PX_SUPPORTED |
190                           ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED))
191                 atpx->functions.power_cntl = true;
192
193         if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {
194                 printk("Hybrid Graphics, ATPX dGPU power cntl disabled\n");
195                 atpx->functions.power_cntl = false;
196         }
197
198         return 0;
199 }
200
201 /**
202  * radeon_atpx_verify_interface - verify ATPX
203  *
204  * @atpx: radeon atpx struct
205  *
206  * Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function
207  * to initialize ATPX and determine what features are supported
208  * (all asics).
209  * returns 0 on success, error on failure.
210  */
211 static int radeon_atpx_verify_interface(struct radeon_atpx *atpx)
212 {
213         union acpi_object *info;
214         struct atpx_verify_interface output;
215         size_t size;
216         int err = 0;
217
218         info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_VERIFY_INTERFACE, NULL);
219         if (!info)
220                 return -EIO;
221
222         memset(&output, 0, sizeof(output));
223
224         size = *(u16 *) info->buffer.pointer;
225         if (size < 8) {
226                 printk("ATPX buffer is too small: %zu\n", size);
227                 err = -EINVAL;
228                 goto out;
229         }
230         size = min(sizeof(output), size);
231
232         memcpy(&output, info->buffer.pointer, size);
233
234         /* TODO: check version? */
235         printk("ATPX version %u, functions 0x%08x\n",
236                output.version, output.function_bits);
237
238         radeon_atpx_parse_functions(&atpx->functions, output.function_bits);
239
240 out:
241         kfree(info);
242         return err;
243 }
244
245 /**
246  * radeon_atpx_set_discrete_state - power up/down discrete GPU
247  *
248  * @atpx: atpx info struct
249  * @state: discrete GPU state (0 = power down, 1 = power up)
250  *
251  * Execute the ATPX_FUNCTION_POWER_CONTROL ATPX function to
252  * power down/up the discrete GPU (all asics).
253  * Returns 0 on success, error on failure.
254  */
255 static int radeon_atpx_set_discrete_state(struct radeon_atpx *atpx, u8 state)
256 {
257         struct acpi_buffer params;
258         union acpi_object *info;
259         struct atpx_power_control input;
260
261         if (atpx->functions.power_cntl) {
262                 input.size = 3;
263                 input.dgpu_state = state;
264                 params.length = input.size;
265                 params.pointer = &input;
266                 info = radeon_atpx_call(atpx->handle,
267                                         ATPX_FUNCTION_POWER_CONTROL,
268                                         &params);
269                 if (!info)
270                         return -EIO;
271                 kfree(info);
272
273                 /* 200ms delay is required after off */
274                 if (state == 0)
275                         msleep(200);
276         }
277         return 0;
278 }
279
280 /**
281  * radeon_atpx_switch_disp_mux - switch display mux
282  *
283  * @atpx: atpx info struct
284  * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
285  *
286  * Execute the ATPX_FUNCTION_DISPLAY_MUX_CONTROL ATPX function to
287  * switch the display mux between the discrete GPU and integrated GPU
288  * (all asics).
289  * Returns 0 on success, error on failure.
290  */
291 static int radeon_atpx_switch_disp_mux(struct radeon_atpx *atpx, u16 mux_id)
292 {
293         struct acpi_buffer params;
294         union acpi_object *info;
295         struct atpx_mux input;
296
297         if (atpx->functions.disp_mux_cntl) {
298                 input.size = 4;
299                 input.mux = mux_id;
300                 params.length = input.size;
301                 params.pointer = &input;
302                 info = radeon_atpx_call(atpx->handle,
303                                         ATPX_FUNCTION_DISPLAY_MUX_CONTROL,
304                                         &params);
305                 if (!info)
306                         return -EIO;
307                 kfree(info);
308         }
309         return 0;
310 }
311
312 /**
313  * radeon_atpx_switch_i2c_mux - switch i2c/hpd mux
314  *
315  * @atpx: atpx info struct
316  * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
317  *
318  * Execute the ATPX_FUNCTION_I2C_MUX_CONTROL ATPX function to
319  * switch the i2c/hpd mux between the discrete GPU and integrated GPU
320  * (all asics).
321  * Returns 0 on success, error on failure.
322  */
323 static int radeon_atpx_switch_i2c_mux(struct radeon_atpx *atpx, u16 mux_id)
324 {
325         struct acpi_buffer params;
326         union acpi_object *info;
327         struct atpx_mux input;
328
329         if (atpx->functions.i2c_mux_cntl) {
330                 input.size = 4;
331                 input.mux = mux_id;
332                 params.length = input.size;
333                 params.pointer = &input;
334                 info = radeon_atpx_call(atpx->handle,
335                                         ATPX_FUNCTION_I2C_MUX_CONTROL,
336                                         &params);
337                 if (!info)
338                         return -EIO;
339                 kfree(info);
340         }
341         return 0;
342 }
343
344 /**
345  * radeon_atpx_switch_start - notify the sbios of a GPU switch
346  *
347  * @atpx: atpx info struct
348  * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
349  *
350  * Execute the ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION ATPX
351  * function to notify the sbios that a switch between the discrete GPU and
352  * integrated GPU has begun (all asics).
353  * Returns 0 on success, error on failure.
354  */
355 static int radeon_atpx_switch_start(struct radeon_atpx *atpx, u16 mux_id)
356 {
357         struct acpi_buffer params;
358         union acpi_object *info;
359         struct atpx_mux input;
360
361         if (atpx->functions.switch_start) {
362                 input.size = 4;
363                 input.mux = mux_id;
364                 params.length = input.size;
365                 params.pointer = &input;
366                 info = radeon_atpx_call(atpx->handle,
367                                         ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION,
368                                         &params);
369                 if (!info)
370                         return -EIO;
371                 kfree(info);
372         }
373         return 0;
374 }
375
376 /**
377  * radeon_atpx_switch_end - notify the sbios of a GPU switch
378  *
379  * @atpx: atpx info struct
380  * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
381  *
382  * Execute the ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION ATPX
383  * function to notify the sbios that a switch between the discrete GPU and
384  * integrated GPU has ended (all asics).
385  * Returns 0 on success, error on failure.
386  */
387 static int radeon_atpx_switch_end(struct radeon_atpx *atpx, u16 mux_id)
388 {
389         struct acpi_buffer params;
390         union acpi_object *info;
391         struct atpx_mux input;
392
393         if (atpx->functions.switch_end) {
394                 input.size = 4;
395                 input.mux = mux_id;
396                 params.length = input.size;
397                 params.pointer = &input;
398                 info = radeon_atpx_call(atpx->handle,
399                                         ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION,
400                                         &params);
401                 if (!info)
402                         return -EIO;
403                 kfree(info);
404         }
405         return 0;
406 }
407
408 /**
409  * radeon_atpx_switchto - switch to the requested GPU
410  *
411  * @id: GPU to switch to
412  *
413  * Execute the necessary ATPX functions to switch between the discrete GPU and
414  * integrated GPU (all asics).
415  * Returns 0 on success, error on failure.
416  */
417 static int radeon_atpx_switchto(enum vga_switcheroo_client_id id)
418 {
419         u16 gpu_id;
420
421         if (id == VGA_SWITCHEROO_IGD)
422                 gpu_id = ATPX_INTEGRATED_GPU;
423         else
424                 gpu_id = ATPX_DISCRETE_GPU;
425
426         radeon_atpx_switch_start(&radeon_atpx_priv.atpx, gpu_id);
427         radeon_atpx_switch_disp_mux(&radeon_atpx_priv.atpx, gpu_id);
428         radeon_atpx_switch_i2c_mux(&radeon_atpx_priv.atpx, gpu_id);
429         radeon_atpx_switch_end(&radeon_atpx_priv.atpx, gpu_id);
430
431         return 0;
432 }
433
434 /**
435  * radeon_atpx_power_state - power down/up the requested GPU
436  *
437  * @id: GPU to power down/up
438  * @state: requested power state (0 = off, 1 = on)
439  *
440  * Execute the necessary ATPX function to power down/up the discrete GPU
441  * (all asics).
442  * Returns 0 on success, error on failure.
443  */
444 static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,
445                                    enum vga_switcheroo_state state)
446 {
447         /* on w500 ACPI can't change intel gpu state */
448         if (id == VGA_SWITCHEROO_IGD)
449                 return 0;
450
451         radeon_atpx_set_discrete_state(&radeon_atpx_priv.atpx, state);
452         return 0;
453 }
454
455 /**
456  * radeon_atpx_pci_probe_handle - look up the ATPX handle
457  *
458  * @pdev: pci device
459  *
460  * Look up the ATPX handles (all asics).
461  * Returns true if the handles are found, false if not.
462  */
463 static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
464 {
465         acpi_handle dhandle, atpx_handle;
466         acpi_status status;
467
468         dhandle = ACPI_HANDLE(&pdev->dev);
469         if (!dhandle)
470                 return false;
471
472         status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
473         if (ACPI_FAILURE(status))
474                 return false;
475
476         radeon_atpx_priv.dhandle = dhandle;
477         radeon_atpx_priv.atpx.handle = atpx_handle;
478         return true;
479 }
480
481 /**
482  * radeon_atpx_init - verify the ATPX interface
483  *
484  * Verify the ATPX interface (all asics).
485  * Returns 0 on success, error on failure.
486  */
487 static int radeon_atpx_init(void)
488 {
489         int r;
490
491         /* set up the ATPX handle */
492         r = radeon_atpx_verify_interface(&radeon_atpx_priv.atpx);
493         if (r)
494                 return r;
495
496         /* validate the atpx setup */
497         r = radeon_atpx_validate(&radeon_atpx_priv.atpx);
498         if (r)
499                 return r;
500
501         return 0;
502 }
503
504 /**
505  * radeon_atpx_get_client_id - get the client id
506  *
507  * @pdev: pci device
508  *
509  * look up whether we are the integrated or discrete GPU (all asics).
510  * Returns the client id.
511  */
512 static int radeon_atpx_get_client_id(struct pci_dev *pdev)
513 {
514         if (radeon_atpx_priv.dhandle == ACPI_HANDLE(&pdev->dev))
515                 return VGA_SWITCHEROO_IGD;
516         else
517                 return VGA_SWITCHEROO_DIS;
518 }
519
520 static const struct vga_switcheroo_handler radeon_atpx_handler = {
521         .switchto = radeon_atpx_switchto,
522         .power_state = radeon_atpx_power_state,
523         .init = radeon_atpx_init,
524         .get_client_id = radeon_atpx_get_client_id,
525 };
526
527 /**
528  * radeon_atpx_detect - detect whether we have PX
529  *
530  * Check if we have a PX system (all asics).
531  * Returns true if we have a PX system, false if not.
532  */
533 static bool radeon_atpx_detect(void)
534 {
535         char acpi_method_name[255] = { 0 };
536         struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
537         struct pci_dev *pdev = NULL;
538         bool has_atpx = false;
539         int vga_count = 0;
540
541         while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
542                 vga_count++;
543
544                 has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
545         }
546
547         /* some newer PX laptops mark the dGPU as a non-VGA display device */
548         while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
549                 vga_count++;
550
551                 has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
552         }
553
554         if (has_atpx && vga_count == 2) {
555                 acpi_get_name(radeon_atpx_priv.atpx.handle, ACPI_FULL_PATHNAME, &buffer);
556                 printk(KERN_INFO "vga_switcheroo: detected switching method %s handle\n",
557                        acpi_method_name);
558                 radeon_atpx_priv.atpx_detected = true;
559                 return true;
560         }
561         return false;
562 }
563
564 /**
565  * radeon_register_atpx_handler - register with vga_switcheroo
566  *
567  * Register the PX callbacks with vga_switcheroo (all asics).
568  */
569 void radeon_register_atpx_handler(void)
570 {
571         bool r;
572         enum vga_switcheroo_handler_flags_t handler_flags = 0;
573
574         /* detect if we have any ATPX + 2 VGA in the system */
575         r = radeon_atpx_detect();
576         if (!r)
577                 return;
578
579         vga_switcheroo_register_handler(&radeon_atpx_handler, handler_flags);
580 }
581
582 /**
583  * radeon_unregister_atpx_handler - unregister with vga_switcheroo
584  *
585  * Unregister the PX callbacks with vga_switcheroo (all asics).
586  */
587 void radeon_unregister_atpx_handler(void)
588 {
589         vga_switcheroo_unregister_handler();
590 }