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

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

drm/nouveau: introduce gpio engine



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent bf563a6b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
             nv50_cursor.o nv50_display.o nv50_fbcon.o \
             nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \
             nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \
             nv17_gpio.o nv50_gpio.o \
             nv10_gpio.o nv50_gpio.o \
	     nv50_calc.o

nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o
+2 −1
Original line number Diff line number Diff line
@@ -3136,6 +3136,7 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
	 */

	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
	struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
	const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
	int i;

@@ -3156,7 +3157,7 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
		BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n",
			offset, gpio->tag, gpio->state_default);
		if (bios->execute)
			nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default);
			pgpio->set(bios->dev, gpio->tag, gpio->state_default);

		/* The NVIDIA binary driver doesn't appear to actually do
		 * any of this, my VBIOS does however.
+4 −2
Original line number Diff line number Diff line
@@ -272,6 +272,8 @@ bool
nouveau_dp_link_train(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
	struct nouveau_connector *nv_connector;
	struct bit_displayport_encoder_table *dpe;
@@ -295,7 +297,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder)
	/* disable hotplug detect, this flips around on some panels during
	 * link training.
	 */
	nv50_gpio_irq_enable(dev, nv_connector->dcb->gpio_tag, false);
	pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, false);

	if (dpe->script0) {
		NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or);
@@ -436,7 +438,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder)
	}

	/* re-enable hotplug detect */
	nv50_gpio_irq_enable(dev, nv_connector->dcb->gpio_tag, true);
	pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, true);

	return eq_done;
}
+15 −3
Original line number Diff line number Diff line
@@ -359,6 +359,16 @@ struct nouveau_display_engine {
	void (*destroy)(struct drm_device *);
};

struct nouveau_gpio_engine {
	int  (*init)(struct drm_device *);
	void (*takedown)(struct drm_device *);

	int  (*get)(struct drm_device *, enum dcb_gpio_tag);
	int  (*set)(struct drm_device *, enum dcb_gpio_tag, int state);

	void (*irq_enable)(struct drm_device *, enum dcb_gpio_tag, bool on);
};

struct nouveau_engine {
	struct nouveau_instmem_engine instmem;
	struct nouveau_mc_engine      mc;
@@ -367,6 +377,7 @@ struct nouveau_engine {
	struct nouveau_pgraph_engine  graph;
	struct nouveau_fifo_engine    fifo;
	struct nouveau_display_engine display;
	struct nouveau_gpio_engine    gpio;
};

struct nouveau_pll_vals {
@@ -1149,11 +1160,12 @@ extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *,
extern int nouveau_gem_ioctl_info(struct drm_device *, void *,
				  struct drm_file *);

/* nv17_gpio.c */
int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
/* nv10_gpio.c */
int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
int nv10_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);

/* nv50_gpio.c */
int nv50_gpio_init(struct drm_device *dev);
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);
+40 −1
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include "nv50_display.h"

static void nouveau_stub_takedown(struct drm_device *dev) {}
static int nouveau_stub_init(struct drm_device *dev) { return 0; }

static int nouveau_init_engine_ptrs(struct drm_device *dev)
{
@@ -89,6 +90,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
		engine->display.create		= nv04_display_create;
		engine->display.init		= nv04_display_init;
		engine->display.destroy		= nv04_display_destroy;
		engine->gpio.init		= nouveau_stub_init;
		engine->gpio.takedown		= nouveau_stub_takedown;
		engine->gpio.get		= NULL;
		engine->gpio.set		= NULL;
		engine->gpio.irq_enable		= NULL;
		break;
	case 0x10:
		engine->instmem.init		= nv04_instmem_init;
@@ -136,6 +142,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
		engine->display.create		= nv04_display_create;
		engine->display.init		= nv04_display_init;
		engine->display.destroy		= nv04_display_destroy;
		engine->gpio.init		= nouveau_stub_init;
		engine->gpio.takedown		= nouveau_stub_takedown;
		engine->gpio.get		= nv10_gpio_get;
		engine->gpio.set		= nv10_gpio_set;
		engine->gpio.irq_enable		= NULL;
		break;
	case 0x20:
		engine->instmem.init		= nv04_instmem_init;
@@ -183,6 +194,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
		engine->display.create		= nv04_display_create;
		engine->display.init		= nv04_display_init;
		engine->display.destroy		= nv04_display_destroy;
		engine->gpio.init		= nouveau_stub_init;
		engine->gpio.takedown		= nouveau_stub_takedown;
		engine->gpio.get		= nv10_gpio_get;
		engine->gpio.set		= nv10_gpio_set;
		engine->gpio.irq_enable		= NULL;
		break;
	case 0x30:
		engine->instmem.init		= nv04_instmem_init;
@@ -230,6 +246,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
		engine->display.create		= nv04_display_create;
		engine->display.init		= nv04_display_init;
		engine->display.destroy		= nv04_display_destroy;
		engine->gpio.init		= nouveau_stub_init;
		engine->gpio.takedown		= nouveau_stub_takedown;
		engine->gpio.get		= nv10_gpio_get;
		engine->gpio.set		= nv10_gpio_set;
		engine->gpio.irq_enable		= NULL;
		break;
	case 0x40:
	case 0x60:
@@ -278,6 +299,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
		engine->display.create		= nv04_display_create;
		engine->display.init		= nv04_display_init;
		engine->display.destroy		= nv04_display_destroy;
		engine->gpio.init		= nouveau_stub_init;
		engine->gpio.takedown		= nouveau_stub_takedown;
		engine->gpio.get		= nv10_gpio_get;
		engine->gpio.set		= nv10_gpio_set;
		engine->gpio.irq_enable		= NULL;
		break;
	case 0x50:
	case 0x80: /* gotta love NVIDIA's consistency.. */
@@ -327,6 +353,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
		engine->display.create		= nv50_display_create;
		engine->display.init		= nv50_display_init;
		engine->display.destroy		= nv50_display_destroy;
		engine->gpio.init		= nv50_gpio_init;
		engine->gpio.takedown		= nouveau_stub_takedown;
		engine->gpio.get		= nv50_gpio_get;
		engine->gpio.set		= nv50_gpio_set;
		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
		break;
	default:
		NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
@@ -485,10 +516,15 @@ nouveau_card_init(struct drm_device *dev)
	if (ret)
		goto out_gpuobj;

	/* PGPIO */
	ret = engine->gpio.init(dev);
	if (ret)
		goto out_mc;

	/* PTIMER */
	ret = engine->timer.init(dev);
	if (ret)
		goto out_mc;
		goto out_gpio;

	/* PFB */
	ret = engine->fb.init(dev);
@@ -554,6 +590,8 @@ nouveau_card_init(struct drm_device *dev)
	engine->fb.takedown(dev);
out_timer:
	engine->timer.takedown(dev);
out_gpio:
	engine->gpio.takedown(dev);
out_mc:
	engine->mc.takedown(dev);
out_gpuobj:
@@ -592,6 +630,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
	}
	engine->fb.takedown(dev);
	engine->timer.takedown(dev);
	engine->gpio.takedown(dev);
	engine->mc.takedown(dev);
	engine->display.late_takedown(dev);

Loading