switch (table[0]) {
case 0x20:
case 0x21:
+ case 0x30:
break;
default:
NV_ERROR(dev, "displayport table 0x%02x unknown\n", table[0]);
int or = dp->or, link = dp->link;
u8 *entry, sink[2];
u32 dp_ctrl;
+ u16 script;
NV_DEBUG_KMS(dev, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw);
*/
entry = ROMPTR(&dev_priv->vbios, dp->entry[10]);
if (entry) {
- while (dp->link_bw < (ROM16(entry[0]) * 10))
- entry += 4;
+ if (dp->table[0] < 0x30) {
+ while (dp->link_bw < (ROM16(entry[0]) * 10))
+ entry += 4;
+ script = ROM16(entry[2]);
+ } else {
+ while (dp->link_bw < (entry[0] * 27000))
+ entry += 3;
+ script = ROM16(entry[1]);
+ }
- nouveau_bios_run_init_table(dev, ROM16(entry[2]), dp->dcb, dp->crtc);
+ nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc);
}
/* configure lane count on the source */
shifts = nvaf_lane_map;
for (i = 0; i < dp->link_nr; i++) {
- u8 lane = (dp->stat[4 + (i >> 1)] >> ((i & 1) * 4)) & 0xf;
u8 *conf = dp->entry + dp->table[4];
- u8 *last = conf + (dp->entry[4] * dp->table[5]);
-
- while (conf < last) {
- if ((lane & 3) == conf[0] &&
- (lane >> 2) == conf[1])
- break;
- conf += 5;
- }
+ u8 lane = (dp->stat[4 + (i >> 1)] >> ((i & 1) * 4)) & 0xf;
+ u8 lpre = (lane & 0x0c) >> 2;
+ u8 lvsw = (lane & 0x03) >> 0;
- if (conf == last)
- return -EINVAL;
+ mask |= 0xff << shifts[i];
+ unk |= 1 << (shifts[i] >> 3);
- dp->conf[i] = (conf[1] << 3) | conf[0];
- if (conf[0] == DP_TRAIN_VOLTAGE_SWING_1200)
+ dp->conf[i] = (lpre << 3) | lvsw;
+ if (lvsw == DP_TRAIN_VOLTAGE_SWING_1200)
dp->conf[i] |= DP_TRAIN_MAX_SWING_REACHED;
- if (conf[1] == DP_TRAIN_PRE_EMPHASIS_9_5)
+ if (lpre == DP_TRAIN_PRE_EMPHASIS_9_5)
dp->conf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
NV_DEBUG_KMS(dev, "config lane %d %02x\n", i, dp->conf[i]);
- mask |= 0xff << shifts[i];
- drv |= conf[2] << shifts[i];
- pre |= conf[3] << shifts[i];
- unk = (unk & ~0x0000ff00) | (conf[4] << 8);
- unk |= 1 << (shifts[i] >> 3);
+ if (dp->table[0] < 0x30) {
+ u8 *last = conf + (dp->entry[4] * dp->table[5]);
+ while (lvsw != conf[0] || lpre != conf[1]) {
+ conf += dp->table[5];
+ if (conf >= last)
+ return -EINVAL;
+ }
+
+ conf += 2;
+ } else {
+ /* no lookup table anymore, set entries for each
+ * combination of voltage swing and pre-emphasis
+ * level allowed by the DP spec.
+ */
+ switch (lvsw) {
+ case 0: lpre += 0; break;
+ case 1: lpre += 4; break;
+ case 2: lpre += 7; break;
+ case 3: lpre += 9; break;
+ }
+
+ conf = conf + (lpre * dp->table[5]);
+ conf++;
+ }
+
+ drv |= conf[0] << shifts[i];
+ pre |= conf[1] << shifts[i];
+ unk = (unk & ~0x0000ff00) | (conf[2] << 8);
}
nv_mask(dev, NV50_SOR_DP_UNK118(or, link), mask, drv);