Skip to content

Commit

Permalink
drm/i915/dpcd_bl: Remove redundant AUX backlight frequency calculations
Browse files Browse the repository at this point in the history
Noticed this while moving all of the VESA backlight code in i915 over to
DRM helpers: it would appear that we calculate the frequency value we want
to write to DP_EDP_BACKLIGHT_FREQ_SET twice even though this value never
actually changes during runtime. So, let's simplify things by just caching
this value in intel_panel.backlight, and re-writing it as-needed.

Changes since v1:
* Wrap panel->backlight.edp.vesa.pwm_freq_pre_divider in
  DP_EDP_BACKLIGHT_FREQ_AUX_SET_CAP check - Jani

Signed-off-by: Lyude Paul <lyude@redhat.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Dave Airlie <airlied@gmail.com>
Cc: greg.depoire@gmail.com
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210514181504.565252-2-lyude@redhat.com
  • Loading branch information
Lyude Paul committed Jun 9, 2021
1 parent 241a9e2 commit 4154fa0
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 46 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/display/intel_display_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ struct intel_panel {
union {
struct {
u8 pwmgen_bit_count;
u8 pwm_freq_pre_divider;
} vesa;
struct {
bool sdr_uses_aux;
Expand Down
65 changes: 19 additions & 46 deletions drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,50 +373,6 @@ intel_dp_aux_vesa_set_backlight(const struct drm_connector_state *conn_state,
}
}

/*
* Set PWM Frequency divider to match desired frequency in vbt.
* The PWM Frequency is calculated as 27Mhz / (F x P).
* - Where F = PWM Frequency Pre-Divider value programmed by field 7:0 of the
* EDP_BACKLIGHT_FREQ_SET register (DPCD Address 00728h)
* - Where P = 2^Pn, where Pn is the value programmed by field 4:0 of the
* EDP_PWMGEN_BIT_COUNT register (DPCD Address 00724h)
*/
static bool intel_dp_aux_vesa_set_pwm_freq(struct intel_connector *connector)
{
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_dp *intel_dp = intel_attached_dp(connector);
const u8 pn = connector->panel.backlight.edp.vesa.pwmgen_bit_count;
int freq, fxp, f, fxp_actual, fxp_min, fxp_max;

freq = dev_priv->vbt.backlight.pwm_freq_hz;
if (!freq) {
drm_dbg_kms(&dev_priv->drm,
"Use panel default backlight frequency\n");
return false;
}

fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq);
f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255);
fxp_actual = f << pn;

/* Ensure frequency is within 25% of desired value */
fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4);
fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4);

if (fxp_min > fxp_actual || fxp_actual > fxp_max) {
drm_dbg_kms(&dev_priv->drm, "Actual frequency out of range\n");
return false;
}

if (drm_dp_dpcd_writeb(&intel_dp->aux,
DP_EDP_BACKLIGHT_FREQ_SET, (u8) f) < 0) {
drm_dbg_kms(&dev_priv->drm,
"Failed to write aux backlight freq\n");
return false;
}
return true;
}

static void
intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state, u32 level)
Expand Down Expand Up @@ -459,9 +415,13 @@ intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state,
break;
}

if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_FREQ_AUX_SET_CAP)
if (intel_dp_aux_vesa_set_pwm_freq(connector))
if (panel->backlight.edp.vesa.pwm_freq_pre_divider) {
if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_BACKLIGHT_FREQ_SET,
panel->backlight.edp.vesa.pwm_freq_pre_divider) == 1)
new_dpcd_buf |= DP_EDP_BACKLIGHT_FREQ_AUX_SET_ENABLE;
else
drm_dbg_kms(&i915->drm, "Failed to write aux backlight frequency\n");
}

if (new_dpcd_buf != dpcd_buf) {
if (drm_dp_dpcd_writeb(&intel_dp->aux,
Expand All @@ -482,6 +442,14 @@ static void intel_dp_aux_vesa_disable_backlight(const struct drm_connector_state
false);
}

/*
* Compute PWM frequency divider value based off the frequency provided to us by the vbt.
* The PWM Frequency is calculated as 27Mhz / (F x P).
* - Where F = PWM Frequency Pre-Divider value programmed by field 7:0 of the
* EDP_BACKLIGHT_FREQ_SET register (DPCD Address 00728h)
* - Where P = 2^Pn, where Pn is the value programmed by field 4:0 of the
* EDP_PWMGEN_BIT_COUNT register (DPCD Address 00724h)
*/
static u32 intel_dp_aux_vesa_calc_max_backlight(struct intel_connector *connector)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
Expand Down Expand Up @@ -533,8 +501,10 @@ static u32 intel_dp_aux_vesa_calc_max_backlight(struct intel_connector *connecto
pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK;

/* Ensure frequency is within 25% of desired value */
fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4);
fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4);

if (fxp_min < (1 << pn_min) || (255 << pn_max) < fxp_max) {
drm_dbg_kms(&i915->drm,
"VBT defined backlight frequency out of range\n");
Expand All @@ -555,7 +525,10 @@ static u32 intel_dp_aux_vesa_calc_max_backlight(struct intel_connector *connecto
"Failed to write aux pwmgen bit count\n");
return max_backlight;
}

panel->backlight.edp.vesa.pwmgen_bit_count = pn;
if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_FREQ_AUX_SET_CAP)
panel->backlight.edp.vesa.pwm_freq_pre_divider = f;

max_backlight = (1 << pn) - 1;

Expand Down

0 comments on commit 4154fa0

Please sign in to comment.