aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-12-06 22:46:52 -0500
committerBen Skeggs <bskeggs@redhat.com>2012-12-23 07:59:28 -0500
commit1ed731668d011d0ee894d949b80dc3d11fc9ef75 (patch)
treeca86937798de45c34cecbf1d5d478c95d560a476 /drivers/gpu
parentd2bcea686f21e11415828fcca21a4eb200c6251f (diff)
drm/nouveau/bios: implement opcode 0xa9
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/gpio.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/init.c47
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c5
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c5
5 files changed, 53 insertions, 8 deletions
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h b/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h
index 9ea2b12cc15..b75e8f18e52 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h
@@ -11,7 +11,7 @@ struct nouveau_gpio {
11 struct nouveau_subdev base; 11 struct nouveau_subdev base;
12 12
13 /* hardware interfaces */ 13 /* hardware interfaces */
14 void (*reset)(struct nouveau_gpio *); 14 void (*reset)(struct nouveau_gpio *, u8 func);
15 int (*drive)(struct nouveau_gpio *, int line, int dir, int out); 15 int (*drive)(struct nouveau_gpio *, int line, int dir, int out);
16 int (*sense)(struct nouveau_gpio *, int line); 16 int (*sense)(struct nouveau_gpio *, int line);
17 void (*irq_enable)(struct nouveau_gpio *, int line, bool); 17 void (*irq_enable)(struct nouveau_gpio *, int line, bool);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
index ae168bbb86d..98f78cf318b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
@@ -2,11 +2,12 @@
2#include <core/device.h> 2#include <core/device.h>
3 3
4#include <subdev/bios.h> 4#include <subdev/bios.h>
5#include <subdev/bios/conn.h>
6#include <subdev/bios/bmp.h> 5#include <subdev/bios/bmp.h>
7#include <subdev/bios/bit.h> 6#include <subdev/bios/bit.h>
7#include <subdev/bios/conn.h>
8#include <subdev/bios/dcb.h> 8#include <subdev/bios/dcb.h>
9#include <subdev/bios/dp.h> 9#include <subdev/bios/dp.h>
10#include <subdev/bios/gpio.h>
10#include <subdev/bios/init.h> 11#include <subdev/bios/init.h>
11#include <subdev/devinit.h> 12#include <subdev/devinit.h>
12#include <subdev/clock.h> 13#include <subdev/clock.h>
@@ -1781,7 +1782,7 @@ init_gpio(struct nvbios_init *init)
1781 init->offset += 1; 1782 init->offset += 1;
1782 1783
1783 if (init_exec(init) && gpio && gpio->reset) 1784 if (init_exec(init) && gpio && gpio->reset)
1784 gpio->reset(gpio); 1785 gpio->reset(gpio, DCB_GPIO_UNUSED);
1785} 1786}
1786 1787
1787/** 1788/**
@@ -1995,6 +1996,47 @@ init_i2c_long_if(struct nvbios_init *init)
1995 init_exec_set(init, false); 1996 init_exec_set(init, false);
1996} 1997}
1997 1998
1999/**
2000 * INIT_GPIO_NE - opcode 0xa9
2001 *
2002 */
2003static void
2004init_gpio_ne(struct nvbios_init *init)
2005{
2006 struct nouveau_bios *bios = init->bios;
2007 struct nouveau_gpio *gpio = nouveau_gpio(bios);
2008 struct dcb_gpio_func func;
2009 u8 count = nv_ro08(bios, init->offset + 1);
2010 u8 idx = 0, ver, len;
2011 u16 data, i;
2012
2013 trace("GPIO_NE\t");
2014 init->offset += 2;
2015
2016 for (i = init->offset; i < init->offset + count; i++)
2017 cont("0x%02x ", nv_ro08(bios, i));
2018 cont("\n");
2019
2020 while ((data = dcb_gpio_parse(bios, 0, idx++, &ver, &len, &func))) {
2021 if (func.func != DCB_GPIO_UNUSED) {
2022 for (i = init->offset; i < init->offset + count; i++) {
2023 if (func.func == nv_ro08(bios, i))
2024 break;
2025 }
2026
2027 trace("\tFUNC[0x%02x]", func.func);
2028 if (i == (init->offset + count)) {
2029 cont(" *");
2030 if (init_exec(init) && gpio && gpio->reset)
2031 gpio->reset(gpio, func.func);
2032 }
2033 cont("\n");
2034 }
2035 }
2036
2037 init->offset += count;
2038}
2039
1998static struct nvbios_init_opcode { 2040static struct nvbios_init_opcode {
1999 void (*exec)(struct nvbios_init *); 2041 void (*exec)(struct nvbios_init *);
2000} init_opcode[] = { 2042} init_opcode[] = {
@@ -2059,6 +2101,7 @@ static struct nvbios_init_opcode {
2059 [0x98] = { init_auxch }, 2101 [0x98] = { init_auxch },
2060 [0x99] = { init_zm_auxch }, 2102 [0x99] = { init_zm_auxch },
2061 [0x9a] = { init_i2c_long_if }, 2103 [0x9a] = { init_i2c_long_if },
2104 [0xa9] = { init_gpio_ne },
2062}; 2105};
2063 2106
2064#define init_opcode_nr (sizeof(init_opcode) / sizeof(init_opcode[0])) 2107#define init_opcode_nr (sizeof(init_opcode) / sizeof(init_opcode[0]))
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
index 39f267c3241..9fb0f9b92d4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
@@ -270,7 +270,7 @@ nouveau_gpio_init(struct nouveau_gpio *gpio)
270 int ret = nouveau_subdev_init(&gpio->base); 270 int ret = nouveau_subdev_init(&gpio->base);
271 if (ret == 0 && gpio->reset) { 271 if (ret == 0 && gpio->reset) {
272 if (dmi_check_system(gpio_reset_ids)) 272 if (dmi_check_system(gpio_reset_ids))
273 gpio->reset(gpio); 273 gpio->reset(gpio, DCB_GPIO_UNUSED);
274 } 274 }
275 return ret; 275 return ret;
276} 276}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
index da2341392ce..bf13a1200f2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
@@ -29,7 +29,7 @@ struct nv50_gpio_priv {
29}; 29};
30 30
31static void 31static void
32nv50_gpio_reset(struct nouveau_gpio *gpio) 32nv50_gpio_reset(struct nouveau_gpio *gpio, u8 match)
33{ 33{
34 struct nouveau_bios *bios = nouveau_bios(gpio); 34 struct nouveau_bios *bios = nouveau_bios(gpio);
35 struct nv50_gpio_priv *priv = (void *)gpio; 35 struct nv50_gpio_priv *priv = (void *)gpio;
@@ -48,7 +48,8 @@ nv50_gpio_reset(struct nouveau_gpio *gpio)
48 u32 val = (unk1 << 16) | unk0; 48 u32 val = (unk1 << 16) | unk0;
49 u32 reg = regs[line >> 4]; line &= 0x0f; 49 u32 reg = regs[line >> 4]; line &= 0x0f;
50 50
51 if (func == 0xff) 51 if ( func == DCB_GPIO_UNUSED ||
52 (match != DCB_GPIO_UNUSED && match != func))
52 continue; 53 continue;
53 54
54 gpio->set(gpio, 0, func, line, defs); 55 gpio->set(gpio, 0, func, line, defs);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c
index cda607f2423..83e8b8f16e6 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c
@@ -29,7 +29,7 @@ struct nvd0_gpio_priv {
29}; 29};
30 30
31static void 31static void
32nvd0_gpio_reset(struct nouveau_gpio *gpio) 32nvd0_gpio_reset(struct nouveau_gpio *gpio, u8 match)
33{ 33{
34 struct nouveau_bios *bios = nouveau_bios(gpio); 34 struct nouveau_bios *bios = nouveau_bios(gpio);
35 struct nvd0_gpio_priv *priv = (void *)gpio; 35 struct nvd0_gpio_priv *priv = (void *)gpio;
@@ -45,7 +45,8 @@ nvd0_gpio_reset(struct nouveau_gpio *gpio)
45 u8 unk0 = (data & 0x00ff0000) >> 16; 45 u8 unk0 = (data & 0x00ff0000) >> 16;
46 u8 unk1 = (data & 0x1f000000) >> 24; 46 u8 unk1 = (data & 0x1f000000) >> 24;
47 47
48 if (func == 0xff) 48 if ( func == DCB_GPIO_UNUSED ||
49 (match != DCB_GPIO_UNUSED && match != func))
49 continue; 50 continue;
50 51
51 gpio->set(gpio, 0, func, line, defs); 52 gpio->set(gpio, 0, func, line, defs);