@@ -470,9 +470,48 @@ mxm_dcb_sanitise(struct drm_device *dev)
470470 mxms_foreach (dev , 0x01 , mxm_show_unmatched , NULL );
471471}
472472
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+
473485static bool
474486mxm_shadow_rom (struct drm_device * dev , u8 version )
475487{
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 ;
476515 return false;
477516}
478517
0 commit comments