Commit b4c26818 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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 \
+9 −1
Original line number Diff line number Diff line
@@ -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);
}
+1 −1
Original line number Diff line number Diff line
@@ -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 *);
+4 −0
Original line number Diff line number Diff line
@@ -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);
+6 −0
Original line number Diff line number Diff line
@@ -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 *);
Loading