Loading drivers/gpu/drm/radeon/radeon.h +1 −1 Original line number Diff line number Diff line Loading @@ -2458,7 +2458,7 @@ extern int radeon_acpi_init(struct radeon_device *rdev); extern void radeon_acpi_fini(struct radeon_device *rdev); extern bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev); extern int radeon_acpi_pcie_performance_request(struct radeon_device *rdev, u8 ref_req, bool advertise); u8 perf_req, bool advertise); extern int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev); #else static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; } Loading drivers/gpu/drm/radeon/radeon_acpi.c +142 −20 Original line number Diff line number Diff line Loading @@ -78,28 +78,21 @@ struct atcs_verify_interface { u32 function_bits; /* supported functions bit vector */ } __packed; bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev) { /* XXX: query ATIF */ #define ATCS_VALID_FLAGS_MASK 0x3 return false; } int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev) { /* XXX: call appropriate ATIF method */ return -EINVAL; } int radeon_acpi_pcie_performance_request(struct radeon_device *rdev, u8 ref_req, bool advertise) { /* XXX: call appropriate ATIF method */ struct atcs_pref_req_input { u16 size; /* structure size in bytes (includes size field) */ u16 client_id; /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */ u16 valid_flags_mask; /* valid flags mask */ u16 flags; /* flags */ u8 req_type; /* request type */ u8 perf_req; /* performance request */ } __packed; return -EINVAL; } struct atcs_pref_req_output { u16 size; /* structure size in bytes (includes size field) */ u8 ret_val; /* return value */ } __packed; /* Call the ATIF method */ Loading Loading @@ -528,6 +521,135 @@ static int radeon_atcs_verify_interface(acpi_handle handle, return err; } /** * radeon_acpi_is_pcie_performance_request_supported * * @rdev: radeon_device pointer * * Check if the ATCS pcie_perf_req and pcie_dev_rdy methods * are supported (all asics). * returns true if supported, false if not. */ bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev) { struct radeon_atcs *atcs = &rdev->atcs; if (atcs->functions.pcie_perf_req && atcs->functions.pcie_dev_rdy) return true; return false; } /** * radeon_acpi_pcie_notify_device_ready * * @rdev: radeon_device pointer * * Executes the PCIE_DEVICE_READY_NOTIFICATION method * (all asics). * returns 0 on success, error on failure. */ int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev) { acpi_handle handle; union acpi_object *info; struct radeon_atcs *atcs = &rdev->atcs; /* Get the device handle */ handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); if (!handle) return -EINVAL; if (!atcs->functions.pcie_dev_rdy) return -EINVAL; info = radeon_atcs_call(handle, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, NULL); if (!info) return -EIO; kfree(info); return 0; } /** * radeon_acpi_pcie_performance_request * * @rdev: radeon_device pointer * @perf_req: requested perf level (pcie gen speed) * @advertise: set advertise caps flag if set * * Executes the PCIE_PERFORMANCE_REQUEST method to * change the pcie gen speed (all asics). * returns 0 on success, error on failure. */ int radeon_acpi_pcie_performance_request(struct radeon_device *rdev, u8 perf_req, bool advertise) { acpi_handle handle; union acpi_object *info; struct radeon_atcs *atcs = &rdev->atcs; struct atcs_pref_req_input atcs_input; struct atcs_pref_req_output atcs_output; struct acpi_buffer params; size_t size; u32 retry = 3; /* Get the device handle */ handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); if (!handle) return -EINVAL; if (!atcs->functions.pcie_perf_req) return -EINVAL; atcs_input.size = sizeof(struct atcs_pref_req_input); /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */ atcs_input.client_id = rdev->pdev->devfn | (rdev->pdev->bus->number << 8); atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK; atcs_input.flags = ATCS_WAIT_FOR_COMPLETION; if (advertise) atcs_input.flags |= ATCS_ADVERTISE_CAPS; atcs_input.req_type = ATCS_PCIE_LINK_SPEED; atcs_input.perf_req = perf_req; params.length = sizeof(struct atcs_pref_req_input); params.pointer = &atcs_input; while (retry--) { info = radeon_atcs_call(handle, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, ¶ms); if (!info) return -EIO; memset(&atcs_output, 0, sizeof(atcs_output)); size = *(u16 *) info->buffer.pointer; if (size < 3) { DRM_INFO("ATCS buffer is too small: %zu\n", size); kfree(info); return -EINVAL; } size = min(sizeof(atcs_output), size); memcpy(&atcs_output, info->buffer.pointer, size); kfree(info); switch (atcs_output.ret_val) { case ATCS_REQUEST_REFUSED: default: return -EINVAL; case ATCS_REQUEST_COMPLETE: return 0; case ATCS_REQUEST_IN_PROGRESS: udelay(10); break; } } return 0; } /** * radeon_acpi_event - handle notify events * Loading Loading
drivers/gpu/drm/radeon/radeon.h +1 −1 Original line number Diff line number Diff line Loading @@ -2458,7 +2458,7 @@ extern int radeon_acpi_init(struct radeon_device *rdev); extern void radeon_acpi_fini(struct radeon_device *rdev); extern bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev); extern int radeon_acpi_pcie_performance_request(struct radeon_device *rdev, u8 ref_req, bool advertise); u8 perf_req, bool advertise); extern int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev); #else static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; } Loading
drivers/gpu/drm/radeon/radeon_acpi.c +142 −20 Original line number Diff line number Diff line Loading @@ -78,28 +78,21 @@ struct atcs_verify_interface { u32 function_bits; /* supported functions bit vector */ } __packed; bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev) { /* XXX: query ATIF */ #define ATCS_VALID_FLAGS_MASK 0x3 return false; } int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev) { /* XXX: call appropriate ATIF method */ return -EINVAL; } int radeon_acpi_pcie_performance_request(struct radeon_device *rdev, u8 ref_req, bool advertise) { /* XXX: call appropriate ATIF method */ struct atcs_pref_req_input { u16 size; /* structure size in bytes (includes size field) */ u16 client_id; /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */ u16 valid_flags_mask; /* valid flags mask */ u16 flags; /* flags */ u8 req_type; /* request type */ u8 perf_req; /* performance request */ } __packed; return -EINVAL; } struct atcs_pref_req_output { u16 size; /* structure size in bytes (includes size field) */ u8 ret_val; /* return value */ } __packed; /* Call the ATIF method */ Loading Loading @@ -528,6 +521,135 @@ static int radeon_atcs_verify_interface(acpi_handle handle, return err; } /** * radeon_acpi_is_pcie_performance_request_supported * * @rdev: radeon_device pointer * * Check if the ATCS pcie_perf_req and pcie_dev_rdy methods * are supported (all asics). * returns true if supported, false if not. */ bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev) { struct radeon_atcs *atcs = &rdev->atcs; if (atcs->functions.pcie_perf_req && atcs->functions.pcie_dev_rdy) return true; return false; } /** * radeon_acpi_pcie_notify_device_ready * * @rdev: radeon_device pointer * * Executes the PCIE_DEVICE_READY_NOTIFICATION method * (all asics). * returns 0 on success, error on failure. */ int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev) { acpi_handle handle; union acpi_object *info; struct radeon_atcs *atcs = &rdev->atcs; /* Get the device handle */ handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); if (!handle) return -EINVAL; if (!atcs->functions.pcie_dev_rdy) return -EINVAL; info = radeon_atcs_call(handle, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, NULL); if (!info) return -EIO; kfree(info); return 0; } /** * radeon_acpi_pcie_performance_request * * @rdev: radeon_device pointer * @perf_req: requested perf level (pcie gen speed) * @advertise: set advertise caps flag if set * * Executes the PCIE_PERFORMANCE_REQUEST method to * change the pcie gen speed (all asics). * returns 0 on success, error on failure. */ int radeon_acpi_pcie_performance_request(struct radeon_device *rdev, u8 perf_req, bool advertise) { acpi_handle handle; union acpi_object *info; struct radeon_atcs *atcs = &rdev->atcs; struct atcs_pref_req_input atcs_input; struct atcs_pref_req_output atcs_output; struct acpi_buffer params; size_t size; u32 retry = 3; /* Get the device handle */ handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); if (!handle) return -EINVAL; if (!atcs->functions.pcie_perf_req) return -EINVAL; atcs_input.size = sizeof(struct atcs_pref_req_input); /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */ atcs_input.client_id = rdev->pdev->devfn | (rdev->pdev->bus->number << 8); atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK; atcs_input.flags = ATCS_WAIT_FOR_COMPLETION; if (advertise) atcs_input.flags |= ATCS_ADVERTISE_CAPS; atcs_input.req_type = ATCS_PCIE_LINK_SPEED; atcs_input.perf_req = perf_req; params.length = sizeof(struct atcs_pref_req_input); params.pointer = &atcs_input; while (retry--) { info = radeon_atcs_call(handle, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, ¶ms); if (!info) return -EIO; memset(&atcs_output, 0, sizeof(atcs_output)); size = *(u16 *) info->buffer.pointer; if (size < 3) { DRM_INFO("ATCS buffer is too small: %zu\n", size); kfree(info); return -EINVAL; } size = min(sizeof(atcs_output), size); memcpy(&atcs_output, info->buffer.pointer, size); kfree(info); switch (atcs_output.ret_val) { case ATCS_REQUEST_REFUSED: default: return -EINVAL; case ATCS_REQUEST_COMPLETE: return 0; case ATCS_REQUEST_IN_PROGRESS: udelay(10); break; } } return 0; } /** * radeon_acpi_event - handle notify events * Loading