include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / gpu / drm / i915 / intel_dp.c
index 8f8d37d..8e283f7 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
 #include "intel_drv.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
-#include "intel_dp.h"
+#include "drm_dp_helper.h"
+
 
 #define DP_LINK_STATUS_SIZE    6
 #define DP_LINK_CHECK_TIMEOUT  (10 * 1000)
 
 #define DP_LINK_CONFIGURATION_SIZE     9
 
+#define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP)
+
 struct intel_dp_priv {
        uint32_t output_reg;
        uint32_t DP;
@@ -63,6 +67,19 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
 static void
 intel_dp_link_down(struct intel_output *intel_output, uint32_t DP);
 
+void
+intel_edp_link_config (struct intel_output *intel_output,
+               int *lane_num, int *link_bw)
+{
+       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+
+       *lane_num = dp_priv->lane_count;
+       if (dp_priv->link_bw == DP_LINK_BW_1_62)
+               *link_bw = 162000;
+       else if (dp_priv->link_bw == DP_LINK_BW_2_7)
+               *link_bw = 270000;
+}
+
 static int
 intel_dp_max_lane_count(struct intel_output *intel_output)
 {
@@ -109,9 +126,15 @@ intel_dp_link_clock(uint8_t link_bw)
 
 /* I think this is a fiction */
 static int
-intel_dp_link_required(int pixel_clock)
+intel_dp_link_required(struct drm_device *dev,
+                      struct intel_output *intel_output, int pixel_clock)
 {
-       return pixel_clock * 3;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       if (IS_eDP(intel_output))
+               return (pixel_clock * dev_priv->edp_bpp) / 8;
+       else
+               return pixel_clock * 3;
 }
 
 static int
@@ -122,7 +145,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
        int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output));
        int max_lanes = intel_dp_max_lane_count(intel_output);
 
-       if (intel_dp_link_required(mode->clock) > max_link_clock * max_lanes)
+       if (intel_dp_link_required(connector->dev, intel_output, mode->clock)
+                       > max_link_clock * max_lanes)
                return MODE_CLOCK_HIGH;
 
        if (mode->clock < 10000)
@@ -206,12 +230,18 @@ intel_dp_aux_ch(struct intel_output *intel_output,
         * and would like to run at 2MHz. So, take the
         * hrawclk value and divide by 2 and use that
         */
-       aux_clock_divider = intel_hrawclk(dev) / 2;
+       if (IS_eDP(intel_output))
+               aux_clock_divider = 225; /* eDP input clock at 450Mhz */
+       else if (HAS_PCH_SPLIT(dev))
+               aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */
+       else
+               aux_clock_divider = intel_hrawclk(dev) / 2;
+
        /* Must try at least 3 times according to DP spec */
        for (try = 0; try < 5; try++) {
                /* Load the send data into the aux channel data registers */
                for (i = 0; i < send_bytes; i += 4) {
-                       uint32_t    d = pack_aux(send + i, send_bytes - i);;
+                       uint32_t    d = pack_aux(send + i, send_bytes - i);
        
                        I915_WRITE(ch_data + i, d);
                }
@@ -236,7 +266,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,
                }
        
                /* Clear done status and any errors */
-               I915_WRITE(ch_ctl, (ctl |
+               I915_WRITE(ch_ctl, (status |
                                DP_AUX_CH_CTL_DONE |
                                DP_AUX_CH_CTL_TIME_OUT_ERROR |
                                DP_AUX_CH_CTL_RECEIVE_ERROR));
@@ -246,7 +276,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,
        }
 
        if ((status & DP_AUX_CH_CTL_DONE) == 0) {
-               printk(KERN_ERR "dp_aux_ch not done status 0x%08x\n", status);
+               DRM_ERROR("dp_aux_ch not done status 0x%08x\n", status);
                return -EBUSY;
        }
 
@@ -254,11 +284,14 @@ intel_dp_aux_ch(struct intel_output *intel_output,
         * Timeouts occur when the sink is not connected
         */
        if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) {
-               printk(KERN_ERR "dp_aux_ch receive error status 0x%08x\n", status);
+               DRM_ERROR("dp_aux_ch receive error status 0x%08x\n", status);
                return -EIO;
        }
+
+       /* Timeouts occur when the device isn't connected, so they're
+        * "normal" -- don't fill the kernel log with these */
        if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) {
-               printk(KERN_ERR "dp_aux_ch timeout status 0x%08x\n", status);
+               DRM_DEBUG_KMS("dp_aux_ch timeout status 0x%08x\n", status);
                return -ETIMEDOUT;
        }
 
@@ -292,7 +325,7 @@ intel_dp_aux_native_write(struct intel_output *intel_output,
                return -1;
        msg[0] = AUX_NATIVE_WRITE << 4;
        msg[1] = address >> 8;
-       msg[2] = address;
+       msg[2] = address & 0xff;
        msg[3] = send_bytes - 1;
        memcpy(&msg[4], send, send_bytes);
        msg_bytes = send_bytes + 4;
@@ -358,17 +391,77 @@ intel_dp_aux_native_read(struct intel_output *intel_output,
 }
 
 static int
-intel_dp_i2c_aux_ch(struct i2c_adapter *adapter,
-                   uint8_t *send, int send_bytes,
-                   uint8_t *recv, int recv_bytes)
+intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
+                   uint8_t write_byte, uint8_t *read_byte)
 {
+       struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
        struct intel_dp_priv *dp_priv = container_of(adapter,
                                                     struct intel_dp_priv,
                                                     adapter);
        struct intel_output *intel_output = dp_priv->intel_output;
+       uint16_t address = algo_data->address;
+       uint8_t msg[5];
+       uint8_t reply[2];
+       int msg_bytes;
+       int reply_bytes;
+       int ret;
 
-       return intel_dp_aux_ch(intel_output,
-                              send, send_bytes, recv, recv_bytes);
+       /* Set up the command byte */
+       if (mode & MODE_I2C_READ)
+               msg[0] = AUX_I2C_READ << 4;
+       else
+               msg[0] = AUX_I2C_WRITE << 4;
+
+       if (!(mode & MODE_I2C_STOP))
+               msg[0] |= AUX_I2C_MOT << 4;
+
+       msg[1] = address >> 8;
+       msg[2] = address;
+
+       switch (mode) {
+       case MODE_I2C_WRITE:
+               msg[3] = 0;
+               msg[4] = write_byte;
+               msg_bytes = 5;
+               reply_bytes = 1;
+               break;
+       case MODE_I2C_READ:
+               msg[3] = 0;
+               msg_bytes = 4;
+               reply_bytes = 2;
+               break;
+       default:
+               msg_bytes = 3;
+               reply_bytes = 1;
+               break;
+       }
+
+       for (;;) {
+         ret = intel_dp_aux_ch(intel_output,
+                               msg, msg_bytes,
+                               reply, reply_bytes);
+               if (ret < 0) {
+                       DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
+                       return ret;
+               }
+               switch (reply[0] & AUX_I2C_REPLY_MASK) {
+               case AUX_I2C_REPLY_ACK:
+                       if (mode == MODE_I2C_READ) {
+                               *read_byte = reply[1];
+                       }
+                       return reply_bytes - 1;
+               case AUX_I2C_REPLY_NACK:
+                       DRM_DEBUG_KMS("aux_ch nack\n");
+                       return -EREMOTEIO;
+               case AUX_I2C_REPLY_DEFER:
+                       DRM_DEBUG_KMS("aux_ch defer\n");
+                       udelay(100);
+                       break;
+               default:
+                       DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]);
+                       return -EREMOTEIO;
+               }
+       }
 }
 
 static int
@@ -376,7 +469,7 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name)
 {
        struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
 
-       DRM_ERROR("i2c_init %s\n", name);
+       DRM_DEBUG_KMS("i2c_init %s\n", name);
        dp_priv->algo.running = false;
        dp_priv->algo.address = 0;
        dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch;
@@ -384,8 +477,8 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name)
        memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter));
        dp_priv->adapter.owner = THIS_MODULE;
        dp_priv->adapter.class = I2C_CLASS_DDC;
-       strncpy (dp_priv->adapter.name, name, sizeof dp_priv->adapter.name - 1);
-       dp_priv->adapter.name[sizeof dp_priv->adapter.name - 1] = '\0';
+       strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1);
+       dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0';
        dp_priv->adapter.algo_data = &dp_priv->algo;
        dp_priv->adapter.dev.parent = &intel_output->base.kdev;
        
@@ -407,11 +500,13 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                for (clock = 0; clock <= max_clock; clock++) {
                        int link_avail = intel_dp_link_clock(bws[clock]) * lane_count;
 
-                       if (intel_dp_link_required(mode->clock) <= link_avail) {
+                       if (intel_dp_link_required(encoder->dev, intel_output, mode->clock)
+                                       <= link_avail) {
                                dp_priv->link_bw = bws[clock];
                                dp_priv->lane_count = lane_count;
                                adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
-                               printk(KERN_ERR "link bw %02x lane count %d clock %d\n",
+                               DRM_DEBUG_KMS("Display port link bw %02x lane "
+                                               "count %d clock %d\n",
                                       dp_priv->link_bw, dp_priv->lane_count,
                                       adjusted_mode->clock);
                                return true;
@@ -490,22 +585,40 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
        intel_dp_compute_m_n(3, lane_count,
                             mode->clock, adjusted_mode->clock, &m_n);
 
-       if (intel_crtc->pipe == 0) {
-               I915_WRITE(PIPEA_GMCH_DATA_M,
-                      ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
-                      m_n.gmch_m);
-               I915_WRITE(PIPEA_GMCH_DATA_N,
-                      m_n.gmch_n);
-               I915_WRITE(PIPEA_DP_LINK_M, m_n.link_m);
-               I915_WRITE(PIPEA_DP_LINK_N, m_n.link_n);
+       if (HAS_PCH_SPLIT(dev)) {
+               if (intel_crtc->pipe == 0) {
+                       I915_WRITE(TRANSA_DATA_M1,
+                                  ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
+                                  m_n.gmch_m);
+                       I915_WRITE(TRANSA_DATA_N1, m_n.gmch_n);
+                       I915_WRITE(TRANSA_DP_LINK_M1, m_n.link_m);
+                       I915_WRITE(TRANSA_DP_LINK_N1, m_n.link_n);
+               } else {
+                       I915_WRITE(TRANSB_DATA_M1,
+                                  ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
+                                  m_n.gmch_m);
+                       I915_WRITE(TRANSB_DATA_N1, m_n.gmch_n);
+                       I915_WRITE(TRANSB_DP_LINK_M1, m_n.link_m);
+                       I915_WRITE(TRANSB_DP_LINK_N1, m_n.link_n);
+               }
        } else {
-               I915_WRITE(PIPEB_GMCH_DATA_M,
-                      ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
-                      m_n.gmch_m);
-               I915_WRITE(PIPEB_GMCH_DATA_N,
-                      m_n.gmch_n);
-               I915_WRITE(PIPEB_DP_LINK_M, m_n.link_m);
-               I915_WRITE(PIPEB_DP_LINK_N, m_n.link_n);
+               if (intel_crtc->pipe == 0) {
+                       I915_WRITE(PIPEA_GMCH_DATA_M,
+                                  ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
+                                  m_n.gmch_m);
+                       I915_WRITE(PIPEA_GMCH_DATA_N,
+                                  m_n.gmch_n);
+                       I915_WRITE(PIPEA_DP_LINK_M, m_n.link_m);
+                       I915_WRITE(PIPEA_DP_LINK_N, m_n.link_n);
+               } else {
+                       I915_WRITE(PIPEB_GMCH_DATA_M,
+                                  ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
+                                  m_n.gmch_m);
+                       I915_WRITE(PIPEB_GMCH_DATA_N,
+                                       m_n.gmch_n);
+                       I915_WRITE(PIPEB_DP_LINK_M, m_n.link_m);
+                       I915_WRITE(PIPEB_DP_LINK_N, m_n.link_n);
+               }
        }
 }
 
@@ -553,8 +666,38 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
 
        if (intel_crtc->pipe == 1)
                dp_priv->DP |= DP_PIPEB_SELECT;
+
+       if (IS_eDP(intel_output)) {
+               /* don't miss out required setting for eDP */
+               dp_priv->DP |= DP_PLL_ENABLE;
+               if (adjusted_mode->clock < 200000)
+                       dp_priv->DP |= DP_PLL_FREQ_160MHZ;
+               else
+                       dp_priv->DP |= DP_PLL_FREQ_270MHZ;
+       }
 }
 
+static void ironlake_edp_backlight_on (struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 pp;
+
+       DRM_DEBUG_KMS("\n");
+       pp = I915_READ(PCH_PP_CONTROL);
+       pp |= EDP_BLC_ENABLE;
+       I915_WRITE(PCH_PP_CONTROL, pp);
+}
+
+static void ironlake_edp_backlight_off (struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 pp;
+
+       DRM_DEBUG_KMS("\n");
+       pp = I915_READ(PCH_PP_CONTROL);
+       pp &= ~EDP_BLC_ENABLE;
+       I915_WRITE(PCH_PP_CONTROL, pp);
+}
 
 static void
 intel_dp_dpms(struct drm_encoder *encoder, int mode)
@@ -566,11 +709,17 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
        uint32_t dp_reg = I915_READ(dp_priv->output_reg);
 
        if (mode != DRM_MODE_DPMS_ON) {
-               if (dp_reg & DP_PORT_EN)
+               if (dp_reg & DP_PORT_EN) {
                        intel_dp_link_down(intel_output, dp_priv->DP);
+                       if (IS_eDP(intel_output))
+                               ironlake_edp_backlight_off(dev);
+               }
        } else {
-               if (!(dp_reg & DP_PORT_EN))
+               if (!(dp_reg & DP_PORT_EN)) {
                        intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
+                       if (IS_eDP(intel_output))
+                               ironlake_edp_backlight_on(dev);
+               }
        }
        dp_priv->dpms_mode = mode;
 }
@@ -932,6 +1081,23 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_dp_priv *dp_priv = intel_output->dev_priv;
 
+       DRM_DEBUG_KMS("\n");
+
+       if (IS_eDP(intel_output)) {
+               DP &= ~DP_PLL_ENABLE;
+               I915_WRITE(dp_priv->output_reg, DP);
+               POSTING_READ(dp_priv->output_reg);
+               udelay(100);
+       }
+
+       DP &= ~DP_LINK_TRAIN_MASK;
+       I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE);
+       POSTING_READ(dp_priv->output_reg);
+
+       udelay(17000);
+
+       if (IS_eDP(intel_output))
+               DP |= DP_LINK_TRAIN_OFF;
        I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN);
        POSTING_READ(dp_priv->output_reg);
 }
@@ -975,6 +1141,24 @@ intel_dp_check_link_status(struct intel_output *intel_output)
                intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
 }
 
+static enum drm_connector_status
+ironlake_dp_detect(struct drm_connector *connector)
+{
+       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       enum drm_connector_status status;
+
+       status = connector_status_disconnected;
+       if (intel_dp_aux_native_read(intel_output,
+                                    0x000, dp_priv->dpcd,
+                                    sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
+       {
+               if (dp_priv->dpcd[0] != 0)
+                       status = connector_status_connected;
+       }
+       return status;
+}
+
 /**
  * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection.
  *
@@ -993,6 +1177,9 @@ intel_dp_detect(struct drm_connector *connector)
 
        dp_priv->has_audio = false;
 
+       if (HAS_PCH_SPLIT(dev))
+               return ironlake_dp_detect(connector);
+
        temp = I915_READ(PORT_HOTPLUG_EN);
 
        I915_WRITE(PORT_HOTPLUG_EN,
@@ -1036,11 +1223,27 @@ intel_dp_detect(struct drm_connector *connector)
 static int intel_dp_get_modes(struct drm_connector *connector)
 {
        struct intel_output *intel_output = to_intel_output(connector);
+       struct drm_device *dev = intel_output->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int ret;
 
        /* We should parse the EDID data and find out if it has an audio sink
         */
 
-       return intel_ddc_get_modes(intel_output);
+       ret = intel_ddc_get_modes(intel_output);
+       if (ret)
+               return ret;
+
+       /* if eDP has no EDID, try to use fixed panel mode from VBT */
+       if (IS_eDP(intel_output)) {
+               if (dev_priv->panel_fixed_mode != NULL) {
+                       struct drm_display_mode *mode;
+                       mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
+                       drm_mode_probed_add(connector, mode);
+                       return 1;
+               }
+       }
+       return 0;
 }
 
 static void
@@ -1103,6 +1306,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
        struct drm_connector *connector;
        struct intel_output *intel_output;
        struct intel_dp_priv *dp_priv;
+       const char *name = NULL;
 
        intel_output = kcalloc(sizeof(struct intel_output) + 
                               sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
@@ -1116,8 +1320,22 @@ intel_dp_init(struct drm_device *dev, int output_reg)
                           DRM_MODE_CONNECTOR_DisplayPort);
        drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
 
-       intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
+       if (output_reg == DP_A)
+               intel_output->type = INTEL_OUTPUT_EDP;
+       else
+               intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
+
+       if (output_reg == DP_B || output_reg == PCH_DP_B)
+               intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
+       else if (output_reg == DP_C || output_reg == PCH_DP_C)
+               intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
+       else if (output_reg == DP_D || output_reg == PCH_DP_D)
+               intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
 
+       if (IS_eDP(intel_output))
+               intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
+
+       intel_output->crtc_mask = (1 << 0) | (1 << 1);
        connector->interlace_allowed = true;
        connector->doublescan_allowed = 0;
 
@@ -1136,12 +1354,47 @@ intel_dp_init(struct drm_device *dev, int output_reg)
        drm_sysfs_connector_add(connector);
 
        /* Set up the DDC bus. */
-       intel_dp_i2c_init(intel_output,
-                         (output_reg == DP_B) ? "DPDDC-B" :
-                         (output_reg == DP_C) ? "DPDDC-C" : "DPDDC-D");
+       switch (output_reg) {
+               case DP_A:
+                       name = "DPDDC-A";
+                       break;
+               case DP_B:
+               case PCH_DP_B:
+                       dev_priv->hotplug_supported_mask |=
+                               HDMIB_HOTPLUG_INT_STATUS;
+                       name = "DPDDC-B";
+                       break;
+               case DP_C:
+               case PCH_DP_C:
+                       dev_priv->hotplug_supported_mask |=
+                               HDMIC_HOTPLUG_INT_STATUS;
+                       name = "DPDDC-C";
+                       break;
+               case DP_D:
+               case PCH_DP_D:
+                       dev_priv->hotplug_supported_mask |=
+                               HDMID_HOTPLUG_INT_STATUS;
+                       name = "DPDDC-D";
+                       break;
+       }
+
+       intel_dp_i2c_init(intel_output, name);
+
        intel_output->ddc_bus = &dp_priv->adapter;
        intel_output->hot_plug = intel_dp_hot_plug;
 
+       if (output_reg == DP_A) {
+               /* initialize panel mode from VBT if available for eDP */
+               if (dev_priv->lfp_lvds_vbt_mode) {
+                       dev_priv->panel_fixed_mode =
+                               drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
+                       if (dev_priv->panel_fixed_mode) {
+                               dev_priv->panel_fixed_mode->type |=
+                                       DRM_MODE_TYPE_PREFERRED;
+                       }
+               }
+       }
+
        /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
         * 0xd.  Failure to do so will result in spurious interrupts being
         * generated on the port when a cable is not attached.