Loading drivers/gpu/drm/i915/i915_drv.c +5 −2 Original line number Diff line number Diff line Loading @@ -79,11 +79,11 @@ MODULE_PARM_DESC(lvds_downclock, "Use panel (LVDS/eDP) downclocking for power savings " "(default: false)"); unsigned int i915_panel_use_ssc __read_mostly = 1; unsigned int i915_panel_use_ssc __read_mostly = -1; module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600); MODULE_PARM_DESC(lvds_use_ssc, "Use Spread Spectrum Clock with panels [LVDS/eDP] " "(default: true)"); "(default: auto from VBT)"); int i915_vbt_sdvo_panel_type __read_mostly = -1; module_param_named(vbt_sdvo_panel_type, i915_vbt_sdvo_panel_type, int, 0600); Loading Loading @@ -471,6 +471,9 @@ static int i915_drm_thaw(struct drm_device *dev) error = i915_gem_init_ringbuffer(dev); mutex_unlock(&dev->struct_mutex); if (HAS_PCH_SPLIT(dev)) ironlake_init_pch_refclk(dev); drm_mode_config_reset(dev); drm_irq_install(dev); Loading drivers/gpu/drm/i915/i915_drv.h +2 −0 Original line number Diff line number Diff line Loading @@ -358,6 +358,7 @@ typedef struct drm_i915_private { unsigned int lvds_vbt:1; unsigned int int_crt_support:1; unsigned int lvds_use_ssc:1; unsigned int display_clock_mode:1; int lvds_ssc_freq; struct { int rate; Loading Loading @@ -1301,6 +1302,7 @@ extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); extern bool intel_fbc_enabled(struct drm_device *dev); extern void intel_disable_fbc(struct drm_device *dev); extern bool ironlake_set_drps(struct drm_device *dev, u8 val); extern void ironlake_init_pch_refclk(struct drm_device *dev); extern void ironlake_enable_rc6(struct drm_device *dev); extern void gen6_set_rps(struct drm_device *dev, u8 val); extern void intel_detect_pch(struct drm_device *dev); Loading drivers/gpu/drm/i915/intel_bios.c +10 −3 Original line number Diff line number Diff line /* * Copyright 2006 Intel Corporation * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), Loading Loading @@ -309,6 +309,13 @@ parse_general_features(struct drm_i915_private *dev_priv, dev_priv->lvds_use_ssc = general->enable_ssc; dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, general->ssc_freq); dev_priv->display_clock_mode = general->display_clock_mode; DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d\n", dev_priv->int_tv_support, dev_priv->int_crt_support, dev_priv->lvds_use_ssc, dev_priv->lvds_ssc_freq, dev_priv->display_clock_mode); } } Loading Loading @@ -610,7 +617,7 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) /* Default to using SSC */ dev_priv->lvds_use_ssc = 1; dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1); DRM_DEBUG("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq); DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq); /* eDP data */ dev_priv->edp.bpp = 18; Loading Loading @@ -639,7 +646,7 @@ intel_parse_bios(struct drm_device *dev) if (dev_priv->opregion.vbt) { struct vbt_header *vbt = dev_priv->opregion.vbt; if (memcmp(vbt->signature, "$VBT", 4) == 0) { DRM_DEBUG_DRIVER("Using VBT from OpRegion: %20s\n", DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n", vbt->signature); bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset); } else Loading drivers/gpu/drm/i915/intel_bios.h +7 −2 Original line number Diff line number Diff line Loading @@ -120,7 +120,9 @@ struct bdb_general_features { u8 ssc_freq:1; u8 enable_lfp_on_override:1; u8 disable_ssc_ddt:1; u8 rsvd8:3; /* finish byte */ u8 rsvd7:1; u8 display_clock_mode:1; u8 rsvd8:1; /* finish byte */ /* bits 3 */ u8 disable_smooth_vision:1; Loading @@ -133,7 +135,10 @@ struct bdb_general_features { /* bits 5 */ u8 int_crt_support:1; u8 int_tv_support:1; u8 rsvd11:6; /* finish byte */ u8 int_efp_support:1; u8 dp_ssc_enb:1; /* PCH attached eDP supports SSC */ u8 dp_ssc_freq:1; /* SSC freq for PCH attached eDP */ u8 rsvd11:3; /* finish byte */ } __attribute__((packed)); /* pre-915 */ Loading drivers/gpu/drm/i915/intel_display.c +91 −53 Original line number Diff line number Diff line Loading @@ -4585,7 +4585,9 @@ static void intel_update_watermarks(struct drm_device *dev) static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) { return dev_priv->lvds_use_ssc && i915_panel_use_ssc if (i915_panel_use_ssc >= 0) return i915_panel_use_ssc != 0; return dev_priv->lvds_use_ssc && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE); } Loading Loading @@ -5108,36 +5110,52 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, return ret; } static void ironlake_update_pch_refclk(struct drm_device *dev) /* * Initialize reference clocks when the driver loads */ void ironlake_init_pch_refclk(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_mode_config *mode_config = &dev->mode_config; struct drm_crtc *crtc; struct intel_encoder *encoder; struct intel_encoder *has_edp_encoder = NULL; u32 temp; bool has_lvds = false; bool has_cpu_edp = false; bool has_pch_edp = false; bool has_panel = false; bool has_ck505 = false; bool can_ssc = false; /* We need to take the global config into account */ list_for_each_entry(crtc, &mode_config->crtc_list, head) { if (!crtc->enabled) continue; list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { if (encoder->base.crtc != crtc) continue; switch (encoder->type) { case INTEL_OUTPUT_LVDS: has_panel = true; has_lvds = true; break; case INTEL_OUTPUT_EDP: has_edp_encoder = encoder; has_panel = true; if (intel_encoder_is_pch_edp(&encoder->base)) has_pch_edp = true; else has_cpu_edp = true; break; } } if (HAS_PCH_IBX(dev)) { has_ck505 = dev_priv->display_clock_mode; can_ssc = has_ck505; } else { has_ck505 = false; can_ssc = true; } DRM_DEBUG_KMS("has_panel %d has_lvds %d has_pch_edp %d has_cpu_edp %d has_ck505 %d\n", has_panel, has_lvds, has_pch_edp, has_cpu_edp, has_ck505); /* Ironlake: try to setup display ref clock before DPLL * enabling. This is only under driver's control after * PCH B stepping, previous chipset stepping should be Loading @@ -5146,37 +5164,62 @@ static void ironlake_update_pch_refclk(struct drm_device *dev) temp = I915_READ(PCH_DREF_CONTROL); /* Always enable nonspread source */ temp &= ~DREF_NONSPREAD_SOURCE_MASK; if (has_ck505) temp |= DREF_NONSPREAD_CK505_ENABLE; else temp |= DREF_NONSPREAD_SOURCE_ENABLE; if (has_panel) { temp &= ~DREF_SSC_SOURCE_MASK; temp |= DREF_SSC_SOURCE_ENABLE; I915_WRITE(PCH_DREF_CONTROL, temp); POSTING_READ(PCH_DREF_CONTROL); udelay(200); if (has_edp_encoder) { if (intel_panel_use_ssc(dev_priv)) { /* SSC must be turned on before enabling the CPU output */ if (intel_panel_use_ssc(dev_priv) && can_ssc) { DRM_DEBUG_KMS("Using SSC on panel\n"); temp |= DREF_SSC1_ENABLE; I915_WRITE(PCH_DREF_CONTROL, temp); } /* Get SSC going before enabling the outputs */ I915_WRITE(PCH_DREF_CONTROL, temp); POSTING_READ(PCH_DREF_CONTROL); udelay(200); } temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; /* Enable CPU source on CPU attached eDP */ if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) { if (intel_panel_use_ssc(dev_priv)) if (has_cpu_edp) { if (intel_panel_use_ssc(dev_priv) && can_ssc) { DRM_DEBUG_KMS("Using SSC on eDP\n"); temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; } else temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; } else temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE; I915_WRITE(PCH_DREF_CONTROL, temp); POSTING_READ(PCH_DREF_CONTROL); udelay(200); } else { /* Enable SSC on PCH eDP if needed */ if (intel_panel_use_ssc(dev_priv)) { DRM_ERROR("enabling SSC on PCH\n"); temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; } } DRM_DEBUG_KMS("Disabling SSC entirely\n"); temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; /* Turn off CPU output */ temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE; I915_WRITE(PCH_DREF_CONTROL, temp); POSTING_READ(PCH_DREF_CONTROL); udelay(200); /* Turn off the SSC source */ temp &= ~DREF_SSC_SOURCE_MASK; temp |= DREF_SSC_SOURCE_DISABLE; /* Turn off SSC1 */ temp &= ~ DREF_SSC1_ENABLE; I915_WRITE(PCH_DREF_CONTROL, temp); POSTING_READ(PCH_DREF_CONTROL); udelay(200); Loading Loading @@ -5242,16 +5285,10 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, num_connectors++; } if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { refclk = dev_priv->lvds_ssc_freq * 1000; DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", refclk / 1000); } else { refclk = 96000; if (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)) refclk = 120000; /* 120Mhz refclk */ } /* * Every reference clock in a PCH system is 120MHz */ refclk = 120000; /* * Returns a set of divisors for the desired target clock with the given Loading Loading @@ -5378,8 +5415,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, &m_n); ironlake_update_pch_refclk(dev); fp = clock.n << 16 | clock.m1 << 8 | clock.m2; if (has_reduced_clock) fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | Loading Loading @@ -7376,6 +7411,9 @@ static void intel_setup_outputs(struct drm_device *dev) /* disable all the possible outputs/crtcs before entering KMS mode */ drm_helper_disable_unused_functions(dev); if (HAS_PCH_SPLIT(dev)) ironlake_init_pch_refclk(dev); } static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) Loading Loading
drivers/gpu/drm/i915/i915_drv.c +5 −2 Original line number Diff line number Diff line Loading @@ -79,11 +79,11 @@ MODULE_PARM_DESC(lvds_downclock, "Use panel (LVDS/eDP) downclocking for power savings " "(default: false)"); unsigned int i915_panel_use_ssc __read_mostly = 1; unsigned int i915_panel_use_ssc __read_mostly = -1; module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600); MODULE_PARM_DESC(lvds_use_ssc, "Use Spread Spectrum Clock with panels [LVDS/eDP] " "(default: true)"); "(default: auto from VBT)"); int i915_vbt_sdvo_panel_type __read_mostly = -1; module_param_named(vbt_sdvo_panel_type, i915_vbt_sdvo_panel_type, int, 0600); Loading Loading @@ -471,6 +471,9 @@ static int i915_drm_thaw(struct drm_device *dev) error = i915_gem_init_ringbuffer(dev); mutex_unlock(&dev->struct_mutex); if (HAS_PCH_SPLIT(dev)) ironlake_init_pch_refclk(dev); drm_mode_config_reset(dev); drm_irq_install(dev); Loading
drivers/gpu/drm/i915/i915_drv.h +2 −0 Original line number Diff line number Diff line Loading @@ -358,6 +358,7 @@ typedef struct drm_i915_private { unsigned int lvds_vbt:1; unsigned int int_crt_support:1; unsigned int lvds_use_ssc:1; unsigned int display_clock_mode:1; int lvds_ssc_freq; struct { int rate; Loading Loading @@ -1301,6 +1302,7 @@ extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); extern bool intel_fbc_enabled(struct drm_device *dev); extern void intel_disable_fbc(struct drm_device *dev); extern bool ironlake_set_drps(struct drm_device *dev, u8 val); extern void ironlake_init_pch_refclk(struct drm_device *dev); extern void ironlake_enable_rc6(struct drm_device *dev); extern void gen6_set_rps(struct drm_device *dev, u8 val); extern void intel_detect_pch(struct drm_device *dev); Loading
drivers/gpu/drm/i915/intel_bios.c +10 −3 Original line number Diff line number Diff line /* * Copyright 2006 Intel Corporation * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), Loading Loading @@ -309,6 +309,13 @@ parse_general_features(struct drm_i915_private *dev_priv, dev_priv->lvds_use_ssc = general->enable_ssc; dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, general->ssc_freq); dev_priv->display_clock_mode = general->display_clock_mode; DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d\n", dev_priv->int_tv_support, dev_priv->int_crt_support, dev_priv->lvds_use_ssc, dev_priv->lvds_ssc_freq, dev_priv->display_clock_mode); } } Loading Loading @@ -610,7 +617,7 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) /* Default to using SSC */ dev_priv->lvds_use_ssc = 1; dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1); DRM_DEBUG("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq); DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq); /* eDP data */ dev_priv->edp.bpp = 18; Loading Loading @@ -639,7 +646,7 @@ intel_parse_bios(struct drm_device *dev) if (dev_priv->opregion.vbt) { struct vbt_header *vbt = dev_priv->opregion.vbt; if (memcmp(vbt->signature, "$VBT", 4) == 0) { DRM_DEBUG_DRIVER("Using VBT from OpRegion: %20s\n", DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n", vbt->signature); bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset); } else Loading
drivers/gpu/drm/i915/intel_bios.h +7 −2 Original line number Diff line number Diff line Loading @@ -120,7 +120,9 @@ struct bdb_general_features { u8 ssc_freq:1; u8 enable_lfp_on_override:1; u8 disable_ssc_ddt:1; u8 rsvd8:3; /* finish byte */ u8 rsvd7:1; u8 display_clock_mode:1; u8 rsvd8:1; /* finish byte */ /* bits 3 */ u8 disable_smooth_vision:1; Loading @@ -133,7 +135,10 @@ struct bdb_general_features { /* bits 5 */ u8 int_crt_support:1; u8 int_tv_support:1; u8 rsvd11:6; /* finish byte */ u8 int_efp_support:1; u8 dp_ssc_enb:1; /* PCH attached eDP supports SSC */ u8 dp_ssc_freq:1; /* SSC freq for PCH attached eDP */ u8 rsvd11:3; /* finish byte */ } __attribute__((packed)); /* pre-915 */ Loading
drivers/gpu/drm/i915/intel_display.c +91 −53 Original line number Diff line number Diff line Loading @@ -4585,7 +4585,9 @@ static void intel_update_watermarks(struct drm_device *dev) static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) { return dev_priv->lvds_use_ssc && i915_panel_use_ssc if (i915_panel_use_ssc >= 0) return i915_panel_use_ssc != 0; return dev_priv->lvds_use_ssc && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE); } Loading Loading @@ -5108,36 +5110,52 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, return ret; } static void ironlake_update_pch_refclk(struct drm_device *dev) /* * Initialize reference clocks when the driver loads */ void ironlake_init_pch_refclk(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_mode_config *mode_config = &dev->mode_config; struct drm_crtc *crtc; struct intel_encoder *encoder; struct intel_encoder *has_edp_encoder = NULL; u32 temp; bool has_lvds = false; bool has_cpu_edp = false; bool has_pch_edp = false; bool has_panel = false; bool has_ck505 = false; bool can_ssc = false; /* We need to take the global config into account */ list_for_each_entry(crtc, &mode_config->crtc_list, head) { if (!crtc->enabled) continue; list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { if (encoder->base.crtc != crtc) continue; switch (encoder->type) { case INTEL_OUTPUT_LVDS: has_panel = true; has_lvds = true; break; case INTEL_OUTPUT_EDP: has_edp_encoder = encoder; has_panel = true; if (intel_encoder_is_pch_edp(&encoder->base)) has_pch_edp = true; else has_cpu_edp = true; break; } } if (HAS_PCH_IBX(dev)) { has_ck505 = dev_priv->display_clock_mode; can_ssc = has_ck505; } else { has_ck505 = false; can_ssc = true; } DRM_DEBUG_KMS("has_panel %d has_lvds %d has_pch_edp %d has_cpu_edp %d has_ck505 %d\n", has_panel, has_lvds, has_pch_edp, has_cpu_edp, has_ck505); /* Ironlake: try to setup display ref clock before DPLL * enabling. This is only under driver's control after * PCH B stepping, previous chipset stepping should be Loading @@ -5146,37 +5164,62 @@ static void ironlake_update_pch_refclk(struct drm_device *dev) temp = I915_READ(PCH_DREF_CONTROL); /* Always enable nonspread source */ temp &= ~DREF_NONSPREAD_SOURCE_MASK; if (has_ck505) temp |= DREF_NONSPREAD_CK505_ENABLE; else temp |= DREF_NONSPREAD_SOURCE_ENABLE; if (has_panel) { temp &= ~DREF_SSC_SOURCE_MASK; temp |= DREF_SSC_SOURCE_ENABLE; I915_WRITE(PCH_DREF_CONTROL, temp); POSTING_READ(PCH_DREF_CONTROL); udelay(200); if (has_edp_encoder) { if (intel_panel_use_ssc(dev_priv)) { /* SSC must be turned on before enabling the CPU output */ if (intel_panel_use_ssc(dev_priv) && can_ssc) { DRM_DEBUG_KMS("Using SSC on panel\n"); temp |= DREF_SSC1_ENABLE; I915_WRITE(PCH_DREF_CONTROL, temp); } /* Get SSC going before enabling the outputs */ I915_WRITE(PCH_DREF_CONTROL, temp); POSTING_READ(PCH_DREF_CONTROL); udelay(200); } temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; /* Enable CPU source on CPU attached eDP */ if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) { if (intel_panel_use_ssc(dev_priv)) if (has_cpu_edp) { if (intel_panel_use_ssc(dev_priv) && can_ssc) { DRM_DEBUG_KMS("Using SSC on eDP\n"); temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; } else temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; } else temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE; I915_WRITE(PCH_DREF_CONTROL, temp); POSTING_READ(PCH_DREF_CONTROL); udelay(200); } else { /* Enable SSC on PCH eDP if needed */ if (intel_panel_use_ssc(dev_priv)) { DRM_ERROR("enabling SSC on PCH\n"); temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; } } DRM_DEBUG_KMS("Disabling SSC entirely\n"); temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; /* Turn off CPU output */ temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE; I915_WRITE(PCH_DREF_CONTROL, temp); POSTING_READ(PCH_DREF_CONTROL); udelay(200); /* Turn off the SSC source */ temp &= ~DREF_SSC_SOURCE_MASK; temp |= DREF_SSC_SOURCE_DISABLE; /* Turn off SSC1 */ temp &= ~ DREF_SSC1_ENABLE; I915_WRITE(PCH_DREF_CONTROL, temp); POSTING_READ(PCH_DREF_CONTROL); udelay(200); Loading Loading @@ -5242,16 +5285,10 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, num_connectors++; } if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { refclk = dev_priv->lvds_ssc_freq * 1000; DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", refclk / 1000); } else { refclk = 96000; if (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)) refclk = 120000; /* 120Mhz refclk */ } /* * Every reference clock in a PCH system is 120MHz */ refclk = 120000; /* * Returns a set of divisors for the desired target clock with the given Loading Loading @@ -5378,8 +5415,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, &m_n); ironlake_update_pch_refclk(dev); fp = clock.n << 16 | clock.m1 << 8 | clock.m2; if (has_reduced_clock) fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | Loading Loading @@ -7376,6 +7411,9 @@ static void intel_setup_outputs(struct drm_device *dev) /* disable all the possible outputs/crtcs before entering KMS mode */ drm_helper_disable_unused_functions(dev); if (HAS_PCH_SPLIT(dev)) ironlake_init_pch_refclk(dev); } static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) Loading