aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c193
1 files changed, 165 insertions, 28 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3c14240cc002..099f420de57a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -863,10 +863,8 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
863 struct drm_device *dev = crtc->dev; 863 struct drm_device *dev = crtc->dev;
864 struct drm_i915_private *dev_priv = dev->dev_private; 864 struct drm_i915_private *dev_priv = dev->dev_private;
865 intel_clock_t clock; 865 intel_clock_t clock;
866 int max_n;
867 bool found;
868 int err_most = 47; 866 int err_most = 47;
869 found = false; 867 int err_min = 10000;
870 868
871 /* eDP has only 2 clock choice, no n/m/p setting */ 869 /* eDP has only 2 clock choice, no n/m/p setting */
872 if (HAS_eDP) 870 if (HAS_eDP)
@@ -890,10 +888,9 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
890 } 888 }
891 889
892 memset(best_clock, 0, sizeof(*best_clock)); 890 memset(best_clock, 0, sizeof(*best_clock));
893 max_n = limit->n.max;
894 for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) { 891 for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
895 /* based on hardware requriment prefer smaller n to precision */ 892 /* based on hardware requriment prefer smaller n to precision */
896 for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { 893 for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) {
897 /* based on hardware requirment prefere larger m1,m2 */ 894 /* based on hardware requirment prefere larger m1,m2 */
898 for (clock.m1 = limit->m1.max; 895 for (clock.m1 = limit->m1.max;
899 clock.m1 >= limit->m1.min; clock.m1--) { 896 clock.m1 >= limit->m1.min; clock.m1--) {
@@ -907,18 +904,18 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
907 this_err = abs((10000 - (target*10000/clock.dot))); 904 this_err = abs((10000 - (target*10000/clock.dot)));
908 if (this_err < err_most) { 905 if (this_err < err_most) {
909 *best_clock = clock; 906 *best_clock = clock;
910 err_most = this_err;
911 max_n = clock.n;
912 found = true;
913 /* found on first matching */ 907 /* found on first matching */
914 goto out; 908 goto out;
909 } else if (this_err < err_min) {
910 *best_clock = clock;
911 err_min = this_err;
915 } 912 }
916 } 913 }
917 } 914 }
918 } 915 }
919 } 916 }
920out: 917out:
921 return found; 918 return true;
922} 919}
923 920
924/* DisplayPort has only two frequencies, 162MHz and 270MHz */ 921/* DisplayPort has only two frequencies, 162MHz and 270MHz */
@@ -943,6 +940,7 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
943 clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2); 940 clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2);
944 clock.p = (clock.p1 * clock.p2); 941 clock.p = (clock.p1 * clock.p2);
945 clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; 942 clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p;
943 clock.vco = 0;
946 memcpy(best_clock, &clock, sizeof(intel_clock_t)); 944 memcpy(best_clock, &clock, sizeof(intel_clock_t));
947 return true; 945 return true;
948} 946}
@@ -1260,9 +1258,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
1260 return ret; 1258 return ret;
1261 } 1259 }
1262 1260
1263 /* Pre-i965 needs to install a fence for tiled scan-out */ 1261 /* Install a fence for tiled scan-out. Pre-i965 always needs a fence,
1264 if (!IS_I965G(dev) && 1262 * whereas 965+ only requires a fence if using framebuffer compression.
1265 obj_priv->fence_reg == I915_FENCE_REG_NONE && 1263 * For simplicity, we always install a fence as the cost is not that onerous.
1264 */
1265 if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
1266 obj_priv->tiling_mode != I915_TILING_NONE) { 1266 obj_priv->tiling_mode != I915_TILING_NONE) {
1267 ret = i915_gem_object_get_fence_reg(obj); 1267 ret = i915_gem_object_get_fence_reg(obj);
1268 if (ret != 0) { 1268 if (ret != 0) {
@@ -1513,7 +1513,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
1513 /* Enable panel fitting for LVDS */ 1513 /* Enable panel fitting for LVDS */
1514 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { 1514 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
1515 temp = I915_READ(pf_ctl_reg); 1515 temp = I915_READ(pf_ctl_reg);
1516 I915_WRITE(pf_ctl_reg, temp | PF_ENABLE); 1516 I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3);
1517 1517
1518 /* currently full aspect */ 1518 /* currently full aspect */
1519 I915_WRITE(pf_win_pos, 0); 1519 I915_WRITE(pf_win_pos, 0);
@@ -1801,6 +1801,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
1801 case DRM_MODE_DPMS_ON: 1801 case DRM_MODE_DPMS_ON:
1802 case DRM_MODE_DPMS_STANDBY: 1802 case DRM_MODE_DPMS_STANDBY:
1803 case DRM_MODE_DPMS_SUSPEND: 1803 case DRM_MODE_DPMS_SUSPEND:
1804 intel_update_watermarks(dev);
1805
1804 /* Enable the DPLL */ 1806 /* Enable the DPLL */
1805 temp = I915_READ(dpll_reg); 1807 temp = I915_READ(dpll_reg);
1806 if ((temp & DPLL_VCO_ENABLE) == 0) { 1808 if ((temp & DPLL_VCO_ENABLE) == 0) {
@@ -1838,7 +1840,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
1838 1840
1839 /* Give the overlay scaler a chance to enable if it's on this pipe */ 1841 /* Give the overlay scaler a chance to enable if it's on this pipe */
1840 //intel_crtc_dpms_video(crtc, true); TODO 1842 //intel_crtc_dpms_video(crtc, true); TODO
1841 intel_update_watermarks(dev);
1842 break; 1843 break;
1843 case DRM_MODE_DPMS_OFF: 1844 case DRM_MODE_DPMS_OFF:
1844 intel_update_watermarks(dev); 1845 intel_update_watermarks(dev);
@@ -2082,7 +2083,7 @@ fdi_reduce_ratio(u32 *num, u32 *den)
2082#define LINK_N 0x80000 2083#define LINK_N 0x80000
2083 2084
2084static void 2085static void
2085igdng_compute_m_n(int bytes_per_pixel, int nlanes, 2086igdng_compute_m_n(int bits_per_pixel, int nlanes,
2086 int pixel_clock, int link_clock, 2087 int pixel_clock, int link_clock,
2087 struct fdi_m_n *m_n) 2088 struct fdi_m_n *m_n)
2088{ 2089{
@@ -2092,7 +2093,8 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes,
2092 2093
2093 temp = (u64) DATA_N * pixel_clock; 2094 temp = (u64) DATA_N * pixel_clock;
2094 temp = div_u64(temp, link_clock); 2095 temp = div_u64(temp, link_clock);
2095 m_n->gmch_m = div_u64(temp * bytes_per_pixel, nlanes); 2096 m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes);
2097 m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */
2096 m_n->gmch_n = DATA_N; 2098 m_n->gmch_n = DATA_N;
2097 fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); 2099 fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
2098 2100
@@ -2140,6 +2142,13 @@ static struct intel_watermark_params igd_cursor_hplloff_wm = {
2140 IGD_CURSOR_GUARD_WM, 2142 IGD_CURSOR_GUARD_WM,
2141 IGD_FIFO_LINE_SIZE 2143 IGD_FIFO_LINE_SIZE
2142}; 2144};
2145static struct intel_watermark_params g4x_wm_info = {
2146 G4X_FIFO_SIZE,
2147 G4X_MAX_WM,
2148 G4X_MAX_WM,
2149 2,
2150 G4X_FIFO_LINE_SIZE,
2151};
2143static struct intel_watermark_params i945_wm_info = { 2152static struct intel_watermark_params i945_wm_info = {
2144 I945_FIFO_SIZE, 2153 I945_FIFO_SIZE,
2145 I915_MAX_WM, 2154 I915_MAX_WM,
@@ -2430,17 +2439,74 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane)
2430 return size; 2439 return size;
2431} 2440}
2432 2441
2433static void g4x_update_wm(struct drm_device *dev, int unused, int unused2, 2442static void g4x_update_wm(struct drm_device *dev, int planea_clock,
2434 int unused3, int unused4) 2443 int planeb_clock, int sr_hdisplay, int pixel_size)
2435{ 2444{
2436 struct drm_i915_private *dev_priv = dev->dev_private; 2445 struct drm_i915_private *dev_priv = dev->dev_private;
2437 u32 fw_blc_self = I915_READ(FW_BLC_SELF); 2446 int total_size, cacheline_size;
2447 int planea_wm, planeb_wm, cursora_wm, cursorb_wm, cursor_sr;
2448 struct intel_watermark_params planea_params, planeb_params;
2449 unsigned long line_time_us;
2450 int sr_clock, sr_entries = 0, entries_required;
2438 2451
2439 if (i915_powersave) 2452 /* Create copies of the base settings for each pipe */
2440 fw_blc_self |= FW_BLC_SELF_EN; 2453 planea_params = planeb_params = g4x_wm_info;
2441 else 2454
2442 fw_blc_self &= ~FW_BLC_SELF_EN; 2455 /* Grab a couple of global values before we overwrite them */
2443 I915_WRITE(FW_BLC_SELF, fw_blc_self); 2456 total_size = planea_params.fifo_size;
2457 cacheline_size = planea_params.cacheline_size;
2458
2459 /*
2460 * Note: we need to make sure we don't overflow for various clock &
2461 * latency values.
2462 * clocks go from a few thousand to several hundred thousand.
2463 * latency is usually a few thousand
2464 */
2465 entries_required = ((planea_clock / 1000) * pixel_size * latency_ns) /
2466 1000;
2467 entries_required /= G4X_FIFO_LINE_SIZE;
2468 planea_wm = entries_required + planea_params.guard_size;
2469
2470 entries_required = ((planeb_clock / 1000) * pixel_size * latency_ns) /
2471 1000;
2472 entries_required /= G4X_FIFO_LINE_SIZE;
2473 planeb_wm = entries_required + planeb_params.guard_size;
2474
2475 cursora_wm = cursorb_wm = 16;
2476 cursor_sr = 32;
2477
2478 DRM_DEBUG("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
2479
2480 /* Calc sr entries for one plane configs */
2481 if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
2482 /* self-refresh has much higher latency */
2483 const static int sr_latency_ns = 12000;
2484
2485 sr_clock = planea_clock ? planea_clock : planeb_clock;
2486 line_time_us = ((sr_hdisplay * 1000) / sr_clock);
2487
2488 /* Use ns/us then divide to preserve precision */
2489 sr_entries = (((sr_latency_ns / line_time_us) + 1) *
2490 pixel_size * sr_hdisplay) / 1000;
2491 sr_entries = roundup(sr_entries / cacheline_size, 1);
2492 DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
2493 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
2494 }
2495
2496 DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n",
2497 planea_wm, planeb_wm, sr_entries);
2498
2499 planea_wm &= 0x3f;
2500 planeb_wm &= 0x3f;
2501
2502 I915_WRITE(DSPFW1, (sr_entries << DSPFW_SR_SHIFT) |
2503 (cursorb_wm << DSPFW_CURSORB_SHIFT) |
2504 (planeb_wm << DSPFW_PLANEB_SHIFT) | planea_wm);
2505 I915_WRITE(DSPFW2, (I915_READ(DSPFW2) & DSPFW_CURSORA_MASK) |
2506 (cursora_wm << DSPFW_CURSORA_SHIFT));
2507 /* HPLL off in SR has some issues on G4x... disable it */
2508 I915_WRITE(DSPFW3, (I915_READ(DSPFW3) & ~DSPFW_HPLL_SR_EN) |
2509 (cursor_sr << DSPFW_CURSOR_SR_SHIFT));
2444} 2510}
2445 2511
2446static void i965_update_wm(struct drm_device *dev, int unused, int unused2, 2512static void i965_update_wm(struct drm_device *dev, int unused, int unused2,
@@ -2586,6 +2652,9 @@ static void intel_update_watermarks(struct drm_device *dev)
2586 unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; 2652 unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0;
2587 int enabled = 0, pixel_size = 0; 2653 int enabled = 0, pixel_size = 0;
2588 2654
2655 if (!dev_priv->display.update_wm)
2656 return;
2657
2589 /* Get the clock config from both planes */ 2658 /* Get the clock config from both planes */
2590 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 2659 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
2591 intel_crtc = to_intel_crtc(crtc); 2660 intel_crtc = to_intel_crtc(crtc);
@@ -2763,7 +2832,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2763 2832
2764 /* FDI link */ 2833 /* FDI link */
2765 if (IS_IGDNG(dev)) { 2834 if (IS_IGDNG(dev)) {
2766 int lane, link_bw; 2835 int lane, link_bw, bpp;
2767 /* eDP doesn't require FDI link, so just set DP M/N 2836 /* eDP doesn't require FDI link, so just set DP M/N
2768 according to current link config */ 2837 according to current link config */
2769 if (is_edp) { 2838 if (is_edp) {
@@ -2782,10 +2851,72 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2782 lane = 4; 2851 lane = 4;
2783 link_bw = 270000; 2852 link_bw = 270000;
2784 } 2853 }
2785 igdng_compute_m_n(3, lane, target_clock, 2854
2855 /* determine panel color depth */
2856 temp = I915_READ(pipeconf_reg);
2857
2858 switch (temp & PIPE_BPC_MASK) {
2859 case PIPE_8BPC:
2860 bpp = 24;
2861 break;
2862 case PIPE_10BPC:
2863 bpp = 30;
2864 break;
2865 case PIPE_6BPC:
2866 bpp = 18;
2867 break;
2868 case PIPE_12BPC:
2869 bpp = 36;
2870 break;
2871 default:
2872 DRM_ERROR("unknown pipe bpc value\n");
2873 bpp = 24;
2874 }
2875
2876 igdng_compute_m_n(bpp, lane, target_clock,
2786 link_bw, &m_n); 2877 link_bw, &m_n);
2787 } 2878 }
2788 2879
2880 /* Ironlake: try to setup display ref clock before DPLL
2881 * enabling. This is only under driver's control after
2882 * PCH B stepping, previous chipset stepping should be
2883 * ignoring this setting.
2884 */
2885 if (IS_IGDNG(dev)) {
2886 temp = I915_READ(PCH_DREF_CONTROL);
2887 /* Always enable nonspread source */
2888 temp &= ~DREF_NONSPREAD_SOURCE_MASK;
2889 temp |= DREF_NONSPREAD_SOURCE_ENABLE;
2890 I915_WRITE(PCH_DREF_CONTROL, temp);
2891 POSTING_READ(PCH_DREF_CONTROL);
2892
2893 temp &= ~DREF_SSC_SOURCE_MASK;
2894 temp |= DREF_SSC_SOURCE_ENABLE;
2895 I915_WRITE(PCH_DREF_CONTROL, temp);
2896 POSTING_READ(PCH_DREF_CONTROL);
2897
2898 udelay(200);
2899
2900 if (is_edp) {
2901 if (dev_priv->lvds_use_ssc) {
2902 temp |= DREF_SSC1_ENABLE;
2903 I915_WRITE(PCH_DREF_CONTROL, temp);
2904 POSTING_READ(PCH_DREF_CONTROL);
2905
2906 udelay(200);
2907
2908 temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
2909 temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
2910 I915_WRITE(PCH_DREF_CONTROL, temp);
2911 POSTING_READ(PCH_DREF_CONTROL);
2912 } else {
2913 temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
2914 I915_WRITE(PCH_DREF_CONTROL, temp);
2915 POSTING_READ(PCH_DREF_CONTROL);
2916 }
2917 }
2918 }
2919
2789 if (IS_IGD(dev)) { 2920 if (IS_IGD(dev)) {
2790 fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; 2921 fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
2791 if (has_reduced_clock) 2922 if (has_reduced_clock)
@@ -2936,6 +3067,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2936 3067
2937 lvds = I915_READ(lvds_reg); 3068 lvds = I915_READ(lvds_reg);
2938 lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT; 3069 lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
3070 /* set the corresponsding LVDS_BORDER bit */
3071 lvds |= dev_priv->lvds_border_bits;
2939 /* Set the B0-B3 data pairs corresponding to whether we're going to 3072 /* Set the B0-B3 data pairs corresponding to whether we're going to
2940 * set the DPLLs for dual-channel mode or not. 3073 * set the DPLLs for dual-channel mode or not.
2941 */ 3074 */
@@ -4124,7 +4257,9 @@ void intel_init_clock_gating(struct drm_device *dev)
4124 * Disable clock gating reported to work incorrectly according to the 4257 * Disable clock gating reported to work incorrectly according to the
4125 * specs, but enable as much else as we can. 4258 * specs, but enable as much else as we can.
4126 */ 4259 */
4127 if (IS_G4X(dev)) { 4260 if (IS_IGDNG(dev)) {
4261 return;
4262 } else if (IS_G4X(dev)) {
4128 uint32_t dspclk_gate; 4263 uint32_t dspclk_gate;
4129 I915_WRITE(RENCLK_GATE_D1, 0); 4264 I915_WRITE(RENCLK_GATE_D1, 0);
4130 I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | 4265 I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE |
@@ -4212,7 +4347,9 @@ static void intel_init_display(struct drm_device *dev)
4212 i830_get_display_clock_speed; 4347 i830_get_display_clock_speed;
4213 4348
4214 /* For FIFO watermark updates */ 4349 /* For FIFO watermark updates */
4215 if (IS_G4X(dev)) 4350 if (IS_IGDNG(dev))
4351 dev_priv->display.update_wm = NULL;
4352 else if (IS_G4X(dev))
4216 dev_priv->display.update_wm = g4x_update_wm; 4353 dev_priv->display.update_wm = g4x_update_wm;
4217 else if (IS_I965G(dev)) 4354 else if (IS_I965G(dev))
4218 dev_priv->display.update_wm = i965_update_wm; 4355 dev_priv->display.update_wm = i965_update_wm;