Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/nouveau/dp: enable down-spread if vbios and sink support it

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

+20 -29
+19 -27
drivers/gpu/drm/nouveau/nouveau_dp.c
··· 160 160 return ret; 161 161 } 162 162 163 - static int 164 - auxch_rd(struct drm_encoder *encoder, int address, uint8_t *buf, int size) 165 - { 166 - struct drm_device *dev = encoder->dev; 167 - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 168 - struct nouveau_i2c_chan *auxch; 169 - int ret; 170 - 171 - auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); 172 - if (!auxch) 173 - return -ENODEV; 174 - 175 - ret = nouveau_dp_auxch(auxch, 9, address, buf, size); 176 - if (ret) 177 - return ret; 178 - 179 - return 0; 180 - } 181 - 182 163 static u32 183 164 dp_link_bw_get(struct drm_device *dev, int or, int link) 184 165 { ··· 279 298 int crtc; 280 299 int or; 281 300 int link; 282 - int enh_frame; 301 + u8 *dpcd; 283 302 int link_nr; 284 303 u32 link_bw; 285 304 u8 stat[6]; ··· 324 343 /* configure lane count on the source */ 325 344 dp_ctrl = ((1 << dp->link_nr) - 1) << 16; 326 345 sink[1] = dp->link_nr; 327 - if (dp->enh_frame) { 346 + if (dp->dpcd[2] & DP_ENHANCED_FRAME_CAP) { 328 347 dp_ctrl |= 0x00004000; 329 348 sink[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; 330 349 } ··· 486 505 const u32 *link_bw = bw_list; 487 506 struct dp_state dp; 488 507 u8 *bios, headerlen; 489 - u16 script; 490 508 491 509 auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); 492 510 if (!auxch) ··· 500 520 dp.auxch = auxch->rd; 501 521 dp.or = nv_encoder->or; 502 522 dp.link = !(nv_encoder->dcb->sorconf.link & 1); 503 - dp.enh_frame = nv_encoder->dp.enhanced_frame; 523 + dp.dpcd = nv_encoder->dp.dpcd; 504 524 505 525 /* some sinks toggle hotplug in response to some of the actions 506 526 * we take during link training (DP_SET_POWER is one), we need 507 527 * to ignore them for the moment to avoid races. 508 528 */ 509 529 pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, false); 530 + 531 + /* enable down-spreading, if possible */ 532 + if (headerlen >= 16) { 533 + u16 script = ROM16(bios[14]); 534 + if (nv_encoder->dp.dpcd[3] & 1) 535 + script = ROM16(bios[12]); 536 + 537 + nouveau_bios_run_init_table(dev, script, dp.dcb, dp.crtc); 538 + } 510 539 511 540 /* execute pre-train script from vbios */ 512 541 nouveau_bios_run_init_table(dev, ROM16(bios[6]), dp.dcb, dp.crtc); ··· 564 575 { 565 576 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 566 577 struct drm_device *dev = encoder->dev; 567 - uint8_t dpcd[4]; 578 + struct nouveau_i2c_chan *auxch; 579 + u8 *dpcd = nv_encoder->dp.dpcd; 568 580 int ret; 569 581 570 - ret = auxch_rd(encoder, 0x0000, dpcd, 4); 582 + auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); 583 + if (!auxch) 584 + return false; 585 + 586 + ret = auxch_tx(dev, auxch->rd, 9, DP_DPCD_REV, dpcd, 8); 571 587 if (ret) 572 588 return false; 573 589 574 - nv_encoder->dp.dpcd_version = dpcd[0]; 575 590 nv_encoder->dp.link_bw = 27000 * dpcd[1]; 576 591 nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK; 577 - nv_encoder->dp.enhanced_frame = dpcd[2] & DP_ENHANCED_FRAME_CAP; 578 592 579 593 NV_DEBUG_KMS(dev, "display: %dx%d dpcd 0x%02x\n", 580 594 nv_encoder->dp.link_nr, nv_encoder->dp.link_bw, dpcd[0]);
+1 -2
drivers/gpu/drm/nouveau/nouveau_encoder.h
··· 49 49 50 50 union { 51 51 struct { 52 - int dpcd_version; 52 + u8 dpcd[8]; 53 53 int link_nr; 54 54 int link_bw; 55 - bool enhanced_frame; 56 55 u32 datarate; 57 56 } dp; 58 57 };