diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-11-07 01:16:24 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-12-21 04:01:43 -0500 |
commit | c37e99050c84c40441e614bd41474e12b6cc2079 (patch) | |
tree | 821a8b022ca2e12f06af4cd5994da9bc53ae5968 /drivers/gpu/drm/nouveau/nouveau_mxm.c | |
parent | 3952315b9d20fb04d43d184f9c1475327811c5aa (diff) |
drm/nouveau/mxm: implement ROM shadow method
Untested, -ENOHW.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_mxm.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_mxm.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_mxm.c b/drivers/gpu/drm/nouveau/nouveau_mxm.c index 840c88fc4f0e..8bccddf4eff0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mxm.c +++ b/drivers/gpu/drm/nouveau/nouveau_mxm.c | |||
@@ -471,8 +471,47 @@ mxm_dcb_sanitise(struct drm_device *dev) | |||
471 | } | 471 | } |
472 | 472 | ||
473 | static bool | 473 | static bool |
474 | mxm_shadow_rom_fetch(struct nouveau_i2c_chan *i2c, u8 addr, | ||
475 | u8 offset, u8 size, u8 *data) | ||
476 | { | ||
477 | struct i2c_msg msgs[] = { | ||
478 | { .addr = addr, .flags = 0, .len = 1, .buf = &offset }, | ||
479 | { .addr = addr, .flags = I2C_M_RD, .len = size, .buf = data, }, | ||
480 | }; | ||
481 | |||
482 | return i2c_transfer(&i2c->adapter, msgs, 2) == 2; | ||
483 | } | ||
484 | |||
485 | static bool | ||
474 | mxm_shadow_rom(struct drm_device *dev, u8 version) | 486 | mxm_shadow_rom(struct drm_device *dev, u8 version) |
475 | { | 487 | { |
488 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
489 | struct nouveau_i2c_chan *i2c = NULL; | ||
490 | u8 i2cidx, mxms[6], addr, size; | ||
491 | |||
492 | i2cidx = mxm_ddc_map(dev, 1 /* LVDS_DDC */) & 0x0f; | ||
493 | if (i2cidx < 0x0f) | ||
494 | i2c = nouveau_i2c_find(dev, i2cidx); | ||
495 | if (!i2c) | ||
496 | return false; | ||
497 | |||
498 | addr = 0x54; | ||
499 | if (!mxm_shadow_rom_fetch(i2c, addr, 0, 6, mxms)) { | ||
500 | addr = 0x56; | ||
501 | if (!mxm_shadow_rom_fetch(i2c, addr, 0, 6, mxms)) | ||
502 | return false; | ||
503 | } | ||
504 | |||
505 | dev_priv->mxms = mxms; | ||
506 | size = mxms_headerlen(dev) + mxms_structlen(dev); | ||
507 | dev_priv->mxms = kmalloc(size, GFP_KERNEL); | ||
508 | |||
509 | if (dev_priv->mxms && | ||
510 | mxm_shadow_rom_fetch(i2c, addr, 0, size, dev_priv->mxms)) | ||
511 | return true; | ||
512 | |||
513 | kfree(dev_priv->mxms); | ||
514 | dev_priv->mxms = NULL; | ||
476 | return false; | 515 | return false; |
477 | } | 516 | } |
478 | 517 | ||