---
 drivers/gpu/drm/i915/intel_display.c |   91 +++++++++++++++++++-
 drivers/gpu/drm/i915/intel_dp.c      |   62 +++++++++-----
 drivers/gpu/drm/i915/intel_dp.h      |   16 ++--
 drivers/gpu/drm/i915/intel_dp_i2c.c  |  157 ++++++++++++++++++++++------------
 drivers/gpu/drm/i915/intel_drv.h     |    3 +
 5 files changed, 242 insertions(+), 87 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 2b042ea..220d54d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -136,8 +136,9 @@ struct intel_limit {
 #define INTEL_LIMIT_G4X_HDMI_DAC   5
 #define INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS   6
 #define INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS   7
-#define INTEL_LIMIT_IGD_SDVO_DAC    8
-#define INTEL_LIMIT_IGD_LVDS       9
+#define INTEL_LIMIT_G4X_DISPLAY_PORT   8
+#define INTEL_LIMIT_IGD_SDVO_DAC    9
+#define INTEL_LIMIT_IGD_LVDS       10
 
 /*The parameter is for SDVO on G4x platform*/
 #define G4X_DOT_SDVO_MIN           25000
@@ -217,6 +218,25 @@ struct intel_limit {
 #define G4X_P2_DUAL_CHANNEL_LVDS_FAST           7
 #define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT          0
 
+/*The parameter is for DISPLAY PORT on G4x platform*/
+#define G4X_DOT_DISPLAY_PORT_MIN           161670
+#define G4X_DOT_DISPLAY_PORT_MAX           227000
+#define G4X_N_DISPLAY_PORT_MIN             1
+#define G4X_N_DISPLAY_PORT_MAX             2
+#define G4X_M_DISPLAY_PORT_MIN             97
+#define G4X_M_DISPLAY_PORT_MAX             108
+#define G4X_M1_DISPLAY_PORT_MIN            0x10
+#define G4X_M1_DISPLAY_PORT_MAX            0x12
+#define G4X_M2_DISPLAY_PORT_MIN            0x05
+#define G4X_M2_DISPLAY_PORT_MAX            0x06
+#define G4X_P_DISPLAY_PORT_MIN             10
+#define G4X_P_DISPLAY_PORT_MAX             20
+#define G4X_P1_DISPLAY_PORT_MIN            1
+#define G4X_P1_DISPLAY_PORT_MAX            2
+#define G4X_P2_DISPLAY_PORT_SLOW           10
+#define G4X_P2_DISPLAY_PORT_FAST           10
+#define G4X_P2_DISPLAY_PORT_LIMIT          0
+
 static bool
 intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
                    int target, int refclk, intel_clock_t *best_clock);
@@ -224,6 +244,10 @@ static bool
 intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
                        int target, int refclk, intel_clock_t *best_clock);
 
+static bool
+intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc,
+                     int target, int refclk, intel_clock_t *best_clock);
+
 static const intel_limit_t intel_limits[] = {
     { /* INTEL_LIMIT_I8XX_DVO_DAC */
         .dot = { .min = I8XX_DOT_MIN,          .max = I8XX_DOT_MAX },
@@ -357,6 +381,28 @@ static const intel_limit_t intel_limits[] = {
        },
        .find_pll = intel_g4x_find_best_PLL,
     },
+    {   /* INTEL_LIMIT_G4X_DISPLAY_PORT */
+        .dot = { .min = G4X_DOT_DISPLAY_PORT_MIN,
+                 .max = G4X_DOT_DISPLAY_PORT_MAX },
+        .vco = { .min = G4X_VCO_MIN,
+                 .max = G4X_VCO_MAX},
+        .n   = { .min = G4X_N_DISPLAY_PORT_MIN,
+                 .max = G4X_N_DISPLAY_PORT_MAX },
+        .m   = { .min = G4X_M_DISPLAY_PORT_MIN,
+                 .max = G4X_M_DISPLAY_PORT_MAX },
+        .m1  = { .min = G4X_M1_DISPLAY_PORT_MIN,
+                 .max = G4X_M1_DISPLAY_PORT_MAX },
+        .m2  = { .min = G4X_M2_DISPLAY_PORT_MIN,
+                 .max = G4X_M2_DISPLAY_PORT_MAX },
+        .p   = { .min = G4X_P_DISPLAY_PORT_MIN,
+                 .max = G4X_P_DISPLAY_PORT_MAX },
+        .p1  = { .min = G4X_P1_DISPLAY_PORT_MIN,
+                 .max = G4X_P1_DISPLAY_PORT_MAX},
+        .p2  = { .dot_limit = G4X_P2_DISPLAY_PORT_LIMIT,
+                 .p2_slow = G4X_P2_DISPLAY_PORT_SLOW,
+                 .p2_fast = G4X_P2_DISPLAY_PORT_FAST },
+        .find_pll = intel_find_pll_g4x_dp,
+    },
     { /* INTEL_LIMIT_IGD_SDVO */
         .dot = { .min = I9XX_DOT_MIN,          .max = I9XX_DOT_MAX},
         .vco = { .min = IGD_VCO_MIN,           .max = IGD_VCO_MAX },
@@ -408,6 +454,8 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc 
*crtc)
                limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC];
        } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) {
                limit = &intel_limits[INTEL_LIMIT_G4X_SDVO];
+       } else if (intel_pipe_has_type (crtc, INTEL_OUTPUT_DISPLAYPORT)) {
+               limit = &intel_limits[INTEL_LIMIT_G4X_DISPLAY_PORT];
        } else /* The option is for other outputs */
                limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
 
@@ -635,6 +683,35 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct 
drm_crtc *crtc,
        return found;
 }
 
+/* DisplayPort has only two frequencies, 162MHz and 270MHz */
+static bool
+intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
+                     int target, int refclk, intel_clock_t *best_clock)
+{
+    intel_clock_t clock;
+    if (target < 200000) {
+       clock.dot = 161670;
+       clock.p = 20;
+       clock.p1 = 2;
+       clock.p2 = 10;
+       clock.n = 0x01;
+       clock.m = 97;
+       clock.m1 = 0x10;
+       clock.m2 = 0x05;
+    } else {
+       clock.dot = 270000;
+       clock.p = 10;
+       clock.p1 = 1;
+       clock.p2 = 10;
+       clock.n = 0x02;
+       clock.m = 108;
+       clock.m1 = 0x12;
+       clock.m2 = 0x06;
+    }
+    memcpy(best_clock, &clock, sizeof(intel_clock_t));
+    return true;
+}
+
 void
 intel_wait_for_vblank(struct drm_device *dev)
 {
@@ -1108,6 +1185,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
        } else {
                refclk = 48000;
        }
+       
 
        /*
         * Returns a set of divisors for the desired target clock with the given
@@ -1275,6 +1353,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                I915_WRITE(LVDS, lvds);
                I915_READ(LVDS);
        }
+       if (is_dp)
+               intel_dp_set_m_n(crtc, mode, adjusted_mode);
 
        I915_WRITE(fp_reg, fp);
        I915_WRITE(dpll_reg, dpll);
@@ -1920,7 +2000,7 @@ static void intel_setup_outputs(struct drm_device *dev)
                                intel_dp_init(dev, DP_C);
                }
                if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & 
DP_DETECTED))
-                       intel_dp_init(dev, DP_C);
+                       intel_dp_init(dev, DP_D);
        } else
                intel_dvo_init(dev);
 
@@ -1963,6 +2043,11 @@ static void intel_setup_outputs(struct drm_device *dev)
                                     (1 << 1));
                        clone_mask = (1 << INTEL_OUTPUT_TVOUT);
                        break;
+               case INTEL_OUTPUT_DISPLAYPORT:
+                       crtc_mask = ((1 << 0) |
+                                    (1 << 1));
+                       clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT);
+                       break;
                }
                encoder->possible_crtcs = crtc_mask;
                encoder->possible_clones = intel_connector_clones(dev, 
clone_mask);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 50a75a1..ed3c7de 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -169,6 +169,12 @@ intel_dp_aux_ch(struct intel_output *intel_output,
        uint32_t ctl;
        uint32_t status;
 
+//     printk(KERN_ERR "dp_aux_ch 0x%08x send %d:",
+//            output_reg, send_bytes);
+//     for (i = 0; i < send_bytes; i++)
+//             printk(" %02x", send[i]);
+//     printk("\n");
+       
        /* 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);;
@@ -189,13 +195,15 @@ intel_dp_aux_ch(struct intel_output *intel_output,
               DP_AUX_CH_CTL_TIME_OUT_ERROR |
               DP_AUX_CH_CTL_RECEIVE_ERROR);
 
+//     printk(KERN_ERR "out ch_ctl 0x%08x 0x%08x\n", ch_ctl, ctl);
        /* Send the command and wait for it to complete */
        I915_WRITE(ch_ctl, ctl);
+       (void) I915_READ(ch_ctl);
        for (;;) {
+               udelay(100);
                status = I915_READ(ch_ctl);
                if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0)
                        break;
-               udelay(100);
        }
 
        /* Clear done status and any errors */
@@ -203,15 +211,20 @@ intel_dp_aux_ch(struct intel_output *intel_output,
                        DP_AUX_CH_CTL_DONE |
                        DP_AUX_CH_CTL_TIME_OUT_ERROR |
                        DP_AUX_CH_CTL_RECEIVE_ERROR));
+       (void) I915_READ(ch_ctl);
 
-       if ((status & DP_AUX_CH_CTL_DONE) == 0)
+       if ((status & DP_AUX_CH_CTL_DONE) == 0) {
+               printk(KERN_ERR "dp_aux_ch not done status 0x%08x\n", status);
                return -1;
+       }
 
        /* Check for timeout or receive error.
         * Timeouts occur when the sink is not connected
         */
-       if (status & (DP_AUX_CH_CTL_TIME_OUT_ERROR | 
DP_AUX_CH_CTL_RECEIVE_ERROR))
+       if (status & (DP_AUX_CH_CTL_TIME_OUT_ERROR | 
DP_AUX_CH_CTL_RECEIVE_ERROR)) {
+               printk(KERN_ERR "dp_aux_ch error status 0x%08x\n", status);
                return -1;
+       }
 
        /* Unload any bytes sent back from the other side */
        recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >>
@@ -219,11 +232,17 @@ intel_dp_aux_ch(struct intel_output *intel_output,
 
        if (recv_bytes > recv_size)
                recv_bytes = recv_size;
+       
        for (i = 0; i < recv_bytes; i += 4) {
                uint32_t    d = I915_READ(ch_data + i);
 
+//             printk(KERN_ERR "bytes %d-%d: 0x%08x\n", i, i + 3, d);
                unpack_aux(d, recv + i, recv_bytes - i);
        }
+//     printk(KERN_ERR "    0x%08x: %d:", status, recv_bytes);
+//     for (i = 0; i < recv_bytes; i ++)
+//             printk(" %02x", recv[i]);
+//     printk("\n");
 
        return recv_bytes;
 }
@@ -238,6 +257,9 @@ intel_dp_aux_native_write(struct intel_output *intel_output,
        int msg_bytes;
        uint8_t ack;
 
+//     printk(KERN_ERR "dp_aux_native_write address 0x%04x num %d\n",
+//            address, send_bytes);
+
        if (send_bytes > 16)
                return -1;
        msg[0] = AUX_NATIVE_WRITE << 4;
@@ -280,6 +302,8 @@ intel_dp_aux_native_read(struct intel_output *intel_output,
        uint8_t ack;
        int ret;
 
+//     printk(KERN_ERR "dp_aux_native_read address 0x%04x num %d\n",
+//            address, recv_bytes);
        msg[0] = AUX_NATIVE_READ << 4;
        msg[1] = address >> 8;
        msg[2] = address & 0xff;
@@ -296,6 +320,7 @@ intel_dp_aux_native_read(struct intel_output *intel_output,
                ack = reply[0];
                if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) {
                        memcpy(recv, reply + 1, ret - 1);
+//                     printk("dp_aux_native_read got %d\n", ret - 1);
                        return ret - 1;
                }
                else if ((ack & AUX_NATIVE_REPLY_MASK) == 
AUX_NATIVE_REPLY_DEFER)
@@ -324,6 +349,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);
        dp_priv->algo.running = false;
        dp_priv->algo.address = 0;
        dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch;
@@ -358,6 +384,9 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct 
drm_display_mode *mode,
                                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",
+                                      dp_priv->link_bw, dp_priv->lane_count,
+                                      adjusted_mode->clock);
                                return true;
                        }
                }
@@ -552,8 +581,9 @@ intel_dp_save(struct drm_connector *connector)
        struct intel_dp_priv *dp_priv = intel_output->dev_priv;
 
        dp_priv->save_DP = I915_READ(dp_priv->output_reg);
-       intel_dp_aux_native_read(intel_output, 0x100,
-                                dp_priv->save_link_configuration, sizeof 
(dp_priv->save_link_configuration));
+       intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET,
+                                dp_priv->save_link_configuration,
+                                sizeof (dp_priv->save_link_configuration));
 }
 
 static uint8_t
@@ -937,15 +967,6 @@ intel_dp_detect(struct drm_connector *connector)
 
        dp_priv->has_audio = false;
 
-       /* 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.
-        */
-       if (IS_G4X(dev) && !IS_GM45(dev)) {
-               temp = I915_READ(PEG_BAND_GAP_DATA);
-               I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
-       }
-
        temp = I915_READ(PORT_HOTPLUG_EN);
 
        I915_WRITE(PORT_HOTPLUG_EN,
@@ -977,7 +998,7 @@ intel_dp_detect(struct drm_connector *connector)
 
        status = connector_status_disconnected;
        if (intel_dp_aux_native_read(intel_output,
-                                    0, dp_priv->dpcd,
+                                    0x000, dp_priv->dpcd,
                                     sizeof (dp_priv->dpcd)) == sizeof 
(dp_priv->dpcd))
        {
                if (dp_priv->dpcd[0] != 0)
@@ -1064,11 +1085,6 @@ intel_dp_init(struct drm_device *dev, int output_reg)
        connector->interlace_allowed = true;
        connector->doublescan_allowed = 0;
 
-       /* 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");
-
        dp_priv->intel_output = intel_output;
        dp_priv->output_reg = output_reg;
        dp_priv->has_audio = false;
@@ -1082,6 +1098,12 @@ intel_dp_init(struct drm_device *dev, int output_reg)
                                          &intel_output->enc);
        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");
+       intel_output->ddc_bus = &dp_priv->adapter;
+
        /* 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.
diff --git a/drivers/gpu/drm/i915/intel_dp.h b/drivers/gpu/drm/i915/intel_dp.h
index 89310b9..2b38054 100644
--- a/drivers/gpu/drm/i915/intel_dp.h
+++ b/drivers/gpu/drm/i915/intel_dp.h
@@ -32,15 +32,15 @@
 #define AUX_I2C_STATUS         0x2
 #define AUX_I2C_MOT            0x4
 
-#define AUX_NATIVE_REPLY_ACK   0x0
-#define AUX_NATIVE_REPLY_NACK  0x1
-#define AUX_NATIVE_REPLY_DEFER 0x2
-#define AUX_NATIVE_REPLY_MASK  0x3
-
-#define AUX_I2C_REPLY_ACK      (0x0 << 2)
-#define AUX_I2C_REPLY_NACK     (0x1 << 2)
-#define AUX_I2C_REPLY_DEFER    (0x2 << 2)
-#define AUX_I2C_REPLY_MASK     (0x3 << 2)
+#define AUX_NATIVE_REPLY_ACK   (0x0 << 4)
+#define AUX_NATIVE_REPLY_NACK  (0x1 << 4)
+#define AUX_NATIVE_REPLY_DEFER (0x2 << 4)
+#define AUX_NATIVE_REPLY_MASK  (0x3 << 4)
+
+#define AUX_I2C_REPLY_ACK      (0x0 << 6)
+#define AUX_I2C_REPLY_NACK     (0x1 << 6)
+#define AUX_I2C_REPLY_DEFER    (0x2 << 6)
+#define AUX_I2C_REPLY_MASK     (0x3 << 6)
 
 /* AUX CH addresses */
 #define        DP_LINK_BW_SET          0x100
diff --git a/drivers/gpu/drm/i915/intel_dp_i2c.c 
b/drivers/gpu/drm/i915/intel_dp_i2c.c
index 4e4611c..11148c7 100644
--- a/drivers/gpu/drm/i915/intel_dp_i2c.c
+++ b/drivers/gpu/drm/i915/intel_dp_i2c.c
@@ -32,16 +32,13 @@
 
 /* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
 
-enum dp_aux_i2c_mode {
-       aux_i2c_start,
-       aux_i2c_write,
-       aux_i2c_read,
-       aux_i2c_stop
-};
+#define MODE_I2C_START 1
+#define MODE_I2C_WRITE 2
+#define MODE_I2C_READ  4
+#define MODE_I2C_STOP  8
 
 static int
-i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter,
-                           enum dp_aux_i2c_mode mode,
+i2c_algo_dp_aux_transaction(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;
@@ -53,55 +50,69 @@ i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter,
        int ret;
 
        /* Set up the command byte */
-       if (address & 1)
+       if (mode & MODE_I2C_READ)
                msg[0] = AUX_I2C_READ << 4;
        else
                msg[0] = AUX_I2C_WRITE << 4;
 
-       if (mode != aux_i2c_stop)
+       if (!(mode & MODE_I2C_STOP))
                msg[0] |= AUX_I2C_MOT << 4;
 
-       /* Note that the AUX_CH I2C stuff wants the read/write
-        * bit stripped off
-        */
-       msg[1] = address >> 9;
-       msg[2] = address >> 1;
+       msg[1] = address >> 8;
+       msg[2] = address;
 
        switch (mode) {
-       case aux_i2c_start:
-       case aux_i2c_stop:
-       default:
-               msg_bytes = 3;
-               reply_bytes = 1;
-               break;
-       case aux_i2c_write:
+       case MODE_I2C_WRITE:
+//             printk(KERN_ERR "dp_aux_transaction address %04x write %02x\n",
+//                    address, write_byte);
                msg[3] = 0;
                msg[4] = write_byte;
                msg_bytes = 5;
                reply_bytes = 1;
                break;
-       case aux_i2c_read:
+       case MODE_I2C_READ:
+//             printk(KERN_ERR "dp_aux_transaction address %04x read\n",
+//                    address);
                msg[3] = 0;
                msg_bytes = 4;
                reply_bytes = 2;
                break;
+       default:
+//             printk(KERN_ERR "dp_aux_transaction address %04x other\n",
+//                    address);
+               msg_bytes = 3;
+               reply_bytes = 1;
+               break;
        }
 
        for (;;) {
                ret = (*algo_data->aux_ch)(adapter,
                                           msg, msg_bytes,
                                           reply, reply_bytes);
-               if (ret <= 0)
-                       return -1;
-               if ((reply[0] & AUX_I2C_REPLY_MASK) == AUX_I2C_REPLY_ACK) {
-                       if (mode == aux_i2c_read)
+               if (ret < 0) {
+                       printk(KERN_ERR "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) {
+//                             printk(KERN_ERR "aux_ch read %02x\n", reply[1]);
                                *read_byte = reply[1];
+                       }
+//                     printk(KERN_ERR "aux_ch_transaction return %d\n",
+//                            reply_bytes - 1);
                        return reply_bytes - 1;
-               }
-               else if ((reply[0] & AUX_I2C_REPLY_MASK) == AUX_I2C_REPLY_DEFER)
+               case AUX_I2C_REPLY_NACK:
+                       printk(KERN_ERR "aux_ch nack\n");
+                       return -EREMOTEIO;
+               case AUX_I2C_REPLY_DEFER:
+                       printk(KERN_ERR "aux_ch defer\n");
                        udelay(100);
-               else
-                       return -1;
+                       break;
+               default:
+                       printk(KERN_ERR "aux_ch invalid reply 0x%02x\n", 
reply[0]);
+                       return -EREMOTEIO;
+               }
        }
 }
 
@@ -115,14 +126,22 @@ i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter,
  * a write followed by a read (as needed for DDC)
  */
 static int
-i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address)
+i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading)
 {
        struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+       int mode = MODE_I2C_START;
+       int ret;
 
+//     printk(KERN_ERR "dp_aux_put_address %04x\n", address);
+       if (reading)
+               mode |= MODE_I2C_READ;
+       else
+               mode |= MODE_I2C_WRITE;
        algo_data->address = address;
        algo_data->running = true;
-       return i2c_algo_dp_aux_transaction(adapter, aux_i2c_start,
-                                           0, NULL);
+       ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
+//     msleep(10);
+       return ret;
 }
 
 /*
@@ -130,15 +149,21 @@ i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 
address)
  * a bare address packet with the MOT bit turned off
  */
 static void
-i2c_algo_dp_aux_stop(struct i2c_adapter *adapter)
+i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading)
 {
        struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+       int mode = MODE_I2C_STOP;
 
+       if (reading)
+               mode |= MODE_I2C_READ;
+       else
+               mode |= MODE_I2C_WRITE;
+//     printk(KERN_ERR "dp_aux_stop\n");
        if (algo_data->running) {
-               (void) i2c_algo_dp_aux_transaction(adapter, aux_i2c_stop,
-                                                   0, NULL);
+               (void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
                algo_data->running = false;
        }
+//     msleep(10);
 }
 
 /*
@@ -149,12 +174,15 @@ static int
 i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte)
 {
        struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+       int ret;
 
+//     printk(KERN_ERR "dp_aux_put_byte %02x\n", byte);
        if (!algo_data->running)
                return -EIO;
 
-       return i2c_algo_dp_aux_transaction(adapter, aux_i2c_write,
-                                          byte, NULL);
+       ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL);
+//     msleep(10);
+       return ret;
 }
 
 /*
@@ -165,12 +193,15 @@ static int
 i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret)
 {
        struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+       int ret;
 
        if (!algo_data->running)
                return -EIO;
 
-       return i2c_algo_dp_aux_transaction(adapter, aux_i2c_read,
-                                           0, byte_ret);
+       ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret);
+//     printk(KERN_ERR "dp_aux_get_byte (status %d) %02x\n", ret, *byte_ret);
+//     msleep(10);
+       return ret;
 }
 
 static int
@@ -178,34 +209,38 @@ i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter,
                     struct i2c_msg *msgs,
                     int num)
 {
-       int orig_num = num;
        int ret = 0;
-       while (num--) {
-               u16 len = msgs->len;
-               u8 *buf = msgs->buf;
-               ret = i2c_algo_dp_aux_address(adapter, msgs->addr);
+       bool reading = false;
+       int m;
+       int b;
+
+       for (m = 0; m < num; m++) {
+               u16 len = msgs[m].len;
+               u8 *buf = msgs[m].buf;
+               reading = (msgs[m].flags & I2C_M_RD) != 0;
+               ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading);
                if (ret < 0)
                        break;
-               if (msgs->flags & I2C_M_RD) {
-                       while (len--) {
-                               ret = i2c_algo_dp_aux_get_byte(adapter, buf++);
+               if (reading) {
+                       for (b = 0; b < len; b++) {
+                               ret = i2c_algo_dp_aux_get_byte(adapter, 
&buf[b]);
                                if (ret < 0)
                                        break;
                        }
                } else {
-                       while (len--) {
-                               ret = i2c_algo_dp_aux_put_byte(adapter, *buf++);
+                       for (b = 0; b < len; b++) {
+                               ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]);
                                if (ret < 0)
                                        break;
                        }
                }
                if (ret < 0)
                        break;
-               msgs++;
        }
-       if (ret == 0)
-               ret = orig_num;
-       i2c_algo_dp_aux_stop(adapter);
+       if (ret >= 0)
+               ret = num;
+       i2c_algo_dp_aux_stop(adapter, reading);
+       printk(KERN_ERR "dp_aux_xfer return %d\n", ret);
        return ret;
 }
 
@@ -223,11 +258,20 @@ static const struct i2c_algorithm i2c_dp_aux_algo = {
        .functionality  = i2c_algo_dp_aux_functionality,
 };
 
+static void
+i2c_dp_aux_reset_bus(struct i2c_adapter *adapter)
+{
+       (void) i2c_algo_dp_aux_address(adapter, 0, false);
+       (void) i2c_algo_dp_aux_stop(adapter, false);
+                                          
+}
+
 static int
 i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
 {
        adapter->algo = &i2c_dp_aux_algo;
        adapter->retries = 3;
+       i2c_dp_aux_reset_bus(adapter);
        return 0;
 }
 
@@ -239,6 +283,7 @@ i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
        error = i2c_dp_aux_prepare_bus(adapter);
        if (error)
                return error;
-       return i2c_add_adapter(adapter);
+       error = i2c_add_adapter(adapter);
+       return error;
 }
 EXPORT_SYMBOL(i2c_dp_aux_add_bus);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 9b0882c..004541c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -118,6 +118,9 @@ extern void intel_dvo_init(struct drm_device *dev);
 extern void intel_tv_init(struct drm_device *dev);
 extern void intel_lvds_init(struct drm_device *dev);
 extern void intel_dp_init(struct drm_device *dev, int dp_reg);
+void
+intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
+                struct drm_display_mode *adjusted_mode);
 
 extern void intel_crtc_load_lut(struct drm_crtc *crtc);
 extern void intel_encoder_prepare (struct drm_encoder *encoder);
-- 
1.6.3.1


------------------------------------------------------------------------------
Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT 
is a gathering of tech-side developers & brand creativity professionals. Meet
the minds behind Google Creative Lab, Visual Complexity, Processing, & 
iPhoneDevCamp as they present alongside digital heavyweights like Barbarian 
Group, R/GA, & Big Spaceship. http://p.sf.net/sfu/creativitycat-com 
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to