aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h1
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c66
2 files changed, 57 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b522eb6e59a4..3da1af46625c 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1807,6 +1807,7 @@ enum skl_disp_power_wells {
1807#define GMBUS_CYCLE_INDEX (2<<25) 1807#define GMBUS_CYCLE_INDEX (2<<25)
1808#define GMBUS_CYCLE_STOP (4<<25) 1808#define GMBUS_CYCLE_STOP (4<<25)
1809#define GMBUS_BYTE_COUNT_SHIFT 16 1809#define GMBUS_BYTE_COUNT_SHIFT 16
1810#define GMBUS_BYTE_COUNT_MAX 256U
1810#define GMBUS_SLAVE_INDEX_SHIFT 8 1811#define GMBUS_SLAVE_INDEX_SHIFT 8
1811#define GMBUS_SLAVE_ADDR_SHIFT 1 1812#define GMBUS_SLAVE_ADDR_SHIFT 1
1812#define GMBUS_SLAVE_READ (1<<0) 1813#define GMBUS_SLAVE_READ (1<<0)
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index b31088a551f2..56e437e31580 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -270,18 +270,17 @@ gmbus_wait_idle(struct drm_i915_private *dev_priv)
270} 270}
271 271
272static int 272static int
273gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, 273gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
274 u32 gmbus1_index) 274 unsigned short addr, u8 *buf, unsigned int len,
275 u32 gmbus1_index)
275{ 276{
276 int reg_offset = dev_priv->gpio_mmio_base; 277 int reg_offset = dev_priv->gpio_mmio_base;
277 u16 len = msg->len;
278 u8 *buf = msg->buf;
279 278
280 I915_WRITE(GMBUS1 + reg_offset, 279 I915_WRITE(GMBUS1 + reg_offset,
281 gmbus1_index | 280 gmbus1_index |
282 GMBUS_CYCLE_WAIT | 281 GMBUS_CYCLE_WAIT |
283 (len << GMBUS_BYTE_COUNT_SHIFT) | 282 (len << GMBUS_BYTE_COUNT_SHIFT) |
284 (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) | 283 (addr << GMBUS_SLAVE_ADDR_SHIFT) |
285 GMBUS_SLAVE_READ | GMBUS_SW_RDY); 284 GMBUS_SLAVE_READ | GMBUS_SW_RDY);
286 while (len) { 285 while (len) {
287 int ret; 286 int ret;
@@ -303,11 +302,35 @@ gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
303} 302}
304 303
305static int 304static int
306gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg) 305gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
306 u32 gmbus1_index)
307{ 307{
308 int reg_offset = dev_priv->gpio_mmio_base;
309 u16 len = msg->len;
310 u8 *buf = msg->buf; 308 u8 *buf = msg->buf;
309 unsigned int rx_size = msg->len;
310 unsigned int len;
311 int ret;
312
313 do {
314 len = min(rx_size, GMBUS_BYTE_COUNT_MAX);
315
316 ret = gmbus_xfer_read_chunk(dev_priv, msg->addr,
317 buf, len, gmbus1_index);
318 if (ret)
319 return ret;
320
321 rx_size -= len;
322 buf += len;
323 } while (rx_size != 0);
324
325 return 0;
326}
327
328static int
329gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
330 unsigned short addr, u8 *buf, unsigned int len)
331{
332 int reg_offset = dev_priv->gpio_mmio_base;
333 unsigned int chunk_size = len;
311 u32 val, loop; 334 u32 val, loop;
312 335
313 val = loop = 0; 336 val = loop = 0;
@@ -319,8 +342,8 @@ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
319 I915_WRITE(GMBUS3 + reg_offset, val); 342 I915_WRITE(GMBUS3 + reg_offset, val);
320 I915_WRITE(GMBUS1 + reg_offset, 343 I915_WRITE(GMBUS1 + reg_offset,
321 GMBUS_CYCLE_WAIT | 344 GMBUS_CYCLE_WAIT |
322 (msg->len << GMBUS_BYTE_COUNT_SHIFT) | 345 (chunk_size << GMBUS_BYTE_COUNT_SHIFT) |
323 (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) | 346 (addr << GMBUS_SLAVE_ADDR_SHIFT) |
324 GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); 347 GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
325 while (len) { 348 while (len) {
326 int ret; 349 int ret;
@@ -337,6 +360,29 @@ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
337 if (ret) 360 if (ret)
338 return ret; 361 return ret;
339 } 362 }
363
364 return 0;
365}
366
367static int
368gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
369{
370 u8 *buf = msg->buf;
371 unsigned int tx_size = msg->len;
372 unsigned int len;
373 int ret;
374
375 do {
376 len = min(tx_size, GMBUS_BYTE_COUNT_MAX);
377
378 ret = gmbus_xfer_write_chunk(dev_priv, msg->addr, buf, len);
379 if (ret)
380 return ret;
381
382 buf += len;
383 tx_size -= len;
384 } while (tx_size != 0);
385
340 return 0; 386 return 0;
341} 387}
342 388