aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_bios.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-09-19 20:06:50 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-09-24 02:27:54 -0400
commite49f70f775335ab1ee0ecd54904d2b25982a2600 (patch)
tree1cd1a9f021caccf7eaba7a736c300c2ffad2452e /drivers/gpu/drm/nouveau/nouveau_bios.c
parent07b1266962085412e85af2e7df471ec9ed0c35f5 (diff)
drm/nouveau: implement parsing of DCB 2.2 GPIO table
Found on NV3x boards, this should allow voltage modifications to work on these chipsets. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_bios.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c156
1 files changed, 63 insertions, 93 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 07171dd3c16..8d60bfdf6c7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -5762,8 +5762,14 @@ static uint16_t findstr(uint8_t *data, int n, const uint8_t *str, int len)
5762static struct dcb_gpio_entry * 5762static struct dcb_gpio_entry *
5763new_gpio_entry(struct nvbios *bios) 5763new_gpio_entry(struct nvbios *bios)
5764{ 5764{
5765 struct drm_device *dev = bios->dev;
5765 struct dcb_gpio_table *gpio = &bios->dcb.gpio; 5766 struct dcb_gpio_table *gpio = &bios->dcb.gpio;
5766 5767
5768 if (gpio->entries >= DCB_MAX_NUM_GPIO_ENTRIES) {
5769 NV_ERROR(dev, "exceeded maximum number of gpio entries!!\n");
5770 return NULL;
5771 }
5772
5767 return &gpio->entry[gpio->entries++]; 5773 return &gpio->entry[gpio->entries++];
5768} 5774}
5769 5775
@@ -5785,113 +5791,77 @@ nouveau_bios_gpio_entry(struct drm_device *dev, enum dcb_gpio_tag tag)
5785} 5791}
5786 5792
5787static void 5793static void
5788parse_dcb30_gpio_entry(struct nvbios *bios, uint16_t offset)
5789{
5790 struct dcb_gpio_entry *gpio;
5791 uint16_t ent = ROM16(bios->data[offset]);
5792 uint8_t line = ent & 0x1f,
5793 tag = ent >> 5 & 0x3f,
5794 flags = ent >> 11 & 0x1f;
5795
5796 if (tag == 0x3f)
5797 return;
5798
5799 gpio = new_gpio_entry(bios);
5800
5801 gpio->tag = tag;
5802 gpio->line = line;
5803 gpio->invert = flags != 4;
5804 gpio->entry = ent;
5805}
5806
5807static void
5808parse_dcb40_gpio_entry(struct nvbios *bios, uint16_t offset)
5809{
5810 uint32_t entry = ROM32(bios->data[offset]);
5811 struct dcb_gpio_entry *gpio;
5812
5813 if ((entry & 0x0000ff00) == 0x0000ff00)
5814 return;
5815
5816 gpio = new_gpio_entry(bios);
5817 gpio->tag = (entry & 0x0000ff00) >> 8;
5818 gpio->line = (entry & 0x0000001f) >> 0;
5819 gpio->state_default = (entry & 0x01000000) >> 24;
5820 gpio->state[0] = (entry & 0x18000000) >> 27;
5821 gpio->state[1] = (entry & 0x60000000) >> 29;
5822 gpio->entry = entry;
5823}
5824
5825static void
5826parse_dcb_gpio_table(struct nvbios *bios) 5794parse_dcb_gpio_table(struct nvbios *bios)
5827{ 5795{
5828 struct drm_device *dev = bios->dev; 5796 struct drm_device *dev = bios->dev;
5829 uint16_t gpio_table_ptr = bios->dcb.gpio_table_ptr; 5797 struct dcb_gpio_entry *e;
5830 uint8_t *gpio_table = &bios->data[gpio_table_ptr]; 5798 u8 headerlen, entries, recordlen;
5831 int header_len = gpio_table[1], 5799 u8 *dcb, *gpio = NULL, *entry;
5832 entries = gpio_table[2],
5833 entry_len = gpio_table[3];
5834 void (*parse_entry)(struct nvbios *, uint16_t) = NULL;
5835 int i; 5800 int i;
5836 5801
5837 if (bios->dcb.version >= 0x40) { 5802 dcb = ROMPTR(bios, bios->data[0x36]);
5838 if (gpio_table_ptr && entry_len != 4) { 5803 if (dcb[0] >= 0x30) {
5839 NV_WARN(dev, "Invalid DCB GPIO table entry length.\n"); 5804 gpio = ROMPTR(bios, dcb[10]);
5840 return; 5805 if (!gpio)
5841 } 5806 goto no_table;
5842
5843 parse_entry = parse_dcb40_gpio_entry;
5844
5845 } else if (bios->dcb.version >= 0x30) {
5846 if (gpio_table_ptr && entry_len != 2) {
5847 NV_WARN(dev, "Invalid DCB GPIO table entry length.\n");
5848 return;
5849 }
5850
5851 parse_entry = parse_dcb30_gpio_entry;
5852 5807
5853 } else if (bios->dcb.version >= 0x22) { 5808 headerlen = gpio[1];
5854 /* 5809 entries = gpio[2];
5855 * DCBs older than v3.0 don't really have a GPIO 5810 recordlen = gpio[3];
5856 * table, instead they keep some GPIO info at fixed 5811 } else
5857 * locations. 5812 if (dcb[0] >= 0x22) {
5858 */ 5813 gpio = ROMPTR(bios, dcb[-15]);
5859 uint16_t dcbptr = ROM16(bios->data[0x36]); 5814 if (!gpio)
5860 uint8_t *tvdac_gpio = &bios->data[dcbptr - 5]; 5815 goto no_table;
5816
5817 headerlen = 3;
5818 entries = gpio[2];
5819 recordlen = gpio[1];
5820 } else {
5821 NV_DEBUG(dev, "no/unknown gpio table on DCB 0x%02x\n", dcb[0]);
5822 goto no_table;
5823 }
5861 5824
5862 if (tvdac_gpio[0] & 1) { 5825 entry = gpio + headerlen;
5863 struct dcb_gpio_entry *gpio = new_gpio_entry(bios); 5826 for (i = 0; i < entries; i++, entry += recordlen) {
5827 e = new_gpio_entry(bios);
5828 if (!e)
5829 break;
5864 5830
5865 gpio->tag = DCB_GPIO_TVDAC0; 5831 if (gpio[0] < 0x40) {
5866 gpio->line = tvdac_gpio[1] >> 4; 5832 e->entry = ROM16(entry[0]);
5867 gpio->invert = tvdac_gpio[0] & 2; 5833 e->tag = (e->entry & 0x07e0) >> 5;
5868 } 5834 if (e->tag == 0x3f) {
5869 } else { 5835 bios->dcb.gpio.entries--;
5870 /* 5836 continue;
5871 * No systematic way to store GPIO info on pre-v2.2 5837 }
5872 * DCBs, try to match the PCI device IDs.
5873 */
5874 5838
5875 /* Apple iMac G4 NV18 */ 5839 e->line = (e->entry & 0x001f);
5876 if (nv_match_device(dev, 0x0189, 0x10de, 0x0010)) { 5840 e->invert = ((e->entry & 0xf800) >> 11) != 4;
5877 struct dcb_gpio_entry *gpio = new_gpio_entry(bios); 5841 } else {
5842 e->entry = ROM32(entry[0]);
5843 e->tag = (e->entry & 0x0000ff00) >> 8;
5844 if (e->tag == 0xff) {
5845 bios->dcb.gpio.entries--;
5846 continue;
5847 }
5878 5848
5879 gpio->tag = DCB_GPIO_TVDAC0; 5849 e->line = (e->entry & 0x0000001f) >> 0;
5880 gpio->line = 4; 5850 e->state_default = (e->entry & 0x01000000) >> 24;
5851 e->state[0] = (e->entry & 0x18000000) >> 27;
5852 e->state[1] = (e->entry & 0x60000000) >> 29;
5881 } 5853 }
5882
5883 } 5854 }
5884 5855
5885 if (!gpio_table_ptr) 5856no_table:
5886 return; 5857 /* Apple iMac G4 NV18 */
5887 5858 if (nv_match_device(dev, 0x0189, 0x10de, 0x0010)) {
5888 if (entries > DCB_MAX_NUM_GPIO_ENTRIES) { 5859 e = new_gpio_entry(bios);
5889 NV_WARN(dev, "Too many entries in the DCB GPIO table.\n"); 5860 if (e) {
5890 entries = DCB_MAX_NUM_GPIO_ENTRIES; 5861 e->tag = DCB_GPIO_TVDAC0;
5862 e->line = 4;
5863 }
5891 } 5864 }
5892
5893 for (i = 0; i < entries; i++)
5894 parse_entry(bios, gpio_table_ptr + header_len + entry_len * i);
5895} 5865}
5896 5866
5897struct dcb_connector_table_entry * 5867struct dcb_connector_table_entry *