Commit b4c26818 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/mxm: initial implementation of dcb sanitisation

The DCB table provided by the VBIOS on most MXM chips has a number of
entries which either need to be disabled, or modified according to the
MXM-SIS Output Device Descriptors.

The x86 vbios code usually takes care of this for us, however, with the
large number of laptops now with switchable graphics or optimus, a lot
of the time nouveau is responsible for POSTing the card instead - leaving
some fun situations like, plugging in a monitor and having nouveau decide
3 connectors actually just got plugged in..

No MXM-SIS fetching methods implemented yet.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent befb51e9
......@@ -11,7 +11,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
nouveau_display.o nouveau_connector.o nouveau_fbcon.o \
nouveau_hdmi.o nouveau_dp.o nouveau_ramht.o \
nouveau_pm.o nouveau_volt.o nouveau_perf.o nouveau_temp.o \
nouveau_mm.o nouveau_vm.o \
nouveau_mm.o nouveau_vm.o nouveau_mxm.o \
nv04_timer.o \
nv04_mc.o nv40_mc.o nv50_mc.o \
nv04_fb.o nv10_fb.o nv30_fb.o nv40_fb.o nv50_fb.o nvc0_fb.o \
......
......@@ -5382,6 +5382,9 @@ bit_table(struct drm_device *dev, u8 id, struct bit_entry *bit)
struct nvbios *bios = &dev_priv->vbios;
u8 entries, *entry;
if (bios->type != NVBIOS_BIT)
return -ENODEV;
entries = bios->data[bios->offset + 10];
entry = &bios->data[bios->offset + 12];
while (entries--) {
......@@ -5832,7 +5835,7 @@ dcb_table(struct drm_device *dev)
return NULL;
}
u8 *
void *
dcb_outp(struct drm_device *dev, u8 idx)
{
u8 *dcb = dcb_table(dev);
......@@ -6663,6 +6666,10 @@ nouveau_bios_init(struct drm_device *dev)
if (ret)
return ret;
ret = nouveau_mxm_init(dev);
if (ret)
return ret;
ret = parse_dcb_table(dev, bios);
if (ret)
return ret;
......@@ -6703,5 +6710,6 @@ nouveau_bios_init(struct drm_device *dev)
void
nouveau_bios_takedown(struct drm_device *dev)
{
nouveau_mxm_fini(dev);
nouveau_i2c_fini(dev);
}
......@@ -315,7 +315,7 @@ struct nvbios {
};
void *dcb_table(struct drm_device *);
u8 *dcb_outp(struct drm_device *, u8 idx);
void *dcb_outp(struct drm_device *, u8 idx);
int dcb_outp_foreach(struct drm_device *, void *data,
int (*)(struct drm_device *, void *, int idx, u8 *outp));
u8 *dcb_conntab(struct drm_device *);
......
......@@ -124,6 +124,10 @@ MODULE_PARM_DESC(ctxfw, "Use external HUB/GPC ucode (fermi)\n");
int nouveau_ctxfw;
module_param_named(ctxfw, nouveau_ctxfw, int, 0400);
MODULE_PARM_DESC(ctxfw, "Santise DCB table according to MXM-SIS\n");
int nouveau_mxmdcb = 1;
module_param_named(mxmdcb, nouveau_mxmdcb, int, 0400);
int nouveau_fbpercrtc;
#if 0
module_param_named(fbpercrtc, nouveau_fbpercrtc, int, 0400);
......
......@@ -793,6 +793,7 @@ struct drm_nouveau_private {
struct nouveau_vm *chan_vm;
struct nvbios vbios;
u8 *mxms;
struct list_head i2c_ports;
struct nv04_mode_state mode_reg;
......@@ -864,6 +865,7 @@ extern char *nouveau_perflvl;
extern int nouveau_perflvl_wr;
extern int nouveau_msi;
extern int nouveau_ctxfw;
extern int nouveau_mxmdcb;
extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state);
extern int nouveau_pci_resume(struct pci_dev *pdev);
......@@ -1108,6 +1110,10 @@ extern int call_lvds_script(struct drm_device *, struct dcb_entry *, int head,
enum LVDS_script, int pxclk);
bool bios_encoder_match(struct dcb_entry *, u32 hash);
/* nouveau_mxm.c */
int nouveau_mxm_init(struct drm_device *dev);
void nouveau_mxm_fini(struct drm_device *dev);
/* nouveau_ttm.c */
int nouveau_ttm_global_init(struct drm_nouveau_private *);
void nouveau_ttm_global_release(struct drm_nouveau_private *);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment