X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=drivers%2Fgpu%2Fdrm%2Fnouveau%2Fnouveau_bios.c;h=075eb894648f5501aa35e2b895a68ef3a75ce97d;hb=f3bbb9ccbf2a0362363ce6d7e4e57dbf34a5cef1;hp=71247da17da5cd4e820dbfe953b61f524cce52c4;hpb=988addf82e4c03739375279de73929580a2d4a6a;p=linux-beck.git diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 71247da17da5..075eb894648f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -3198,7 +3198,6 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int struct nvbios *bios = &dev_priv->vbios; unsigned int outputset = (dcbent->or == 4) ? 1 : 0; uint16_t scriptptr = 0, clktable; - uint8_t clktableptr = 0; /* * For now we assume version 3.0 table - g80 support will need some @@ -3217,26 +3216,29 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]); break; case LVDS_RESET: + clktable = bios->fp.lvdsmanufacturerpointer + 15; + if (dcbent->or == 4) + clktable += 8; + if (dcbent->lvdsconf.use_straps_for_mode) { if (bios->fp.dual_link) - clktableptr += 2; - if (bios->fp.BITbit1) - clktableptr++; + clktable += 4; + if (bios->fp.if_is_24bit) + clktable += 2; } else { /* using EDID */ - uint8_t fallback = bios->data[bios->fp.lvdsmanufacturerpointer + 4]; - int fallbackcmpval = (dcbent->or == 4) ? 4 : 1; + int cmpval_24bit = (dcbent->or == 4) ? 4 : 1; if (bios->fp.dual_link) { - clktableptr += 2; - fallbackcmpval *= 2; + clktable += 4; + cmpval_24bit <<= 1; } - if (fallbackcmpval & fallback) - clktableptr++; + + if (bios->fp.strapless_is_24bit & cmpval_24bit) + clktable += 2; } - /* adding outputset * 8 may not be correct */ - clktable = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 15 + clktableptr * 2 + outputset * 8]); + clktable = ROM16(bios->data[clktable]); if (!clktable) { NV_ERROR(dev, "Pixel clock comparison table not found\n"); return -ENOENT; @@ -3545,7 +3547,7 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b * at which modes should be set up in the dual link style. * * Following the header, the BMP (ver 0xa) table has several records, - * indexed by a seperate xlat table, indexed in turn by the fp strap in + * indexed by a separate xlat table, indexed in turn by the fp strap in * EXTDEV_BOOT. Each record had a config byte, followed by 6 script * numbers for use by INIT_SUB which controlled panel init and power, * and finally a dword of ms to sleep between power off and on @@ -3638,31 +3640,19 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b *if_is_24bit = bios->data[lvdsofs] & 16; break; case 0x30: - /* - * My money would be on there being a 24 bit interface bit in - * this table, but I have no example of a laptop bios with a - * 24 bit panel to confirm that. Hence we shout loudly if any - * bit other than bit 0 is set (I've not even seen bit 1) - */ - if (bios->data[lvdsofs] > 1) - NV_ERROR(dev, - "You have a very unusual laptop display; please report it\n"); + case 0x40: /* * No sign of the "power off for reset" or "reset for panel * on" bits, but it's safer to assume we should */ bios->fp.power_off_for_reset = true; bios->fp.reset_after_pclk_change = true; + /* * It's ok lvdsofs is wrong for nv4x edid case; dual_link is - * over-written, and BITbit1 isn't used + * over-written, and if_is_24bit isn't used */ bios->fp.dual_link = bios->data[lvdsofs] & 1; - bios->fp.BITbit1 = bios->data[lvdsofs] & 2; - bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10; - break; - case 0x40: - bios->fp.dual_link = bios->data[lvdsofs] & 1; bios->fp.if_is_24bit = bios->data[lvdsofs] & 2; bios->fp.strapless_is_24bit = bios->data[bios->fp.lvdsmanufacturerpointer + 4]; bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10; @@ -5210,6 +5200,21 @@ divine_connector_type(struct nvbios *bios, int index) return type; } +static void +apply_dcb_connector_quirks(struct nvbios *bios, int idx) +{ + struct dcb_connector_table_entry *cte = &bios->dcb.connector.entry[idx]; + struct drm_device *dev = bios->dev; + + /* Gigabyte NX85T */ + if ((dev->pdev->device == 0x0421) && + (dev->pdev->subsystem_vendor == 0x1458) && + (dev->pdev->subsystem_device == 0x344c)) { + if (cte->type == DCB_CONNECTOR_HDMI_1) + cte->type = DCB_CONNECTOR_DVI_I; + } +} + static void parse_dcb_connector_table(struct nvbios *bios) { @@ -5238,13 +5243,14 @@ parse_dcb_connector_table(struct nvbios *bios) entry = conntab + conntab[1]; cte = &ct->entry[0]; for (i = 0; i < conntab[2]; i++, entry += conntab[3], cte++) { + cte->index = i; if (conntab[3] == 2) cte->entry = ROM16(entry[0]); else cte->entry = ROM32(entry[0]); cte->type = (cte->entry & 0x000000ff) >> 0; - cte->index = (cte->entry & 0x00000f00) >> 8; + cte->index2 = (cte->entry & 0x00000f00) >> 8; switch (cte->entry & 0x00033000) { case 0x00001000: cte->gpio_tag = 0x07; @@ -5266,6 +5272,8 @@ parse_dcb_connector_table(struct nvbios *bios) if (cte->type == 0xff) continue; + apply_dcb_connector_quirks(bios, i); + NV_INFO(dev, " %d: 0x%08x: type 0x%02x idx %d tag 0x%02x\n", i, cte->entry, cte->type, cte->index, cte->gpio_tag); @@ -5287,10 +5295,16 @@ parse_dcb_connector_table(struct nvbios *bios) break; default: cte->type = divine_connector_type(bios, cte->index); - NV_WARN(dev, "unknown type, using 0x%02x", cte->type); + NV_WARN(dev, "unknown type, using 0x%02x\n", cte->type); break; } + if (nouveau_override_conntype) { + int type = divine_connector_type(bios, cte->index); + if (type != cte->type) + NV_WARN(dev, " -> type 0x%02x\n", cte->type); + } + } }