aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-11-17 19:23:59 -0500
committerBen Skeggs <bskeggs@redhat.com>2011-12-21 04:01:41 -0500
commitbefb51e9c97e783c86a1da27bdda3a638d2f02c7 (patch)
tree320f1a7a6d730decc566542e49e17c1a680956c4 /drivers/gpu/drm/nouveau
parentf553b79c03f0dbd52f6f03abe8233a2bef8cbd0d (diff)
drm/nouveau/disp: parse connector info directly in nouveau_connector.c
Another case where we parsed vbios data to some structs, then again use that info once to construct another set of data. Skip the intermediate step. This is also slightly improved in that we can now use DCB 3.x connector table info, which will allow NV4x to gain hotplug support, and to make quirks for SPWG LVDS panels unnecessary. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c315
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.h19
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c216
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.h6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dp.c4
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c6
-rw-r--r--drivers/gpu/drm/nouveau/nvd0_display.c2
7 files changed, 240 insertions, 328 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 7922bb969d25..35b18f4f7c4e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -1100,13 +1100,9 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1100 1100
1101 switch (cond) { 1101 switch (cond) {
1102 case 0: 1102 case 0:
1103 { 1103 entry = dcb_conn(dev, dcb->connector);
1104 struct dcb_connector_table_entry *ent = 1104 if (!entry || entry[0] != DCB_CONNECTOR_eDP)
1105 &bios->dcb.connector.entry[dcb->connector];
1106
1107 if (ent->type != DCB_CONNECTOR_eDP)
1108 iexec->execute = false; 1105 iexec->execute = false;
1109 }
1110 break; 1106 break;
1111 case 1: 1107 case 1:
1112 case 2: 1108 case 2:
@@ -5782,164 +5778,6 @@ no_table:
5782 } 5778 }
5783} 5779}
5784 5780
5785struct dcb_connector_table_entry *
5786nouveau_bios_connector_entry(struct drm_device *dev, int index)
5787{
5788 struct drm_nouveau_private *dev_priv = dev->dev_private;
5789 struct nvbios *bios = &dev_priv->vbios;
5790 struct dcb_connector_table_entry *cte;
5791
5792 if (index >= bios->dcb.connector.entries)
5793 return NULL;
5794
5795 cte = &bios->dcb.connector.entry[index];
5796 if (cte->type == 0xff)
5797 return NULL;
5798
5799 return cte;
5800}
5801
5802static enum dcb_connector_type
5803divine_connector_type(struct nvbios *bios, int index)
5804{
5805 struct dcb_table *dcb = &bios->dcb;
5806 unsigned encoders = 0, type = DCB_CONNECTOR_NONE;
5807 int i;
5808
5809 for (i = 0; i < dcb->entries; i++) {
5810 if (dcb->entry[i].connector == index)
5811 encoders |= (1 << dcb->entry[i].type);
5812 }
5813
5814 if (encoders & (1 << OUTPUT_DP)) {
5815 if (encoders & (1 << OUTPUT_TMDS))
5816 type = DCB_CONNECTOR_DP;
5817 else
5818 type = DCB_CONNECTOR_eDP;
5819 } else
5820 if (encoders & (1 << OUTPUT_TMDS)) {
5821 if (encoders & (1 << OUTPUT_ANALOG))
5822 type = DCB_CONNECTOR_DVI_I;
5823 else
5824 type = DCB_CONNECTOR_DVI_D;
5825 } else
5826 if (encoders & (1 << OUTPUT_ANALOG)) {
5827 type = DCB_CONNECTOR_VGA;
5828 } else
5829 if (encoders & (1 << OUTPUT_LVDS)) {
5830 type = DCB_CONNECTOR_LVDS;
5831 } else
5832 if (encoders & (1 << OUTPUT_TV)) {
5833 type = DCB_CONNECTOR_TV_0;
5834 }
5835
5836 return type;
5837}
5838
5839static void
5840apply_dcb_connector_quirks(struct nvbios *bios, int idx)
5841{
5842 struct dcb_connector_table_entry *cte = &bios->dcb.connector.entry[idx];
5843 struct drm_device *dev = bios->dev;
5844
5845 /* Gigabyte NX85T */
5846 if (nv_match_device(dev, 0x0421, 0x1458, 0x344c)) {
5847 if (cte->type == DCB_CONNECTOR_HDMI_1)
5848 cte->type = DCB_CONNECTOR_DVI_I;
5849 }
5850
5851 /* Gigabyte GV-NX86T512H */
5852 if (nv_match_device(dev, 0x0402, 0x1458, 0x3455)) {
5853 if (cte->type == DCB_CONNECTOR_HDMI_1)
5854 cte->type = DCB_CONNECTOR_DVI_I;
5855 }
5856}
5857
5858static const u8 hpd_gpio[16] = {
5859 0xff, 0x07, 0x08, 0xff, 0xff, 0x51, 0x52, 0xff,
5860 0xff, 0xff, 0xff, 0xff, 0xff, 0x5e, 0x5f, 0x60,
5861};
5862
5863static void
5864parse_dcb_connector_table(struct nvbios *bios)
5865{
5866 struct drm_device *dev = bios->dev;
5867 struct dcb_connector_table *ct = &bios->dcb.connector;
5868 struct dcb_connector_table_entry *cte;
5869 uint8_t *conntab = &bios->data[bios->dcb.connector_table_ptr];
5870 uint8_t *entry;
5871 int i;
5872
5873 if (!bios->dcb.connector_table_ptr) {
5874 NV_DEBUG_KMS(dev, "No DCB connector table present\n");
5875 return;
5876 }
5877
5878 NV_INFO(dev, "DCB connector table: VHER 0x%02x %d %d %d\n",
5879 conntab[0], conntab[1], conntab[2], conntab[3]);
5880 if ((conntab[0] != 0x30 && conntab[0] != 0x40) ||
5881 (conntab[3] != 2 && conntab[3] != 4)) {
5882 NV_ERROR(dev, " Unknown! Please report.\n");
5883 return;
5884 }
5885
5886 ct->entries = conntab[2];
5887
5888 entry = conntab + conntab[1];
5889 cte = &ct->entry[0];
5890 for (i = 0; i < conntab[2]; i++, entry += conntab[3], cte++) {
5891 cte->index = i;
5892 if (conntab[3] == 2)
5893 cte->entry = ROM16(entry[0]);
5894 else
5895 cte->entry = ROM32(entry[0]);
5896
5897 cte->type = (cte->entry & 0x000000ff) >> 0;
5898 cte->index2 = (cte->entry & 0x00000f00) >> 8;
5899
5900 cte->gpio_tag = ffs((cte->entry & 0x07033000) >> 12);
5901 cte->gpio_tag = hpd_gpio[cte->gpio_tag];
5902
5903 if (cte->type == 0xff)
5904 continue;
5905
5906 apply_dcb_connector_quirks(bios, i);
5907
5908 NV_INFO(dev, " %d: 0x%08x: type 0x%02x idx %d tag 0x%02x\n",
5909 i, cte->entry, cte->type, cte->index, cte->gpio_tag);
5910
5911 /* check for known types, fallback to guessing the type
5912 * from attached encoders if we hit an unknown.
5913 */
5914 switch (cte->type) {
5915 case DCB_CONNECTOR_VGA:
5916 case DCB_CONNECTOR_TV_0:
5917 case DCB_CONNECTOR_TV_1:
5918 case DCB_CONNECTOR_TV_3:
5919 case DCB_CONNECTOR_DVI_I:
5920 case DCB_CONNECTOR_DVI_D:
5921 case DCB_CONNECTOR_LVDS:
5922 case DCB_CONNECTOR_LVDS_SPWG:
5923 case DCB_CONNECTOR_DP:
5924 case DCB_CONNECTOR_eDP:
5925 case DCB_CONNECTOR_HDMI_0:
5926 case DCB_CONNECTOR_HDMI_1:
5927 break;
5928 default:
5929 cte->type = divine_connector_type(bios, cte->index);
5930 NV_WARN(dev, "unknown type, using 0x%02x\n", cte->type);
5931 break;
5932 }
5933
5934 if (nouveau_override_conntype) {
5935 int type = divine_connector_type(bios, cte->index);
5936 if (type != cte->type)
5937 NV_WARN(dev, " -> type 0x%02x\n", cte->type);
5938 }
5939
5940 }
5941}
5942
5943void * 5781void *
5944dcb_table(struct drm_device *dev) 5782dcb_table(struct drm_device *dev)
5945{ 5783{
@@ -6043,6 +5881,27 @@ dcb_outp_foreach(struct drm_device *dev, void *data,
6043 return 0; 5881 return 0;
6044} 5882}
6045 5883
5884u8 *
5885dcb_conntab(struct drm_device *dev)
5886{
5887 u8 *dcb = dcb_table(dev);
5888 if (dcb && dcb[0] >= 0x30 && dcb[1] >= 0x16) {
5889 u8 *conntab = ROMPTR(dev, dcb[0x14]);
5890 if (conntab && conntab[0] >= 0x30 && conntab[0] <= 0x40)
5891 return conntab;
5892 }
5893 return NULL;
5894}
5895
5896u8 *
5897dcb_conn(struct drm_device *dev, u8 idx)
5898{
5899 u8 *conntab = dcb_conntab(dev);
5900 if (conntab && idx < conntab[2])
5901 return conntab + conntab[1] + (idx * conntab[3]);
5902 return NULL;
5903}
5904
6046static struct dcb_entry *new_dcb_entry(struct dcb_table *dcb) 5905static struct dcb_entry *new_dcb_entry(struct dcb_table *dcb)
6047{ 5906{
6048 struct dcb_entry *entry = &dcb->entry[dcb->entries]; 5907 struct dcb_entry *entry = &dcb->entry[dcb->entries];
@@ -6073,8 +5932,7 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
6073 entry->type = conn & 0xf; 5932 entry->type = conn & 0xf;
6074 entry->i2c_index = (conn >> 4) & 0xf; 5933 entry->i2c_index = (conn >> 4) & 0xf;
6075 entry->heads = (conn >> 8) & 0xf; 5934 entry->heads = (conn >> 8) & 0xf;
6076 if (dcb->version >= 0x40) 5935 entry->connector = (conn >> 12) & 0xf;
6077 entry->connector = (conn >> 12) & 0xf;
6078 entry->bus = (conn >> 16) & 0xf; 5936 entry->bus = (conn >> 16) & 0xf;
6079 entry->location = (conn >> 20) & 0x3; 5937 entry->location = (conn >> 20) & 0x3;
6080 entry->or = (conn >> 24) & 0xf; 5938 entry->or = (conn >> 24) & 0xf;
@@ -6433,7 +6291,7 @@ parse_dcb_entry(struct drm_device *dev, void *data, int idx, u8 *outp)
6433 if (apply_dcb_encoder_quirks(dev, idx, &conn, &conf)) { 6291 if (apply_dcb_encoder_quirks(dev, idx, &conn, &conf)) {
6434 struct dcb_entry *entry = new_dcb_entry(dcb); 6292 struct dcb_entry *entry = new_dcb_entry(dcb);
6435 6293
6436 NV_TRACEWARN(dev, "DCB entry %02d: %08x %08x\n", idx, conn, conf); 6294 NV_TRACEWARN(dev, "DCB outp %02d: %08x %08x\n", idx, conn, conf);
6437 6295
6438 if (dcb->version >= 0x20) 6296 if (dcb->version >= 0x20)
6439 ret = parse_dcb20_entry(dev, dcb, conn, conf, entry); 6297 ret = parse_dcb20_entry(dev, dcb, conn, conf, entry);
@@ -6441,16 +6299,67 @@ parse_dcb_entry(struct drm_device *dev, void *data, int idx, u8 *outp)
6441 ret = parse_dcb15_entry(dev, dcb, conn, conf, entry); 6299 ret = parse_dcb15_entry(dev, dcb, conn, conf, entry);
6442 if (!ret) 6300 if (!ret)
6443 return 1; /* stop parsing */ 6301 return 1; /* stop parsing */
6302
6303 /* Ignore the I2C index for on-chip TV-out, as there
6304 * are cards with bogus values (nv31m in bug 23212),
6305 * and it's otherwise useless.
6306 */
6307 if (entry->type == OUTPUT_TV &&
6308 entry->location == DCB_LOC_ON_CHIP)
6309 entry->i2c_index = 0x0f;
6444 } 6310 }
6445 6311
6446 return 0; 6312 return 0;
6447} 6313}
6448 6314
6315static void
6316dcb_fake_connectors(struct nvbios *bios)
6317{
6318 struct dcb_table *dcbt = &bios->dcb;
6319 u8 map[16] = { };
6320 int i, idx = 0;
6321
6322 /* heuristic: if we ever get a non-zero connector field, assume
6323 * that all the indices are valid and we don't need fake them.
6324 */
6325 for (i = 0; i < dcbt->entries; i++) {
6326 if (dcbt->entry[i].connector)
6327 return;
6328 }
6329
6330 /* no useful connector info available, we need to make it up
6331 * ourselves. the rule here is: anything on the same i2c bus
6332 * is considered to be on the same connector. any output
6333 * without an associated i2c bus is assigned its own unique
6334 * connector index.
6335 */
6336 for (i = 0; i < dcbt->entries; i++) {
6337 u8 i2c = dcbt->entry[i].i2c_index;
6338 if (i2c == 0x0f) {
6339 dcbt->entry[i].connector = idx++;
6340 } else {
6341 if (!map[i2c])
6342 map[i2c] = ++idx;
6343 dcbt->entry[i].connector = map[i2c] - 1;
6344 }
6345 }
6346
6347 /* if we created more than one connector, destroy the connector
6348 * table - just in case it has random, rather than stub, entries.
6349 */
6350 if (i > 1) {
6351 u8 *conntab = dcb_conntab(bios->dev);
6352 if (conntab)
6353 conntab[0] = 0x00;
6354 }
6355}
6356
6449static int 6357static int
6450parse_dcb_table(struct drm_device *dev, struct nvbios *bios) 6358parse_dcb_table(struct drm_device *dev, struct nvbios *bios)
6451{ 6359{
6452 struct dcb_table *dcb = &bios->dcb; 6360 struct dcb_table *dcb = &bios->dcb;
6453 u8 *dcbt; 6361 u8 *dcbt, *conn;
6362 int idx;
6454 6363
6455 dcbt = dcb_table(dev); 6364 dcbt = dcb_table(dev);
6456 if (!dcbt) { 6365 if (!dcbt) {
@@ -6466,10 +6375,8 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios)
6466 NV_TRACE(dev, "DCB version %d.%d\n", dcbt[0] >> 4, dcbt[0] & 0xf); 6375 NV_TRACE(dev, "DCB version %d.%d\n", dcbt[0] >> 4, dcbt[0] & 0xf);
6467 6376
6468 dcb->version = dcbt[0]; 6377 dcb->version = dcbt[0];
6469 if (dcb->version >= 0x30) { 6378 if (dcb->version >= 0x30)
6470 dcb->gpio_table_ptr = ROM16(dcbt[10]); 6379 dcb->gpio_table_ptr = ROM16(dcbt[10]);
6471 dcb->connector_table_ptr = ROM16(dcbt[20]);
6472 }
6473 6380
6474 dcb_outp_foreach(dev, NULL, parse_dcb_entry); 6381 dcb_outp_foreach(dev, NULL, parse_dcb_entry);
6475 6382
@@ -6483,61 +6390,21 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios)
6483 if (!dcb->entries) 6390 if (!dcb->entries)
6484 return -ENXIO; 6391 return -ENXIO;
6485 6392
6486 parse_dcb_gpio_table(bios); 6393 /* dump connector table entries to log, if any exist */
6487 parse_dcb_connector_table(bios); 6394 idx = -1;
6488 return 0; 6395 while ((conn = dcb_conn(dev, ++idx))) {
6489} 6396 if (conn[0] != 0xff) {
6490 6397 NV_TRACE(dev, "DCB conn %02d: ", idx);
6491static void 6398 if (dcb_conntab(dev)[3] < 4)
6492fixup_legacy_connector(struct nvbios *bios) 6399 printk("%04x\n", ROM16(conn[0]));
6493{ 6400 else
6494 struct dcb_table *dcb = &bios->dcb; 6401 printk("%08x\n", ROM32(conn[0]));
6495 int i, i2c, i2c_conn[DCB_MAX_NUM_I2C_ENTRIES] = { };
6496
6497 /*
6498 * DCB 3.0 also has the table in most cases, but there are some cards
6499 * where the table is filled with stub entries, and the DCB entriy
6500 * indices are all 0. We don't need the connector indices on pre-G80
6501 * chips (yet?) so limit the use to DCB 4.0 and above.
6502 */
6503 if (dcb->version >= 0x40)
6504 return;
6505
6506 dcb->connector.entries = 0;
6507
6508 /*
6509 * No known connector info before v3.0, so make it up. the rule here
6510 * is: anything on the same i2c bus is considered to be on the same
6511 * connector. any output without an associated i2c bus is assigned
6512 * its own unique connector index.
6513 */
6514 for (i = 0; i < dcb->entries; i++) {
6515 /*
6516 * Ignore the I2C index for on-chip TV-out, as there
6517 * are cards with bogus values (nv31m in bug 23212),
6518 * and it's otherwise useless.
6519 */
6520 if (dcb->entry[i].type == OUTPUT_TV &&
6521 dcb->entry[i].location == DCB_LOC_ON_CHIP)
6522 dcb->entry[i].i2c_index = 0xf;
6523 i2c = dcb->entry[i].i2c_index;
6524
6525 if (i2c_conn[i2c]) {
6526 dcb->entry[i].connector = i2c_conn[i2c] - 1;
6527 continue;
6528 } 6402 }
6529
6530 dcb->entry[i].connector = dcb->connector.entries++;
6531 if (i2c != 0xf)
6532 i2c_conn[i2c] = dcb->connector.entries;
6533 } 6403 }
6404 dcb_fake_connectors(bios);
6534 6405
6535 /* Fake the connector table as well as just connector indices */ 6406 parse_dcb_gpio_table(bios);
6536 for (i = 0; i < dcb->connector.entries; i++) { 6407 return 0;
6537 dcb->connector.entry[i].index = i;
6538 dcb->connector.entry[i].type = divine_connector_type(bios, i);
6539 dcb->connector.entry[i].gpio_tag = 0xff;
6540 }
6541} 6408}
6542 6409
6543static int load_nv17_hwsq_ucode_entry(struct drm_device *dev, struct nvbios *bios, uint16_t hwsq_offset, int entry) 6410static int load_nv17_hwsq_ucode_entry(struct drm_device *dev, struct nvbios *bios, uint16_t hwsq_offset, int entry)
@@ -6800,8 +6667,6 @@ nouveau_bios_init(struct drm_device *dev)
6800 if (ret) 6667 if (ret)
6801 return ret; 6668 return ret;
6802 6669
6803 fixup_legacy_connector(bios);
6804
6805 if (!bios->major_version) /* we don't run version 0 bios */ 6670 if (!bios->major_version) /* we don't run version 0 bios */
6806 return 0; 6671 return 0;
6807 6672
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index a0e9c2c7ae8c..481e1f23f2f1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -58,6 +58,7 @@ enum dcb_gpio_tag {
58 DCB_GPIO_TVDAC1 = 0x2d, 58 DCB_GPIO_TVDAC1 = 0x2d,
59 DCB_GPIO_PWM_FAN = 0x9, 59 DCB_GPIO_PWM_FAN = 0x9,
60 DCB_GPIO_FAN_SENSE = 0x3d, 60 DCB_GPIO_FAN_SENSE = 0x3d,
61 DCB_GPIO_UNUSED = 0xff
61}; 62};
62 63
63struct dcb_gpio_entry { 64struct dcb_gpio_entry {
@@ -89,20 +90,6 @@ enum dcb_connector_type {
89 DCB_CONNECTOR_NONE = 0xff 90 DCB_CONNECTOR_NONE = 0xff
90}; 91};
91 92
92struct dcb_connector_table_entry {
93 uint8_t index;
94 uint32_t entry;
95 enum dcb_connector_type type;
96 uint8_t index2;
97 uint8_t gpio_tag;
98 void *drm;
99};
100
101struct dcb_connector_table {
102 int entries;
103 struct dcb_connector_table_entry entry[DCB_MAX_NUM_CONNECTOR_ENTRIES];
104};
105
106enum dcb_type { 93enum dcb_type {
107 OUTPUT_ANALOG = 0, 94 OUTPUT_ANALOG = 0,
108 OUTPUT_TV = 1, 95 OUTPUT_TV = 1,
@@ -161,8 +148,6 @@ struct dcb_table {
161 148
162 uint16_t gpio_table_ptr; 149 uint16_t gpio_table_ptr;
163 struct dcb_gpio_table gpio; 150 struct dcb_gpio_table gpio;
164 uint16_t connector_table_ptr;
165 struct dcb_connector_table connector;
166}; 151};
167 152
168enum nouveau_or { 153enum nouveau_or {
@@ -333,5 +318,7 @@ void *dcb_table(struct drm_device *);
333u8 *dcb_outp(struct drm_device *, u8 idx); 318u8 *dcb_outp(struct drm_device *, u8 idx);
334int dcb_outp_foreach(struct drm_device *, void *data, 319int dcb_outp_foreach(struct drm_device *, void *data,
335 int (*)(struct drm_device *, void *, int idx, u8 *outp)); 320 int (*)(struct drm_device *, void *, int idx, u8 *outp));
321u8 *dcb_conntab(struct drm_device *);
322u8 *dcb_conn(struct drm_device *, u8 idx);
336 323
337#endif 324#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 576fb9af5d13..f6c8e1da4228 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -112,7 +112,7 @@ nouveau_connector_destroy(struct drm_connector *connector)
112 112
113 pgpio = &dev_priv->engine.gpio; 113 pgpio = &dev_priv->engine.gpio;
114 if (pgpio->irq_unregister) { 114 if (pgpio->irq_unregister) {
115 pgpio->irq_unregister(dev, nv_connector->dcb->gpio_tag, 115 pgpio->irq_unregister(dev, nv_connector->hpd,
116 nouveau_connector_hotplug, connector); 116 nouveau_connector_hotplug, connector);
117 } 117 }
118 118
@@ -218,7 +218,7 @@ nouveau_connector_set_encoder(struct drm_connector *connector,
218 connector->interlace_allowed = true; 218 connector->interlace_allowed = true;
219 } 219 }
220 220
221 if (nv_connector->dcb->type == DCB_CONNECTOR_DVI_I) { 221 if (nv_connector->type == DCB_CONNECTOR_DVI_I) {
222 drm_connector_property_set_value(connector, 222 drm_connector_property_set_value(connector,
223 dev->mode_config.dvi_i_subconnector_property, 223 dev->mode_config.dvi_i_subconnector_property,
224 nv_encoder->dcb->type == OUTPUT_TMDS ? 224 nv_encoder->dcb->type == OUTPUT_TMDS ?
@@ -401,7 +401,7 @@ nouveau_connector_force(struct drm_connector *connector)
401 struct nouveau_encoder *nv_encoder; 401 struct nouveau_encoder *nv_encoder;
402 int type; 402 int type;
403 403
404 if (nv_connector->dcb->type == DCB_CONNECTOR_DVI_I) { 404 if (nv_connector->type == DCB_CONNECTOR_DVI_I) {
405 if (connector->force == DRM_FORCE_ON_DIGITAL) 405 if (connector->force == DRM_FORCE_ON_DIGITAL)
406 type = OUTPUT_TMDS; 406 type = OUTPUT_TMDS;
407 else 407 else
@@ -675,7 +675,7 @@ nouveau_connector_detect_depth(struct drm_connector *connector)
675 * know which if_is_24bit flag to check... 675 * know which if_is_24bit flag to check...
676 */ 676 */
677 if (nv_connector->edid && 677 if (nv_connector->edid &&
678 nv_connector->dcb->type == DCB_CONNECTOR_LVDS_SPWG) 678 nv_connector->type == DCB_CONNECTOR_LVDS_SPWG)
679 duallink = ((u8 *)nv_connector->edid)[121] == 2; 679 duallink = ((u8 *)nv_connector->edid)[121] == 2;
680 else 680 else
681 duallink = mode->clock >= bios->fp.duallink_transition_clk; 681 duallink = mode->clock >= bios->fp.duallink_transition_clk;
@@ -738,9 +738,9 @@ nouveau_connector_get_modes(struct drm_connector *connector)
738 if (nv_encoder->dcb->type == OUTPUT_TV) 738 if (nv_encoder->dcb->type == OUTPUT_TV)
739 ret = get_slave_funcs(encoder)->get_modes(encoder, connector); 739 ret = get_slave_funcs(encoder)->get_modes(encoder, connector);
740 740
741 if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS || 741 if (nv_connector->type == DCB_CONNECTOR_LVDS ||
742 nv_connector->dcb->type == DCB_CONNECTOR_LVDS_SPWG || 742 nv_connector->type == DCB_CONNECTOR_LVDS_SPWG ||
743 nv_connector->dcb->type == DCB_CONNECTOR_eDP) 743 nv_connector->type == DCB_CONNECTOR_eDP)
744 ret += nouveau_connector_scaler_modes_add(connector); 744 ret += nouveau_connector_scaler_modes_add(connector);
745 745
746 return ret; 746 return ret;
@@ -857,6 +857,29 @@ nouveau_connector_funcs_lvds = {
857 .force = nouveau_connector_force 857 .force = nouveau_connector_force
858}; 858};
859 859
860static int
861drm_conntype_from_dcb(enum dcb_connector_type dcb)
862{
863 switch (dcb) {
864 case DCB_CONNECTOR_VGA : return DRM_MODE_CONNECTOR_VGA;
865 case DCB_CONNECTOR_TV_0 :
866 case DCB_CONNECTOR_TV_1 :
867 case DCB_CONNECTOR_TV_3 : return DRM_MODE_CONNECTOR_TV;
868 case DCB_CONNECTOR_DVI_I : return DRM_MODE_CONNECTOR_DVII;
869 case DCB_CONNECTOR_DVI_D : return DRM_MODE_CONNECTOR_DVID;
870 case DCB_CONNECTOR_LVDS :
871 case DCB_CONNECTOR_LVDS_SPWG: return DRM_MODE_CONNECTOR_LVDS;
872 case DCB_CONNECTOR_DP : return DRM_MODE_CONNECTOR_DisplayPort;
873 case DCB_CONNECTOR_eDP : return DRM_MODE_CONNECTOR_eDP;
874 case DCB_CONNECTOR_HDMI_0 :
875 case DCB_CONNECTOR_HDMI_1 : return DRM_MODE_CONNECTOR_HDMIA;
876 default:
877 break;
878 }
879
880 return DRM_MODE_CONNECTOR_Unknown;
881}
882
860struct drm_connector * 883struct drm_connector *
861nouveau_connector_create(struct drm_device *dev, int index) 884nouveau_connector_create(struct drm_device *dev, int index)
862{ 885{
@@ -865,90 +888,133 @@ nouveau_connector_create(struct drm_device *dev, int index)
865 struct nouveau_display_engine *disp = &dev_priv->engine.display; 888 struct nouveau_display_engine *disp = &dev_priv->engine.display;
866 struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; 889 struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
867 struct nouveau_connector *nv_connector = NULL; 890 struct nouveau_connector *nv_connector = NULL;
868 struct dcb_connector_table_entry *dcb = NULL;
869 struct drm_connector *connector; 891 struct drm_connector *connector;
870 int type, ret = 0; 892 int type, ret = 0;
893 bool dummy;
871 894
872 NV_DEBUG_KMS(dev, "\n"); 895 NV_DEBUG_KMS(dev, "\n");
873 896
874 if (index >= dev_priv->vbios.dcb.connector.entries) 897 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
875 return ERR_PTR(-EINVAL); 898 nv_connector = nouveau_connector(connector);
876 899 if (nv_connector->index == index)
877 dcb = &dev_priv->vbios.dcb.connector.entry[index]; 900 return connector;
878 if (dcb->drm)
879 return dcb->drm;
880
881 switch (dcb->type) {
882 case DCB_CONNECTOR_VGA:
883 type = DRM_MODE_CONNECTOR_VGA;
884 break;
885 case DCB_CONNECTOR_TV_0:
886 case DCB_CONNECTOR_TV_1:
887 case DCB_CONNECTOR_TV_3:
888 type = DRM_MODE_CONNECTOR_TV;
889 break;
890 case DCB_CONNECTOR_DVI_I:
891 type = DRM_MODE_CONNECTOR_DVII;
892 break;
893 case DCB_CONNECTOR_DVI_D:
894 type = DRM_MODE_CONNECTOR_DVID;
895 break;
896 case DCB_CONNECTOR_HDMI_0:
897 case DCB_CONNECTOR_HDMI_1:
898 type = DRM_MODE_CONNECTOR_HDMIA;
899 break;
900 case DCB_CONNECTOR_LVDS:
901 case DCB_CONNECTOR_LVDS_SPWG:
902 type = DRM_MODE_CONNECTOR_LVDS;
903 funcs = &nouveau_connector_funcs_lvds;
904 break;
905 case DCB_CONNECTOR_DP:
906 type = DRM_MODE_CONNECTOR_DisplayPort;
907 break;
908 case DCB_CONNECTOR_eDP:
909 type = DRM_MODE_CONNECTOR_eDP;
910 break;
911 default:
912 NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type);
913 return ERR_PTR(-EINVAL);
914 } 901 }
915 902
916 nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); 903 nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
917 if (!nv_connector) 904 if (!nv_connector)
918 return ERR_PTR(-ENOMEM); 905 return ERR_PTR(-ENOMEM);
919 nv_connector->dcb = dcb; 906
920 connector = &nv_connector->base; 907 connector = &nv_connector->base;
908 nv_connector->index = index;
909
910 /* attempt to parse vbios connector type and hotplug gpio */
911 nv_connector->dcb = dcb_conn(dev, index);
912 if (nv_connector->dcb) {
913 static const u8 hpd[16] = {
914 0xff, 0x07, 0x08, 0xff, 0xff, 0x51, 0x52, 0xff,
915 0xff, 0xff, 0xff, 0xff, 0xff, 0x5e, 0x5f, 0x60,
916 };
917
918 u32 entry = ROM16(nv_connector->dcb[0]);
919 if (dcb_conntab(dev)[3] >= 4)
920 entry |= (u32)ROM16(nv_connector->dcb[2]) << 16;
921
922 nv_connector->hpd = ffs((entry & 0x07033000) >> 12);
923 nv_connector->hpd = hpd[nv_connector->hpd];
924
925 nv_connector->type = nv_connector->dcb[0];
926 if (drm_conntype_from_dcb(nv_connector->type) ==
927 DRM_MODE_CONNECTOR_Unknown) {
928 NV_WARN(dev, "unknown connector type %02x\n",
929 nv_connector->type);
930 nv_connector->type = DCB_CONNECTOR_NONE;
931 }
921 932
922 /* defaults, will get overridden in detect() */ 933 /* Gigabyte NX85T */
923 connector->interlace_allowed = false; 934 if (nv_match_device(dev, 0x0421, 0x1458, 0x344c)) {
924 connector->doublescan_allowed = false; 935 if (nv_connector->type == DCB_CONNECTOR_HDMI_1)
936 nv_connector->type = DCB_CONNECTOR_DVI_I;
937 }
925 938
926 drm_connector_init(dev, connector, funcs, type); 939 /* Gigabyte GV-NX86T512H */
927 drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); 940 if (nv_match_device(dev, 0x0402, 0x1458, 0x3455)) {
941 if (nv_connector->type == DCB_CONNECTOR_HDMI_1)
942 nv_connector->type = DCB_CONNECTOR_DVI_I;
943 }
944 } else {
945 nv_connector->type = DCB_CONNECTOR_NONE;
946 nv_connector->hpd = DCB_GPIO_UNUSED;
947 }
948
949 /* no vbios data, or an unknown dcb connector type - attempt to
950 * figure out something suitable ourselves
951 */
952 if (nv_connector->type == DCB_CONNECTOR_NONE) {
953 struct drm_nouveau_private *dev_priv = dev->dev_private;
954 struct dcb_table *dcbt = &dev_priv->vbios.dcb;
955 u32 encoders = 0;
956 int i;
957
958 for (i = 0; i < dcbt->entries; i++) {
959 if (dcbt->entry[i].connector == nv_connector->index)
960 encoders |= (1 << dcbt->entry[i].type);
961 }
928 962
929 /* parse lvds table now, we depend on bios->fp.* values later */ 963 if (encoders & (1 << OUTPUT_DP)) {
930 if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { 964 if (encoders & (1 << OUTPUT_TMDS))
931 bool dummy, is_24bit = false; 965 nv_connector->type = DCB_CONNECTOR_DP;
966 else
967 nv_connector->type = DCB_CONNECTOR_eDP;
968 } else
969 if (encoders & (1 << OUTPUT_TMDS)) {
970 if (encoders & (1 << OUTPUT_ANALOG))
971 nv_connector->type = DCB_CONNECTOR_DVI_I;
972 else
973 nv_connector->type = DCB_CONNECTOR_DVI_D;
974 } else
975 if (encoders & (1 << OUTPUT_ANALOG)) {
976 nv_connector->type = DCB_CONNECTOR_VGA;
977 } else
978 if (encoders & (1 << OUTPUT_LVDS)) {
979 nv_connector->type = DCB_CONNECTOR_LVDS;
980 } else
981 if (encoders & (1 << OUTPUT_TV)) {
982 nv_connector->type = DCB_CONNECTOR_TV_0;
983 }
984 }
932 985
933 ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &is_24bit); 986 type = drm_conntype_from_dcb(nv_connector->type);
987 if (type == DRM_MODE_CONNECTOR_LVDS) {
988 ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &dummy);
934 if (ret) { 989 if (ret) {
935 NV_ERROR(dev, "Error parsing LVDS table, disabling " 990 NV_ERROR(dev, "Error parsing LVDS table, disabling\n");
936 "LVDS\n"); 991 kfree(nv_connector);
937 goto fail; 992 return ERR_PTR(ret);
938 } 993 }
994
995 funcs = &nouveau_connector_funcs_lvds;
996 } else {
997 funcs = &nouveau_connector_funcs;
939 } 998 }
940 999
1000 /* defaults, will get overridden in detect() */
1001 connector->interlace_allowed = false;
1002 connector->doublescan_allowed = false;
1003
1004 drm_connector_init(dev, connector, funcs, type);
1005 drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
1006
941 /* Init DVI-I specific properties */ 1007 /* Init DVI-I specific properties */
942 if (dcb->type == DCB_CONNECTOR_DVI_I) 1008 if (nv_connector->type == DCB_CONNECTOR_DVI_I)
943 drm_connector_attach_property(connector, dev->mode_config.dvi_i_subconnector_property, 0); 1009 drm_connector_attach_property(connector, dev->mode_config.dvi_i_subconnector_property, 0);
944 1010
945 /* Add overscan compensation options to digital outputs */ 1011 /* Add overscan compensation options to digital outputs */
946 if (disp->underscan_property && 1012 if (disp->underscan_property &&
947 (dcb->type == DCB_CONNECTOR_DVI_D || 1013 (nv_connector->type == DCB_CONNECTOR_DVI_D ||
948 dcb->type == DCB_CONNECTOR_DVI_I || 1014 nv_connector->type == DCB_CONNECTOR_DVI_I ||
949 dcb->type == DCB_CONNECTOR_HDMI_0 || 1015 nv_connector->type == DCB_CONNECTOR_HDMI_0 ||
950 dcb->type == DCB_CONNECTOR_HDMI_1 || 1016 nv_connector->type == DCB_CONNECTOR_HDMI_1 ||
951 dcb->type == DCB_CONNECTOR_DP)) { 1017 nv_connector->type == DCB_CONNECTOR_DP)) {
952 drm_connector_attach_property(connector, 1018 drm_connector_attach_property(connector,
953 disp->underscan_property, 1019 disp->underscan_property,
954 UNDERSCAN_OFF); 1020 UNDERSCAN_OFF);
@@ -960,7 +1026,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
960 0); 1026 0);
961 } 1027 }
962 1028
963 switch (dcb->type) { 1029 switch (nv_connector->type) {
964 case DCB_CONNECTOR_VGA: 1030 case DCB_CONNECTOR_VGA:
965 if (dev_priv->card_type >= NV_50) { 1031 if (dev_priv->card_type >= NV_50) {
966 drm_connector_attach_property(connector, 1032 drm_connector_attach_property(connector,
@@ -994,8 +1060,8 @@ nouveau_connector_create(struct drm_device *dev, int index)
994 break; 1060 break;
995 } 1061 }
996 1062
997 if (nv_connector->dcb->gpio_tag != 0xff && pgpio->irq_register) { 1063 if (nv_connector->hpd != DCB_GPIO_UNUSED && pgpio->irq_register) {
998 pgpio->irq_register(dev, nv_connector->dcb->gpio_tag, 1064 pgpio->irq_register(dev, nv_connector->hpd,
999 nouveau_connector_hotplug, connector); 1065 nouveau_connector_hotplug, connector);
1000 1066
1001 connector->polled = DRM_CONNECTOR_POLL_HPD; 1067 connector->polled = DRM_CONNECTOR_POLL_HPD;
@@ -1004,15 +1070,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
1004 } 1070 }
1005 1071
1006 drm_sysfs_connector_add(connector); 1072 drm_sysfs_connector_add(connector);
1007 1073 return connector;
1008 dcb->drm = connector;
1009 return dcb->drm;
1010
1011fail:
1012 drm_connector_cleanup(connector);
1013 kfree(connector);
1014 return ERR_PTR(ret);
1015
1016} 1074}
1017 1075
1018static void 1076static void
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h
index 6468f5e67ccf..e4857021304c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -56,8 +56,10 @@ enum nouveau_dithering_depth {
56 56
57struct nouveau_connector { 57struct nouveau_connector {
58 struct drm_connector base; 58 struct drm_connector base;
59 59 enum dcb_connector_type type;
60 struct dcb_connector_table_entry *dcb; 60 u8 index;
61 u8 *dcb;
62 u8 hpd;
61 63
62 int dithering_mode; 64 int dithering_mode;
63 int dithering_depth; 65 int dithering_depth;
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index 07bac3602453..02b00c827da3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -587,7 +587,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate)
587 * we take during link training (DP_SET_POWER is one), we need 587 * we take during link training (DP_SET_POWER is one), we need
588 * to ignore them for the moment to avoid races. 588 * to ignore them for the moment to avoid races.
589 */ 589 */
590 pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, false); 590 pgpio->irq_enable(dev, nv_connector->hpd, false);
591 591
592 /* enable down-spreading, if possible */ 592 /* enable down-spreading, if possible */
593 if (dp.table[1] >= 16) { 593 if (dp.table[1] >= 16) {
@@ -636,7 +636,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate)
636 nouveau_bios_run_init_table(dev, ROM16(dp.entry[8]), dp.dcb, dp.crtc); 636 nouveau_bios_run_init_table(dev, ROM16(dp.entry[8]), dp.dcb, dp.crtc);
637 637
638 /* re-enable hotplug detect */ 638 /* re-enable hotplug detect */
639 pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, true); 639 pgpio->irq_enable(dev, nv_connector->hpd, true);
640 return true; 640 return true;
641} 641}
642 642
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index a3d28a1e8bb2..9708b94a0a7b 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -241,10 +241,10 @@ nv50_display_init(struct drm_device *dev)
241 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 241 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
242 struct nouveau_connector *conn = nouveau_connector(connector); 242 struct nouveau_connector *conn = nouveau_connector(connector);
243 243
244 if (conn->dcb->gpio_tag == 0xff) 244 if (conn->hpd == DCB_GPIO_UNUSED)
245 continue; 245 continue;
246 246
247 pgpio->irq_enable(dev, conn->dcb->gpio_tag, true); 247 pgpio->irq_enable(dev, conn->hpd, true);
248 } 248 }
249 249
250 ret = nv50_evo_init(dev); 250 ret = nv50_evo_init(dev);
@@ -581,7 +581,7 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb,
581 } else { 581 } else {
582 /* determine number of lvds links */ 582 /* determine number of lvds links */
583 if (nv_connector && nv_connector->edid && 583 if (nv_connector && nv_connector->edid &&
584 nv_connector->dcb->type == DCB_CONNECTOR_LVDS_SPWG) { 584 nv_connector->type == DCB_CONNECTOR_LVDS_SPWG) {
585 /* http://www.spwg.org */ 585 /* http://www.spwg.org */
586 if (((u8 *)nv_connector->edid)[121] == 2) 586 if (((u8 *)nv_connector->edid)[121] == 2)
587 script |= 0x0100; 587 script |= 0x0100;
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c
index 89a31851e83a..d2ba2f07400b 100644
--- a/drivers/gpu/drm/nouveau/nvd0_display.c
+++ b/drivers/gpu/drm/nouveau/nvd0_display.c
@@ -1285,7 +1285,7 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
1285 if (bios->fp.if_is_24bit) 1285 if (bios->fp.if_is_24bit)
1286 or_config |= 0x0200; 1286 or_config |= 0x0200;
1287 } else { 1287 } else {
1288 if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS_SPWG) { 1288 if (nv_connector->type == DCB_CONNECTOR_LVDS_SPWG) {
1289 if (((u8 *)nv_connector->edid)[121] == 2) 1289 if (((u8 *)nv_connector->edid)[121] == 2)
1290 or_config |= 0x0100; 1290 or_config |= 0x0100;
1291 } else 1291 } else