From 02e4f5877dc7b963b3dd2beaf9664cf29c12d728 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 6 Jul 2011 21:21:42 +1000 Subject: [PATCH] drm/nouveau/bios: allow passing in crtc to the init table parser Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 49 ++++++++++++++------------ drivers/gpu/drm/nouveau/nouveau_bios.h | 1 + drivers/gpu/drm/nouveau/nouveau_dp.c | 4 +-- drivers/gpu/drm/nouveau/nouveau_drv.h | 7 ++-- drivers/gpu/drm/nouveau/nv50_display.c | 8 ++--- drivers/gpu/drm/nouveau/nv50_pm.c | 8 ++--- 6 files changed, 41 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index f0a77b7ce60e..58d8c85b85d1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -296,6 +296,11 @@ munge_reg(struct nvbios *bios, uint32_t reg) if (dev_priv->card_type < NV_50) return reg; + if (reg & 0x80000000) { + BUG_ON(bios->display.crtc < 0); + reg += bios->display.crtc * 0x800; + } + if (reg & 0x40000000) { BUG_ON(!dcbent); @@ -304,7 +309,7 @@ munge_reg(struct nvbios *bios, uint32_t reg) reg += 0x00000080; } - reg &= ~0x60000000; + reg &= ~0xe0000000; return reg; } @@ -4496,8 +4501,8 @@ nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent, } int -nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, - uint32_t sub, int pxclk) +nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk, + struct dcb_entry *dcbent, int crtc) { /* * The display script table is located by the BIT 'U' table. @@ -4587,22 +4592,22 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, return 1; } - if (pxclk < -2 || pxclk > 0) { + if (pclk < -2 || pclk > 0) { /* Try to find matching script table entry */ for (i = 0; i < otable[5]; i++) { - if (ROM16(otable[table[4] + i*6]) == sub) + if (ROM16(otable[table[4] + i*6]) == type) break; } if (i == otable[5]) { NV_ERROR(dev, "Table 0x%04x not found for %d/%d, " "using first\n", - sub, dcbent->type, dcbent->or); + type, dcbent->type, dcbent->or); i = 0; } } - if (pxclk == 0) { + if (pclk == 0) { script = ROM16(otable[6]); if (!script) { NV_DEBUG_KMS(dev, "output script 0 not found\n"); @@ -4610,9 +4615,9 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, } NV_DEBUG_KMS(dev, "0x%04X: parsing output script 0\n", script); - nouveau_bios_run_init_table(dev, script, dcbent); + nouveau_bios_run_init_table(dev, script, dcbent, crtc); } else - if (pxclk == -1) { + if (pclk == -1) { script = ROM16(otable[8]); if (!script) { NV_DEBUG_KMS(dev, "output script 1 not found\n"); @@ -4620,9 +4625,9 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, } NV_DEBUG_KMS(dev, "0x%04X: parsing output script 1\n", script); - nouveau_bios_run_init_table(dev, script, dcbent); + nouveau_bios_run_init_table(dev, script, dcbent, crtc); } else - if (pxclk == -2) { + if (pclk == -2) { if (table[4] >= 12) script = ROM16(otable[10]); else @@ -4633,31 +4638,31 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, } NV_DEBUG_KMS(dev, "0x%04X: parsing output script 2\n", script); - nouveau_bios_run_init_table(dev, script, dcbent); + nouveau_bios_run_init_table(dev, script, dcbent, crtc); } else - if (pxclk > 0) { + if (pclk > 0) { script = ROM16(otable[table[4] + i*6 + 2]); if (script) - script = clkcmptable(bios, script, pxclk); + script = clkcmptable(bios, script, pclk); if (!script) { NV_DEBUG_KMS(dev, "clock script 0 not found\n"); return 1; } NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 0\n", script); - nouveau_bios_run_init_table(dev, script, dcbent); + nouveau_bios_run_init_table(dev, script, dcbent, crtc); } else - if (pxclk < 0) { + if (pclk < 0) { script = ROM16(otable[table[4] + i*6 + 4]); if (script) - script = clkcmptable(bios, script, -pxclk); + script = clkcmptable(bios, script, -pclk); if (!script) { NV_DEBUG_KMS(dev, "clock script 1 not found\n"); return 1; } NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 1\n", script); - nouveau_bios_run_init_table(dev, script, dcbent); + nouveau_bios_run_init_table(dev, script, dcbent, crtc); } return 0; @@ -6804,7 +6809,7 @@ uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev) void nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table, - struct dcb_entry *dcbent) + struct dcb_entry *dcbent, int crtc) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nvbios *bios = &dev_priv->vbios; @@ -6812,6 +6817,7 @@ nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table, spin_lock_bh(&bios->lock); bios->display.output = dcbent; + bios->display.crtc = crtc; parse_init_table(bios, table, &iexec); bios->display.output = NULL; spin_unlock_bh(&bios->lock); @@ -6898,9 +6904,8 @@ nouveau_run_vbios_init(struct drm_device *dev) if (dev_priv->card_type >= NV_50) { for (i = 0; i < bios->dcb.entries; i++) { - nouveau_bios_run_display_table(dev, - &bios->dcb.entry[i], - 0, 0); + nouveau_bios_run_display_table(dev, 0, 0, + &bios->dcb.entry[i], -1); } } diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index 050c314119df..b28f0bceaed4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h @@ -289,6 +289,7 @@ struct nvbios { struct { struct dcb_entry *output; + int crtc; uint16_t script_table_ptr; uint16_t dp_table_ptr; } display; diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index 7beb82a0315d..44de23d9a437 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -300,7 +300,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder) if (dpe->script0) { NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or); nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0), - nv_encoder->dcb); + nv_encoder->dcb, -1); } train: @@ -433,7 +433,7 @@ stop: if (dpe->script1) { NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or); nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1), - nv_encoder->dcb); + nv_encoder->dcb, -1); } /* re-enable hotplug detect */ diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 721845add9b2..6469ffee6fc0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1039,7 +1039,7 @@ extern int nouveau_bios_init(struct drm_device *); extern void nouveau_bios_takedown(struct drm_device *dev); extern int nouveau_run_vbios_init(struct drm_device *); extern void nouveau_bios_run_init_table(struct drm_device *, uint16_t table, - struct dcb_entry *); + struct dcb_entry *, int crtc); extern struct dcb_gpio_entry *nouveau_bios_gpio_entry(struct drm_device *, enum dcb_gpio_tag); extern struct dcb_connector_table_entry * @@ -1047,9 +1047,8 @@ nouveau_bios_connector_entry(struct drm_device *, int index); extern u32 get_pll_register(struct drm_device *, enum pll_types); extern int get_pll_limits(struct drm_device *, uint32_t limit_match, struct pll_lims *); -extern int nouveau_bios_run_display_table(struct drm_device *, - struct dcb_entry *, - uint32_t script, int pxclk); +extern int nouveau_bios_run_display_table(struct drm_device *, u16 id, int clk, + struct dcb_entry *, int crtc); extern void *nouveau_bios_dp_table(struct drm_device *, struct dcb_entry *, int *length); extern bool nouveau_bios_fp_mode(struct drm_device *, struct drm_display_mode *); diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 5754c0ac8937..8260303c2fca 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -689,7 +689,7 @@ nv50_display_unk10_handler(struct drm_device *dev) struct dcb_entry *dcb = &dev_priv->vbios.dcb.entry[i]; if (dcb->type == type && (dcb->or & (1 << or))) { - nouveau_bios_run_display_table(dev, dcb, 0, -1); + nouveau_bios_run_display_table(dev, 0, -1, dcb, -1); disp->irq.dcb = dcb; goto ack; } @@ -744,7 +744,7 @@ nv50_display_unk20_handler(struct drm_device *dev) NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); dcb = disp->irq.dcb; if (dcb) { - nouveau_bios_run_display_table(dev, dcb, 0, -2); + nouveau_bios_run_display_table(dev, 0, -2, dcb, -1); disp->irq.dcb = NULL; } @@ -828,7 +828,7 @@ nv50_display_unk20_handler(struct drm_device *dev) } script = nv50_display_script_select(dev, dcb, mc, pclk); - nouveau_bios_run_display_table(dev, dcb, script, pclk); + nouveau_bios_run_display_table(dev, script, pclk, dcb, -1); nv50_display_unk20_dp_hack(dev, dcb); @@ -895,7 +895,7 @@ nv50_display_unk40_handler(struct drm_device *dev) if (!dcb) goto ack; - nouveau_bios_run_display_table(dev, dcb, script, -pclk); + nouveau_bios_run_display_table(dev, script, -pclk, dcb, -1); nv50_display_unk40_dp_set_tmds(dev, dcb); ack: diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c index 8a2810011bda..3d5a86b98282 100644 --- a/drivers/gpu/drm/nouveau/nv50_pm.c +++ b/drivers/gpu/drm/nouveau/nv50_pm.c @@ -115,15 +115,15 @@ nv50_pm_clock_set(struct drm_device *dev, void *pre_state) BIT_M.version == 1 && BIT_M.length >= 0x0b) { script = ROM16(BIT_M.data[0x05]); if (script) - nouveau_bios_run_init_table(dev, script, NULL); + nouveau_bios_run_init_table(dev, script, NULL, -1); script = ROM16(BIT_M.data[0x07]); if (script) - nouveau_bios_run_init_table(dev, script, NULL); + nouveau_bios_run_init_table(dev, script, NULL, -1); script = ROM16(BIT_M.data[0x09]); if (script) - nouveau_bios_run_init_table(dev, script, NULL); + nouveau_bios_run_init_table(dev, script, NULL, -1); - nouveau_bios_run_init_table(dev, perflvl->memscript, NULL); + nouveau_bios_run_init_table(dev, perflvl->memscript, NULL, -1); } if (state->type == PLL_MEMORY) {