aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRamalingam C <ramalingam.c@intel.com>2018-06-28 09:34:49 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2018-07-12 11:31:28 -0400
commitd5dc0f43f268bf2b6bb61f109a18a652a49c6f4e (patch)
treede68a81289a693f1b7f2b2d90a84f9920f704542
parent73675cf6979bb80534641b1814a971eaf9f649b5 (diff)
drm/i915/gmbus: Enable burst read
Support for Burst read in HW is added for HDCP2.2 compliance requirement. This patch enables the burst read for all the gmbus read of more than 511Bytes, on capable platforms. v2: Extra line is removed. v3: Macro is added for detecting the BURST_READ Support [Jani] Runtime detection of the need for burst_read [Jani] Calculation enhancement. v4: GMBUS0 reg val is passed from caller [ville] Removed a extra var [ville] Extra brackets are removed [ville] Implemented the handling of 512Bytes Burst Read. v5: Burst read max length is fixed at 767Bytes [Ville] v6: Collecting the received reviewed-by. Signed-off-by: Ramalingam C <ramalingam.c@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/1530192889-5789-3-git-send-email-ramalingam.c@intel.com
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h3
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h1
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c61
3 files changed, 55 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 48b350116cba..a6c6decd0546 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2560,6 +2560,9 @@ intel_info(const struct drm_i915_private *dev_priv)
2560 IS_SKL_GT3(dev_priv) || IS_SKL_GT4(dev_priv)) 2560 IS_SKL_GT3(dev_priv) || IS_SKL_GT4(dev_priv))
2561 2561
2562#define HAS_GMBUS_IRQ(dev_priv) (INTEL_GEN(dev_priv) >= 4) 2562#define HAS_GMBUS_IRQ(dev_priv) (INTEL_GEN(dev_priv) >= 4)
2563#define HAS_GMBUS_BURST_READ(dev_priv) (INTEL_GEN(dev_priv) >= 10 || \
2564 IS_GEMINILAKE(dev_priv) || \
2565 IS_KABYLAKE(dev_priv))
2563 2566
2564/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte 2567/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
2565 * rows, which changed the alignment requirements and fence programming. 2568 * rows, which changed the alignment requirements and fence programming.
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2da870a8948e..1f222af0324d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3123,6 +3123,7 @@ enum i915_power_well_id {
3123#define GMBUS_RATE_400KHZ (2 << 8) /* reserved on Pineview */ 3123#define GMBUS_RATE_400KHZ (2 << 8) /* reserved on Pineview */
3124#define GMBUS_RATE_1MHZ (3 << 8) /* reserved on Pineview */ 3124#define GMBUS_RATE_1MHZ (3 << 8) /* reserved on Pineview */
3125#define GMBUS_HOLD_EXT (1 << 7) /* 300ns hold time, rsvd on Pineview */ 3125#define GMBUS_HOLD_EXT (1 << 7) /* 300ns hold time, rsvd on Pineview */
3126#define GMBUS_BYTE_CNT_OVERRIDE (1 << 6)
3126#define GMBUS_PIN_DISABLED 0 3127#define GMBUS_PIN_DISABLED 0
3127#define GMBUS_PIN_SSC 1 3128#define GMBUS_PIN_SSC 1
3128#define GMBUS_PIN_VGADDC 2 3129#define GMBUS_PIN_VGADDC 2
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 82bb9c33ab1c..bef32b7c248e 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -371,12 +371,29 @@ unsigned int gmbus_max_xfer_size(struct drm_i915_private *dev_priv)
371static int 371static int
372gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv, 372gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
373 unsigned short addr, u8 *buf, unsigned int len, 373 unsigned short addr, u8 *buf, unsigned int len,
374 u32 gmbus1_index) 374 u32 gmbus0_reg, u32 gmbus1_index)
375{ 375{
376 unsigned int size = len;
377 bool burst_read = len > gmbus_max_xfer_size(dev_priv);
378 bool extra_byte_added = false;
379
380 if (burst_read) {
381 /*
382 * As per HW Spec, for 512Bytes need to read extra Byte and
383 * Ignore the extra byte read.
384 */
385 if (len == 512) {
386 extra_byte_added = true;
387 len++;
388 }
389 size = len % 256 + 256;
390 I915_WRITE_FW(GMBUS0, gmbus0_reg | GMBUS_BYTE_CNT_OVERRIDE);
391 }
392
376 I915_WRITE_FW(GMBUS1, 393 I915_WRITE_FW(GMBUS1,
377 gmbus1_index | 394 gmbus1_index |
378 GMBUS_CYCLE_WAIT | 395 GMBUS_CYCLE_WAIT |
379 (len << GMBUS_BYTE_COUNT_SHIFT) | 396 (size << GMBUS_BYTE_COUNT_SHIFT) |
380 (addr << GMBUS_SLAVE_ADDR_SHIFT) | 397 (addr << GMBUS_SLAVE_ADDR_SHIFT) |
381 GMBUS_SLAVE_READ | GMBUS_SW_RDY); 398 GMBUS_SLAVE_READ | GMBUS_SW_RDY);
382 while (len) { 399 while (len) {
@@ -389,17 +406,34 @@ gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
389 406
390 val = I915_READ_FW(GMBUS3); 407 val = I915_READ_FW(GMBUS3);
391 do { 408 do {
409 if (extra_byte_added && len == 1)
410 break;
411
392 *buf++ = val & 0xff; 412 *buf++ = val & 0xff;
393 val >>= 8; 413 val >>= 8;
394 } while (--len && ++loop < 4); 414 } while (--len && ++loop < 4);
415
416 if (burst_read && len == size - 4)
417 /* Reset the override bit */
418 I915_WRITE_FW(GMBUS0, gmbus0_reg);
395 } 419 }
396 420
397 return 0; 421 return 0;
398} 422}
399 423
424/*
425 * HW spec says that 512Bytes in Burst read need special treatment.
426 * But it doesn't talk about other multiple of 256Bytes. And couldn't locate
427 * an I2C slave, which supports such a lengthy burst read too for experiments.
428 *
429 * So until things get clarified on HW support, to avoid the burst read length
430 * in fold of 256Bytes except 512, max burst read length is fixed at 767Bytes.
431 */
432#define INTEL_GMBUS_BURST_READ_MAX_LEN 767U
433
400static int 434static int
401gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, 435gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
402 u32 gmbus1_index) 436 u32 gmbus0_reg, u32 gmbus1_index)
403{ 437{
404 u8 *buf = msg->buf; 438 u8 *buf = msg->buf;
405 unsigned int rx_size = msg->len; 439 unsigned int rx_size = msg->len;
@@ -407,10 +441,13 @@ gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
407 int ret; 441 int ret;
408 442
409 do { 443 do {
410 len = min(rx_size, gmbus_max_xfer_size(dev_priv)); 444 if (HAS_GMBUS_BURST_READ(dev_priv))
445 len = min(rx_size, INTEL_GMBUS_BURST_READ_MAX_LEN);
446 else
447 len = min(rx_size, gmbus_max_xfer_size(dev_priv));
411 448
412 ret = gmbus_xfer_read_chunk(dev_priv, msg->addr, 449 ret = gmbus_xfer_read_chunk(dev_priv, msg->addr, buf, len,
413 buf, len, gmbus1_index); 450 gmbus0_reg, gmbus1_index);
414 if (ret) 451 if (ret)
415 return ret; 452 return ret;
416 453
@@ -498,7 +535,8 @@ gmbus_is_index_xfer(struct i2c_msg *msgs, int i, int num)
498} 535}
499 536
500static int 537static int
501gmbus_index_xfer(struct drm_i915_private *dev_priv, struct i2c_msg *msgs) 538gmbus_index_xfer(struct drm_i915_private *dev_priv, struct i2c_msg *msgs,
539 u32 gmbus0_reg)
502{ 540{
503 u32 gmbus1_index = 0; 541 u32 gmbus1_index = 0;
504 u32 gmbus5 = 0; 542 u32 gmbus5 = 0;
@@ -516,7 +554,8 @@ gmbus_index_xfer(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
516 I915_WRITE_FW(GMBUS5, gmbus5); 554 I915_WRITE_FW(GMBUS5, gmbus5);
517 555
518 if (msgs[1].flags & I2C_M_RD) 556 if (msgs[1].flags & I2C_M_RD)
519 ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus1_index); 557 ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus0_reg,
558 gmbus1_index);
520 else 559 else
521 ret = gmbus_xfer_write(dev_priv, &msgs[1], gmbus1_index); 560 ret = gmbus_xfer_write(dev_priv, &msgs[1], gmbus1_index);
522 561
@@ -551,10 +590,12 @@ retry:
551 for (; i < num; i += inc) { 590 for (; i < num; i += inc) {
552 inc = 1; 591 inc = 1;
553 if (gmbus_is_index_xfer(msgs, i, num)) { 592 if (gmbus_is_index_xfer(msgs, i, num)) {
554 ret = gmbus_index_xfer(dev_priv, &msgs[i]); 593 ret = gmbus_index_xfer(dev_priv, &msgs[i],
594 gmbus0_source | bus->reg0);
555 inc = 2; /* an index transmission is two msgs */ 595 inc = 2; /* an index transmission is two msgs */
556 } else if (msgs[i].flags & I2C_M_RD) { 596 } else if (msgs[i].flags & I2C_M_RD) {
557 ret = gmbus_xfer_read(dev_priv, &msgs[i], 0); 597 ret = gmbus_xfer_read(dev_priv, &msgs[i],
598 gmbus0_source | bus->reg0, 0);
558 } else { 599 } else {
559 ret = gmbus_xfer_write(dev_priv, &msgs[i], 0); 600 ret = gmbus_xfer_write(dev_priv, &msgs[i], 0);
560 } 601 }