Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ed73166 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/bios: implement opcode 0xa9



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent d2bcea68
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ struct nouveau_gpio {
	struct nouveau_subdev base;

	/* hardware interfaces */
	void (*reset)(struct nouveau_gpio *);
	void (*reset)(struct nouveau_gpio *, u8 func);
	int  (*drive)(struct nouveau_gpio *, int line, int dir, int out);
	int  (*sense)(struct nouveau_gpio *, int line);
	void (*irq_enable)(struct nouveau_gpio *, int line, bool);
+45 −2
Original line number Diff line number Diff line
@@ -2,11 +2,12 @@
#include <core/device.h>

#include <subdev/bios.h>
#include <subdev/bios/conn.h>
#include <subdev/bios/bmp.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/conn.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/dp.h>
#include <subdev/bios/gpio.h>
#include <subdev/bios/init.h>
#include <subdev/devinit.h>
#include <subdev/clock.h>
@@ -1781,7 +1782,7 @@ init_gpio(struct nvbios_init *init)
	init->offset += 1;

	if (init_exec(init) && gpio && gpio->reset)
		gpio->reset(gpio);
		gpio->reset(gpio, DCB_GPIO_UNUSED);
}

/**
@@ -1995,6 +1996,47 @@ init_i2c_long_if(struct nvbios_init *init)
	init_exec_set(init, false);
}

/**
 * INIT_GPIO_NE - opcode 0xa9
 *
 */
static void
init_gpio_ne(struct nvbios_init *init)
{
	struct nouveau_bios *bios = init->bios;
	struct nouveau_gpio *gpio = nouveau_gpio(bios);
	struct dcb_gpio_func func;
	u8 count = nv_ro08(bios, init->offset + 1);
	u8 idx = 0, ver, len;
	u16 data, i;

	trace("GPIO_NE\t");
	init->offset += 2;

	for (i = init->offset; i < init->offset + count; i++)
		cont("0x%02x ", nv_ro08(bios, i));
	cont("\n");

	while ((data = dcb_gpio_parse(bios, 0, idx++, &ver, &len, &func))) {
		if (func.func != DCB_GPIO_UNUSED) {
			for (i = init->offset; i < init->offset + count; i++) {
				if (func.func == nv_ro08(bios, i))
					break;
			}

			trace("\tFUNC[0x%02x]", func.func);
			if (i == (init->offset + count)) {
				cont(" *");
				if (init_exec(init) && gpio && gpio->reset)
					gpio->reset(gpio, func.func);
			}
			cont("\n");
		}
	}

	init->offset += count;
}

static struct nvbios_init_opcode {
	void (*exec)(struct nvbios_init *);
} init_opcode[] = {
@@ -2059,6 +2101,7 @@ static struct nvbios_init_opcode {
	[0x98] = { init_auxch },
	[0x99] = { init_zm_auxch },
	[0x9a] = { init_i2c_long_if },
	[0xa9] = { init_gpio_ne },
};

#define init_opcode_nr (sizeof(init_opcode) / sizeof(init_opcode[0]))
+1 −1
Original line number Diff line number Diff line
@@ -270,7 +270,7 @@ nouveau_gpio_init(struct nouveau_gpio *gpio)
	int ret = nouveau_subdev_init(&gpio->base);
	if (ret == 0 && gpio->reset) {
		if (dmi_check_system(gpio_reset_ids))
			gpio->reset(gpio);
			gpio->reset(gpio, DCB_GPIO_UNUSED);
	}
	return ret;
}
+3 −2
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ struct nv50_gpio_priv {
};

static void
nv50_gpio_reset(struct nouveau_gpio *gpio)
nv50_gpio_reset(struct nouveau_gpio *gpio, u8 match)
{
	struct nouveau_bios *bios = nouveau_bios(gpio);
	struct nv50_gpio_priv *priv = (void *)gpio;
@@ -48,7 +48,8 @@ nv50_gpio_reset(struct nouveau_gpio *gpio)
		u32 val = (unk1 << 16) | unk0;
		u32 reg = regs[line >> 4]; line &= 0x0f;

		if (func == 0xff)
		if ( func  == DCB_GPIO_UNUSED ||
		    (match != DCB_GPIO_UNUSED && match != func))
			continue;

		gpio->set(gpio, 0, func, line, defs);
+3 −2
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ struct nvd0_gpio_priv {
};

static void
nvd0_gpio_reset(struct nouveau_gpio *gpio)
nvd0_gpio_reset(struct nouveau_gpio *gpio, u8 match)
{
	struct nouveau_bios *bios = nouveau_bios(gpio);
	struct nvd0_gpio_priv *priv = (void *)gpio;
@@ -45,7 +45,8 @@ nvd0_gpio_reset(struct nouveau_gpio *gpio)
		u8  unk0 =   (data & 0x00ff0000) >> 16;
		u8  unk1 =   (data & 0x1f000000) >> 24;

		if (func == 0xff)
		if ( func  == DCB_GPIO_UNUSED ||
		    (match != DCB_GPIO_UNUSED && match != func))
			continue;

		gpio->set(gpio, 0, func, line, defs);