Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2012 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  */
0023 
0024 #include <linux/pci.h>
0025 #include <linux/acpi.h>
0026 #include <linux/slab.h>
0027 #include <linux/power_supply.h>
0028 #include <linux/pm_runtime.h>
0029 #include <linux/suspend.h>
0030 #include <acpi/video.h>
0031 #include <acpi/actbl.h>
0032 
0033 #include <drm/drm_crtc_helper.h>
0034 #include "amdgpu.h"
0035 #include "amdgpu_pm.h"
0036 #include "amdgpu_display.h"
0037 #include "amd_acpi.h"
0038 #include "atom.h"
0039 
0040 struct amdgpu_atif_notification_cfg {
0041     bool enabled;
0042     int command_code;
0043 };
0044 
0045 struct amdgpu_atif_notifications {
0046     bool thermal_state;
0047     bool forced_power_state;
0048     bool system_power_state;
0049     bool brightness_change;
0050     bool dgpu_display_event;
0051     bool gpu_package_power_limit;
0052 };
0053 
0054 struct amdgpu_atif_functions {
0055     bool system_params;
0056     bool sbios_requests;
0057     bool temperature_change;
0058     bool query_backlight_transfer_characteristics;
0059     bool ready_to_undock;
0060     bool external_gpu_information;
0061 };
0062 
0063 struct amdgpu_atif {
0064     acpi_handle handle;
0065 
0066     struct amdgpu_atif_notifications notifications;
0067     struct amdgpu_atif_functions functions;
0068     struct amdgpu_atif_notification_cfg notification_cfg;
0069     struct backlight_device *bd;
0070     struct amdgpu_dm_backlight_caps backlight_caps;
0071 };
0072 
0073 struct amdgpu_atcs_functions {
0074     bool get_ext_state;
0075     bool pcie_perf_req;
0076     bool pcie_dev_rdy;
0077     bool pcie_bus_width;
0078     bool power_shift_control;
0079 };
0080 
0081 struct amdgpu_atcs {
0082     acpi_handle handle;
0083 
0084     struct amdgpu_atcs_functions functions;
0085 };
0086 
0087 static struct amdgpu_acpi_priv {
0088     struct amdgpu_atif atif;
0089     struct amdgpu_atcs atcs;
0090 } amdgpu_acpi_priv;
0091 
0092 /* Call the ATIF method
0093  */
0094 /**
0095  * amdgpu_atif_call - call an ATIF method
0096  *
0097  * @atif: atif structure
0098  * @function: the ATIF function to execute
0099  * @params: ATIF function params
0100  *
0101  * Executes the requested ATIF function (all asics).
0102  * Returns a pointer to the acpi output buffer.
0103  */
0104 static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
0105                        int function,
0106                        struct acpi_buffer *params)
0107 {
0108     acpi_status status;
0109     union acpi_object atif_arg_elements[2];
0110     struct acpi_object_list atif_arg;
0111     struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
0112 
0113     atif_arg.count = 2;
0114     atif_arg.pointer = &atif_arg_elements[0];
0115 
0116     atif_arg_elements[0].type = ACPI_TYPE_INTEGER;
0117     atif_arg_elements[0].integer.value = function;
0118 
0119     if (params) {
0120         atif_arg_elements[1].type = ACPI_TYPE_BUFFER;
0121         atif_arg_elements[1].buffer.length = params->length;
0122         atif_arg_elements[1].buffer.pointer = params->pointer;
0123     } else {
0124         /* We need a second fake parameter */
0125         atif_arg_elements[1].type = ACPI_TYPE_INTEGER;
0126         atif_arg_elements[1].integer.value = 0;
0127     }
0128 
0129     status = acpi_evaluate_object(atif->handle, NULL, &atif_arg,
0130                       &buffer);
0131 
0132     /* Fail only if calling the method fails and ATIF is supported */
0133     if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
0134         DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
0135                  acpi_format_exception(status));
0136         kfree(buffer.pointer);
0137         return NULL;
0138     }
0139 
0140     return buffer.pointer;
0141 }
0142 
0143 /**
0144  * amdgpu_atif_parse_notification - parse supported notifications
0145  *
0146  * @n: supported notifications struct
0147  * @mask: supported notifications mask from ATIF
0148  *
0149  * Use the supported notifications mask from ATIF function
0150  * ATIF_FUNCTION_VERIFY_INTERFACE to determine what notifications
0151  * are supported (all asics).
0152  */
0153 static void amdgpu_atif_parse_notification(struct amdgpu_atif_notifications *n, u32 mask)
0154 {
0155     n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED;
0156     n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED;
0157     n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED;
0158     n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED;
0159     n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED;
0160     n->gpu_package_power_limit = mask & ATIF_GPU_PACKAGE_POWER_LIMIT_REQUEST_SUPPORTED;
0161 }
0162 
0163 /**
0164  * amdgpu_atif_parse_functions - parse supported functions
0165  *
0166  * @f: supported functions struct
0167  * @mask: supported functions mask from ATIF
0168  *
0169  * Use the supported functions mask from ATIF function
0170  * ATIF_FUNCTION_VERIFY_INTERFACE to determine what functions
0171  * are supported (all asics).
0172  */
0173 static void amdgpu_atif_parse_functions(struct amdgpu_atif_functions *f, u32 mask)
0174 {
0175     f->system_params = mask & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED;
0176     f->sbios_requests = mask & ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED;
0177     f->temperature_change = mask & ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED;
0178     f->query_backlight_transfer_characteristics =
0179         mask & ATIF_QUERY_BACKLIGHT_TRANSFER_CHARACTERISTICS_SUPPORTED;
0180     f->ready_to_undock = mask & ATIF_READY_TO_UNDOCK_NOTIFICATION_SUPPORTED;
0181     f->external_gpu_information = mask & ATIF_GET_EXTERNAL_GPU_INFORMATION_SUPPORTED;
0182 }
0183 
0184 /**
0185  * amdgpu_atif_verify_interface - verify ATIF
0186  *
0187  * @atif: amdgpu atif struct
0188  *
0189  * Execute the ATIF_FUNCTION_VERIFY_INTERFACE ATIF function
0190  * to initialize ATIF and determine what features are supported
0191  * (all asics).
0192  * returns 0 on success, error on failure.
0193  */
0194 static int amdgpu_atif_verify_interface(struct amdgpu_atif *atif)
0195 {
0196     union acpi_object *info;
0197     struct atif_verify_interface output;
0198     size_t size;
0199     int err = 0;
0200 
0201     info = amdgpu_atif_call(atif, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
0202     if (!info)
0203         return -EIO;
0204 
0205     memset(&output, 0, sizeof(output));
0206 
0207     size = *(u16 *) info->buffer.pointer;
0208     if (size < 12) {
0209         DRM_INFO("ATIF buffer is too small: %zu\n", size);
0210         err = -EINVAL;
0211         goto out;
0212     }
0213     size = min(sizeof(output), size);
0214 
0215     memcpy(&output, info->buffer.pointer, size);
0216 
0217     /* TODO: check version? */
0218     DRM_DEBUG_DRIVER("ATIF version %u\n", output.version);
0219 
0220     amdgpu_atif_parse_notification(&atif->notifications, output.notification_mask);
0221     amdgpu_atif_parse_functions(&atif->functions, output.function_bits);
0222 
0223 out:
0224     kfree(info);
0225     return err;
0226 }
0227 
0228 /**
0229  * amdgpu_atif_get_notification_params - determine notify configuration
0230  *
0231  * @atif: acpi handle
0232  *
0233  * Execute the ATIF_FUNCTION_GET_SYSTEM_PARAMETERS ATIF function
0234  * to determine if a notifier is used and if so which one
0235  * (all asics).  This is either Notify(VGA, 0x81) or Notify(VGA, n)
0236  * where n is specified in the result if a notifier is used.
0237  * Returns 0 on success, error on failure.
0238  */
0239 static int amdgpu_atif_get_notification_params(struct amdgpu_atif *atif)
0240 {
0241     union acpi_object *info;
0242     struct amdgpu_atif_notification_cfg *n = &atif->notification_cfg;
0243     struct atif_system_params params;
0244     size_t size;
0245     int err = 0;
0246 
0247     info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS,
0248                 NULL);
0249     if (!info) {
0250         err = -EIO;
0251         goto out;
0252     }
0253 
0254     size = *(u16 *) info->buffer.pointer;
0255     if (size < 10) {
0256         err = -EINVAL;
0257         goto out;
0258     }
0259 
0260     memset(&params, 0, sizeof(params));
0261     size = min(sizeof(params), size);
0262     memcpy(&params, info->buffer.pointer, size);
0263 
0264     DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n",
0265             params.flags, params.valid_mask);
0266     params.flags = params.flags & params.valid_mask;
0267 
0268     if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) {
0269         n->enabled = false;
0270         n->command_code = 0;
0271     } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) {
0272         n->enabled = true;
0273         n->command_code = 0x81;
0274     } else {
0275         if (size < 11) {
0276             err = -EINVAL;
0277             goto out;
0278         }
0279         n->enabled = true;
0280         n->command_code = params.command_code;
0281     }
0282 
0283 out:
0284     DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n",
0285             (n->enabled ? "enabled" : "disabled"),
0286             n->command_code);
0287     kfree(info);
0288     return err;
0289 }
0290 
0291 /**
0292  * amdgpu_atif_query_backlight_caps - get min and max backlight input signal
0293  *
0294  * @atif: acpi handle
0295  *
0296  * Execute the QUERY_BRIGHTNESS_TRANSFER_CHARACTERISTICS ATIF function
0297  * to determine the acceptable range of backlight values
0298  *
0299  * Backlight_caps.caps_valid will be set to true if the query is successful
0300  *
0301  * The input signals are in range 0-255
0302  *
0303  * This function assumes the display with backlight is the first LCD
0304  *
0305  * Returns 0 on success, error on failure.
0306  */
0307 static int amdgpu_atif_query_backlight_caps(struct amdgpu_atif *atif)
0308 {
0309     union acpi_object *info;
0310     struct atif_qbtc_output characteristics;
0311     struct atif_qbtc_arguments arguments;
0312     struct acpi_buffer params;
0313     size_t size;
0314     int err = 0;
0315 
0316     arguments.size = sizeof(arguments);
0317     arguments.requested_display = ATIF_QBTC_REQUEST_LCD1;
0318 
0319     params.length = sizeof(arguments);
0320     params.pointer = (void *)&arguments;
0321 
0322     info = amdgpu_atif_call(atif,
0323         ATIF_FUNCTION_QUERY_BRIGHTNESS_TRANSFER_CHARACTERISTICS,
0324         &params);
0325     if (!info) {
0326         err = -EIO;
0327         goto out;
0328     }
0329 
0330     size = *(u16 *) info->buffer.pointer;
0331     if (size < 10) {
0332         err = -EINVAL;
0333         goto out;
0334     }
0335 
0336     memset(&characteristics, 0, sizeof(characteristics));
0337     size = min(sizeof(characteristics), size);
0338     memcpy(&characteristics, info->buffer.pointer, size);
0339 
0340     atif->backlight_caps.caps_valid = true;
0341     atif->backlight_caps.min_input_signal =
0342             characteristics.min_input_signal;
0343     atif->backlight_caps.max_input_signal =
0344             characteristics.max_input_signal;
0345 out:
0346     kfree(info);
0347     return err;
0348 }
0349 
0350 /**
0351  * amdgpu_atif_get_sbios_requests - get requested sbios event
0352  *
0353  * @atif: acpi handle
0354  * @req: atif sbios request struct
0355  *
0356  * Execute the ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS ATIF function
0357  * to determine what requests the sbios is making to the driver
0358  * (all asics).
0359  * Returns 0 on success, error on failure.
0360  */
0361 static int amdgpu_atif_get_sbios_requests(struct amdgpu_atif *atif,
0362                       struct atif_sbios_requests *req)
0363 {
0364     union acpi_object *info;
0365     size_t size;
0366     int count = 0;
0367 
0368     info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS,
0369                 NULL);
0370     if (!info)
0371         return -EIO;
0372 
0373     size = *(u16 *)info->buffer.pointer;
0374     if (size < 0xd) {
0375         count = -EINVAL;
0376         goto out;
0377     }
0378     memset(req, 0, sizeof(*req));
0379 
0380     size = min(sizeof(*req), size);
0381     memcpy(req, info->buffer.pointer, size);
0382     DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending);
0383 
0384     count = hweight32(req->pending);
0385 
0386 out:
0387     kfree(info);
0388     return count;
0389 }
0390 
0391 /**
0392  * amdgpu_atif_handler - handle ATIF notify requests
0393  *
0394  * @adev: amdgpu_device pointer
0395  * @event: atif sbios request struct
0396  *
0397  * Checks the acpi event and if it matches an atif event,
0398  * handles it.
0399  *
0400  * Returns:
0401  * NOTIFY_BAD or NOTIFY_DONE, depending on the event.
0402  */
0403 static int amdgpu_atif_handler(struct amdgpu_device *adev,
0404                    struct acpi_bus_event *event)
0405 {
0406     struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;
0407     int count;
0408 
0409     DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n",
0410             event->device_class, event->type);
0411 
0412     if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
0413         return NOTIFY_DONE;
0414 
0415     /* Is this actually our event? */
0416     if (!atif->notification_cfg.enabled ||
0417         event->type != atif->notification_cfg.command_code) {
0418         /* These events will generate keypresses otherwise */
0419         if (event->type == ACPI_VIDEO_NOTIFY_PROBE)
0420             return NOTIFY_BAD;
0421         else
0422             return NOTIFY_DONE;
0423     }
0424 
0425     if (atif->functions.sbios_requests) {
0426         struct atif_sbios_requests req;
0427 
0428         /* Check pending SBIOS requests */
0429         count = amdgpu_atif_get_sbios_requests(atif, &req);
0430 
0431         if (count <= 0)
0432             return NOTIFY_BAD;
0433 
0434         DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);
0435 
0436         if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) {
0437             if (atif->bd) {
0438                 DRM_DEBUG_DRIVER("Changing brightness to %d\n",
0439                          req.backlight_level);
0440                 /*
0441                  * XXX backlight_device_set_brightness() is
0442                  * hardwired to post BACKLIGHT_UPDATE_SYSFS.
0443                  * It probably should accept 'reason' parameter.
0444                  */
0445                 backlight_device_set_brightness(atif->bd, req.backlight_level);
0446             }
0447         }
0448 
0449         if (req.pending & ATIF_DGPU_DISPLAY_EVENT) {
0450             if (adev->flags & AMD_IS_PX) {
0451                 pm_runtime_get_sync(adev_to_drm(adev)->dev);
0452                 /* Just fire off a uevent and let userspace tell us what to do */
0453                 drm_helper_hpd_irq_event(adev_to_drm(adev));
0454                 pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
0455                 pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
0456             }
0457         }
0458         /* TODO: check other events */
0459     }
0460 
0461     /* We've handled the event, stop the notifier chain. The ACPI interface
0462      * overloads ACPI_VIDEO_NOTIFY_PROBE, we don't want to send that to
0463      * userspace if the event was generated only to signal a SBIOS
0464      * request.
0465      */
0466     return NOTIFY_BAD;
0467 }
0468 
0469 /* Call the ATCS method
0470  */
0471 /**
0472  * amdgpu_atcs_call - call an ATCS method
0473  *
0474  * @atcs: atcs structure
0475  * @function: the ATCS function to execute
0476  * @params: ATCS function params
0477  *
0478  * Executes the requested ATCS function (all asics).
0479  * Returns a pointer to the acpi output buffer.
0480  */
0481 static union acpi_object *amdgpu_atcs_call(struct amdgpu_atcs *atcs,
0482                        int function,
0483                        struct acpi_buffer *params)
0484 {
0485     acpi_status status;
0486     union acpi_object atcs_arg_elements[2];
0487     struct acpi_object_list atcs_arg;
0488     struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
0489 
0490     atcs_arg.count = 2;
0491     atcs_arg.pointer = &atcs_arg_elements[0];
0492 
0493     atcs_arg_elements[0].type = ACPI_TYPE_INTEGER;
0494     atcs_arg_elements[0].integer.value = function;
0495 
0496     if (params) {
0497         atcs_arg_elements[1].type = ACPI_TYPE_BUFFER;
0498         atcs_arg_elements[1].buffer.length = params->length;
0499         atcs_arg_elements[1].buffer.pointer = params->pointer;
0500     } else {
0501         /* We need a second fake parameter */
0502         atcs_arg_elements[1].type = ACPI_TYPE_INTEGER;
0503         atcs_arg_elements[1].integer.value = 0;
0504     }
0505 
0506     status = acpi_evaluate_object(atcs->handle, NULL, &atcs_arg, &buffer);
0507 
0508     /* Fail only if calling the method fails and ATIF is supported */
0509     if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
0510         DRM_DEBUG_DRIVER("failed to evaluate ATCS got %s\n",
0511                  acpi_format_exception(status));
0512         kfree(buffer.pointer);
0513         return NULL;
0514     }
0515 
0516     return buffer.pointer;
0517 }
0518 
0519 /**
0520  * amdgpu_atcs_parse_functions - parse supported functions
0521  *
0522  * @f: supported functions struct
0523  * @mask: supported functions mask from ATCS
0524  *
0525  * Use the supported functions mask from ATCS function
0526  * ATCS_FUNCTION_VERIFY_INTERFACE to determine what functions
0527  * are supported (all asics).
0528  */
0529 static void amdgpu_atcs_parse_functions(struct amdgpu_atcs_functions *f, u32 mask)
0530 {
0531     f->get_ext_state = mask & ATCS_GET_EXTERNAL_STATE_SUPPORTED;
0532     f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED;
0533     f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED;
0534     f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED;
0535     f->power_shift_control = mask & ATCS_SET_POWER_SHIFT_CONTROL_SUPPORTED;
0536 }
0537 
0538 /**
0539  * amdgpu_atcs_verify_interface - verify ATCS
0540  *
0541  * @atcs: amdgpu atcs struct
0542  *
0543  * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function
0544  * to initialize ATCS and determine what features are supported
0545  * (all asics).
0546  * returns 0 on success, error on failure.
0547  */
0548 static int amdgpu_atcs_verify_interface(struct amdgpu_atcs *atcs)
0549 {
0550     union acpi_object *info;
0551     struct atcs_verify_interface output;
0552     size_t size;
0553     int err = 0;
0554 
0555     info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_VERIFY_INTERFACE, NULL);
0556     if (!info)
0557         return -EIO;
0558 
0559     memset(&output, 0, sizeof(output));
0560 
0561     size = *(u16 *) info->buffer.pointer;
0562     if (size < 8) {
0563         DRM_INFO("ATCS buffer is too small: %zu\n", size);
0564         err = -EINVAL;
0565         goto out;
0566     }
0567     size = min(sizeof(output), size);
0568 
0569     memcpy(&output, info->buffer.pointer, size);
0570 
0571     /* TODO: check version? */
0572     DRM_DEBUG_DRIVER("ATCS version %u\n", output.version);
0573 
0574     amdgpu_atcs_parse_functions(&atcs->functions, output.function_bits);
0575 
0576 out:
0577     kfree(info);
0578     return err;
0579 }
0580 
0581 /**
0582  * amdgpu_acpi_is_pcie_performance_request_supported
0583  *
0584  * @adev: amdgpu_device pointer
0585  *
0586  * Check if the ATCS pcie_perf_req and pcie_dev_rdy methods
0587  * are supported (all asics).
0588  * returns true if supported, false if not.
0589  */
0590 bool amdgpu_acpi_is_pcie_performance_request_supported(struct amdgpu_device *adev)
0591 {
0592     struct amdgpu_atcs *atcs = &amdgpu_acpi_priv.atcs;
0593 
0594     if (atcs->functions.pcie_perf_req && atcs->functions.pcie_dev_rdy)
0595         return true;
0596 
0597     return false;
0598 }
0599 
0600 /**
0601  * amdgpu_acpi_is_power_shift_control_supported
0602  *
0603  * Check if the ATCS power shift control method
0604  * is supported.
0605  * returns true if supported, false if not.
0606  */
0607 bool amdgpu_acpi_is_power_shift_control_supported(void)
0608 {
0609     return amdgpu_acpi_priv.atcs.functions.power_shift_control;
0610 }
0611 
0612 /**
0613  * amdgpu_acpi_pcie_notify_device_ready
0614  *
0615  * @adev: amdgpu_device pointer
0616  *
0617  * Executes the PCIE_DEVICE_READY_NOTIFICATION method
0618  * (all asics).
0619  * returns 0 on success, error on failure.
0620  */
0621 int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev)
0622 {
0623     union acpi_object *info;
0624     struct amdgpu_atcs *atcs = &amdgpu_acpi_priv.atcs;
0625 
0626     if (!atcs->functions.pcie_dev_rdy)
0627         return -EINVAL;
0628 
0629     info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, NULL);
0630     if (!info)
0631         return -EIO;
0632 
0633     kfree(info);
0634 
0635     return 0;
0636 }
0637 
0638 /**
0639  * amdgpu_acpi_pcie_performance_request
0640  *
0641  * @adev: amdgpu_device pointer
0642  * @perf_req: requested perf level (pcie gen speed)
0643  * @advertise: set advertise caps flag if set
0644  *
0645  * Executes the PCIE_PERFORMANCE_REQUEST method to
0646  * change the pcie gen speed (all asics).
0647  * returns 0 on success, error on failure.
0648  */
0649 int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
0650                      u8 perf_req, bool advertise)
0651 {
0652     union acpi_object *info;
0653     struct amdgpu_atcs *atcs = &amdgpu_acpi_priv.atcs;
0654     struct atcs_pref_req_input atcs_input;
0655     struct atcs_pref_req_output atcs_output;
0656     struct acpi_buffer params;
0657     size_t size;
0658     u32 retry = 3;
0659 
0660     if (amdgpu_acpi_pcie_notify_device_ready(adev))
0661         return -EINVAL;
0662 
0663     if (!atcs->functions.pcie_perf_req)
0664         return -EINVAL;
0665 
0666     atcs_input.size = sizeof(struct atcs_pref_req_input);
0667     /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */
0668     atcs_input.client_id = adev->pdev->devfn | (adev->pdev->bus->number << 8);
0669     atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK;
0670     atcs_input.flags = ATCS_WAIT_FOR_COMPLETION;
0671     if (advertise)
0672         atcs_input.flags |= ATCS_ADVERTISE_CAPS;
0673     atcs_input.req_type = ATCS_PCIE_LINK_SPEED;
0674     atcs_input.perf_req = perf_req;
0675 
0676     params.length = sizeof(struct atcs_pref_req_input);
0677     params.pointer = &atcs_input;
0678 
0679     while (retry--) {
0680         info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, &params);
0681         if (!info)
0682             return -EIO;
0683 
0684         memset(&atcs_output, 0, sizeof(atcs_output));
0685 
0686         size = *(u16 *) info->buffer.pointer;
0687         if (size < 3) {
0688             DRM_INFO("ATCS buffer is too small: %zu\n", size);
0689             kfree(info);
0690             return -EINVAL;
0691         }
0692         size = min(sizeof(atcs_output), size);
0693 
0694         memcpy(&atcs_output, info->buffer.pointer, size);
0695 
0696         kfree(info);
0697 
0698         switch (atcs_output.ret_val) {
0699         case ATCS_REQUEST_REFUSED:
0700         default:
0701             return -EINVAL;
0702         case ATCS_REQUEST_COMPLETE:
0703             return 0;
0704         case ATCS_REQUEST_IN_PROGRESS:
0705             udelay(10);
0706             break;
0707         }
0708     }
0709 
0710     return 0;
0711 }
0712 
0713 /**
0714  * amdgpu_acpi_power_shift_control
0715  *
0716  * @adev: amdgpu_device pointer
0717  * @dev_state: device acpi state
0718  * @drv_state: driver state
0719  *
0720  * Executes the POWER_SHIFT_CONTROL method to
0721  * communicate current dGPU device state and
0722  * driver state to APU/SBIOS.
0723  * returns 0 on success, error on failure.
0724  */
0725 int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
0726                     u8 dev_state, bool drv_state)
0727 {
0728     union acpi_object *info;
0729     struct amdgpu_atcs *atcs = &amdgpu_acpi_priv.atcs;
0730     struct atcs_pwr_shift_input atcs_input;
0731     struct acpi_buffer params;
0732 
0733     if (!amdgpu_acpi_is_power_shift_control_supported())
0734         return -EINVAL;
0735 
0736     atcs_input.size = sizeof(struct atcs_pwr_shift_input);
0737     /* dGPU id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */
0738     atcs_input.dgpu_id = adev->pdev->devfn | (adev->pdev->bus->number << 8);
0739     atcs_input.dev_acpi_state = dev_state;
0740     atcs_input.drv_state = drv_state;
0741 
0742     params.length = sizeof(struct atcs_pwr_shift_input);
0743     params.pointer = &atcs_input;
0744 
0745     info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_POWER_SHIFT_CONTROL, &params);
0746     if (!info) {
0747         DRM_ERROR("ATCS PSC update failed\n");
0748         return -EIO;
0749     }
0750 
0751     return 0;
0752 }
0753 
0754 /**
0755  * amdgpu_acpi_smart_shift_update - update dGPU device state to SBIOS
0756  *
0757  * @dev: drm_device pointer
0758  * @ss_state: current smart shift event
0759  *
0760  * returns 0 on success,
0761  * otherwise return error number.
0762  */
0763 int amdgpu_acpi_smart_shift_update(struct drm_device *dev, enum amdgpu_ss ss_state)
0764 {
0765     struct amdgpu_device *adev = drm_to_adev(dev);
0766     int r;
0767 
0768     if (!amdgpu_device_supports_smart_shift(dev))
0769         return 0;
0770 
0771     switch (ss_state) {
0772     /* SBIOS trigger “stop”, “enable” and “start” at D0, Driver Operational.
0773      * SBIOS trigger “stop” at D3, Driver Not Operational.
0774      * SBIOS trigger “stop” and “disable” at D0, Driver NOT operational.
0775      */
0776     case AMDGPU_SS_DRV_LOAD:
0777         r = amdgpu_acpi_power_shift_control(adev,
0778                             AMDGPU_ATCS_PSC_DEV_STATE_D0,
0779                             AMDGPU_ATCS_PSC_DRV_STATE_OPR);
0780         break;
0781     case AMDGPU_SS_DEV_D0:
0782         r = amdgpu_acpi_power_shift_control(adev,
0783                             AMDGPU_ATCS_PSC_DEV_STATE_D0,
0784                             AMDGPU_ATCS_PSC_DRV_STATE_OPR);
0785         break;
0786     case AMDGPU_SS_DEV_D3:
0787         r = amdgpu_acpi_power_shift_control(adev,
0788                             AMDGPU_ATCS_PSC_DEV_STATE_D3_HOT,
0789                             AMDGPU_ATCS_PSC_DRV_STATE_NOT_OPR);
0790         break;
0791     case AMDGPU_SS_DRV_UNLOAD:
0792         r = amdgpu_acpi_power_shift_control(adev,
0793                             AMDGPU_ATCS_PSC_DEV_STATE_D0,
0794                             AMDGPU_ATCS_PSC_DRV_STATE_NOT_OPR);
0795         break;
0796     default:
0797         return -EINVAL;
0798     }
0799 
0800     return r;
0801 }
0802 
0803 /**
0804  * amdgpu_acpi_event - handle notify events
0805  *
0806  * @nb: notifier block
0807  * @val: val
0808  * @data: acpi event
0809  *
0810  * Calls relevant amdgpu functions in response to various
0811  * acpi events.
0812  * Returns NOTIFY code
0813  */
0814 static int amdgpu_acpi_event(struct notifier_block *nb,
0815                  unsigned long val,
0816                  void *data)
0817 {
0818     struct amdgpu_device *adev = container_of(nb, struct amdgpu_device, acpi_nb);
0819     struct acpi_bus_event *entry = (struct acpi_bus_event *)data;
0820 
0821     if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) {
0822         if (power_supply_is_system_supplied() > 0)
0823             DRM_DEBUG_DRIVER("pm: AC\n");
0824         else
0825             DRM_DEBUG_DRIVER("pm: DC\n");
0826 
0827         amdgpu_pm_acpi_event_handler(adev);
0828     }
0829 
0830     /* Check for pending SBIOS requests */
0831     return amdgpu_atif_handler(adev, entry);
0832 }
0833 
0834 /* Call all ACPI methods here */
0835 /**
0836  * amdgpu_acpi_init - init driver acpi support
0837  *
0838  * @adev: amdgpu_device pointer
0839  *
0840  * Verifies the AMD ACPI interfaces and registers with the acpi
0841  * notifier chain (all asics).
0842  * Returns 0 on success, error on failure.
0843  */
0844 int amdgpu_acpi_init(struct amdgpu_device *adev)
0845 {
0846     struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;
0847 
0848     if (atif->notifications.brightness_change) {
0849         if (amdgpu_device_has_dc_support(adev)) {
0850 #if defined(CONFIG_DRM_AMD_DC)
0851             struct amdgpu_display_manager *dm = &adev->dm;
0852             if (dm->backlight_dev[0])
0853                 atif->bd = dm->backlight_dev[0];
0854 #endif
0855         } else {
0856             struct drm_encoder *tmp;
0857 
0858             /* Find the encoder controlling the brightness */
0859             list_for_each_entry(tmp, &adev_to_drm(adev)->mode_config.encoder_list,
0860                         head) {
0861                 struct amdgpu_encoder *enc = to_amdgpu_encoder(tmp);
0862 
0863                 if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
0864                     enc->enc_priv) {
0865                     struct amdgpu_encoder_atom_dig *dig = enc->enc_priv;
0866                     if (dig->bl_dev) {
0867                         atif->bd = dig->bl_dev;
0868                         break;
0869                     }
0870                 }
0871             }
0872         }
0873     }
0874     adev->acpi_nb.notifier_call = amdgpu_acpi_event;
0875     register_acpi_notifier(&adev->acpi_nb);
0876 
0877     return 0;
0878 }
0879 
0880 void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps)
0881 {
0882     struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;
0883 
0884     caps->caps_valid = atif->backlight_caps.caps_valid;
0885     caps->min_input_signal = atif->backlight_caps.min_input_signal;
0886     caps->max_input_signal = atif->backlight_caps.max_input_signal;
0887 }
0888 
0889 /**
0890  * amdgpu_acpi_fini - tear down driver acpi support
0891  *
0892  * @adev: amdgpu_device pointer
0893  *
0894  * Unregisters with the acpi notifier chain (all asics).
0895  */
0896 void amdgpu_acpi_fini(struct amdgpu_device *adev)
0897 {
0898     unregister_acpi_notifier(&adev->acpi_nb);
0899 }
0900 
0901 /**
0902  * amdgpu_atif_pci_probe_handle - look up the ATIF handle
0903  *
0904  * @pdev: pci device
0905  *
0906  * Look up the ATIF handles (all asics).
0907  * Returns true if the handle is found, false if not.
0908  */
0909 static bool amdgpu_atif_pci_probe_handle(struct pci_dev *pdev)
0910 {
0911     char acpi_method_name[255] = { 0 };
0912     struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
0913     acpi_handle dhandle, atif_handle;
0914     acpi_status status;
0915     int ret;
0916 
0917     dhandle = ACPI_HANDLE(&pdev->dev);
0918     if (!dhandle)
0919         return false;
0920 
0921     status = acpi_get_handle(dhandle, "ATIF", &atif_handle);
0922     if (ACPI_FAILURE(status)) {
0923         return false;
0924     }
0925     amdgpu_acpi_priv.atif.handle = atif_handle;
0926     acpi_get_name(amdgpu_acpi_priv.atif.handle, ACPI_FULL_PATHNAME, &buffer);
0927     DRM_DEBUG_DRIVER("Found ATIF handle %s\n", acpi_method_name);
0928     ret = amdgpu_atif_verify_interface(&amdgpu_acpi_priv.atif);
0929     if (ret) {
0930         amdgpu_acpi_priv.atif.handle = 0;
0931         return false;
0932     }
0933     return true;
0934 }
0935 
0936 /**
0937  * amdgpu_atcs_pci_probe_handle - look up the ATCS handle
0938  *
0939  * @pdev: pci device
0940  *
0941  * Look up the ATCS handles (all asics).
0942  * Returns true if the handle is found, false if not.
0943  */
0944 static bool amdgpu_atcs_pci_probe_handle(struct pci_dev *pdev)
0945 {
0946     char acpi_method_name[255] = { 0 };
0947     struct acpi_buffer buffer = { sizeof(acpi_method_name), acpi_method_name };
0948     acpi_handle dhandle, atcs_handle;
0949     acpi_status status;
0950     int ret;
0951 
0952     dhandle = ACPI_HANDLE(&pdev->dev);
0953     if (!dhandle)
0954         return false;
0955 
0956     status = acpi_get_handle(dhandle, "ATCS", &atcs_handle);
0957     if (ACPI_FAILURE(status)) {
0958         return false;
0959     }
0960     amdgpu_acpi_priv.atcs.handle = atcs_handle;
0961     acpi_get_name(amdgpu_acpi_priv.atcs.handle, ACPI_FULL_PATHNAME, &buffer);
0962     DRM_DEBUG_DRIVER("Found ATCS handle %s\n", acpi_method_name);
0963     ret = amdgpu_atcs_verify_interface(&amdgpu_acpi_priv.atcs);
0964     if (ret) {
0965         amdgpu_acpi_priv.atcs.handle = 0;
0966         return false;
0967     }
0968     return true;
0969 }
0970 
0971 /*
0972  * amdgpu_acpi_detect - detect ACPI ATIF/ATCS methods
0973  *
0974  * Check if we have the ATIF/ATCS methods and populate
0975  * the structures in the driver.
0976  */
0977 void amdgpu_acpi_detect(void)
0978 {
0979     struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;
0980     struct amdgpu_atcs *atcs = &amdgpu_acpi_priv.atcs;
0981     struct pci_dev *pdev = NULL;
0982     int ret;
0983 
0984     while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
0985         if (!atif->handle)
0986             amdgpu_atif_pci_probe_handle(pdev);
0987         if (!atcs->handle)
0988             amdgpu_atcs_pci_probe_handle(pdev);
0989     }
0990 
0991     while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
0992         if (!atif->handle)
0993             amdgpu_atif_pci_probe_handle(pdev);
0994         if (!atcs->handle)
0995             amdgpu_atcs_pci_probe_handle(pdev);
0996     }
0997 
0998     if (atif->functions.sbios_requests && !atif->functions.system_params) {
0999         /* XXX check this workraround, if sbios request function is
1000          * present we have to see how it's configured in the system
1001          * params
1002          */
1003         atif->functions.system_params = true;
1004     }
1005 
1006     if (atif->functions.system_params) {
1007         ret = amdgpu_atif_get_notification_params(atif);
1008         if (ret) {
1009             DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",
1010                     ret);
1011             /* Disable notification */
1012             atif->notification_cfg.enabled = false;
1013         }
1014     }
1015 
1016     if (atif->functions.query_backlight_transfer_characteristics) {
1017         ret = amdgpu_atif_query_backlight_caps(atif);
1018         if (ret) {
1019             DRM_DEBUG_DRIVER("Call to QUERY_BACKLIGHT_TRANSFER_CHARACTERISTICS failed: %d\n",
1020                     ret);
1021             atif->backlight_caps.caps_valid = false;
1022         }
1023     } else {
1024         atif->backlight_caps.caps_valid = false;
1025     }
1026 }
1027 
1028 #if IS_ENABLED(CONFIG_SUSPEND)
1029 /**
1030  * amdgpu_acpi_is_s3_active
1031  *
1032  * @adev: amdgpu_device_pointer
1033  *
1034  * returns true if supported, false if not.
1035  */
1036 bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev)
1037 {
1038     return !(adev->flags & AMD_IS_APU) ||
1039         (pm_suspend_target_state == PM_SUSPEND_MEM);
1040 }
1041 
1042 /**
1043  * amdgpu_acpi_should_gpu_reset
1044  *
1045  * @adev: amdgpu_device_pointer
1046  *
1047  * returns true if should reset GPU, false if not
1048  */
1049 bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev)
1050 {
1051     if (adev->flags & AMD_IS_APU)
1052         return false;
1053 
1054     if (amdgpu_sriov_vf(adev))
1055         return false;
1056 
1057     return pm_suspend_target_state != PM_SUSPEND_TO_IDLE;
1058 }
1059 
1060 /**
1061  * amdgpu_acpi_is_s0ix_active
1062  *
1063  * @adev: amdgpu_device_pointer
1064  *
1065  * returns true if supported, false if not.
1066  */
1067 bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev)
1068 {
1069     if (!(adev->flags & AMD_IS_APU) ||
1070         (pm_suspend_target_state != PM_SUSPEND_TO_IDLE))
1071         return false;
1072 
1073     if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
1074         dev_warn_once(adev->dev,
1075                   "Power consumption will be higher as BIOS has not been configured for suspend-to-idle.\n"
1076                   "To use suspend-to-idle change the sleep mode in BIOS setup.\n");
1077         return false;
1078     }
1079 
1080 #if !IS_ENABLED(CONFIG_AMD_PMC)
1081     dev_warn_once(adev->dev,
1082               "Power consumption will be higher as the kernel has not been compiled with CONFIG_AMD_PMC.\n");
1083     return false;
1084 #else
1085     return true;
1086 #endif /* CONFIG_AMD_PMC */
1087 }
1088 
1089 #endif /* CONFIG_SUSPEND */