drm/nouveau/bios: allow passing in crtc to the init table parser
authorBen Skeggs <bskeggs@redhat.com>
Wed, 6 Jul 2011 11:21:42 +0000 (21:21 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 20 Sep 2011 06:05:48 +0000 (16:05 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_bios.h
drivers/gpu/drm/nouveau/nouveau_dp.c
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nv50_pm.c

index f0a77b7ce60e952aa7a7b4df4cf1430af2de6507..58d8c85b85d1f3945e5e8ca965c3f649208d368c 100644 (file)
@@ -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);
                }
        }
 
index 050c314119dff4c0eb37fb36df860031ba61397c..b28f0bceaed4470a52d918861e5cd1d5727691f5 100644 (file)
@@ -289,6 +289,7 @@ struct nvbios {
 
        struct {
                struct dcb_entry *output;
+               int crtc;
                uint16_t script_table_ptr;
                uint16_t dp_table_ptr;
        } display;
index 7beb82a0315d73ec5aae3a4848e0d92e4d4d36e6..44de23d9a437e2c256e9f15437224fb1d91b625f 100644 (file)
@@ -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 */
index 721845add9b2f0a8ca0eb85be1a373e43ea76003..6469ffee6fc032708ddaa15e92f1a499983b41fd 100644 (file)
@@ -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 *);
index 5754c0ac8937ef7f5f652a71833d4f55612a6073..8260303c2fcabe5178d2574ad390468b32326f4a 100644 (file)
@@ -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:
index 8a2810011bda5e9cd1861d03ecf3482229be20da..3d5a86b98282b6ee74b046a600fe19a6778a0e71 100644 (file)
@@ -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) {