aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/0730-drm-amd-display-Expand-dc-to-use-16.16-bit-backlight.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/0730-drm-amd-display-Expand-dc-to-use-16.16-bit-backlight.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.19.8/0730-drm-amd-display-Expand-dc-to-use-16.16-bit-backlight.patch432
1 files changed, 432 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/0730-drm-amd-display-Expand-dc-to-use-16.16-bit-backlight.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/0730-drm-amd-display-Expand-dc-to-use-16.16-bit-backlight.patch
new file mode 100644
index 00000000..dfc85f77
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/0730-drm-amd-display-Expand-dc-to-use-16.16-bit-backlight.patch
@@ -0,0 +1,432 @@
+From 5ea12a15e32ad184fd7e61d91d9efc95d94cc89c Mon Sep 17 00:00:00 2001
+From: Anthony Koo <Anthony.Koo@amd.com>
+Date: Fri, 12 Oct 2018 21:34:32 -0400
+Subject: [PATCH 0730/2940] drm/amd/display: Expand dc to use 16.16 bit
+ backlight
+
+[Why] We want to increase precision for backlight setting.
+But DC interface takes 8 bit backlight level value only.
+
+[How] DMCU already takes 16 bit backlight level.
+Expand the DC interface to take 16.16 bit value.
+Max 32 bit backlight value (0xFFFF) will represent
+max backlight (100%)
+
+Signed-off-by: Anthony Koo <Anthony.Koo@amd.com>
+Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
+Acked-by: Leo Li <sunpeng.li@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 +-
+ drivers/gpu/drm/amd/display/dc/core/dc_link.c | 34 ++++---
+ drivers/gpu/drm/amd/display/dc/dc_link.h | 11 ++-
+ drivers/gpu/drm/amd/display/dc/dce/dce_abm.c | 92 ++++++++-----------
+ .../display/dc/dce110/dce110_hw_sequencer.c | 1 -
+ drivers/gpu/drm/amd/display/dc/inc/hw/abm.h | 11 ++-
+ .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 2 -
+ 7 files changed, 80 insertions(+), 79 deletions(-)
+
+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 b275445e0e47..9f13e65ed5f0 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1579,8 +1579,14 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
+ */
+ if (bd->props.brightness < 1)
+ return 1;
++
++ /* 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.
++ */
+ if (dc_link_set_backlight_level(dm->backlight_link,
+- bd->props.brightness, 0, 0))
++ (bd->props.brightness * 0x101), 0, 0))
+ return 0;
+ else
+ return 1;
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+index f4936f7c5545..643407d18cce 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+@@ -2141,14 +2141,16 @@ int dc_link_get_backlight_level(const struct dc_link *link)
+ {
+ struct abm *abm = link->ctx->dc->res_pool->abm;
+
+- if (abm == NULL || abm->funcs->get_current_backlight_8_bit == NULL)
++ if (abm == NULL || abm->funcs->get_current_backlight == NULL)
+ return DC_ERROR_UNEXPECTED;
+
+- return (int) abm->funcs->get_current_backlight_8_bit(abm);
++ return (int) abm->funcs->get_current_backlight(abm);
+ }
+
+-bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level,
+- uint32_t frame_ramp, const struct dc_stream_state *stream)
++bool dc_link_set_backlight_level(const struct dc_link *link,
++ uint32_t backlight_pwm_u16_16,
++ uint32_t frame_ramp,
++ const struct dc_stream_state *stream)
+ {
+ struct dc *core_dc = link->ctx->dc;
+ struct abm *abm = core_dc->res_pool->abm;
+@@ -2160,19 +2162,17 @@ bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level,
+
+ if ((dmcu == NULL) ||
+ (abm == NULL) ||
+- (abm->funcs->set_backlight_level == NULL))
++ (abm->funcs->set_backlight_level_pwm == NULL))
+ return false;
+
+- if (stream) {
+- if (stream->bl_pwm_level == EDP_BACKLIGHT_RAMP_DISABLE_LEVEL)
+- frame_ramp = 0;
+-
+- ((struct dc_stream_state *)stream)->bl_pwm_level = level;
+- }
++ if (stream)
++ ((struct dc_stream_state *)stream)->bl_pwm_level =
++ backlight_pwm_u16_16;
+
+ use_smooth_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
+
+- DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n", level, level);
++ DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
++ backlight_pwm_u16_16, backlight_pwm_u16_16);
+
+ if (dc_is_embedded_signal(link->connector_signal)) {
+ if (stream != NULL) {
+@@ -2189,9 +2189,9 @@ bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level,
+ 1;
+ }
+ }
+- abm->funcs->set_backlight_level(
++ abm->funcs->set_backlight_level_pwm(
+ abm,
+- level,
++ backlight_pwm_u16_16,
+ frame_ramp,
+ controller_id,
+ use_smooth_brightness);
+@@ -2205,7 +2205,7 @@ bool dc_link_set_abm_disable(const struct dc_link *link)
+ struct dc *core_dc = link->ctx->dc;
+ struct abm *abm = core_dc->res_pool->abm;
+
+- if ((abm == NULL) || (abm->funcs->set_backlight_level == NULL))
++ if ((abm == NULL) || (abm->funcs->set_backlight_level_pwm == NULL))
+ return false;
+
+ abm->funcs->set_abm_immediate_disable(abm);
+@@ -2594,6 +2594,10 @@ void core_link_enable_stream(
+ core_dc->hwss.unblank_stream(pipe_ctx,
+ &pipe_ctx->stream->sink->link->cur_link_settings);
+
++ dc_link_set_backlight_level(pipe_ctx->stream->sink->link,
++ pipe_ctx->stream->bl_pwm_level,
++ 0,
++ pipe_ctx->stream);
+ }
+
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
+index 3bfdccceb524..8738f27a8708 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
+@@ -138,9 +138,14 @@ static inline struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_
+ return dc->links[link_index];
+ }
+
+-/* Set backlight level of an embedded panel (eDP, LVDS). */
+-bool dc_link_set_backlight_level(const struct dc_link *dc_link, uint32_t level,
+- uint32_t frame_ramp, const struct dc_stream_state *stream);
++/* Set backlight level of an embedded panel (eDP, LVDS).
++ * backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer
++ * and 16 bit fractional, where 1.0 is max backlight value.
++ */
++bool dc_link_set_backlight_level(const struct dc_link *dc_link,
++ uint32_t backlight_pwm_u16_16,
++ uint32_t frame_ramp,
++ const struct dc_stream_state *stream);
+
+ int dc_link_get_backlight_level(const struct dc_link *dc_link);
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
+index 29294db1a96b..e9765bb38a8b 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
+@@ -54,7 +54,7 @@
+ #define MCP_DISABLE_ABM_IMMEDIATELY 255
+
+
+-static unsigned int get_current_backlight_16_bit(struct dce_abm *abm_dce)
++static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_abm *abm_dce)
+ {
+ uint64_t current_backlight;
+ uint32_t round_result;
+@@ -103,45 +103,21 @@ static unsigned int get_current_backlight_16_bit(struct dce_abm *abm_dce)
+ return (uint32_t)(current_backlight);
+ }
+
+-static void driver_set_backlight_level(struct dce_abm *abm_dce, uint32_t level)
++static void driver_set_backlight_level(struct dce_abm *abm_dce,
++ uint32_t backlight_pwm_u16_16)
+ {
+- uint32_t backlight_24bit;
+- uint32_t backlight_17bit;
+ uint32_t backlight_16bit;
+ uint32_t masked_pwm_period;
+- uint8_t rounding_bit;
+ uint8_t bit_count;
+ uint64_t active_duty_cycle;
+ uint32_t pwm_period_bitcnt;
+
+ /*
+- * 1. Convert 8-bit value to 17 bit U1.16 format
+- * (1 integer, 16 fractional bits)
+- */
+-
+- /* 1.1 multiply 8 bit value by 0x10101 to get a 24 bit value,
+- * effectively multiplying value by 256/255
+- * eg. for a level of 0xEF, backlight_24bit = 0xEF * 0x10101 = 0xEFEFEF
+- */
+- backlight_24bit = level * 0x10101;
+-
+- /* 1.2 The upper 16 bits of the 24 bit value is the fraction, lower 8
+- * used for rounding, take most significant bit of fraction for
+- * rounding, e.g. for 0xEFEFEF, rounding bit is 1
+- */
+- rounding_bit = (backlight_24bit >> 7) & 1;
+-
+- /* 1.3 Add the upper 16 bits of the 24 bit value with the rounding bit
+- * resulting in a 17 bit value e.g. 0xEFF0 = (0xEFEFEF >> 8) + 1
+- */
+- backlight_17bit = (backlight_24bit >> 8) + rounding_bit;
+-
+- /*
+- * 2. Find 16 bit backlight active duty cycle, where 0 <= backlight
++ * 1. Find 16 bit backlight active duty cycle, where 0 <= backlight
+ * active duty cycle <= backlight period
+ */
+
+- /* 2.1 Apply bitmask for backlight period value based on value of BITCNT
++ /* 1.1 Apply bitmask for backlight period value based on value of BITCNT
+ */
+ REG_GET_2(BL_PWM_PERIOD_CNTL,
+ BL_PWM_PERIOD_BITCNT, &pwm_period_bitcnt,
+@@ -155,13 +131,13 @@ static void driver_set_backlight_level(struct dce_abm *abm_dce, uint32_t level)
+ /* e.g. maskedPwmPeriod = 0x24 when bitCount is 6 */
+ masked_pwm_period = masked_pwm_period & ((1 << bit_count) - 1);
+
+- /* 2.2 Calculate integer active duty cycle required upper 16 bits
++ /* 1.2 Calculate integer active duty cycle required upper 16 bits
+ * contain integer component, lower 16 bits contain fractional component
+ * of active duty cycle e.g. 0x21BDC0 = 0xEFF0 * 0x24
+ */
+- active_duty_cycle = backlight_17bit * masked_pwm_period;
++ active_duty_cycle = backlight_pwm_u16_16 * masked_pwm_period;
+
+- /* 2.3 Calculate 16 bit active duty cycle from integer and fractional
++ /* 1.3 Calculate 16 bit active duty cycle from integer and fractional
+ * components shift by bitCount then mask 16 bits and add rounding bit
+ * from MSB of fraction e.g. 0x86F7 = ((0x21BDC0 >> 6) & 0xFFF) + 0
+ */
+@@ -170,23 +146,23 @@ static void driver_set_backlight_level(struct dce_abm *abm_dce, uint32_t level)
+ backlight_16bit += (active_duty_cycle >> (bit_count - 1)) & 0x1;
+
+ /*
+- * 3. Program register with updated value
++ * 2. Program register with updated value
+ */
+
+- /* 3.1 Lock group 2 backlight registers */
++ /* 2.1 Lock group 2 backlight registers */
+
+ REG_UPDATE_2(BL_PWM_GRP1_REG_LOCK,
+ BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, 1,
+ BL_PWM_GRP1_REG_LOCK, 1);
+
+- // 3.2 Write new active duty cycle
++ // 2.2 Write new active duty cycle
+ REG_UPDATE(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, backlight_16bit);
+
+- /* 3.3 Unlock group 2 backlight registers */
++ /* 2.3 Unlock group 2 backlight registers */
+ REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
+ BL_PWM_GRP1_REG_LOCK, 0);
+
+- /* 5.4.4 Wait for pending bit to be cleared */
++ /* 3 Wait for pending bit to be cleared */
+ REG_WAIT(BL_PWM_GRP1_REG_LOCK,
+ BL_PWM_GRP1_REG_UPDATE_PENDING, 0,
+ 1, 10000);
+@@ -194,16 +170,21 @@ static void driver_set_backlight_level(struct dce_abm *abm_dce, uint32_t level)
+
+ static void dmcu_set_backlight_level(
+ struct dce_abm *abm_dce,
+- uint32_t level,
++ uint32_t backlight_pwm_u16_16,
+ uint32_t frame_ramp,
+ uint32_t controller_id)
+ {
+- unsigned int backlight_16_bit = (level * 0x10101) >> 8;
+- unsigned int backlight_17_bit = backlight_16_bit +
+- (((backlight_16_bit & 0x80) >> 7) & 1);
++ unsigned int backlight_8_bit = 0;
+ uint32_t rampingBoundary = 0xFFFF;
+ uint32_t s2;
+
++ if (backlight_pwm_u16_16 & 0x10000)
++ // Check for max backlight condition
++ backlight_8_bit = 0xFF;
++ else
++ // Take MSB of fractional part since backlight is not max
++ backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF;
++
+ /* set ramping boundary */
+ REG_WRITE(MASTER_COMM_DATA_REG1, rampingBoundary);
+
+@@ -220,7 +201,7 @@ static void dmcu_set_backlight_level(
+ 0, 1, 80000);
+
+ /* setDMCUParam_BL */
+- REG_UPDATE(BL1_PWM_USER_LEVEL, BL1_PWM_USER_LEVEL, backlight_17_bit);
++ REG_UPDATE(BL1_PWM_USER_LEVEL, BL1_PWM_USER_LEVEL, backlight_pwm_u16_16);
+
+ /* write ramp */
+ if (controller_id == 0)
+@@ -237,9 +218,9 @@ static void dmcu_set_backlight_level(
+ s2 = REG_READ(BIOS_SCRATCH_2);
+
+ s2 &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK;
+- level &= (ATOM_S2_CURRENT_BL_LEVEL_MASK >>
++ backlight_8_bit &= (ATOM_S2_CURRENT_BL_LEVEL_MASK >>
+ ATOM_S2_CURRENT_BL_LEVEL_SHIFT);
+- s2 |= (level << ATOM_S2_CURRENT_BL_LEVEL_SHIFT);
++ s2 |= (backlight_8_bit << ATOM_S2_CURRENT_BL_LEVEL_SHIFT);
+
+ REG_WRITE(BIOS_SCRATCH_2, s2);
+ }
+@@ -247,7 +228,7 @@ static void dmcu_set_backlight_level(
+ static void dce_abm_init(struct abm *abm)
+ {
+ struct dce_abm *abm_dce = TO_DCE_ABM(abm);
+- unsigned int backlight = get_current_backlight_16_bit(abm_dce);
++ unsigned int backlight = calculate_16_bit_backlight_from_pwm(abm_dce);
+
+ REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x103);
+ REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101);
+@@ -284,12 +265,15 @@ static void dce_abm_init(struct abm *abm)
+ ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, 1);
+ }
+
+-static unsigned int dce_abm_get_current_backlight_8_bit(struct abm *abm)
++static unsigned int dce_abm_get_current_backlight(struct abm *abm)
+ {
+ struct dce_abm *abm_dce = TO_DCE_ABM(abm);
+ unsigned int backlight = REG_READ(BL1_PWM_CURRENT_ABM_LEVEL);
+
+- return (backlight >> 8);
++ /* return backlight in hardware format which is unsigned 17 bits, with
++ * 1 bit integer and 16 bit fractional
++ */
++ return backlight;
+ }
+
+ static bool dce_abm_set_level(struct abm *abm, uint32_t level)
+@@ -396,9 +380,9 @@ static bool dce_abm_init_backlight(struct abm *abm)
+ return true;
+ }
+
+-static bool dce_abm_set_backlight_level(
++static bool dce_abm_set_backlight_level_pwm(
+ struct abm *abm,
+- unsigned int backlight_level,
++ unsigned int backlight_pwm_u16_16,
+ unsigned int frame_ramp,
+ unsigned int controller_id,
+ bool use_smooth_brightness)
+@@ -406,16 +390,16 @@ static bool dce_abm_set_backlight_level(
+ struct dce_abm *abm_dce = TO_DCE_ABM(abm);
+
+ DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
+- backlight_level, backlight_level);
++ backlight_pwm_u16_16, backlight_pwm_u16_16);
+
+ /* If DMCU is in reset state, DMCU is uninitialized */
+ if (use_smooth_brightness)
+ dmcu_set_backlight_level(abm_dce,
+- backlight_level,
++ backlight_pwm_u16_16,
+ frame_ramp,
+ controller_id);
+ else
+- driver_set_backlight_level(abm_dce, backlight_level);
++ driver_set_backlight_level(abm_dce, backlight_pwm_u16_16);
+
+ return true;
+ }
+@@ -424,8 +408,8 @@ static const struct abm_funcs dce_funcs = {
+ .abm_init = dce_abm_init,
+ .set_abm_level = dce_abm_set_level,
+ .init_backlight = dce_abm_init_backlight,
+- .set_backlight_level = dce_abm_set_backlight_level,
+- .get_current_backlight_8_bit = dce_abm_get_current_backlight_8_bit,
++ .set_backlight_level_pwm = dce_abm_set_backlight_level_pwm,
++ .get_current_backlight = dce_abm_get_current_backlight,
+ .set_abm_immediate_disable = dce_abm_immediate_disable
+ };
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+index 76240a28f467..d8bf90046b1b 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+@@ -1085,7 +1085,6 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
+
+ if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
+ link->dc->hwss.edp_backlight_control(link, true);
+- stream->bl_pwm_level = EDP_BACKLIGHT_RAMP_DISABLE_LEVEL;
+ }
+ }
+ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
+index a83a48494613..458a641dc796 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
+@@ -47,12 +47,17 @@ struct abm_funcs {
+ bool (*set_abm_level)(struct abm *abm, unsigned int abm_level);
+ bool (*set_abm_immediate_disable)(struct abm *abm);
+ bool (*init_backlight)(struct abm *abm);
+- bool (*set_backlight_level)(struct abm *abm,
+- unsigned int backlight_level,
++
++ /* backlight_pwm_u16_16 is unsigned 32 bit,
++ * 16 bit integer + 16 fractional, where 1.0 is max backlight value.
++ */
++ bool (*set_backlight_level_pwm)(struct abm *abm,
++ unsigned int backlight_pwm_u16_16,
+ unsigned int frame_ramp,
+ unsigned int controller_id,
+ bool use_smooth_brightness);
+- unsigned int (*get_current_backlight_8_bit)(struct abm *abm);
++
++ unsigned int (*get_current_backlight)(struct abm *abm);
+ };
+
+ #endif
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+index 75de1d8d0c20..e5a85a0563b6 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+@@ -32,8 +32,6 @@
+ #include "inc/hw/link_encoder.h"
+ #include "core_status.h"
+
+-#define EDP_BACKLIGHT_RAMP_DISABLE_LEVEL 0xFFFFFFFF
+-
+ enum pipe_gating_control {
+ PIPE_GATING_CONTROL_DISABLE = 0,
+ PIPE_GATING_CONTROL_ENABLE,
+--
+2.17.1
+