diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-12-06 22:46:52 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-12-23 07:59:28 -0500 |
commit | 1ed731668d011d0ee894d949b80dc3d11fc9ef75 (patch) | |
tree | ca86937798de45c34cecbf1d5d478c95d560a476 | |
parent | d2bcea686f21e11415828fcca21a4eb200c6251f (diff) |
drm/nouveau/bios: implement opcode 0xa9
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/subdev/gpio.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/bios/init.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/gpio/base.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c | 5 |
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 | */ | ||
2003 | static void | ||
2004 | init_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 | |||
1998 | static struct nvbios_init_opcode { | 2040 | static 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 | ||
31 | static void | 31 | static void |
32 | nv50_gpio_reset(struct nouveau_gpio *gpio) | 32 | nv50_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 | ||
31 | static void | 31 | static void |
32 | nvd0_gpio_reset(struct nouveau_gpio *gpio) | 32 | nvd0_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); |