static int
 gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
                      unsigned short addr, u8 *buf, unsigned int len,
-                     u32 gmbus1_index)
+                     u32 gmbus0_reg, u32 gmbus1_index)
 {
+       unsigned int size = len;
+       bool burst_read = len > gmbus_max_xfer_size(dev_priv);
+       bool extra_byte_added = false;
+
+       if (burst_read) {
+               /*
+                * As per HW Spec, for 512Bytes need to read extra Byte and
+                * Ignore the extra byte read.
+                */
+               if (len == 512) {
+                       extra_byte_added = true;
+                       len++;
+               }
+               size = len % 256 + 256;
+               I915_WRITE_FW(GMBUS0, gmbus0_reg | GMBUS_BYTE_CNT_OVERRIDE);
+       }
+
        I915_WRITE_FW(GMBUS1,
                      gmbus1_index |
                      GMBUS_CYCLE_WAIT |
-                     (len << GMBUS_BYTE_COUNT_SHIFT) |
+                     (size << GMBUS_BYTE_COUNT_SHIFT) |
                      (addr << GMBUS_SLAVE_ADDR_SHIFT) |
                      GMBUS_SLAVE_READ | GMBUS_SW_RDY);
        while (len) {
 
                val = I915_READ_FW(GMBUS3);
                do {
+                       if (extra_byte_added && len == 1)
+                               break;
+
                        *buf++ = val & 0xff;
                        val >>= 8;
                } while (--len && ++loop < 4);
+
+               if (burst_read && len == size - 4)
+                       /* Reset the override bit */
+                       I915_WRITE_FW(GMBUS0, gmbus0_reg);
        }
 
        return 0;
 }
 
+/*
+ * HW spec says that 512Bytes in Burst read need special treatment.
+ * But it doesn't talk about other multiple of 256Bytes. And couldn't locate
+ * an I2C slave, which supports such a lengthy burst read too for experiments.
+ *
+ * So until things get clarified on HW support, to avoid the burst read length
+ * in fold of 256Bytes except 512, max burst read length is fixed at 767Bytes.
+ */
+#define INTEL_GMBUS_BURST_READ_MAX_LEN         767U
+
 static int
 gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
-               u32 gmbus1_index)
+               u32 gmbus0_reg, u32 gmbus1_index)
 {
        u8 *buf = msg->buf;
        unsigned int rx_size = msg->len;
        int ret;
 
        do {
-               len = min(rx_size, gmbus_max_xfer_size(dev_priv));
+               if (HAS_GMBUS_BURST_READ(dev_priv))
+                       len = min(rx_size, INTEL_GMBUS_BURST_READ_MAX_LEN);
+               else
+                       len = min(rx_size, gmbus_max_xfer_size(dev_priv));
 
-               ret = gmbus_xfer_read_chunk(dev_priv, msg->addr,
-                                           buf, len, gmbus1_index);
+               ret = gmbus_xfer_read_chunk(dev_priv, msg->addr, buf, len,
+                                           gmbus0_reg, gmbus1_index);
                if (ret)
                        return ret;
 
 }
 
 static int
-gmbus_index_xfer(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
+gmbus_index_xfer(struct drm_i915_private *dev_priv, struct i2c_msg *msgs,
+                u32 gmbus0_reg)
 {
        u32 gmbus1_index = 0;
        u32 gmbus5 = 0;
                I915_WRITE_FW(GMBUS5, gmbus5);
 
        if (msgs[1].flags & I2C_M_RD)
-               ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus1_index);
+               ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus0_reg,
+                                     gmbus1_index);
        else
                ret = gmbus_xfer_write(dev_priv, &msgs[1], gmbus1_index);
 
        for (; i < num; i += inc) {
                inc = 1;
                if (gmbus_is_index_xfer(msgs, i, num)) {
-                       ret = gmbus_index_xfer(dev_priv, &msgs[i]);
+                       ret = gmbus_index_xfer(dev_priv, &msgs[i],
+                                              gmbus0_source | bus->reg0);
                        inc = 2; /* an index transmission is two msgs */
                } else if (msgs[i].flags & I2C_M_RD) {
-                       ret = gmbus_xfer_read(dev_priv, &msgs[i], 0);
+                       ret = gmbus_xfer_read(dev_priv, &msgs[i],
+                                             gmbus0_source | bus->reg0, 0);
                } else {
                        ret = gmbus_xfer_write(dev_priv, &msgs[i], 0);
                }