/* these defines are made up */ #define NV_CIO_CRE_44_HEADA 0x0 #define NV_CIO_CRE_44_HEADB 0x3 #define FEATURE_MOBILE 0x10 /* also FEATURE_QUADRO for BMP */
sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000;
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, sel_clk | sel_clk_binding); /* some scripts set a value in NV_PBUS_POWERCTRL_2 and break video overlay */
nvif_wr32(device, NV_PBUS_POWERCTRL_2, 0);
if (bios->fp.fptablepointer == 0x0) { /* Most laptop cards lack an fp table. They use DDC. */
NV_DEBUG(drm, "Pointer to flat panel table invalid\n");
bios->digital_min_front_porch = 0x4b; return0;
}
/* nv4x cards need both a strap value and fpindex of 0xf to use DDC */ if (lth.lvds_ver > 0x10)
bios->fp_no_ddc = fpstrapping != 0xf || fpindex != 0xf;
/* set dual_link flag for EDID case */ if (pxclk && (chip_version < 0x25 || chip_version > 0x28))
bios->fp.dual_link = (pxclk >= bios->fp.duallink_transition_clk);
*dl = bios->fp.dual_link;
return0;
}
int run_tmds_table(struct drm_device *dev, struct dcb_output *dcbent, int head, int pxclk)
{ /* *thepxclkparameterisinkHz * *ThisrunstheTMDSregssettingcodefoundonBITbioscards * *Forffs(or)==1usethefirsttable,forffs(or)==2and *ffs(or)==3,usethesecond.
*/
if (bit_table(dev, table->id, &bitentry) == 0)
return table->parse_fn(dev, bios, &bitentry);
NV_INFO(drm, "BIT table '%c' not found\n", table->id);
return -ENOSYS;
}
static int
parse_bit_structure(struct nvbios *bios, const uint16_t bitoffset)
{
int ret;
/*
* The only restriction on parsing order currently is having 'i' first
* for use of bios->*_version or bios->feature_byte while parsing;
* functions shouldn't be actually *doing* anything apart from pulling
* data from the image into the bios struct, thus no interdependencies
*/
ret = parse_bit_table(bios, bitoffset, &BIT_TABLE('i', i));
if (ret) /* info? */
return ret;
if (bios->major_version >= 0x60) /* g80+ */
parse_bit_table(bios, bitoffset, &BIT_TABLE('A', A));
parse_bit_table(bios, bitoffset, &BIT_TABLE('D', display));
ret = parse_bit_table(bios, bitoffset, &BIT_TABLE('I', init));
if (ret)
return ret;
parse_bit_table(bios, bitoffset, &BIT_TABLE('M', M)); /* memory? */
parse_bit_table(bios, bitoffset, &BIT_TABLE('L', lvds));
parse_bit_table(bios, bitoffset, &BIT_TABLE('T', tmds));
return 0;
}
static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsigned int offset)
{
/*
* Parses the BMP structure for useful things, but does not act on them
*
* offset + 5: BMP major version
* offset + 6: BMP minor version
* offset + 9: BMP feature byte
* offset + 10: BCD encoded BIOS version
*
* offset + 18: init script table pointer (for bios versions < 5.10h)
* offset + 20: extra init script table pointer (for bios
* versions < 5.10h)
*
* offset + 24: memory init table pointer (used on early bios versions)
* offset + 26: SDR memory sequencing setup data table
* offset + 28: DDR memory sequencing setup data table
*
* offset + 54: index of I2C CRTC pair to use for CRT output
* offset + 55: index of I2C CRTC pair to use for TV output
* offset + 56: index of I2C CRTC pair to use for flat panel output
* offset + 58: write CRTC index for I2C pair 0
* offset + 59: read CRTC index for I2C pair 0
* offset + 60: write CRTC index for I2C pair 1
* offset + 61: read CRTC index for I2C pair 1
*
* offset + 67: maximum internal PLL frequency (single stage PLL)
* offset + 71: minimum internal PLL frequency (single stage PLL)
*
* offset + 75: script table pointers, as described in
* parse_script_table_pointers
*
* offset + 89: TMDS single link output A table pointer
* offset + 91: TMDS single link output B table pointer
* offset + 95: LVDS single link output A table pointer
* offset + 105: flat panel timings table pointer
* offset + 107: flat panel strapping translation table pointer
* offset + 117: LVDS manufacturer panel config table pointer
* offset + 119: LVDS manufacturer strapping translation table pointer
*
* offset + 142: PLL limits table pointer
*
* offset + 156: minimum pixel clock for LVDS dual link
*/
/* load needed defaults in case we can't parse this info */
bios->digital_min_front_porch = 0x4b;
bios->fmaxvco = 256000;
bios->fminvco = 128000;
bios->fp.duallink_transition_clk = 90000;
NV_INFO(drm, "BMP version %d.%d\n",
bmp_version_major, bmp_version_minor);
/*
* Make sure that 0x36 is blank and can't be mistaken for a DCB
* pointer on early versions
*/
if (bmp_version_major < 5)
*(uint16_t *)&bios->data[0x36] = 0;
/*
* Seems that the minor version was 1 for all major versions prior
* to 5. Version 6 could theoretically exist, but I suspect BIT
* happened instead.
*/
if ((bmp_version_major < 5 && bmp_version_minor != 1) || bmp_version_major > 5) {
NV_ERROR(drm, "You have an unsupported BMP version. "
"Please send in your bios\n");
return -ENOSYS;
}
if (bmp_version_major == 0)
/* nothing that's currently useful in this version */
return 0;
else if (bmp_version_major == 1)
bmplength = 44; /* exact for 1.01 */
else if (bmp_version_major == 2)
bmplength = 48; /* exact for 2.01 */
else if (bmp_version_major == 3)
bmplength = 54;
/* guessed - mem init tables added in this version */
else if (bmp_version_major == 4 || bmp_version_minor < 0x1)
/* don't know if 5.0 exists... */
bmplength = 62;
/* guessed - BMP I2C indices added in version 4*/
else if (bmp_version_minor < 0x6)
bmplength = 67; /* exact for 5.01 */
else if (bmp_version_minor < 0x10)
bmplength = 75; /* exact for 5.06 */
else if (bmp_version_minor == 0x10)
bmplength = 89; /* exact for 5.10h */
else if (bmp_version_minor < 0x14)
bmplength = 118; /* exact for 5.11h */
else if (bmp_version_minor < 0x24)
/*
* Not sure of version where pll limits came in;
* certainly exist by 0x24 though.
*/
/* length not exact: this is long enough to get lvds members */
bmplength = 123;
else if (bmp_version_minor < 0x27)
/*
* Length not exact: this is long enough to get pll limit
* member
*/
bmplength = 144;
else
/*
* Length not exact: this is long enough to get dual link
* transition clock.
*/
bmplength = 158;
/*
* Bit 4 seems to indicate either a mobile bios or a quadro card --
* mobile behaviour consistent (nv11+), quadro only seen nv18gl-nv36gl
* (not nv10gl), bit 5 that the flat panel tables are present, and
* bit 6 a tv bios.
*/
bios->feature_byte = bmp[9];
if (drm->client.device.info.family > NV_DEVICE_INFO_V0_TNT)
dcb = ROMPTR(dev, drm->vbios.data[0x36]);
if (!dcb) {
NV_WARN(drm, "No DCB data found in VBIOS\n");
return NULL;
}
if (dcb[0] >= 0x42) {
NV_WARN(drm, "DCB version 0x%02x unknown\n", dcb[0]);
return NULL;
} else
if (dcb[0] >= 0x30) {
if (ROM32(dcb[6]) == 0x4edcbdcb)
return dcb;
} else
if (dcb[0] >= 0x20) {
if (ROM32(dcb[4]) == 0x4edcbdcb)
return dcb;
} else
if (dcb[0] >= 0x15) {
if (!memcmp(&dcb[-7], "DEV_REC", 7))
return dcb;
} else {
/*
* v1.4 (some NV15/16, NV11+) seems the same as v1.5, but
* always has the same single (crt) entry, even when tv-out
* present, so the conclusion is this version cannot really
* be used.
*
* v1.2 tables (some NV6/10, and NV15+) normally have the
* same 5 entries, which are not specific to the card and so
* no use.
*
* v1.2 does have an I2C table that read_dcb_i2c_table can
* handle, but cards exist (nv11 in #14821) with a bad i2c
* table pointer, so use the indices parsed in
* parse_bmp_structure.
*
* v1.1 (NV5+, maybe some NV4) is entirely unhelpful
*/
NV_WARN(drm, "No useful DCB data in VBIOS\n");
return NULL;
}
int
olddcb_outp_foreach(struct drm_device *dev, void *data,
int (*exec)(struct drm_device *, void *, int idx, u8 *outp))
{
int ret, idx = -1;
u8 *outp = NULL;
while ((outp = olddcb_outp(dev, ++idx))) {
if (ROM32(outp[0]) == 0x00000000)
break; /* seen on an NV11 with DCB v1.5 */
if (ROM32(outp[0]) == 0xffffffff)
break; /* seen on an NV17 with DCB v2.0 */
if ((outp[0] & 0x0f) == DCB_OUTPUT_UNUSED)
continue;
if ((outp[0] & 0x0f) == DCB_OUTPUT_EOL)
break;
ret = exec(dev, data, idx, outp);
if (ret)
return ret;
}
switch (entry->type) {
case DCB_OUTPUT_ANALOG:
/*
* Although the rest of a CRT conf dword is usually
* zeros, mac biosen have stuff there so we must mask
*/
entry->crtconf.maxfreq = (dcb->version < 0x30) ?
(conf & 0xffff) * 10 :
(conf & 0xff) * 10000;
break;
case DCB_OUTPUT_LVDS:
{
uint32_t mask;
if (conf & 0x1)
entry->lvdsconf.use_straps_for_mode = true;
if (dcb->version < 0x22) {
mask = ~0xd;
/*
* The laptop in bug 14567 lies and claims to not use
* straps when it does, so assume all DCB 2.0 laptops
* use straps, until a broken EDID using one is produced
*/
entry->lvdsconf.use_straps_for_mode = true;
/*
* Both 0x4 and 0x8 show up in v2.0 tables; assume they
* mean the same thing (probably wrong, but might work)
*/
if (conf & 0x4 || conf & 0x8)
entry->lvdsconf.use_power_scripts = true;
} else {
mask = ~0x7;
if (conf & 0x2)
entry->lvdsconf.use_acpi_for_edid = true;
if (conf & 0x4)
entry->lvdsconf.use_power_scripts = true;
entry->lvdsconf.sor.link = (conf & 0x00000030) >> 4;
link = entry->lvdsconf.sor.link;
}
if (conf & mask) {
/*
* Until we even try to use these on G8x, it's
* useless reporting unknown bits. They all are.
*/
if (dcb->version >= 0x40)
break;
break;
}
case DCB_OUTPUT_DP:
entry->dpconf.sor.link = (conf & 0x00000030) >> 4;
entry->extdev = (conf & 0x0000ff00) >> 8;
switch ((conf & 0x00e00000) >> 21) {
case 0:
entry->dpconf.link_bw = 162000;
break;
case 1:
entry->dpconf.link_bw = 270000;
break;
case 2:
entry->dpconf.link_bw = 540000;
break;
case 3:
default:
entry->dpconf.link_bw = 810000;
break;
}
switch ((conf & 0x0f000000) >> 24) {
case 0xf:
case 0x4:
entry->dpconf.link_nr = 4;
break;
case 0x3:
case 0x2:
entry->dpconf.link_nr = 2;
break;
default:
entry->dpconf.link_nr = 1;
break;
}
link = entry->dpconf.sor.link;
break;
case DCB_OUTPUT_TMDS:
if (dcb->version >= 0x40) {
entry->tmdsconf.sor.link = (conf & 0x00000030) >> 4;
entry->extdev = (conf & 0x0000ff00) >> 8;
link = entry->tmdsconf.sor.link;
}
else if (dcb->version >= 0x30)
entry->tmdsconf.slave_addr = (conf & 0x00000700) >> 8;
else if (dcb->version >= 0x22)
entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4;
break;
case DCB_OUTPUT_EOL:
/* weird g80 mobile type that "nv" treats as a terminator */
dcb->entries--;
return false;
default:
break;
}
if (dcb->version < 0x40) {
/* Normal entries consist of a single bit, but dual link has
* the next most significant bit set too
*/
entry->duallink_possible =
((1 << (ffs(entry->or) - 1)) * 3 == entry->or);
} else {
entry->duallink_possible = (entry->sorconf.link == 3);
}
/* unsure what DCB version introduces this, 3.0? */
if (conf & 0x100000)
entry->i2c_upper_default = true;
switch (entry->type) {
case DCB_OUTPUT_ANALOG:
entry->crtconf.maxfreq = (conf & 0xffff) * 10;
break;
case DCB_OUTPUT_TV:
entry->tvconf.has_component_output = false;
break;
case DCB_OUTPUT_LVDS:
if ((conn & 0x00003f00) >> 8 != 0x10)
entry->lvdsconf.use_straps_for_mode = true;
entry->lvdsconf.use_power_scripts = true;
break;
default:
break;
}
return true;
}
static
void merge_like_dcb_entries(struct drm_device *dev, struct dcb_table *dcb)
{
/*
* DCB v2.0 lists each output combination separately.
* Here we merge compatible entries to have fewer outputs, with
* more options
*/
struct nouveau_drm *drm = nouveau_drm(dev);
int i, newentries = 0;
for (i = 0; i < dcb->entries; i++) {
struct dcb_output *ient = &dcb->entry[i];
int j;
for (j = i + 1; j < dcb->entries; j++) {
struct dcb_output *jent = &dcb->entry[j];
if (jent->type == 100) /* already merged entry */
continue;
/* merge heads field when all other fields the same */
if (jent->i2c_index == ient->i2c_index &&
jent->type == ient->type &&
jent->location == ient->location &&
jent->or == ient->or) {
NV_INFO(drm, "Merging DCB entries %d and %d\n",
i, j);
ient->heads |= jent->heads;
jent->type = 100; /* dummy value */
}
}
}
/* Compact entries merged into others out of dcb */
for (i = 0; i < dcb->entries; i++) {
if (dcb->entry[i].type == 100)
continue;
/* Dell Precision M6300
* DCB entry 2: 0202531200000010
* DCB entry 3: 0202631200000020
*
* Identical, except apparently a different connector on a
* different SOR link. Not a clue how we're supposed to know
* which one is in use if it even shares an i2c line...
*
* Ignore the connector on the second SOR link to prevent
* nasty problems until this is sorted (assuming it's not a
* VBIOS bug).
*/
if (nv_match_device(dev, 0x040d, 0x1028, 0x019b)) {
if (*conn == 0x02026312 && *conf == 0x00000020)
return false;
}
/* GeForce3 Ti 200
*
* DCB reports an LVDS output that should be TMDS:
* DCB entry 1: f2005014 ffffffff
*/
if (nv_match_device(dev, 0x0201, 0x1462, 0x8851)) {
if (*conn == 0xf2005014 && *conf == 0xffffffff) {
fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 1, 1, DCB_OUTPUT_B);
return false;
}
}
if (dcb->version >= 0x20)
ret = parse_dcb20_entry(dev, dcb, conn, conf, entry);
else
ret = parse_dcb15_entry(dev, dcb, conn, conf, entry);
entry->id = idx;
if (!ret)
return 1; /* stop parsing */
/* Ignore the I2C index for on-chip TV-out, as there
* are cards with bogus values (nv31m in bug 23212),
* and it's otherwise useless.
*/
if (entry->type == DCB_OUTPUT_TV &&
entry->location == DCB_LOC_ON_CHIP)
entry->i2c_index = 0x0f;
}
/* heuristic: if we ever get a non-zero connector field, assume
* that all the indices are valid and we don't need fake them.
*
* and, as usual, a blacklist of boards with bad bios data..
*/
if (!nv_match_device(bios->dev, 0x0392, 0x107d, 0x20a2)) {
for (i = 0; i < dcbt->entries; i++) {
if (dcbt->entry[i].connector)
return;
}
}
/* no useful connector info available, we need to make it up
* ourselves. the rule here is: anything on the same i2c bus
* is considered to be on the same connector. any output
* without an associated i2c bus is assigned its own unique
* connector index.
*/
for (i = 0; i < dcbt->entries; i++) {
u8 i2c = dcbt->entry[i].i2c_index;
if (i2c == 0x0f) {
dcbt->entry[i].connector = idx++;
} else {
if (!map[i2c])
map[i2c] = ++idx;
dcbt->entry[i].connector = map[i2c] - 1;
}
}
/* if we created more than one connector, destroy the connector
* table - just in case it has random, rather than stub, entries.
*/
if (i > 1) {
u8 *conntab = olddcb_conntab(bios->dev);
if (conntab)
conntab[0] = 0x00;
}
}
/*
* apart for v2.1+ not being known for requiring merging, this
* guarantees dcbent->index is the index of the entry in the rom image
*/
if (dcb->version < 0x21)
merge_like_dcb_entries(dev, dcb);
/* dump connector table entries to log, if any exist */
idx = -1;
while ((conn = olddcb_conn(dev, ++idx))) {
if (conn[0] != 0xff) {
if (olddcb_conntab(dev)[3] < 4)
NV_INFO(drm, "DCB conn %02d: %04x\n",
idx, ROM16(conn[0]));
else
NV_INFO(drm, "DCB conn %02d: %08x\n",
idx, ROM32(conn[0]));
}
}
dcb_fake_connectors(bios);
return 0;
}
static int load_nv17_hwsq_ucode_entry(struct drm_device *dev, struct nvbios *bios, uint16_t hwsq_offset, int entry)
{
/*
* The header following the "HWSQ" signature has the number of entries,
* and the entry size
*
* An entry consists of a dword to write to the sequencer control reg
* (0x00001304), followed by the ucode bytes, written sequentially,
* starting at reg 0x00001400
*/
static int load_nv17_hw_sequencer_ucode(struct drm_device *dev,
struct nvbios *bios)
{
/*
* BMP based cards, from NV17, need a microcode loading to correctly
* control the GPIO etc for LVDS panels
*
* BIT based cards seem to do this directly in the init scripts
*
* The microcode entries are found by the "HWSQ" signature.
*/
static const uint8_t hwsq_signature[] = { 'H', 'W', 'S', 'Q' };
const int sz = sizeof(hwsq_signature);
int hwsq_offset;
hwsq_offset = findstr(bios->data, bios->length, hwsq_signature, sz);
if (!hwsq_offset)
return 0;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.