NV50: Use bios table for load pattern when possible.
authorMaarten Maathuis <madman2003@gmail.com>
Mon, 21 Jul 2008 12:50:07 +0000 (14:50 +0200)
committerMaarten Maathuis <madman2003@gmail.com>
Mon, 21 Jul 2008 12:50:07 +0000 (14:50 +0200)
linux-core/nouveau_bios.c
linux-core/nv50_connector.c
linux-core/nv50_dac.c

index 3e7fe23..370d652 100644 (file)
@@ -128,6 +128,39 @@ struct bit_entry {
        uint16_t offset;
 };
 
+static int parse_bit_A_tbl_entry(struct drm_device *dev, struct bios *bios, struct bit_entry *bitentry)
+{
+       /* Parses the load detect value table.
+        *
+        * Starting at bitentry->offset:
+        *
+        * offset + 0 (16 bits): table pointer
+        */
+
+       uint16_t load_table_pointer;
+
+       if (bitentry->length != 3) {
+               DRM_ERROR("Do not understand BIT loadval table\n");
+               return 0;
+       }
+
+       load_table_pointer = le16_to_cpu(*((uint16_t *)(&bios->data[bitentry->offset])));
+
+       if (load_table_pointer == 0x0) {
+               DRM_ERROR("Pointer to loadval table invalid\n");
+               return 0;
+       }
+
+       /* Some kind of signature */
+       if (bios->data[load_table_pointer] != 16 || bios->data[load_table_pointer + 1] != 4 || 
+               bios->data[load_table_pointer + 2] != 4 || bios->data[load_table_pointer + 3] != 2)
+               return 0;
+
+       bios->dactestval = le32_to_cpu(*((uint32_t *)&bios->data[load_table_pointer + 4])) & 0x3FF;
+
+       return 1;
+}
+
 static int parse_bit_C_tbl_entry(struct drm_device *dev, struct bios *bios, struct bit_entry *bitentry)
 {
        /* offset + 8  (16 bits): PLL limits table pointer
@@ -136,7 +169,7 @@ static int parse_bit_C_tbl_entry(struct drm_device *dev, struct bios *bios, stru
         */
 
        if (bitentry->length < 10) {
-               DRM_ERROR( "Do not understand BIT C table\n");
+               DRM_ERROR("Do not understand BIT C table\n");
                return 0;
        }
 
@@ -149,7 +182,7 @@ static void parse_bit_structure(struct drm_device *dev, struct bios *bios, const
 {
        int entries = bios->data[bitoffset + 4];
        /* parse i first, I next (which needs C & M before it), and L before D */
-       char parseorder[] = "iCMILDT";
+       char parseorder[] = "iCMILDTA";
        struct bit_entry bitentry;
        int i, j, offset;
 
@@ -164,6 +197,9 @@ static void parse_bit_structure(struct drm_device *dev, struct bios *bios, const
                                continue;
 
                        switch (bitentry.id[0]) {
+                       case 'A':
+                               parse_bit_A_tbl_entry(dev, bios, &bitentry);
+                               break;
                        case 'C':
                                parse_bit_C_tbl_entry(dev, bios, &bitentry);
                                break;
index 6e5fb91..34706ba 100644 (file)
@@ -79,7 +79,6 @@ static struct nv50_output *nv50_connector_to_output(struct nv50_connector *conne
 static int nv50_connector_hpd_detect(struct nv50_connector *connector)
 {
        struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
-       struct nv50_output *output = NULL;
        bool present = 0;
        uint32_t reg = 0;
 
index 3f00716..5dddb46 100644 (file)
@@ -146,7 +146,14 @@ static int nv50_dac_detect(struct nv50_output *output)
        NV_WRITE(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or), 0x00150000 | NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_PENDING);
        while (NV_READ(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or)) & NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_PENDING);
 
-       load_pattern = 340; /* TODO: use a bios table for this */
+       /* Use bios provided value if possible. */
+       if (dev_priv->bios.dactestval) {
+               load_pattern = dev_priv->bios.dactestval;
+               NV50_DEBUG("Using bios provided load_pattern of %d\n", load_pattern);
+       } else {
+               load_pattern = 340;
+               NV50_DEBUG("Using default load_pattern of %d\n", load_pattern);
+       }
 
        NV_WRITE(NV50_PDISPLAY_DAC_REGS_LOAD_CTRL(or), NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_ACTIVE | load_pattern);
        udelay(10000); /* give it some time to process */