diff options
| -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 { | 
