aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/0845-drm-amd-Query-and-use-ACPI-backlight-caps.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/0845-drm-amd-Query-and-use-ACPI-backlight-caps.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.19.8/0845-drm-amd-Query-and-use-ACPI-backlight-caps.patch309
1 files changed, 309 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/0845-drm-amd-Query-and-use-ACPI-backlight-caps.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/0845-drm-amd-Query-and-use-ACPI-backlight-caps.patch
new file mode 100644
index 00000000..54ece729
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/0845-drm-amd-Query-and-use-ACPI-backlight-caps.patch
@@ -0,0 +1,309 @@
+From 05ed87883240b0e86068929a38531cf606d840e6 Mon Sep 17 00:00:00 2001
+From: David Francis <David.Francis@amd.com>
+Date: Mon, 26 Nov 2018 11:44:06 -0500
+Subject: [PATCH 0845/2940] drm/amd: Query and use ACPI backlight caps
+
+ACPI ATIF has a function called query
+backlight transfer characteristics. Among the
+information returned by this function is
+the minimum and maximum input signals for the
+backlight
+
+Call that function on ACPI init. When DM
+backlight device is updated, copy over the
+backlight caps into DM, but only once. Use
+the backlight caps in the backlight-to-dc
+calculation
+
+Signed-off-by: David Francis <David.Francis@amd.com>
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 83 +++++++++++++++++++
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 56 +++++++++++--
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 13 +++
+ drivers/gpu/drm/amd/include/amd_acpi.h | 24 ++++++
+ 5 files changed, 172 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index ae419c8bdc8d..9671f53d44c3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -1290,6 +1290,9 @@ bool amdgpu_acpi_is_pcie_performance_request_supported(struct amdgpu_device *ade
+ int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
+ u8 perf_req, bool advertise);
+ int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev);
++
++void amdgpu_acpi_get_backlight_caps(struct amdgpu_device *adev,
++ struct amdgpu_dm_backlight_caps *caps);
+ #else
+ static inline int amdgpu_acpi_init(struct amdgpu_device *adev) { return 0; }
+ static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+index 471266901d1b..47db65926d71 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+@@ -65,6 +65,7 @@ struct amdgpu_atif {
+ struct amdgpu_atif_functions functions;
+ struct amdgpu_atif_notification_cfg notification_cfg;
+ struct amdgpu_encoder *encoder_for_bl;
++ struct amdgpu_dm_backlight_caps backlight_caps;
+ };
+
+ /* Call the ATIF method
+@@ -297,6 +298,65 @@ static int amdgpu_atif_get_notification_params(struct amdgpu_atif *atif)
+ return err;
+ }
+
++/**
++ * amdgpu_atif_query_backlight_caps - get min and max backlight input signal
++ *
++ * @handle: acpi handle
++ *
++ * Execute the QUERY_BRIGHTNESS_TRANSFER_CHARACTERISTICS ATIF function
++ * to determine the acceptable range of backlight values
++ *
++ * Backlight_caps.caps_valid will be set to true if the query is successful
++ *
++ * The input signals are in range 0-255
++ *
++ * This function assumes the display with backlight is the first LCD
++ *
++ * Returns 0 on success, error on failure.
++ */
++static int amdgpu_atif_query_backlight_caps(struct amdgpu_atif *atif)
++{
++ union acpi_object *info;
++ struct atif_qbtc_output characteristics;
++ struct atif_qbtc_arguments arguments;
++ struct acpi_buffer params;
++ size_t size;
++ int err = 0;
++
++ arguments.size = sizeof(arguments);
++ arguments.requested_display = ATIF_QBTC_REQUEST_LCD1;
++
++ params.length = sizeof(arguments);
++ params.pointer = (void *)&arguments;
++
++ info = amdgpu_atif_call(atif,
++ ATIF_FUNCTION_QUERY_BRIGHTNESS_TRANSFER_CHARACTERISTICS,
++ &params);
++ if (!info) {
++ err = -EIO;
++ goto out;
++ }
++
++ size = *(u16 *) info->buffer.pointer;
++ if (size < 10) {
++ err = -EINVAL;
++ goto out;
++ }
++
++ memset(&characteristics, 0, sizeof(characteristics));
++ size = min(sizeof(characteristics), size);
++ memcpy(&characteristics, info->buffer.pointer, size);
++
++ atif->backlight_caps.caps_valid = true;
++ atif->backlight_caps.min_input_signal =
++ characteristics.min_input_signal;
++ atif->backlight_caps.max_input_signal =
++ characteristics.max_input_signal;
++out:
++ kfree(info);
++ return err;
++}
++
+ /**
+ * amdgpu_atif_get_sbios_requests - get requested sbios event
+ *
+@@ -786,6 +846,17 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
+ }
+ }
+
++ if (atif->functions.query_backlight_transfer_characteristics) {
++ ret = amdgpu_atif_query_backlight_caps(atif);
++ if (ret) {
++ DRM_DEBUG_DRIVER("Call to QUERY_BACKLIGHT_TRANSFER_CHARACTERISTICS failed: %d\n",
++ ret);
++ atif->backlight_caps.caps_valid = false;
++ }
++ } else {
++ atif->backlight_caps.caps_valid = false;
++ }
++
+ out:
+ adev->acpi_nb.notifier_call = amdgpu_acpi_event;
+ register_acpi_notifier(&adev->acpi_nb);
+@@ -793,6 +864,18 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
+ return ret;
+ }
+
++void amdgpu_acpi_get_backlight_caps(struct amdgpu_device *adev,
++ struct amdgpu_dm_backlight_caps *caps)
++{
++ if (!adev->atif) {
++ caps->caps_valid = false;
++ return;
++ }
++ caps->caps_valid = adev->atif->backlight_caps.caps_valid;
++ caps->min_input_signal = adev->atif->backlight_caps.min_input_signal;
++ caps->max_input_signal = adev->atif->backlight_caps.max_input_signal;
++}
++
+ /**
+ * amdgpu_acpi_fini - tear down driver acpi support
+ *
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 2d5b0bf695d3..a6e3e4d7e883 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1588,22 +1588,62 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev)
+ return 0;
+ }
+
++#define AMDGPU_DM_DEFAULT_MIN_BACKLIGHT 12
++#define AMDGPU_DM_DEFAULT_MAX_BACKLIGHT 255
++
+ #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\
+ defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
+
++static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm)
++{
++#if defined(CONFIG_ACPI)
++ struct amdgpu_dm_backlight_caps caps;
++
++ if (dm->backlight_caps.caps_valid)
++ return;
++
++ amdgpu_acpi_get_backlight_caps(dm->adev, &caps);
++ if (caps.caps_valid) {
++ dm->backlight_caps.min_input_signal = caps.min_input_signal;
++ dm->backlight_caps.max_input_signal = caps.max_input_signal;
++ dm->backlight_caps.caps_valid = true;
++ } else {
++ dm->backlight_caps.min_input_signal =
++ AMDGPU_DM_DEFAULT_MIN_BACKLIGHT;
++ dm->backlight_caps.max_input_signal =
++ AMDGPU_DM_DEFAULT_MAX_BACKLIGHT;
++ }
++#else
++ dm->backlight_min_input_signal = AMDGPU_DM_DEFAULT_MIN_BACKLIGHT;
++ dm->backlight_max_input_signal = AMDGPU_DM_DEFAULT_MAX_BACKLIGHT;
++#endif
++}
++
++
+ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
+ {
+ struct amdgpu_display_manager *dm = bl_get_data(bd);
++ struct amdgpu_dm_backlight_caps caps;
++ uint32_t brightness = bd->props.brightness;
+
+- /* backlight_pwm_u16_16 parameter is in unsigned 32 bit, 16 bit integer
+- * and 16 bit fractional, where 1.0 is max backlight value.
+- * bd->props.brightness is 8 bit format and needs to be converted by
+- * scaling via copy lower byte to upper byte of 16 bit value.
++ amdgpu_dm_update_backlight_caps(dm);
++ caps = dm->backlight_caps;
++ /*
++ * The brightness input is in the range 0-255
++ * It needs to be rescaled to be between the
++ * requested min and max input signal
++ *
++ * It also needs to be scaled up by 0x101 to
++ * match the DC interface which has a range of
++ * 0 to 0xffff
+ */
+- uint32_t brightness = bd->props.brightness * 0x101;
+
+- if (bd->props.brightness < 1)
+- brightness = 0x101;
++ brightness =
++ brightness
++ * 0x101
++ * (caps.max_input_signal - caps.min_input_signal)
++ / AMDGPU_MAX_BL_LEVEL
++ + caps.min_input_signal * 0x101;
+
+ if (dc_link_set_backlight_level(dm->backlight_link,
+ brightness, 0, 0))
+@@ -1633,6 +1673,8 @@ amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm)
+ char bl_name[16];
+ struct backlight_properties props = { 0 };
+
++ amdgpu_dm_update_backlight_caps(dm);
++
+ props.max_brightness = AMDGPU_MAX_BL_LEVEL;
+ props.brightness = AMDGPU_MAX_BL_LEVEL;
+ props.type = BACKLIGHT_RAW;
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+index 63ee581b55a0..a84d72120275 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+@@ -83,6 +83,18 @@ struct dm_comressor_info {
+ uint64_t gpu_addr;
+ };
+
++/**
++ * struct amdgpu_dm_backlight_caps - Usable range of backlight values from ACPI
++ * @min_input_signal: minimum possible input in range 0-255
++ * @max_input_signal: maximum possible input in range 0-255
++ * @caps_valid: true if these values are from the ACPI interface
++ */
++struct amdgpu_dm_backlight_caps {
++ int min_input_signal;
++ int max_input_signal;
++ bool caps_valid;
++};
++
+ /**
+ * struct amdgpu_display_manager - Central amdgpu display manager device
+ *
+@@ -155,6 +167,7 @@ struct amdgpu_display_manager {
+ struct backlight_device *backlight_dev;
+
+ const struct dc_link *backlight_link;
++ struct amdgpu_dm_backlight_caps backlight_caps;
+
+ struct mod_freesync *freesync_module;
+
+diff --git a/drivers/gpu/drm/amd/include/amd_acpi.h b/drivers/gpu/drm/amd/include/amd_acpi.h
+index 8980edfe5fa9..c72cbfe8f684 100644
+--- a/drivers/gpu/drm/amd/include/amd_acpi.h
++++ b/drivers/gpu/drm/amd/include/amd_acpi.h
+@@ -52,6 +52,30 @@ struct atif_sbios_requests {
+ u8 backlight_level; /* panel backlight level (0-255) */
+ } __packed;
+
++struct atif_qbtc_arguments {
++ u16 size; /* structure size in bytes (includes size field) */
++ u8 requested_display; /* which display is requested */
++} __packed;
++
++#define ATIF_QBTC_MAX_DATA_POINTS 99
++
++struct atif_qbtc_data_point {
++ u8 luminance; /* luminance in percent */
++ u8 ipnut_signal; /* input signal in range 0-255 */
++} __packed;
++
++struct atif_qbtc_output {
++ u16 size; /* structure size in bytes (includes size field) */
++ u16 flags; /* all zeroes */
++ u8 error_code; /* error code */
++ u8 ac_level; /* default brightness on AC power */
++ u8 dc_level; /* default brightness on DC power */
++ u8 min_input_signal; /* max input signal in range 0-255 */
++ u8 max_input_signal; /* min input signal in range 0-255 */
++ u8 number_of_points; /* number of data points */
++ struct atif_qbtc_data_point data_points[ATIF_QBTC_MAX_DATA_POINTS];
++} __packed;
++
+ #define ATIF_NOTIFY_MASK 0x3
+ #define ATIF_NOTIFY_NONE 0
+ #define ATIF_NOTIFY_81 1
+--
+2.17.1
+