struct dcb_entry *dcb = bios->display.output;
struct drm_device *dev = bios->dev;
uint8_t cond = bios->data[offset + 1];
- uint8_t *table, headerlen;
+ uint8_t *table, *entry;
BIOSLOG(bios, "0x%04X: subop 0x%02X\n", offset, cond);
if (!iexec->execute)
return 3;
- table = nouveau_bios_dp_table(dev, dcb, &headerlen);
- if (!table) {
- NV_ERROR(dev, "0x%04X: INIT_3A: no encoder table!!\n", offset);
+ table = nouveau_dp_bios_data(dev, dcb, &entry);
+ if (!table)
return 3;
- }
switch (cond) {
case 0:
break;
case 1:
case 2:
- if (!(table[5] & cond))
+ if (!(entry[5] & cond))
iexec->execute = false;
break;
case 5:
}
}
-void *
-nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent,
- uint8_t *headerlen)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
- uint8_t *table, *entry;
- int i;
-
- if (!bios->display.dp_table_ptr) {
- NV_ERROR(dev, "No pointer to DisplayPort table\n");
- return NULL;
- }
- table = &bios->data[bios->display.dp_table_ptr];
-
- if (table[0] != 0x20 && table[0] != 0x21) {
- NV_ERROR(dev, "DisplayPort table version 0x%02x unknown\n",
- table[0]);
- return NULL;
- }
-
- entry = table + table[1];
- for (i = 0; i < table[3]; i++, entry += table[2]) {
- u8 *etable = ROMPTR(bios, entry[0]);
- if (etable && bios_encoder_match(dcbent, ROM32(etable[0]))) {
- *headerlen = table[4];
- return etable;
- }
- }
-
- NV_ERROR(dev, "DisplayPort encoder table not found\n");
- return NULL;
-}
-
int
nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
struct dcb_entry *dcbent, int crtc)
return 0;
}
-static int
-parse_bit_displayport_tbl_entry(struct drm_device *dev, struct nvbios *bios,
- struct bit_entry *bitentry)
-{
- bios->display.dp_table_ptr = ROM16(bios->data[bitentry->offset]);
- return 0;
-}
-
struct bit_table {
const char id;
int (* const parse_fn)(struct drm_device *, struct nvbios *, struct bit_entry *);
parse_bit_table(bios, bitoffset, &BIT_TABLE('L', lvds));
parse_bit_table(bios, bitoffset, &BIT_TABLE('T', tmds));
parse_bit_table(bios, bitoffset, &BIT_TABLE('U', U));
- parse_bit_table(bios, bitoffset, &BIT_TABLE('d', displayport));
return 0;
}
unk);
}
+u8 *
+nouveau_dp_bios_data(struct drm_device *dev, struct dcb_entry *dcb, u8 **entry)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nvbios *bios = &dev_priv->vbios;
+ struct bit_entry d;
+ u8 *table;
+ int i;
+
+ if (bit_table(dev, 'd', &d)) {
+ NV_ERROR(dev, "BIT 'd' table not found\n");
+ return NULL;
+ }
+
+ if (d.version != 1) {
+ NV_ERROR(dev, "BIT 'd' table version %d unknown\n", d.version);
+ return NULL;
+ }
+
+ table = ROMPTR(bios, d.data[0]);
+ if (!table) {
+ NV_ERROR(dev, "displayport table pointer invalid\n");
+ return NULL;
+ }
+
+ switch (table[0]) {
+ case 0x20:
+ case 0x21:
+ break;
+ default:
+ NV_ERROR(dev, "displayport table 0x%02x unknown\n", table[0]);
+ return NULL;
+ }
+
+ for (i = 0; i < table[3]; i++) {
+ *entry = ROMPTR(bios, table[table[1] + (i * table[2])]);
+ if (*entry && bios_encoder_match(dcb, ROM32((*entry)[0])))
+ return table;
+ }
+
+ NV_ERROR(dev, "displayport encoder table not found\n");
+ return NULL;
+}
+
/******************************************************************************
* link training
*****************************************************************************/
struct dp_state {
struct dcb_entry *dcb;
+ u8 *table;
+ u8 *entry;
int auxch;
int crtc;
int or;
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
int or = dp->or, link = dp->link;
- u8 *bios, headerlen, sink[2];
+ u8 *entry, sink[2];
u32 dp_ctrl;
NV_DEBUG_KMS(dev, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw);
* table, that has (among other things) pointers to more scripts that
* need to be executed, this time depending on link speed.
*/
- bios = nouveau_bios_dp_table(dev, dp->dcb, &headerlen);
- if (bios && (bios = ROMPTR(&dev_priv->vbios, bios[10]))) {
- while (dp->link_bw < (ROM16(bios[0]) * 10))
- bios += 4;
+ entry = ROMPTR(&dev_priv->vbios, dp->entry[10]);
+ if (entry) {
+ while (dp->link_bw < (ROM16(entry[0]) * 10))
+ entry += 4;
- nouveau_bios_run_init_table(dev, ROM16(bios[2]), dp->dcb, dp->crtc);
+ nouveau_bios_run_init_table(dev, ROM16(entry[2]), dp->dcb, dp->crtc);
}
/* configure lane count on the source */
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
u32 mask = 0, drv = 0, pre = 0, unk = 0;
- u8 *bios, *last, headerlen;
const u8 *shifts;
int link = dp->link;
int or = dp->or;
else
shifts = nvaf_lane_map;
- bios = nouveau_bios_dp_table(dev, dp->dcb, &headerlen);
- last = bios + headerlen + (bios[4] * 5);
for (i = 0; i < dp->link_nr; i++) {
u8 lane = (dp->stat[4 + (i >> 1)] >> ((i & 1) * 4)) & 0xf;
- u8 *conf = bios + headerlen;
+ u8 *conf = dp->entry + dp->table[4];
+ u8 *last = conf + (dp->entry[4] * dp->table[5]);
while (conf < last) {
if ((lane & 3) == conf[0] &&
const u32 bw_list[] = { 270000, 162000, 0 };
const u32 *link_bw = bw_list;
struct dp_state dp;
- u8 *bios, headerlen;
auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
if (!auxch)
return false;
- bios = nouveau_bios_dp_table(dev, nv_encoder->dcb, &headerlen);
- if (!bios)
+ dp.table = nouveau_dp_bios_data(dev, nv_encoder->dcb, &dp.entry);
+ if (!dp.table)
return -EINVAL;
dp.dcb = nv_encoder->dcb;
pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, false);
/* enable down-spreading, if possible */
- if (headerlen >= 16) {
- u16 script = ROM16(bios[14]);
+ if (dp.table[1] >= 16) {
+ u16 script = ROM16(dp.entry[14]);
if (nv_encoder->dp.dpcd[3] & 1)
- script = ROM16(bios[12]);
+ script = ROM16(dp.entry[12]);
nouveau_bios_run_init_table(dev, script, dp.dcb, dp.crtc);
}
/* execute pre-train script from vbios */
- nouveau_bios_run_init_table(dev, ROM16(bios[6]), dp.dcb, dp.crtc);
+ nouveau_bios_run_init_table(dev, ROM16(dp.entry[6]), dp.dcb, dp.crtc);
/* start off at highest link rate supported by encoder and display */
while (*link_bw > nv_encoder->dp.link_bw)
dp_set_training_pattern(dev, &dp, DP_TRAINING_PATTERN_DISABLE);
/* execute post-train script from vbios */
- nouveau_bios_run_init_table(dev, ROM16(bios[8]), dp.dcb, dp.crtc);
+ nouveau_bios_run_init_table(dev, ROM16(dp.entry[8]), dp.dcb, dp.crtc);
/* re-enable hotplug detect */
pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, true);