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

Commit d0875edd authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nv50: add function to control GPIO IRQ reporting



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 49eed80a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1140,6 +1140,7 @@ int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
/* nv50_gpio.c */
int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
void nv50_gpio_irq_enable(struct drm_device *, enum dcb_gpio_tag, bool on);

/* nv50_calc. */
int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk,
+2 −18
Original line number Diff line number Diff line
@@ -184,7 +184,7 @@ nv50_display_init(struct drm_device *dev)
	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
	struct nouveau_channel *evo = dev_priv->evo;
	struct drm_connector *connector;
	uint32_t val, ram_amount, hpd_en[2];
	uint32_t val, ram_amount;
	uint64_t start;
	int ret, i;

@@ -365,26 +365,10 @@ nv50_display_init(struct drm_device *dev)
					     NV50_PDISPLAY_INTR_EN_CLK_UNK40));

	/* enable hotplug interrupts */
	hpd_en[0] = hpd_en[1] = 0;
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
		struct nouveau_connector *conn = nouveau_connector(connector);
		struct dcb_gpio_entry *gpio;

		if (conn->dcb->gpio_tag == 0xff)
			continue;

		gpio = nouveau_bios_gpio_entry(dev, conn->dcb->gpio_tag);
		if (!gpio)
			continue;

		hpd_en[gpio->line >> 4] |= (0x00010001 << (gpio->line & 0xf));
	}

	nv_wr32(dev, 0xe054, 0xffffffff);
	nv_wr32(dev, 0xe050, hpd_en[0]);
	if (dev_priv->chipset >= 0x90) {
		nv_wr32(dev, 0xe074, 0xffffffff);
		nv_wr32(dev, 0xe070, hpd_en[1]);
		nv50_gpio_irq_enable(dev, conn->dcb->gpio_tag, true);
	}

	return 0;
+19 −0
Original line number Diff line number Diff line
@@ -74,3 +74,22 @@ nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state)
	nv_wr32(dev, r, v);
	return 0;
}

void
nv50_gpio_irq_enable(struct drm_device *dev, enum dcb_gpio_tag tag, bool on)
{
	struct dcb_gpio_entry *gpio;
	u32 reg, mask;

	gpio = nouveau_bios_gpio_entry(dev, tag);
	if (!gpio) {
		NV_ERROR(dev, "gpio tag 0x%02x not found\n", tag);
		return;
	}

	reg  = gpio->line < 16 ? 0xe050 : 0xe070;
	mask = 0x00010001 << (gpio->line & 0xf);

	nv_wr32(dev, reg + 4, mask);
	nv_mask(dev, reg + 0, mask, on ? mask : 0);
}
+13 −0
Original line number Diff line number Diff line
@@ -31,7 +31,20 @@
int
nv50_mc_init(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);

	/* disable, and ack any pending gpio interrupts
	 * XXX doesn't technically belong here, but it'll do for the moment
	 */
	nv_wr32(dev, 0xe050, 0x00000000);
	nv_wr32(dev, 0xe054, 0xffffffff);
	if (dev_priv->chipset >= 0x90) {
		nv_wr32(dev, 0xe070, 0x00000000);
		nv_wr32(dev, 0xe074, 0xffffffff);
	}

	return 0;
}