aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-04-06 22:00:14 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-04-08 20:15:44 -0400
commit2535d71c80b3d79090c9d44ec6d35342e2d258f0 (patch)
tree9d0cc01bd721e1d3ae749fce66c2c80635b212e7 /drivers/gpu/drm
parent2295e17a4a0c339ca8507deb2cab5f339007e5e5 (diff)
drm/nouveau: store raw gpio table entry in bios gpio structs
And use our own version of the GPIO table for the INIT_GPIO opcode. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c48
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.h1
2 files changed, 21 insertions, 28 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index ad6c2d4520ae..84b03e0a3865 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -2573,48 +2573,38 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
2573 * each GPIO according to various values listed in each entry 2573 * each GPIO according to various values listed in each entry
2574 */ 2574 */
2575 2575
2576 struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
2576 const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; 2577 const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
2577 const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; 2578 const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
2578 const uint8_t *gpio_table = &bios->data[bios->dcb.gpio_table_ptr];
2579 const uint8_t *gpio_entry;
2580 int i; 2579 int i;
2581 2580
2582 if (!iexec->execute) 2581 if (dev_priv->card_type != NV_50) {
2583 return 1; 2582 NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n");
2584 2583 return -ENODEV;
2585 if (bios->dcb.version != 0x40) {
2586 NV_ERROR(bios->dev, "DCB table not version 4.0\n");
2587 return 0;
2588 }
2589
2590 if (!bios->dcb.gpio_table_ptr) {
2591 NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n");
2592 return 0;
2593 } 2584 }
2594 2585
2595 gpio_entry = gpio_table + gpio_table[1]; 2586 if (!iexec->execute)
2596 for (i = 0; i < gpio_table[2]; i++, gpio_entry += gpio_table[3]) { 2587 return 1;
2597 uint32_t entry = ROM32(gpio_entry[0]), r, s, v;
2598 int line = (entry & 0x0000001f);
2599 2588
2600 BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, entry); 2589 for (i = 0; i < bios->dcb.gpio.entries; i++) {
2590 struct dcb_gpio_entry *gpio = &bios->dcb.gpio.entry[i];
2591 uint32_t r, s, v;
2601 2592
2602 if ((entry & 0x0000ff00) == 0x0000ff00) 2593 BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry);
2603 continue;
2604 2594
2605 r = nv50_gpio_reg[line >> 3]; 2595 r = nv50_gpio_reg[gpio->line >> 3];
2606 s = (line & 0x07) << 2; 2596 s = (gpio->line & 0x07) << 2;
2607 v = bios_rd32(bios, r) & ~(0x00000003 << s); 2597 v = bios_rd32(bios, r) & ~(0x00000003 << s);
2608 if (entry & 0x01000000) 2598 if (gpio->entry & 0x01000000)
2609 v |= (((entry & 0x60000000) >> 29) ^ 2) << s; 2599 v |= (((gpio->entry & 0x60000000) >> 29) ^ 2) << s;
2610 else 2600 else
2611 v |= (((entry & 0x18000000) >> 27) ^ 2) << s; 2601 v |= (((gpio->entry & 0x18000000) >> 27) ^ 2) << s;
2612 bios_wr32(bios, r, v); 2602 bios_wr32(bios, r, v);
2613 2603
2614 r = nv50_gpio_ctl[line >> 4]; 2604 r = nv50_gpio_ctl[gpio->line >> 4];
2615 s = (line & 0x0f); 2605 s = (gpio->line & 0x0f);
2616 v = bios_rd32(bios, r) & ~(0x00010001 << s); 2606 v = bios_rd32(bios, r) & ~(0x00010001 << s);
2617 switch ((entry & 0x06000000) >> 25) { 2607 switch ((gpio->entry & 0x06000000) >> 25) {
2618 case 1: 2608 case 1:
2619 v |= (0x00000001 << s); 2609 v |= (0x00000001 << s);
2620 break; 2610 break;
@@ -5082,6 +5072,7 @@ parse_dcb30_gpio_entry(struct nvbios *bios, uint16_t offset)
5082 gpio->tag = tag; 5072 gpio->tag = tag;
5083 gpio->line = line; 5073 gpio->line = line;
5084 gpio->invert = flags != 4; 5074 gpio->invert = flags != 4;
5075 gpio->entry = ent;
5085} 5076}
5086 5077
5087static void 5078static void
@@ -5101,6 +5092,7 @@ parse_dcb40_gpio_entry(struct nvbios *bios, uint16_t offset)
5101 * point. */ 5092 * point. */
5102 gpio->tag = tag; 5093 gpio->tag = tag;
5103 gpio->line = line; 5094 gpio->line = line;
5095 gpio->entry = ent;
5104} 5096}
5105 5097
5106static void 5098static void
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index fd6274a90148..3706493c014d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -49,6 +49,7 @@ struct dcb_gpio_entry {
49 enum dcb_gpio_tag tag; 49 enum dcb_gpio_tag tag;
50 int line; 50 int line;
51 bool invert; 51 bool invert;
52 uint32_t entry;
52}; 53};
53 54
54struct dcb_gpio_table { 55struct dcb_gpio_table {