diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 147 |
1 files changed, 105 insertions, 42 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c index b8d4e07d2043..516ab9cf88fc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c @@ -116,7 +116,9 @@ struct amdgpu_atcs_functions { bool pcie_perf_req; bool pcie_dev_rdy; bool pcie_bus_width; + bool get_uma_size; bool power_shift_control; + bool set_uma_allocation_size; }; struct amdgpu_atcs { @@ -241,7 +243,8 @@ static void amdgpu_atif_parse_functions(struct amdgpu_atif_functions *f, u32 mas * (all asics). * returns 0 on success, error on failure. */ -static int amdgpu_atif_verify_interface(struct amdgpu_atif *atif) +static noinline_for_stack +int amdgpu_atif_verify_interface(struct amdgpu_atif *atif) { union acpi_object *info; struct atif_verify_interface output; @@ -286,7 +289,8 @@ out: * where n is specified in the result if a notifier is used. * Returns 0 on success, error on failure. */ -static int amdgpu_atif_get_notification_params(struct amdgpu_atif *atif) +static noinline_for_stack +int amdgpu_atif_get_notification_params(struct amdgpu_atif *atif) { union acpi_object *info; struct amdgpu_atif_notification_cfg *n = &atif->notification_cfg; @@ -354,7 +358,8 @@ out: * * Returns 0 on success, error on failure. */ -static int amdgpu_atif_query_backlight_caps(struct amdgpu_atif *atif) +static noinline_for_stack +int amdgpu_atif_query_backlight_caps(struct amdgpu_atif *atif) { union acpi_object *info; struct atif_qbtc_output characteristics; @@ -394,6 +399,10 @@ static int amdgpu_atif_query_backlight_caps(struct amdgpu_atif *atif) characteristics.max_input_signal; atif->backlight_caps.ac_level = characteristics.ac_level; atif->backlight_caps.dc_level = characteristics.dc_level; + atif->backlight_caps.data_points = characteristics.number_of_points; + memcpy(atif->backlight_caps.luminance_data, + characteristics.data_points, + sizeof(atif->backlight_caps.luminance_data)); out: kfree(info); return err; @@ -503,7 +512,6 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev, pm_runtime_get_sync(adev_to_drm(adev)->dev); /* Just fire off a uevent and let userspace tell us what to do */ drm_helper_hpd_irq_event(adev_to_drm(adev)); - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); } } @@ -584,7 +592,9 @@ static void amdgpu_atcs_parse_functions(struct amdgpu_atcs_functions *f, u32 mas f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED; f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED; f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED; + f->get_uma_size = mask & ACPI_ATCS_GET_UMA_SIZE_SUPPORTED; f->power_shift_control = mask & ATCS_SET_POWER_SHIFT_CONTROL_SUPPORTED; + f->set_uma_allocation_size = mask & ACPI_ATCS_SET_UMA_ALLOCATION_SIZE_SUPPORTED; } /** @@ -597,7 +607,8 @@ static void amdgpu_atcs_parse_functions(struct amdgpu_atcs_functions *f, u32 mas * (all asics). * returns 0 on success, error on failure. */ -static int amdgpu_atcs_verify_interface(struct amdgpu_atcs *atcs) +static noinline_for_stack +int amdgpu_atcs_verify_interface(struct amdgpu_atcs *atcs) { union acpi_object *info; struct atcs_verify_interface output; @@ -661,6 +672,11 @@ bool amdgpu_acpi_is_power_shift_control_supported(void) return amdgpu_acpi_priv.atcs.functions.power_shift_control; } +bool amdgpu_acpi_is_set_uma_allocation_size_supported(void) +{ + return amdgpu_acpi_priv.atcs.functions.set_uma_allocation_size; +} + /** * amdgpu_acpi_pcie_notify_device_ready * @@ -737,7 +753,8 @@ int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev, size = *(u16 *) info->buffer.pointer; if (size < 3) { - DRM_INFO("ATCS buffer is too small: %zu\n", size); + drm_info(adev_to_drm(adev), + "ATCS buffer is too small: %zu\n", size); kfree(info); return -EINVAL; } @@ -796,7 +813,7 @@ int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev, info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_POWER_SHIFT_CONTROL, ¶ms); if (!info) { - DRM_ERROR("ATCS PSC update failed\n"); + drm_err(adev_to_drm(adev), "ATCS PSC call failed\n"); return -EIO; } @@ -807,18 +824,18 @@ int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev, /** * amdgpu_acpi_smart_shift_update - update dGPU device state to SBIOS * - * @dev: drm_device pointer + * @adev: amdgpu device pointer * @ss_state: current smart shift event * * returns 0 on success, * otherwise return error number. */ -int amdgpu_acpi_smart_shift_update(struct drm_device *dev, enum amdgpu_ss ss_state) +int amdgpu_acpi_smart_shift_update(struct amdgpu_device *adev, + enum amdgpu_ss ss_state) { - struct amdgpu_device *adev = drm_to_adev(dev); int r; - if (!amdgpu_device_supports_smart_shift(dev)) + if (!amdgpu_device_supports_smart_shift(adev)) return 0; switch (ss_state) { @@ -880,7 +897,7 @@ static struct amdgpu_numa_info *amdgpu_acpi_get_numa_info(uint32_t pxm) if (!numa_info) { struct sysinfo info; - numa_info = kzalloc(sizeof(*numa_info), GFP_KERNEL); + numa_info = kzalloc_obj(*numa_info); if (!numa_info) return NULL; @@ -902,6 +919,44 @@ static struct amdgpu_numa_info *amdgpu_acpi_get_numa_info(uint32_t pxm) #endif /** + * amdgpu_acpi_set_uma_allocation_size - Set Unified Memory Architecture allocation size via ACPI + * @adev: Pointer to the amdgpu_device structure + * @index: Index specifying the UMA allocation + * @type: Type of UMA allocation + * + * This function configures the UMA allocation size for the specified device + * using ACPI methods. The allocation is determined by the provided index and type. + * Returns 0 on success or a negative error code on failure. + */ +int amdgpu_acpi_set_uma_allocation_size(struct amdgpu_device *adev, u8 index, u8 type) +{ + struct atcs_set_uma_allocation_size_input atcs_input; + struct amdgpu_atcs *atcs = &amdgpu_acpi_priv.atcs; + struct acpi_buffer params; + union acpi_object *info; + + if (!amdgpu_acpi_is_set_uma_allocation_size_supported()) + return -EINVAL; + + atcs_input.size = sizeof(struct atcs_set_uma_allocation_size_input); + atcs_input.uma_size_index = index; + atcs_input.uma_size_type = type; + + params.length = sizeof(struct atcs_set_uma_allocation_size_input); + params.pointer = &atcs_input; + + info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_SET_UMA_ALLOCATION_SIZE, ¶ms); + if (!info) { + drm_err(adev_to_drm(adev), "ATCS UMA allocation size update failed\n"); + return -EIO; + } + + kfree(info); + + return 0; +} + +/** * amdgpu_acpi_get_node_id - obtain the NUMA node id for corresponding amdgpu * acpi device handle * @@ -961,7 +1016,7 @@ static int amdgpu_acpi_dev_init(struct amdgpu_acpi_dev_info **dev_info, int ret = -ENOENT; *dev_info = NULL; - tmp = kzalloc(sizeof(struct amdgpu_acpi_dev_info), GFP_KERNEL); + tmp = kzalloc_obj(struct amdgpu_acpi_dev_info); if (!tmp) return -ENOMEM; @@ -1086,7 +1141,8 @@ out: return ret; } -static int amdgpu_acpi_enumerate_xcc(void) +static noinline_for_stack +int amdgpu_acpi_enumerate_xcc(void) { struct amdgpu_acpi_dev_info *dev_info = NULL; struct amdgpu_acpi_xcc_info *xcc_info; @@ -1105,17 +1161,14 @@ static int amdgpu_acpi_enumerate_xcc(void) * one is not found, no need to check the rest. */ if (!acpi_dev) { - DRM_DEBUG_DRIVER("No matching acpi device found for %s", + DRM_DEBUG_DRIVER("No matching acpi device found for %s\n", hid); break; } - xcc_info = kzalloc(sizeof(struct amdgpu_acpi_xcc_info), - GFP_KERNEL); - if (!xcc_info) { - DRM_ERROR("Failed to allocate memory for xcc info\n"); + xcc_info = kzalloc_obj(struct amdgpu_acpi_xcc_info); + if (!xcc_info) return -ENOMEM; - } INIT_LIST_HEAD(&xcc_info->list); xcc_info->handle = acpi_device_handle(acpi_dev); @@ -1132,8 +1185,10 @@ static int amdgpu_acpi_enumerate_xcc(void) if (!dev_info) ret = amdgpu_acpi_dev_init(&dev_info, xcc_info, sbdf); - if (ret == -ENOMEM) + if (ret == -ENOMEM) { + kfree(xcc_info); return ret; + } if (!dev_info) { kfree(xcc_info); @@ -1277,11 +1332,7 @@ void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps) { struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif; - caps->caps_valid = atif->backlight_caps.caps_valid; - caps->min_input_signal = atif->backlight_caps.min_input_signal; - caps->max_input_signal = atif->backlight_caps.max_input_signal; - caps->ac_level = atif->backlight_caps.ac_level; - caps->dc_level = atif->backlight_caps.dc_level; + memcpy(caps, &atif->backlight_caps, sizeof(*caps)); } /** @@ -1532,23 +1583,35 @@ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) return true; #endif /* CONFIG_AMD_PMC */ } +#endif /* CONFIG_SUSPEND */ -/** - * amdgpu_choose_low_power_state - * - * @adev: amdgpu_device_pointer - * - * Choose the target low power state for the GPU - */ -void amdgpu_choose_low_power_state(struct amdgpu_device *adev) -{ - if (adev->in_runpm) - return; +#if IS_ENABLED(CONFIG_DRM_AMD_ISP) +static const struct acpi_device_id isp_sensor_ids[] = { + { "OMNI5C10" }, + { } +}; - if (amdgpu_acpi_is_s0ix_active(adev)) - adev->in_s0ix = true; - else if (amdgpu_acpi_is_s3_active(adev)) - adev->in_s3 = true; +static int isp_match_acpi_device_ids(struct device *dev, const void *data) +{ + return acpi_match_device(data, dev) ? 1 : 0; } -#endif /* CONFIG_SUSPEND */ +int amdgpu_acpi_get_isp4_dev(struct acpi_device **dev) +{ + struct device *pdev __free(put_device) = NULL; + struct acpi_device *acpi_pdev; + + pdev = bus_find_device(&platform_bus_type, NULL, isp_sensor_ids, + isp_match_acpi_device_ids); + if (!pdev) + return -EINVAL; + + acpi_pdev = ACPI_COMPANION(pdev); + if (!acpi_pdev) + return -ENODEV; + + *dev = acpi_pdev; + + return 0; +} +#endif /* CONFIG_DRM_AMD_ISP */ |
