aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-08-05 00:07:04 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-09-20 02:11:18 -0400
commit5f1800bd8a774f773e3be71702da7ec77188b283 (patch)
tree00ee052cf8f838434c92a24409e5bbfb6e8c807f
parent721b0821ad8fea80ea1b6b84cb9646881959e662 (diff)
drm/nouveau/dp: return master dp table pointer too when looking up encoder
Will need to be able to distinguish 2.0/2.1 from 3.0 soon. Also, move the vbios parsing to nouveau_dp where it belongs. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c53
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dp.c79
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h3
4 files changed, 66 insertions, 70 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 73b590a71949..58b2535e3b6b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -1182,18 +1182,16 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1182 struct dcb_entry *dcb = bios->display.output; 1182 struct dcb_entry *dcb = bios->display.output;
1183 struct drm_device *dev = bios->dev; 1183 struct drm_device *dev = bios->dev;
1184 uint8_t cond = bios->data[offset + 1]; 1184 uint8_t cond = bios->data[offset + 1];
1185 uint8_t *table, headerlen; 1185 uint8_t *table, *entry;
1186 1186
1187 BIOSLOG(bios, "0x%04X: subop 0x%02X\n", offset, cond); 1187 BIOSLOG(bios, "0x%04X: subop 0x%02X\n", offset, cond);
1188 1188
1189 if (!iexec->execute) 1189 if (!iexec->execute)
1190 return 3; 1190 return 3;
1191 1191
1192 table = nouveau_bios_dp_table(dev, dcb, &headerlen); 1192 table = nouveau_dp_bios_data(dev, dcb, &entry);
1193 if (!table) { 1193 if (!table)
1194 NV_ERROR(dev, "0x%04X: INIT_3A: no encoder table!!\n", offset);
1195 return 3; 1194 return 3;
1196 }
1197 1195
1198 switch (cond) { 1196 switch (cond) {
1199 case 0: 1197 case 0:
@@ -1207,7 +1205,7 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1207 break; 1205 break;
1208 case 1: 1206 case 1:
1209 case 2: 1207 case 2:
1210 if (!(table[5] & cond)) 1208 if (!(entry[5] & cond))
1211 iexec->execute = false; 1209 iexec->execute = false;
1212 break; 1210 break;
1213 case 5: 1211 case 5:
@@ -4454,40 +4452,6 @@ bios_encoder_match(struct dcb_entry *dcb, u32 hash)
4454 } 4452 }
4455} 4453}
4456 4454
4457void *
4458nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent,
4459 uint8_t *headerlen)
4460{
4461 struct drm_nouveau_private *dev_priv = dev->dev_private;
4462 struct nvbios *bios = &dev_priv->vbios;
4463 uint8_t *table, *entry;
4464 int i;
4465
4466 if (!bios->display.dp_table_ptr) {
4467 NV_ERROR(dev, "No pointer to DisplayPort table\n");
4468 return NULL;
4469 }
4470 table = &bios->data[bios->display.dp_table_ptr];
4471
4472 if (table[0] != 0x20 && table[0] != 0x21) {
4473 NV_ERROR(dev, "DisplayPort table version 0x%02x unknown\n",
4474 table[0]);
4475 return NULL;
4476 }
4477
4478 entry = table + table[1];
4479 for (i = 0; i < table[3]; i++, entry += table[2]) {
4480 u8 *etable = ROMPTR(bios, entry[0]);
4481 if (etable && bios_encoder_match(dcbent, ROM32(etable[0]))) {
4482 *headerlen = table[4];
4483 return etable;
4484 }
4485 }
4486
4487 NV_ERROR(dev, "DisplayPort encoder table not found\n");
4488 return NULL;
4489}
4490
4491int 4455int
4492nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk, 4456nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
4493 struct dcb_entry *dcbent, int crtc) 4457 struct dcb_entry *dcbent, int crtc)
@@ -5503,14 +5467,6 @@ parse_bit_U_tbl_entry(struct drm_device *dev, struct nvbios *bios,
5503 return 0; 5467 return 0;
5504} 5468}
5505 5469
5506static int
5507parse_bit_displayport_tbl_entry(struct drm_device *dev, struct nvbios *bios,
5508 struct bit_entry *bitentry)
5509{
5510 bios->display.dp_table_ptr = ROM16(bios->data[bitentry->offset]);
5511 return 0;
5512}
5513
5514struct bit_table { 5470struct bit_table {
5515 const char id; 5471 const char id;
5516 int (* const parse_fn)(struct drm_device *, struct nvbios *, struct bit_entry *); 5472 int (* const parse_fn)(struct drm_device *, struct nvbios *, struct bit_entry *);
@@ -5584,7 +5540,6 @@ parse_bit_structure(struct nvbios *bios, const uint16_t bitoffset)
5584 parse_bit_table(bios, bitoffset, &BIT_TABLE('L', lvds)); 5540 parse_bit_table(bios, bitoffset, &BIT_TABLE('L', lvds));
5585 parse_bit_table(bios, bitoffset, &BIT_TABLE('T', tmds)); 5541 parse_bit_table(bios, bitoffset, &BIT_TABLE('T', tmds));
5586 parse_bit_table(bios, bitoffset, &BIT_TABLE('U', U)); 5542 parse_bit_table(bios, bitoffset, &BIT_TABLE('U', U));
5587 parse_bit_table(bios, bitoffset, &BIT_TABLE('d', displayport));
5588 5543
5589 return 0; 5544 return 0;
5590} 5545}
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index b28f0bceaed4..8adb69e4a6b1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -291,7 +291,6 @@ struct nvbios {
291 struct dcb_entry *output; 291 struct dcb_entry *output;
292 int crtc; 292 int crtc;
293 uint16_t script_table_ptr; 293 uint16_t script_table_ptr;
294 uint16_t dp_table_ptr;
295 } display; 294 } display;
296 295
297 struct { 296 struct {
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index d3552e766647..25ecb776c7bc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -270,11 +270,57 @@ nouveau_dp_tu_update(struct drm_device *dev, int or, int link, u32 clk, u32 bpp)
270 unk); 270 unk);
271} 271}
272 272
273u8 *
274nouveau_dp_bios_data(struct drm_device *dev, struct dcb_entry *dcb, u8 **entry)
275{
276 struct drm_nouveau_private *dev_priv = dev->dev_private;
277 struct nvbios *bios = &dev_priv->vbios;
278 struct bit_entry d;
279 u8 *table;
280 int i;
281
282 if (bit_table(dev, 'd', &d)) {
283 NV_ERROR(dev, "BIT 'd' table not found\n");
284 return NULL;
285 }
286
287 if (d.version != 1) {
288 NV_ERROR(dev, "BIT 'd' table version %d unknown\n", d.version);
289 return NULL;
290 }
291
292 table = ROMPTR(bios, d.data[0]);
293 if (!table) {
294 NV_ERROR(dev, "displayport table pointer invalid\n");
295 return NULL;
296 }
297
298 switch (table[0]) {
299 case 0x20:
300 case 0x21:
301 break;
302 default:
303 NV_ERROR(dev, "displayport table 0x%02x unknown\n", table[0]);
304 return NULL;
305 }
306
307 for (i = 0; i < table[3]; i++) {
308 *entry = ROMPTR(bios, table[table[1] + (i * table[2])]);
309 if (*entry && bios_encoder_match(dcb, ROM32((*entry)[0])))
310 return table;
311 }
312
313 NV_ERROR(dev, "displayport encoder table not found\n");
314 return NULL;
315}
316
273/****************************************************************************** 317/******************************************************************************
274 * link training 318 * link training
275 *****************************************************************************/ 319 *****************************************************************************/
276struct dp_state { 320struct dp_state {
277 struct dcb_entry *dcb; 321 struct dcb_entry *dcb;
322 u8 *table;
323 u8 *entry;
278 int auxch; 324 int auxch;
279 int crtc; 325 int crtc;
280 int or; 326 int or;
@@ -291,7 +337,7 @@ dp_set_link_config(struct drm_device *dev, struct dp_state *dp)
291{ 337{
292 struct drm_nouveau_private *dev_priv = dev->dev_private; 338 struct drm_nouveau_private *dev_priv = dev->dev_private;
293 int or = dp->or, link = dp->link; 339 int or = dp->or, link = dp->link;
294 u8 *bios, headerlen, sink[2]; 340 u8 *entry, sink[2];
295 u32 dp_ctrl; 341 u32 dp_ctrl;
296 342
297 NV_DEBUG_KMS(dev, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw); 343 NV_DEBUG_KMS(dev, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw);
@@ -312,12 +358,12 @@ dp_set_link_config(struct drm_device *dev, struct dp_state *dp)
312 * table, that has (among other things) pointers to more scripts that 358 * table, that has (among other things) pointers to more scripts that
313 * need to be executed, this time depending on link speed. 359 * need to be executed, this time depending on link speed.
314 */ 360 */
315 bios = nouveau_bios_dp_table(dev, dp->dcb, &headerlen); 361 entry = ROMPTR(&dev_priv->vbios, dp->entry[10]);
316 if (bios && (bios = ROMPTR(&dev_priv->vbios, bios[10]))) { 362 if (entry) {
317 while (dp->link_bw < (ROM16(bios[0]) * 10)) 363 while (dp->link_bw < (ROM16(entry[0]) * 10))
318 bios += 4; 364 entry += 4;
319 365
320 nouveau_bios_run_init_table(dev, ROM16(bios[2]), dp->dcb, dp->crtc); 366 nouveau_bios_run_init_table(dev, ROM16(entry[2]), dp->dcb, dp->crtc);
321 } 367 }
322 368
323 /* configure lane count on the source */ 369 /* configure lane count on the source */
@@ -357,7 +403,6 @@ dp_link_train_commit(struct drm_device *dev, struct dp_state *dp)
357{ 403{
358 struct drm_nouveau_private *dev_priv = dev->dev_private; 404 struct drm_nouveau_private *dev_priv = dev->dev_private;
359 u32 mask = 0, drv = 0, pre = 0, unk = 0; 405 u32 mask = 0, drv = 0, pre = 0, unk = 0;
360 u8 *bios, *last, headerlen;
361 const u8 *shifts; 406 const u8 *shifts;
362 int link = dp->link; 407 int link = dp->link;
363 int or = dp->or; 408 int or = dp->or;
@@ -368,11 +413,10 @@ dp_link_train_commit(struct drm_device *dev, struct dp_state *dp)
368 else 413 else
369 shifts = nvaf_lane_map; 414 shifts = nvaf_lane_map;
370 415
371 bios = nouveau_bios_dp_table(dev, dp->dcb, &headerlen);
372 last = bios + headerlen + (bios[4] * 5);
373 for (i = 0; i < dp->link_nr; i++) { 416 for (i = 0; i < dp->link_nr; i++) {
374 u8 lane = (dp->stat[4 + (i >> 1)] >> ((i & 1) * 4)) & 0xf; 417 u8 lane = (dp->stat[4 + (i >> 1)] >> ((i & 1) * 4)) & 0xf;
375 u8 *conf = bios + headerlen; 418 u8 *conf = dp->entry + dp->table[4];
419 u8 *last = conf + (dp->entry[4] * dp->table[5]);
376 420
377 while (conf < last) { 421 while (conf < last) {
378 if ((lane & 3) == conf[0] && 422 if ((lane & 3) == conf[0] &&
@@ -500,14 +544,13 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate)
500 const u32 bw_list[] = { 270000, 162000, 0 }; 544 const u32 bw_list[] = { 270000, 162000, 0 };
501 const u32 *link_bw = bw_list; 545 const u32 *link_bw = bw_list;
502 struct dp_state dp; 546 struct dp_state dp;
503 u8 *bios, headerlen;
504 547
505 auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); 548 auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
506 if (!auxch) 549 if (!auxch)
507 return false; 550 return false;
508 551
509 bios = nouveau_bios_dp_table(dev, nv_encoder->dcb, &headerlen); 552 dp.table = nouveau_dp_bios_data(dev, nv_encoder->dcb, &dp.entry);
510 if (!bios) 553 if (!dp.table)
511 return -EINVAL; 554 return -EINVAL;
512 555
513 dp.dcb = nv_encoder->dcb; 556 dp.dcb = nv_encoder->dcb;
@@ -524,16 +567,16 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate)
524 pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, false); 567 pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, false);
525 568
526 /* enable down-spreading, if possible */ 569 /* enable down-spreading, if possible */
527 if (headerlen >= 16) { 570 if (dp.table[1] >= 16) {
528 u16 script = ROM16(bios[14]); 571 u16 script = ROM16(dp.entry[14]);
529 if (nv_encoder->dp.dpcd[3] & 1) 572 if (nv_encoder->dp.dpcd[3] & 1)
530 script = ROM16(bios[12]); 573 script = ROM16(dp.entry[12]);
531 574
532 nouveau_bios_run_init_table(dev, script, dp.dcb, dp.crtc); 575 nouveau_bios_run_init_table(dev, script, dp.dcb, dp.crtc);
533 } 576 }
534 577
535 /* execute pre-train script from vbios */ 578 /* execute pre-train script from vbios */
536 nouveau_bios_run_init_table(dev, ROM16(bios[6]), dp.dcb, dp.crtc); 579 nouveau_bios_run_init_table(dev, ROM16(dp.entry[6]), dp.dcb, dp.crtc);
537 580
538 /* start off at highest link rate supported by encoder and display */ 581 /* start off at highest link rate supported by encoder and display */
539 while (*link_bw > nv_encoder->dp.link_bw) 582 while (*link_bw > nv_encoder->dp.link_bw)
@@ -567,7 +610,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate)
567 dp_set_training_pattern(dev, &dp, DP_TRAINING_PATTERN_DISABLE); 610 dp_set_training_pattern(dev, &dp, DP_TRAINING_PATTERN_DISABLE);
568 611
569 /* execute post-train script from vbios */ 612 /* execute post-train script from vbios */
570 nouveau_bios_run_init_table(dev, ROM16(bios[8]), dp.dcb, dp.crtc); 613 nouveau_bios_run_init_table(dev, ROM16(dp.entry[8]), dp.dcb, dp.crtc);
571 614
572 /* re-enable hotplug detect */ 615 /* re-enable hotplug detect */
573 pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, true); 616 pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, true);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index d269b7ba45cc..ecaa4ffbeab9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1080,8 +1080,6 @@ extern int get_pll_limits(struct drm_device *, uint32_t limit_match,
1080 struct pll_lims *); 1080 struct pll_lims *);
1081extern int nouveau_bios_run_display_table(struct drm_device *, u16 id, int clk, 1081extern int nouveau_bios_run_display_table(struct drm_device *, u16 id, int clk,
1082 struct dcb_entry *, int crtc); 1082 struct dcb_entry *, int crtc);
1083extern void *nouveau_bios_dp_table(struct drm_device *, struct dcb_entry *,
1084 u8 *headerlen);
1085extern bool nouveau_bios_fp_mode(struct drm_device *, struct drm_display_mode *); 1083extern bool nouveau_bios_fp_mode(struct drm_device *, struct drm_display_mode *);
1086extern uint8_t *nouveau_bios_embedded_edid(struct drm_device *); 1084extern uint8_t *nouveau_bios_embedded_edid(struct drm_device *);
1087extern int nouveau_bios_parse_lvds_table(struct drm_device *, int pxclk, 1085extern int nouveau_bios_parse_lvds_table(struct drm_device *, int pxclk,
@@ -1103,6 +1101,7 @@ int nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
1103bool nouveau_dp_detect(struct drm_encoder *); 1101bool nouveau_dp_detect(struct drm_encoder *);
1104bool nouveau_dp_link_train(struct drm_encoder *, u32 datarate); 1102bool nouveau_dp_link_train(struct drm_encoder *, u32 datarate);
1105void nouveau_dp_tu_update(struct drm_device *, int, int, u32, u32); 1103void nouveau_dp_tu_update(struct drm_device *, int, int, u32, u32);
1104u8 *nouveau_dp_bios_data(struct drm_device *, struct dcb_entry *, u8 **);
1106 1105
1107/* nv04_fb.c */ 1106/* nv04_fb.c */
1108extern int nv04_fb_init(struct drm_device *); 1107extern int nv04_fb_init(struct drm_device *);