diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-04-06 22:00:14 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-04-08 20:15:44 -0400 |
commit | 2535d71c80b3d79090c9d44ec6d35342e2d258f0 (patch) | |
tree | 9d0cc01bd721e1d3ae749fce66c2c80635b212e7 /drivers | |
parent | 2295e17a4a0c339ca8507deb2cab5f339007e5e5 (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')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bios.c | 48 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bios.h | 1 |
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 | ||
5087 | static void | 5078 | static 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 | ||
5106 | static void | 5098 | static 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 | ||
54 | struct dcb_gpio_table { | 55 | struct dcb_gpio_table { |