diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_panel.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_panel.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index e480cf41c536..20ebc3e83d39 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -845,11 +845,14 @@ static int intel_backlight_device_get_brightness(struct backlight_device *bd) { struct intel_connector *connector = bl_get_data(bd); struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; int ret; + intel_runtime_pm_get(dev_priv); mutex_lock(&dev->mode_config.mutex); ret = intel_panel_get_backlight(connector); mutex_unlock(&dev->mode_config.mutex); + intel_runtime_pm_put(dev_priv); return ret; } @@ -1104,6 +1107,59 @@ void intel_panel_destroy_backlight(struct drm_connector *connector) intel_backlight_device_unregister(intel_connector); } +/** + * intel_find_panel_downclock - find the reduced downclock for LVDS in EDID + * @dev: drm device + * @fixed_mode : panel native mode + * @connector: LVDS/eDP connector + * + * Return downclock_avail + * Find the reduced downclock for LVDS/eDP in EDID. + */ +struct drm_display_mode * +intel_find_panel_downclock(struct drm_device *dev, + struct drm_display_mode *fixed_mode, + struct drm_connector *connector) +{ + struct drm_display_mode *scan, *tmp_mode; + int temp_downclock; + + temp_downclock = fixed_mode->clock; + tmp_mode = NULL; + + list_for_each_entry(scan, &connector->probed_modes, head) { + /* + * If one mode has the same resolution with the fixed_panel + * mode while they have the different refresh rate, it means + * that the reduced downclock is found. In such + * case we can set the different FPx0/1 to dynamically select + * between low and high frequency. + */ + if (scan->hdisplay == fixed_mode->hdisplay && + scan->hsync_start == fixed_mode->hsync_start && + scan->hsync_end == fixed_mode->hsync_end && + scan->htotal == fixed_mode->htotal && + scan->vdisplay == fixed_mode->vdisplay && + scan->vsync_start == fixed_mode->vsync_start && + scan->vsync_end == fixed_mode->vsync_end && + scan->vtotal == fixed_mode->vtotal) { + if (scan->clock < temp_downclock) { + /* + * The downclock is already found. But we + * expect to find the lower downclock. + */ + temp_downclock = scan->clock; + tmp_mode = scan; + } + } + } + + if (temp_downclock < fixed_mode->clock) + return drm_mode_duplicate(dev, tmp_mode); + else + return NULL; +} + /* Set up chip specific backlight functions */ void intel_panel_init_backlight_funcs(struct drm_device *dev) { @@ -1157,4 +1213,8 @@ void intel_panel_fini(struct intel_panel *panel) if (panel->fixed_mode) drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode); + + if (panel->downclock_mode) + drm_mode_destroy(intel_connector->base.dev, + panel->downclock_mode); } |