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