diff options
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.patch | 432 |
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 + |