[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1391224618-3794-14-git-send-email-acourbot@nvidia.com>
Date: Sat, 1 Feb 2014 12:16:55 +0900
From: Alexandre Courbot <acourbot@...dia.com>
To: Ben Skeggs <bskeggs@...hat.com>, nouveau@...ts.freedesktop.org,
dri-devel@...ts.freedesktop.org
Cc: Terje Bergstrom <tbergstrom@...dia.com>,
Ken Adams <KAdams@...dia.com>,
Thierry Reding <thierry.reding@...il.com>,
Stephen Warren <swarren@...dotorg.org>,
Eric Brower <ebrower@...dia.com>, linux-tegra@...r.kernel.org,
linux-kernel@...r.kernel.org, gnurou@...il.com,
Alexandre Courbot <acourbot@...dia.com>
Subject: [RFC 13/16] drm/nouveau/ibus: add GK20A support
Add support for initializing the priv ring of GK20A. This is done by the
BIOS on desktop GPUs, but needs to be done by hand on Tegra.
Signed-off-by: Alexandre Courbot <acourbot@...dia.com>
---
drivers/gpu/drm/nouveau/Makefile | 1 +
drivers/gpu/drm/nouveau/core/include/subdev/ibus.h | 1 +
drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c | 108 +++++++++++++++++++++
3 files changed, 110 insertions(+)
create mode 100644 drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 6c4b76d..3548fcd 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -132,6 +132,7 @@ nouveau-y += core/subdev/i2c/nv94.o
nouveau-y += core/subdev/i2c/nvd0.o
nouveau-y += core/subdev/ibus/nvc0.o
nouveau-y += core/subdev/ibus/nve0.o
+nouveau-y += core/subdev/ibus/nvea.o
nouveau-y += core/subdev/instmem/base.o
nouveau-y += core/subdev/instmem/nv04.o
nouveau-y += core/subdev/instmem/nv40.o
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
index 88814f1..056a42f 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
@@ -30,5 +30,6 @@ nouveau_ibus(void *obj)
extern struct nouveau_oclass nvc0_ibus_oclass;
extern struct nouveau_oclass nve0_ibus_oclass;
+extern struct nouveau_oclass nvea_ibus_oclass;
#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c b/drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c
new file mode 100644
index 0000000..0bcd281
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <subdev/ibus.h>
+
+struct nvea_ibus_priv {
+ struct nouveau_ibus base;
+};
+
+static void
+nvea_ibus_init_priv_ring(struct nvea_ibus_priv *priv)
+{
+ u32 data;
+
+ data = nv_rd32(priv, 0x137250);
+ data &= (~0x3f);
+ nv_wr32(priv, 0x137250, data);
+
+ nv_mask(priv, 0x000200, 0x20, 0);
+ udelay(20);
+ nv_mask(priv, 0x000200, 0x20, 0x20);
+
+ nv_wr32(priv, 0x12004c, 0x4);
+ nv_wr32(priv, 0x122204, 0x2);
+ nv_rd32(priv, 0x122204);
+}
+
+static void
+nvea_ibus_intr(struct nouveau_subdev *subdev)
+{
+ struct nvea_ibus_priv *priv = (void *)subdev;
+ u32 status0 = nv_rd32(priv, 0x120058);
+ s32 retry = 100;
+ u32 command;
+
+ if (status0 & 0x7) {
+ nv_debug(priv, "resetting priv ring\n");
+ nvea_ibus_init_priv_ring(priv);
+ }
+
+ /* Acknowledge interrupt */
+ command = nv_rd32(priv, 0x0012004c);
+ command |= 0x2;
+ nv_wr32(priv, 0x0012004c, command);
+
+ while (--retry >= 0) {
+ command = nv_rd32(priv, 0x12004c) & 0x3f;
+ if (command == 0)
+ break;
+ }
+
+ if (retry < 0)
+ nv_debug(priv, "timeout waiting for ringmaster ack\n");
+}
+
+static int
+nvea_ibus_init(struct nouveau_object *object)
+{
+ struct nvea_ibus_priv *priv = (void *)object;
+ int ret;
+
+ ret = _nouveau_ibus_init(object);
+ if (ret)
+ return ret;
+
+ nvea_ibus_init_priv_ring(priv);
+
+ return 0;
+}
+
+static int
+nvea_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvea_ibus_priv *priv;
+ int ret;
+
+ ret = nouveau_ibus_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->intr = nvea_ibus_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nvea_ibus_oclass = {
+ .handle = NV_SUBDEV(IBUS, 0xea),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvea_ibus_ctor,
+ .dtor = _nouveau_ibus_dtor,
+ .init = nvea_ibus_init,
+ .fini = _nouveau_ibus_fini,
+ },
+};
--
1.8.5.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists