]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/i915/intel_ddi.c
Merge tag 'v3.10-rc2' into drm-intel-next-queued
[karo-tx-linux.git] / drivers / gpu / drm / i915 / intel_ddi.c
index fb961bb81903c95550289845a846bd0308c448d7..062de679f38f3ebd9143c61ac3c6fca24bfbd785 100644 (file)
@@ -174,6 +174,8 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
         * mode set "sequence for CRT port" document:
         * - TP1 to TP2 time with the default value
         * - FDI delay to 90h
+        *
+        * WaFDIAutoLinkSetTimingOverrride:hsw
         */
        I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) |
                                  FDI_RX_PWRDN_LANE0_VAL(2) |
@@ -181,7 +183,8 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
 
        /* Enable the PCH Receiver FDI PLL */
        rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
-                    FDI_RX_PLL_ENABLE | ((intel_crtc->fdi_lanes - 1) << 19);
+                    FDI_RX_PLL_ENABLE |
+                    FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
        I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
        POSTING_READ(_FDI_RXA_CTL);
        udelay(220);
@@ -209,7 +212,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
                 * port reversal bit */
                I915_WRITE(DDI_BUF_CTL(PORT_E),
                           DDI_BUF_CTL_ENABLE |
-                          ((intel_crtc->fdi_lanes - 1) << 1) |
+                          ((intel_crtc->config.fdi_lanes - 1) << 1) |
                           hsw_ddi_buf_ctl_values[i / 2]);
                POSTING_READ(DDI_BUF_CTL(PORT_E));
 
@@ -278,392 +281,6 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
        DRM_ERROR("FDI link training failed!\n");
 }
 
-/* WRPLL clock dividers */
-struct wrpll_tmds_clock {
-       u32 clock;
-       u16 p;          /* Post divider */
-       u16 n2;         /* Feedback divider */
-       u16 r2;         /* Reference divider */
-};
-
-/* Table of matching values for WRPLL clocks programming for each frequency.
- * The code assumes this table is sorted. */
-static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
-       {19750, 38,     25,     18},
-       {20000, 48,     32,     18},
-       {21000, 36,     21,     15},
-       {21912, 42,     29,     17},
-       {22000, 36,     22,     15},
-       {23000, 36,     23,     15},
-       {23500, 40,     40,     23},
-       {23750, 26,     16,     14},
-       {24000, 36,     24,     15},
-       {25000, 36,     25,     15},
-       {25175, 26,     40,     33},
-       {25200, 30,     21,     15},
-       {26000, 36,     26,     15},
-       {27000, 30,     21,     14},
-       {27027, 18,     100,    111},
-       {27500, 30,     29,     19},
-       {28000, 34,     30,     17},
-       {28320, 26,     30,     22},
-       {28322, 32,     42,     25},
-       {28750, 24,     23,     18},
-       {29000, 30,     29,     18},
-       {29750, 32,     30,     17},
-       {30000, 30,     25,     15},
-       {30750, 30,     41,     24},
-       {31000, 30,     31,     18},
-       {31500, 30,     28,     16},
-       {32000, 30,     32,     18},
-       {32500, 28,     32,     19},
-       {33000, 24,     22,     15},
-       {34000, 28,     30,     17},
-       {35000, 26,     32,     19},
-       {35500, 24,     30,     19},
-       {36000, 26,     26,     15},
-       {36750, 26,     46,     26},
-       {37000, 24,     23,     14},
-       {37762, 22,     40,     26},
-       {37800, 20,     21,     15},
-       {38000, 24,     27,     16},
-       {38250, 24,     34,     20},
-       {39000, 24,     26,     15},
-       {40000, 24,     32,     18},
-       {40500, 20,     21,     14},
-       {40541, 22,     147,    89},
-       {40750, 18,     19,     14},
-       {41000, 16,     17,     14},
-       {41500, 22,     44,     26},
-       {41540, 22,     44,     26},
-       {42000, 18,     21,     15},
-       {42500, 22,     45,     26},
-       {43000, 20,     43,     27},
-       {43163, 20,     24,     15},
-       {44000, 18,     22,     15},
-       {44900, 20,     108,    65},
-       {45000, 20,     25,     15},
-       {45250, 20,     52,     31},
-       {46000, 18,     23,     15},
-       {46750, 20,     45,     26},
-       {47000, 20,     40,     23},
-       {48000, 18,     24,     15},
-       {49000, 18,     49,     30},
-       {49500, 16,     22,     15},
-       {50000, 18,     25,     15},
-       {50500, 18,     32,     19},
-       {51000, 18,     34,     20},
-       {52000, 18,     26,     15},
-       {52406, 14,     34,     25},
-       {53000, 16,     22,     14},
-       {54000, 16,     24,     15},
-       {54054, 16,     173,    108},
-       {54500, 14,     24,     17},
-       {55000, 12,     22,     18},
-       {56000, 14,     45,     31},
-       {56250, 16,     25,     15},
-       {56750, 14,     25,     17},
-       {57000, 16,     27,     16},
-       {58000, 16,     43,     25},
-       {58250, 16,     38,     22},
-       {58750, 16,     40,     23},
-       {59000, 14,     26,     17},
-       {59341, 14,     40,     26},
-       {59400, 16,     44,     25},
-       {60000, 16,     32,     18},
-       {60500, 12,     39,     29},
-       {61000, 14,     49,     31},
-       {62000, 14,     37,     23},
-       {62250, 14,     42,     26},
-       {63000, 12,     21,     15},
-       {63500, 14,     28,     17},
-       {64000, 12,     27,     19},
-       {65000, 14,     32,     19},
-       {65250, 12,     29,     20},
-       {65500, 12,     32,     22},
-       {66000, 12,     22,     15},
-       {66667, 14,     38,     22},
-       {66750, 10,     21,     17},
-       {67000, 14,     33,     19},
-       {67750, 14,     58,     33},
-       {68000, 14,     30,     17},
-       {68179, 14,     46,     26},
-       {68250, 14,     46,     26},
-       {69000, 12,     23,     15},
-       {70000, 12,     28,     18},
-       {71000, 12,     30,     19},
-       {72000, 12,     24,     15},
-       {73000, 10,     23,     17},
-       {74000, 12,     23,     14},
-       {74176, 8,      100,    91},
-       {74250, 10,     22,     16},
-       {74481, 12,     43,     26},
-       {74500, 10,     29,     21},
-       {75000, 12,     25,     15},
-       {75250, 10,     39,     28},
-       {76000, 12,     27,     16},
-       {77000, 12,     53,     31},
-       {78000, 12,     26,     15},
-       {78750, 12,     28,     16},
-       {79000, 10,     38,     26},
-       {79500, 10,     28,     19},
-       {80000, 12,     32,     18},
-       {81000, 10,     21,     14},
-       {81081, 6,      100,    111},
-       {81624, 8,      29,     24},
-       {82000, 8,      17,     14},
-       {83000, 10,     40,     26},
-       {83950, 10,     28,     18},
-       {84000, 10,     28,     18},
-       {84750, 6,      16,     17},
-       {85000, 6,      17,     18},
-       {85250, 10,     30,     19},
-       {85750, 10,     27,     17},
-       {86000, 10,     43,     27},
-       {87000, 10,     29,     18},
-       {88000, 10,     44,     27},
-       {88500, 10,     41,     25},
-       {89000, 10,     28,     17},
-       {89012, 6,      90,     91},
-       {89100, 10,     33,     20},
-       {90000, 10,     25,     15},
-       {91000, 10,     32,     19},
-       {92000, 10,     46,     27},
-       {93000, 10,     31,     18},
-       {94000, 10,     40,     23},
-       {94500, 10,     28,     16},
-       {95000, 10,     44,     25},
-       {95654, 10,     39,     22},
-       {95750, 10,     39,     22},
-       {96000, 10,     32,     18},
-       {97000, 8,      23,     16},
-       {97750, 8,      42,     29},
-       {98000, 8,      45,     31},
-       {99000, 8,      22,     15},
-       {99750, 8,      34,     23},
-       {100000,        6,      20,     18},
-       {100500,        6,      19,     17},
-       {101000,        6,      37,     33},
-       {101250,        8,      21,     14},
-       {102000,        6,      17,     15},
-       {102250,        6,      25,     22},
-       {103000,        8,      29,     19},
-       {104000,        8,      37,     24},
-       {105000,        8,      28,     18},
-       {106000,        8,      22,     14},
-       {107000,        8,      46,     29},
-       {107214,        8,      27,     17},
-       {108000,        8,      24,     15},
-       {108108,        8,      173,    108},
-       {109000,        6,      23,     19},
-       {110000,        6,      22,     18},
-       {110013,        6,      22,     18},
-       {110250,        8,      49,     30},
-       {110500,        8,      36,     22},
-       {111000,        8,      23,     14},
-       {111264,        8,      150,    91},
-       {111375,        8,      33,     20},
-       {112000,        8,      63,     38},
-       {112500,        8,      25,     15},
-       {113100,        8,      57,     34},
-       {113309,        8,      42,     25},
-       {114000,        8,      27,     16},
-       {115000,        6,      23,     18},
-       {116000,        8,      43,     25},
-       {117000,        8,      26,     15},
-       {117500,        8,      40,     23},
-       {118000,        6,      38,     29},
-       {119000,        8,      30,     17},
-       {119500,        8,      46,     26},
-       {119651,        8,      39,     22},
-       {120000,        8,      32,     18},
-       {121000,        6,      39,     29},
-       {121250,        6,      31,     23},
-       {121750,        6,      23,     17},
-       {122000,        6,      42,     31},
-       {122614,        6,      30,     22},
-       {123000,        6,      41,     30},
-       {123379,        6,      37,     27},
-       {124000,        6,      51,     37},
-       {125000,        6,      25,     18},
-       {125250,        4,      13,     14},
-       {125750,        4,      27,     29},
-       {126000,        6,      21,     15},
-       {127000,        6,      24,     17},
-       {127250,        6,      41,     29},
-       {128000,        6,      27,     19},
-       {129000,        6,      43,     30},
-       {129859,        4,      25,     26},
-       {130000,        6,      26,     18},
-       {130250,        6,      42,     29},
-       {131000,        6,      32,     22},
-       {131500,        6,      38,     26},
-       {131850,        6,      41,     28},
-       {132000,        6,      22,     15},
-       {132750,        6,      28,     19},
-       {133000,        6,      34,     23},
-       {133330,        6,      37,     25},
-       {134000,        6,      61,     41},
-       {135000,        6,      21,     14},
-       {135250,        6,      167,    111},
-       {136000,        6,      62,     41},
-       {137000,        6,      35,     23},
-       {138000,        6,      23,     15},
-       {138500,        6,      40,     26},
-       {138750,        6,      37,     24},
-       {139000,        6,      34,     22},
-       {139050,        6,      34,     22},
-       {139054,        6,      34,     22},
-       {140000,        6,      28,     18},
-       {141000,        6,      36,     23},
-       {141500,        6,      22,     14},
-       {142000,        6,      30,     19},
-       {143000,        6,      27,     17},
-       {143472,        4,      17,     16},
-       {144000,        6,      24,     15},
-       {145000,        6,      29,     18},
-       {146000,        6,      47,     29},
-       {146250,        6,      26,     16},
-       {147000,        6,      49,     30},
-       {147891,        6,      23,     14},
-       {148000,        6,      23,     14},
-       {148250,        6,      28,     17},
-       {148352,        4,      100,    91},
-       {148500,        6,      33,     20},
-       {149000,        6,      48,     29},
-       {150000,        6,      25,     15},
-       {151000,        4,      19,     17},
-       {152000,        6,      27,     16},
-       {152280,        6,      44,     26},
-       {153000,        6,      34,     20},
-       {154000,        6,      53,     31},
-       {155000,        6,      31,     18},
-       {155250,        6,      50,     29},
-       {155750,        6,      45,     26},
-       {156000,        6,      26,     15},
-       {157000,        6,      61,     35},
-       {157500,        6,      28,     16},
-       {158000,        6,      65,     37},
-       {158250,        6,      44,     25},
-       {159000,        6,      53,     30},
-       {159500,        6,      39,     22},
-       {160000,        6,      32,     18},
-       {161000,        4,      31,     26},
-       {162000,        4,      18,     15},
-       {162162,        4,      131,    109},
-       {162500,        4,      53,     44},
-       {163000,        4,      29,     24},
-       {164000,        4,      17,     14},
-       {165000,        4,      22,     18},
-       {166000,        4,      32,     26},
-       {167000,        4,      26,     21},
-       {168000,        4,      46,     37},
-       {169000,        4,      104,    83},
-       {169128,        4,      64,     51},
-       {169500,        4,      39,     31},
-       {170000,        4,      34,     27},
-       {171000,        4,      19,     15},
-       {172000,        4,      51,     40},
-       {172750,        4,      32,     25},
-       {172800,        4,      32,     25},
-       {173000,        4,      41,     32},
-       {174000,        4,      49,     38},
-       {174787,        4,      22,     17},
-       {175000,        4,      35,     27},
-       {176000,        4,      30,     23},
-       {177000,        4,      38,     29},
-       {178000,        4,      29,     22},
-       {178500,        4,      37,     28},
-       {179000,        4,      53,     40},
-       {179500,        4,      73,     55},
-       {180000,        4,      20,     15},
-       {181000,        4,      55,     41},
-       {182000,        4,      31,     23},
-       {183000,        4,      42,     31},
-       {184000,        4,      30,     22},
-       {184750,        4,      26,     19},
-       {185000,        4,      37,     27},
-       {186000,        4,      51,     37},
-       {187000,        4,      36,     26},
-       {188000,        4,      32,     23},
-       {189000,        4,      21,     15},
-       {190000,        4,      38,     27},
-       {190960,        4,      41,     29},
-       {191000,        4,      41,     29},
-       {192000,        4,      27,     19},
-       {192250,        4,      37,     26},
-       {193000,        4,      20,     14},
-       {193250,        4,      53,     37},
-       {194000,        4,      23,     16},
-       {194208,        4,      23,     16},
-       {195000,        4,      26,     18},
-       {196000,        4,      45,     31},
-       {197000,        4,      35,     24},
-       {197750,        4,      41,     28},
-       {198000,        4,      22,     15},
-       {198500,        4,      25,     17},
-       {199000,        4,      28,     19},
-       {200000,        4,      37,     25},
-       {201000,        4,      61,     41},
-       {202000,        4,      112,    75},
-       {202500,        4,      21,     14},
-       {203000,        4,      146,    97},
-       {204000,        4,      62,     41},
-       {204750,        4,      44,     29},
-       {205000,        4,      38,     25},
-       {206000,        4,      29,     19},
-       {207000,        4,      23,     15},
-       {207500,        4,      40,     26},
-       {208000,        4,      37,     24},
-       {208900,        4,      48,     31},
-       {209000,        4,      48,     31},
-       {209250,        4,      31,     20},
-       {210000,        4,      28,     18},
-       {211000,        4,      25,     16},
-       {212000,        4,      22,     14},
-       {213000,        4,      30,     19},
-       {213750,        4,      38,     24},
-       {214000,        4,      46,     29},
-       {214750,        4,      35,     22},
-       {215000,        4,      43,     27},
-       {216000,        4,      24,     15},
-       {217000,        4,      37,     23},
-       {218000,        4,      42,     26},
-       {218250,        4,      42,     26},
-       {218750,        4,      34,     21},
-       {219000,        4,      47,     29},
-       {220000,        4,      44,     27},
-       {220640,        4,      49,     30},
-       {220750,        4,      36,     22},
-       {221000,        4,      36,     22},
-       {222000,        4,      23,     14},
-       {222525,        4,      28,     17},
-       {222750,        4,      33,     20},
-       {227000,        4,      37,     22},
-       {230250,        4,      29,     17},
-       {233500,        4,      38,     22},
-       {235000,        4,      40,     23},
-       {238000,        4,      30,     17},
-       {241500,        2,      17,     19},
-       {245250,        2,      20,     22},
-       {247750,        2,      22,     24},
-       {253250,        2,      15,     16},
-       {256250,        2,      18,     19},
-       {262500,        2,      31,     32},
-       {267250,        2,      66,     67},
-       {268500,        2,      94,     95},
-       {270000,        2,      14,     14},
-       {272500,        2,      77,     76},
-       {273750,        2,      57,     56},
-       {280750,        2,      24,     23},
-       {281250,        2,      23,     22},
-       {286000,        2,      17,     16},
-       {291750,        2,      26,     24},
-       {296703,        2,      56,     51},
-       {297000,        2,      22,     20},
-       {298000,        2,      21,     19},
-};
-
 static void intel_ddi_mode_set(struct drm_encoder *encoder,
                               struct drm_display_mode *mode,
                               struct drm_display_mode *adjusted_mode)
@@ -675,7 +292,7 @@ static void intel_ddi_mode_set(struct drm_encoder *encoder,
        int pipe = intel_crtc->pipe;
        int type = intel_encoder->type;
 
-       DRM_DEBUG_KMS("Preparing DDI mode for Haswell on port %c, pipe %c\n",
+       DRM_DEBUG_KMS("Preparing DDI mode on port %c, pipe %c\n",
                      port_name(port), pipe_name(pipe));
 
        intel_crtc->eld_vld = false;
@@ -686,22 +303,7 @@ static void intel_ddi_mode_set(struct drm_encoder *encoder,
 
                intel_dp->DP = intel_dig_port->port_reversal |
                               DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW;
-               switch (intel_dp->lane_count) {
-               case 1:
-                       intel_dp->DP |= DDI_PORT_WIDTH_X1;
-                       break;
-               case 2:
-                       intel_dp->DP |= DDI_PORT_WIDTH_X2;
-                       break;
-               case 4:
-                       intel_dp->DP |= DDI_PORT_WIDTH_X4;
-                       break;
-               default:
-                       intel_dp->DP |= DDI_PORT_WIDTH_X4;
-                       WARN(1, "Unexpected DP lane count %d\n",
-                            intel_dp->lane_count);
-                       break;
-               }
+               intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
 
                if (intel_dp->has_audio) {
                        DRM_DEBUG_DRIVER("DP audio on pipe %c on DDI\n",
@@ -748,8 +350,8 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
        }
 
        if (num_encoders != 1)
-               WARN(1, "%d encoders on crtc for pipe %d\n", num_encoders,
-                    intel_crtc->pipe);
+               WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
+                    pipe_name(intel_crtc->pipe));
 
        BUG_ON(ret == NULL);
        return ret;
@@ -802,27 +404,224 @@ void intel_ddi_put_crtc_pll(struct drm_crtc *crtc)
        intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE;
 }
 
-static void intel_ddi_calculate_wrpll(int clock, int *p, int *n2, int *r2)
+#define LC_FREQ 2700
+#define LC_FREQ_2K (LC_FREQ * 2000)
+
+#define P_MIN 2
+#define P_MAX 64
+#define P_INC 2
+
+/* Constraints for PLL good behavior */
+#define REF_MIN 48
+#define REF_MAX 400
+#define VCO_MIN 2400
+#define VCO_MAX 4800
+
+#define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a))
+
+struct wrpll_rnp {
+       unsigned p, n2, r2;
+};
+
+static unsigned wrpll_get_budget_for_freq(int clock)
+{
+       unsigned budget;
+
+       switch (clock) {
+       case 25175000:
+       case 25200000:
+       case 27000000:
+       case 27027000:
+       case 37762500:
+       case 37800000:
+       case 40500000:
+       case 40541000:
+       case 54000000:
+       case 54054000:
+       case 59341000:
+       case 59400000:
+       case 72000000:
+       case 74176000:
+       case 74250000:
+       case 81000000:
+       case 81081000:
+       case 89012000:
+       case 89100000:
+       case 108000000:
+       case 108108000:
+       case 111264000:
+       case 111375000:
+       case 148352000:
+       case 148500000:
+       case 162000000:
+       case 162162000:
+       case 222525000:
+       case 222750000:
+       case 296703000:
+       case 297000000:
+               budget = 0;
+               break;
+       case 233500000:
+       case 245250000:
+       case 247750000:
+       case 253250000:
+       case 298000000:
+               budget = 1500;
+               break;
+       case 169128000:
+       case 169500000:
+       case 179500000:
+       case 202000000:
+               budget = 2000;
+               break;
+       case 256250000:
+       case 262500000:
+       case 270000000:
+       case 272500000:
+       case 273750000:
+       case 280750000:
+       case 281250000:
+       case 286000000:
+       case 291750000:
+               budget = 4000;
+               break;
+       case 267250000:
+       case 268500000:
+               budget = 5000;
+               break;
+       default:
+               budget = 1000;
+               break;
+       }
+
+       return budget;
+}
+
+static void wrpll_update_rnp(uint64_t freq2k, unsigned budget,
+                            unsigned r2, unsigned n2, unsigned p,
+                            struct wrpll_rnp *best)
 {
-       u32 i;
+       uint64_t a, b, c, d, diff, diff_best;
 
-       for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++)
-               if (clock <= wrpll_tmds_clock_table[i].clock)
-                       break;
+       /* No best (r,n,p) yet */
+       if (best->p == 0) {
+               best->p = p;
+               best->n2 = n2;
+               best->r2 = r2;
+               return;
+       }
+
+       /*
+        * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
+        * freq2k.
+        *
+        * delta = 1e6 *
+        *         abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
+        *         freq2k;
+        *
+        * and we would like delta <= budget.
+        *
+        * If the discrepancy is above the PPM-based budget, always prefer to
+        * improve upon the previous solution.  However, if you're within the
+        * budget, try to maximize Ref * VCO, that is N / (P * R^2).
+        */
+       a = freq2k * budget * p * r2;
+       b = freq2k * budget * best->p * best->r2;
+       diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2));
+       diff_best = ABS_DIFF((freq2k * best->p * best->r2),
+                            (LC_FREQ_2K * best->n2));
+       c = 1000000 * diff;
+       d = 1000000 * diff_best;
+
+       if (a < c && b < d) {
+               /* If both are above the budget, pick the closer */
+               if (best->p * best->r2 * diff < p * r2 * diff_best) {
+                       best->p = p;
+                       best->n2 = n2;
+                       best->r2 = r2;
+               }
+       } else if (a >= c && b < d) {
+               /* If A is below the threshold but B is above it?  Update. */
+               best->p = p;
+               best->n2 = n2;
+               best->r2 = r2;
+       } else if (a >= c && b >= d) {
+               /* Both are below the limit, so pick the higher n2/(r2*r2) */
+               if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
+                       best->p = p;
+                       best->n2 = n2;
+                       best->r2 = r2;
+               }
+       }
+       /* Otherwise a < c && b >= d, do nothing */
+}
+
+static void
+intel_ddi_calculate_wrpll(int clock /* in Hz */,
+                         unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
+{
+       uint64_t freq2k;
+       unsigned p, n2, r2;
+       struct wrpll_rnp best = { 0, 0, 0 };
+       unsigned budget;
+
+       freq2k = clock / 100;
+
+       budget = wrpll_get_budget_for_freq(clock);
+
+       /* Special case handling for 540 pixel clock: bypass WR PLL entirely
+        * and directly pass the LC PLL to it. */
+       if (freq2k == 5400000) {
+               *n2_out = 2;
+               *p_out = 1;
+               *r2_out = 2;
+               return;
+       }
 
-       if (i == ARRAY_SIZE(wrpll_tmds_clock_table))
-               i--;
+       /*
+        * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
+        * the WR PLL.
+        *
+        * We want R so that REF_MIN <= Ref <= REF_MAX.
+        * Injecting R2 = 2 * R gives:
+        *   REF_MAX * r2 > LC_FREQ * 2 and
+        *   REF_MIN * r2 < LC_FREQ * 2
+        *
+        * Which means the desired boundaries for r2 are:
+        *  LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
+        *
+        */
+       for (r2 = LC_FREQ * 2 / REF_MAX + 1;
+            r2 <= LC_FREQ * 2 / REF_MIN;
+            r2++) {
+
+               /*
+                * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
+                *
+                * Once again we want VCO_MIN <= VCO <= VCO_MAX.
+                * Injecting R2 = 2 * R and N2 = 2 * N, we get:
+                *   VCO_MAX * r2 > n2 * LC_FREQ and
+                *   VCO_MIN * r2 < n2 * LC_FREQ)
+                *
+                * Which means the desired boundaries for n2 are:
+                * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
+                */
+               for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
+                    n2 <= VCO_MAX * r2 / LC_FREQ;
+                    n2++) {
 
-       *p = wrpll_tmds_clock_table[i].p;
-       *n2 = wrpll_tmds_clock_table[i].n2;
-       *r2 = wrpll_tmds_clock_table[i].r2;
+                       for (p = P_MIN; p <= P_MAX; p += P_INC)
+                               wrpll_update_rnp(freq2k, budget,
+                                                r2, n2, p, &best);
+               }
+       }
 
-       if (wrpll_tmds_clock_table[i].clock != clock)
-               DRM_INFO("WRPLL: using settings for %dKHz on %dKHz mode\n",
-                        wrpll_tmds_clock_table[i].clock, clock);
+       *n2_out = best.n2;
+       *p_out = best.p;
+       *r2_out = best.r2;
 
-       DRM_DEBUG_KMS("WRPLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n",
-                     clock, *p, *n2, *r2);
+       DRM_DEBUG_KMS("WRPLL: %dHz refresh rate with p=%d, n2=%d r2=%d\n",
+                     clock, *p_out, *n2_out, *r2_out);
 }
 
 bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock)
@@ -863,7 +662,7 @@ bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock)
                return true;
 
        } else if (type == INTEL_OUTPUT_HDMI) {
-               int p, n2, r2;
+               unsigned p, n2, r2;
 
                if (plls->wrpll1_refcount == 0) {
                        DRM_DEBUG_KMS("Using WRPLL 1 on pipe %c\n",
@@ -885,7 +684,7 @@ bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock)
                WARN(I915_READ(reg) & WRPLL_PLL_ENABLE,
                     "WRPLL already enabled\n");
 
-               intel_ddi_calculate_wrpll(clock, &p, &n2, &r2);
+               intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
 
                val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 |
                      WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
@@ -995,7 +794,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
                        /* Can only use the always-on power well for eDP when
                         * not using the panel fitter, and when not using motion
                          * blur mitigation (which we don't support). */
-                       if (dev_priv->pch_pf_size)
+                       if (intel_crtc->config.pch_pfit.size)
                                temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
                        else
                                temp |= TRANS_DDI_EDP_INPUT_A_ON;
@@ -1022,7 +821,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
 
        } else if (type == INTEL_OUTPUT_ANALOG) {
                temp |= TRANS_DDI_MODE_SELECT_FDI;
-               temp |= (intel_crtc->fdi_lanes - 1) << 1;
+               temp |= (intel_crtc->config.fdi_lanes - 1) << 1;
 
        } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
                   type == INTEL_OUTPUT_EDP) {
@@ -1030,25 +829,10 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
 
                temp |= TRANS_DDI_MODE_SELECT_DP_SST;
 
-               switch (intel_dp->lane_count) {
-               case 1:
-                       temp |= TRANS_DDI_PORT_WIDTH_X1;
-                       break;
-               case 2:
-                       temp |= TRANS_DDI_PORT_WIDTH_X2;
-                       break;
-               case 4:
-                       temp |= TRANS_DDI_PORT_WIDTH_X4;
-                       break;
-               default:
-                       temp |= TRANS_DDI_PORT_WIDTH_X4;
-                       WARN(1, "Unsupported lane count %d\n",
-                            intel_dp->lane_count);
-               }
-
+               temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
        } else {
-               WARN(1, "Invalid encoder type %d for pipe %d\n",
-                    intel_encoder->type, pipe);
+               WARN(1, "Invalid encoder type %d for pipe %c\n",
+                    intel_encoder->type, pipe_name(pipe));
        }
 
        I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
@@ -1148,7 +932,7 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
                }
        }
 
-       DRM_DEBUG_KMS("No pipe for ddi port %i found\n", port);
+       DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
 
        return false;
 }
@@ -1334,7 +1118,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
                ironlake_edp_backlight_on(intel_dp);
        }
 
-       if (intel_crtc->eld_vld) {
+       if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) {
                tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
                tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4));
                I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
@@ -1352,9 +1136,12 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t tmp;
 
-       tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
-       tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4));
-       I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
+       if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) {
+               tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
+               tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) <<
+                        (pipe * 4));
+               I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
+       }
 
        if (type == INTEL_OUTPUT_EDP) {
                struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
@@ -1518,16 +1305,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
                return;
        }
 
-       if (port != PORT_A) {
-               hdmi_connector = kzalloc(sizeof(struct intel_connector),
-                                        GFP_KERNEL);
-               if (!hdmi_connector) {
-                       kfree(dp_connector);
-                       kfree(intel_dig_port);
-                       return;
-               }
-       }
-
        intel_encoder = &intel_dig_port->base;
        encoder = &intel_encoder->base;
 
@@ -1545,8 +1322,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
        intel_dig_port->port = port;
        intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) &
                                        DDI_BUF_PORT_REVERSAL;
-       if (hdmi_connector)
-               intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
        intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
 
        intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
@@ -1554,7 +1329,16 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
        intel_encoder->cloneable = false;
        intel_encoder->hot_plug = intel_ddi_hot_plug;
 
-       if (hdmi_connector)
-               intel_hdmi_init_connector(intel_dig_port, hdmi_connector);
        intel_dp_init_connector(intel_dig_port, dp_connector);
+
+       if (intel_encoder->type != INTEL_OUTPUT_EDP) {
+               hdmi_connector = kzalloc(sizeof(struct intel_connector),
+                                        GFP_KERNEL);
+               if (!hdmi_connector) {
+                       return;
+               }
+
+               intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
+               intel_hdmi_init_connector(intel_dig_port, hdmi_connector);
+       }
 }