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

Commit 2535d71c authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau: store raw gpio table entry in bios gpio structs



And use our own version of the GPIO table for the INIT_GPIO opcode.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 2295e17a
Loading
Loading
Loading
Loading
+20 −28
Original line number Original line Diff line number Diff line
@@ -2573,48 +2573,38 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
	 * each GPIO according to various values listed in each entry
	 * each GPIO according to various values listed in each entry
	 */
	 */


	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
	const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
	const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
	const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
	const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
	const uint8_t *gpio_table = &bios->data[bios->dcb.gpio_table_ptr];
	const uint8_t *gpio_entry;
	int i;
	int i;


	if (!iexec->execute)
	if (dev_priv->card_type != NV_50) {
		return 1;
		NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n");

		return -ENODEV;
	if (bios->dcb.version != 0x40) {
		NV_ERROR(bios->dev, "DCB table not version 4.0\n");
		return 0;
	}

	if (!bios->dcb.gpio_table_ptr) {
		NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n");
		return 0;
	}
	}


	gpio_entry = gpio_table + gpio_table[1];
	if (!iexec->execute)
	for (i = 0; i < gpio_table[2]; i++, gpio_entry += gpio_table[3]) {
		return 1;
		uint32_t entry = ROM32(gpio_entry[0]), r, s, v;
		int line = (entry & 0x0000001f);


		BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, entry);
	for (i = 0; i < bios->dcb.gpio.entries; i++) {
		struct dcb_gpio_entry *gpio = &bios->dcb.gpio.entry[i];
		uint32_t r, s, v;


		if ((entry & 0x0000ff00) == 0x0000ff00)
		BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry);
			continue;


		r = nv50_gpio_reg[line >> 3];
		r = nv50_gpio_reg[gpio->line >> 3];
		s = (line & 0x07) << 2;
		s = (gpio->line & 0x07) << 2;
		v = bios_rd32(bios, r) & ~(0x00000003 << s);
		v = bios_rd32(bios, r) & ~(0x00000003 << s);
		if (entry & 0x01000000)
		if (gpio->entry & 0x01000000)
			v |= (((entry & 0x60000000) >> 29) ^ 2) << s;
			v |= (((gpio->entry & 0x60000000) >> 29) ^ 2) << s;
		else
		else
			v |= (((entry & 0x18000000) >> 27) ^ 2) << s;
			v |= (((gpio->entry & 0x18000000) >> 27) ^ 2) << s;
		bios_wr32(bios, r, v);
		bios_wr32(bios, r, v);


		r = nv50_gpio_ctl[line >> 4];
		r = nv50_gpio_ctl[gpio->line >> 4];
		s = (line & 0x0f);
		s = (gpio->line & 0x0f);
		v = bios_rd32(bios, r) & ~(0x00010001 << s);
		v = bios_rd32(bios, r) & ~(0x00010001 << s);
		switch ((entry & 0x06000000) >> 25) {
		switch ((gpio->entry & 0x06000000) >> 25) {
		case 1:
		case 1:
			v |= (0x00000001 << s);
			v |= (0x00000001 << s);
			break;
			break;
@@ -5082,6 +5072,7 @@ parse_dcb30_gpio_entry(struct nvbios *bios, uint16_t offset)
	gpio->tag = tag;
	gpio->tag = tag;
	gpio->line = line;
	gpio->line = line;
	gpio->invert = flags != 4;
	gpio->invert = flags != 4;
	gpio->entry = ent;
}
}


static void
static void
@@ -5101,6 +5092,7 @@ parse_dcb40_gpio_entry(struct nvbios *bios, uint16_t offset)
	 * point. */
	 * point. */
	gpio->tag = tag;
	gpio->tag = tag;
	gpio->line = line;
	gpio->line = line;
	gpio->entry = ent;
}
}


static void
static void
+1 −0
Original line number Original line Diff line number Diff line
@@ -49,6 +49,7 @@ struct dcb_gpio_entry {
	enum dcb_gpio_tag tag;
	enum dcb_gpio_tag tag;
	int line;
	int line;
	bool invert;
	bool invert;
	uint32_t entry;
};
};


struct dcb_gpio_table {
struct dcb_gpio_table {