Skip to content

Commit

Permalink
drm/nvc0-/gr: share headers between fermi and kepler graphics code
Browse files Browse the repository at this point in the history
v2: Ben Skeggs <bskeggs@redhat.com>
- de-inline nv_icmd, triggers some gcc issue causing ctxnv[ce]0.c to
  take a *very* *very* long time to build on some configs.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information
Ben Skeggs committed Oct 3, 2012
1 parent f589be8 commit c4afbe7
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 204 deletions.
49 changes: 21 additions & 28 deletions drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,14 @@
#include <core/mm.h>
#include "nvc0.h"

static void
void
nv_icmd(struct drm_device *priv, u32 icmd, u32 data)
{
nv_wr32(priv, 0x400204, data);
nv_wr32(priv, 0x400200, icmd);
while (nv_rd32(priv, 0x400700) & 2) {}
}

static void
nv_mthd(struct drm_device *priv, u32 class, u32 mthd, u32 data)
{
nv_wr32(priv, 0x40448c, data);
nv_wr32(priv, 0x404488, 0x80000000 | (mthd << 14) | class);
}

static void
nvc0_grctx_generate_9097(struct drm_device *priv)
{
Expand Down Expand Up @@ -1823,22 +1816,22 @@ nvc0_grctx_generate(struct nouveau_channel *chan)

for (tp = 0, id = 0; tp < 4; tp++) {
for (gpc = 0; gpc < oprv->gpc_nr; gpc++) {
if (tp < oprv->tp_nr[gpc]) {
nv_wr32(priv, TP_UNIT(gpc, tp, 0x698), id);
nv_wr32(priv, TP_UNIT(gpc, tp, 0x4e8), id);
if (tp < oprv->tpc_nr[gpc]) {
nv_wr32(priv, TPC_UNIT(gpc, tp, 0x698), id);
nv_wr32(priv, TPC_UNIT(gpc, tp, 0x4e8), id);
nv_wr32(priv, GPC_UNIT(gpc, 0x0c10 + tp * 4), id);
nv_wr32(priv, TP_UNIT(gpc, tp, 0x088), id);
nv_wr32(priv, TPC_UNIT(gpc, tp, 0x088), id);
id++;
}

nv_wr32(priv, GPC_UNIT(gpc, 0x0c08), oprv->tp_nr[gpc]);
nv_wr32(priv, GPC_UNIT(gpc, 0x0c8c), oprv->tp_nr[gpc]);
nv_wr32(priv, GPC_UNIT(gpc, 0x0c08), oprv->tpc_nr[gpc]);
nv_wr32(priv, GPC_UNIT(gpc, 0x0c8c), oprv->tpc_nr[gpc]);
}
}

tmp = 0;
for (i = 0; i < oprv->gpc_nr; i++)
tmp |= oprv->tp_nr[i] << (i * 4);
tmp |= oprv->tpc_nr[i] << (i * 4);
nv_wr32(priv, 0x406028, tmp);
nv_wr32(priv, 0x405870, tmp);

Expand All @@ -1850,13 +1843,13 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
nv_wr32(priv, 0x40587c, 0x00000000);

if (1) {
u8 tpnr[GPC_MAX], data[TP_MAX];
u8 tpnr[GPC_MAX], data[TPC_MAX];

memcpy(tpnr, oprv->tp_nr, sizeof(oprv->tp_nr));
memcpy(tpnr, oprv->tpc_nr, sizeof(oprv->tpc_nr));
memset(data, 0x1f, sizeof(data));

gpc = -1;
for (tp = 0; tp < oprv->tp_total; tp++) {
for (tp = 0; tp < oprv->tpc_total; tp++) {
do {
gpc = (gpc + 1) % oprv->gpc_nr;
} while (!tpnr[gpc]);
Expand All @@ -1874,10 +1867,10 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
u8 shift, ntpcv;

/* calculate first set of magics */
memcpy(tpnr, oprv->tp_nr, sizeof(oprv->tp_nr));
memcpy(tpnr, oprv->tpc_nr, sizeof(oprv->tpc_nr));

gpc = -1;
for (tp = 0; tp < oprv->tp_total; tp++) {
for (tp = 0; tp < oprv->tpc_total; tp++) {
do {
gpc = (gpc + 1) % oprv->gpc_nr;
} while (!tpnr[gpc]);
Expand All @@ -1891,7 +1884,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan)

/* and the second... */
shift = 0;
ntpcv = oprv->tp_total;
ntpcv = oprv->tpc_total;
while (!(ntpcv & (1 << 4))) {
ntpcv <<= 1;
shift++;
Expand All @@ -1904,21 +1897,21 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5);

/* GPC_BROADCAST */
nv_wr32(priv, 0x418bb8, (oprv->tp_total << 8) |
nv_wr32(priv, 0x418bb8, (oprv->tpc_total << 8) |
oprv->magic_not_rop_nr);
for (i = 0; i < 6; i++)
nv_wr32(priv, 0x418b08 + (i * 4), data[i]);

/* GPC_BROADCAST.TP_BROADCAST */
nv_wr32(priv, 0x419bd0, (oprv->tp_total << 8) |
nv_wr32(priv, 0x419bd0, (oprv->tpc_total << 8) |
oprv->magic_not_rop_nr |
data2[0]);
nv_wr32(priv, 0x419be4, data2[1]);
for (i = 0; i < 6; i++)
nv_wr32(priv, 0x419b00 + (i * 4), data[i]);

/* UNK78xx */
nv_wr32(priv, 0x4078bc, (oprv->tp_total << 8) |
nv_wr32(priv, 0x4078bc, (oprv->tpc_total << 8) |
oprv->magic_not_rop_nr);
for (i = 0; i < 6; i++)
nv_wr32(priv, 0x40780c + (i * 4), data[i]);
Expand All @@ -1928,18 +1921,18 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
u32 tp_mask = 0, tp_set = 0;
u8 tpnr[GPC_MAX], a, b;

memcpy(tpnr, oprv->tp_nr, sizeof(oprv->tp_nr));
memcpy(tpnr, oprv->tpc_nr, sizeof(oprv->tpc_nr));
for (gpc = 0; gpc < oprv->gpc_nr; gpc++)
tp_mask |= ((1 << oprv->tp_nr[gpc]) - 1) << (gpc * 8);
tp_mask |= ((1 << oprv->tpc_nr[gpc]) - 1) << (gpc * 8);

for (i = 0, gpc = -1, b = -1; i < 32; i++) {
a = (i * (oprv->tp_total - 1)) / 32;
a = (i * (oprv->tpc_total - 1)) / 32;
if (a != b) {
b = a;
do {
gpc = (gpc + 1) % oprv->gpc_nr;
} while (!tpnr[gpc]);
tp = oprv->tp_nr[gpc] - tpnr[gpc]--;
tp = oprv->tpc_nr[gpc] - tpnr[gpc]--;

tp_set |= 1 << ((gpc * 8) + tp);
}
Expand Down
21 changes: 3 additions & 18 deletions drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,7 @@
#include "drmP.h"
#include "nouveau_drv.h"
#include <core/mm.h>
#include "nve0.h"

static void
nv_icmd(struct drm_device *priv, u32 icmd, u32 data)
{
nv_wr32(priv, 0x400204, data);
nv_wr32(priv, 0x400200, icmd);
while (nv_rd32(priv, 0x400700) & 0x00000002) {}
}
#include "nvc0.h"

static void
nve0_grctx_generate_icmd(struct drm_device *priv)
Expand Down Expand Up @@ -923,13 +915,6 @@ nve0_grctx_generate_icmd(struct drm_device *priv)
nv_wr32(priv, 0x400208, 0x00000000);
}

static void
nv_mthd(struct drm_device *priv, u32 class, u32 mthd, u32 data)
{
nv_wr32(priv, 0x40448c, data);
nv_wr32(priv, 0x404488, 0x80000000 | (mthd << 14) | class);
}

static void
nve0_grctx_generate_a097(struct drm_device *priv)
{
Expand Down Expand Up @@ -2621,8 +2606,8 @@ nve0_graph_generate_tpcunk(struct drm_device *priv)
int
nve0_grctx_generate(struct nouveau_channel *chan)
{
struct nve0_graph_priv *oprv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
struct nve0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
struct nvc0_graph_priv *oprv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
struct drm_device *priv = chan->dev;
u32 data[6] = {}, data2[2] = {}, tmp;
u32 tpc_set = 0, tpc_mask = 0;
Expand Down
58 changes: 29 additions & 29 deletions drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,8 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
nv_wo32(grch->mmio, i++ * 4, 0x00405830);
nv_wo32(grch->mmio, i++ * 4, magic);
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
u32 reg = TP_UNIT(gpc, tp, 0x520);
for (tp = 0; tp < priv->tpc_nr[gpc]; tp++) {
u32 reg = TPC_UNIT(gpc, tp, 0x520);
nv_wo32(grch->mmio, i++ * 4, reg);
nv_wo32(grch->mmio, i++ * 4, magic);
magic += 0x0324;
Expand All @@ -243,14 +243,14 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
nv_wo32(grch->mmio, i++ * 4, 0x004064c4);
nv_wo32(grch->mmio, i++ * 4, 0x0086ffff);
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
u32 reg = TP_UNIT(gpc, tp, 0x520);
for (tp = 0; tp < priv->tpc_nr[gpc]; tp++) {
u32 reg = TPC_UNIT(gpc, tp, 0x520);
nv_wo32(grch->mmio, i++ * 4, reg);
nv_wo32(grch->mmio, i++ * 4, (1 << 28) | magic);
magic += 0x0324;
}
for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
u32 reg = TP_UNIT(gpc, tp, 0x544);
for (tp = 0; tp < priv->tpc_nr[gpc]; tp++) {
u32 reg = TPC_UNIT(gpc, tp, 0x544);
nv_wo32(grch->mmio, i++ * 4, reg);
nv_wo32(grch->mmio, i++ * 4, magic);
magic += 0x0324;
Expand Down Expand Up @@ -393,12 +393,12 @@ static void
nvc0_graph_init_gpc_0(struct drm_device *dev)
{
struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tp_total);
u32 data[TP_MAX / 8];
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
u32 data[TPC_MAX / 8];
u8 tpnr[GPC_MAX];
int i, gpc, tpc;

nv_wr32(dev, TP_UNIT(0, 0, 0x5c), 1); /* affects TFB offset queries */
nv_wr32(dev, TPC_UNIT(0, 0, 0x5c), 1); /* affects TFB offset queries */

/*
* TP ROP UNKVAL(magic_not_rop_nr)
Expand All @@ -410,12 +410,12 @@ nvc0_graph_init_gpc_0(struct drm_device *dev)
*/

memset(data, 0x00, sizeof(data));
memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
for (i = 0, gpc = -1; i < priv->tp_total; i++) {
memcpy(tpnr, priv->tpc_nr, sizeof(priv->tpc_nr));
for (i = 0, gpc = -1; i < priv->tpc_total; i++) {
do {
gpc = (gpc + 1) % priv->gpc_nr;
} while (!tpnr[gpc]);
tpc = priv->tp_nr[gpc] - tpnr[gpc]--;
tpc = priv->tpc_nr[gpc] - tpnr[gpc]--;

data[i / 8] |= tpc << ((i % 8) * 4);
}
Expand All @@ -427,8 +427,8 @@ nvc0_graph_init_gpc_0(struct drm_device *dev)

for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
nv_wr32(dev, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 |
priv->tp_nr[gpc]);
nv_wr32(dev, GPC_UNIT(gpc, 0x0910), 0x00040000 | priv->tp_total);
priv->tpc_nr[gpc]);
nv_wr32(dev, GPC_UNIT(gpc, 0x0910), 0x00040000 | priv->tpc_total);
nv_wr32(dev, GPC_UNIT(gpc, 0x0918), magicgpc918);
}

Expand Down Expand Up @@ -463,14 +463,14 @@ nvc0_graph_init_gpc_1(struct drm_device *dev)
nv_wr32(dev, GPC_UNIT(gpc, 0x0900), 0xc0000000);
nv_wr32(dev, GPC_UNIT(gpc, 0x1028), 0xc0000000);
nv_wr32(dev, GPC_UNIT(gpc, 0x0824), 0xc0000000);
for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
nv_wr32(dev, TP_UNIT(gpc, tp, 0x508), 0xffffffff);
nv_wr32(dev, TP_UNIT(gpc, tp, 0x50c), 0xffffffff);
nv_wr32(dev, TP_UNIT(gpc, tp, 0x224), 0xc0000000);
nv_wr32(dev, TP_UNIT(gpc, tp, 0x48c), 0xc0000000);
nv_wr32(dev, TP_UNIT(gpc, tp, 0x084), 0xc0000000);
nv_wr32(dev, TP_UNIT(gpc, tp, 0x644), 0x001ffffe);
nv_wr32(dev, TP_UNIT(gpc, tp, 0x64c), 0x0000000f);
for (tp = 0; tp < priv->tpc_nr[gpc]; tp++) {
nv_wr32(dev, TPC_UNIT(gpc, tp, 0x508), 0xffffffff);
nv_wr32(dev, TPC_UNIT(gpc, tp, 0x50c), 0xffffffff);
nv_wr32(dev, TPC_UNIT(gpc, tp, 0x224), 0xc0000000);
nv_wr32(dev, TPC_UNIT(gpc, tp, 0x48c), 0xc0000000);
nv_wr32(dev, TPC_UNIT(gpc, tp, 0x084), 0xc0000000);
nv_wr32(dev, TPC_UNIT(gpc, tp, 0x644), 0x001ffffe);
nv_wr32(dev, TPC_UNIT(gpc, tp, 0x64c), 0x0000000f);
}
nv_wr32(dev, GPC_UNIT(gpc, 0x2c90), 0xffffffff);
nv_wr32(dev, GPC_UNIT(gpc, 0x2c94), 0xffffffff);
Expand Down Expand Up @@ -858,20 +858,20 @@ nvc0_graph_create(struct drm_device *dev)
priv->gpc_nr = nv_rd32(dev, 0x409604) & 0x0000001f;
priv->rop_nr = (nv_rd32(dev, 0x409604) & 0x001f0000) >> 16;
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
priv->tp_nr[gpc] = nv_rd32(dev, GPC_UNIT(gpc, 0x2608));
priv->tp_total += priv->tp_nr[gpc];
priv->tpc_nr[gpc] = nv_rd32(dev, GPC_UNIT(gpc, 0x2608));
priv->tpc_total += priv->tpc_nr[gpc];
}

/*XXX: these need figuring out... */
switch (dev_priv->chipset) {
case 0xc0:
if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */
if (priv->tpc_total == 11) { /* 465, 3/4/4/0, 4 */
priv->magic_not_rop_nr = 0x07;
} else
if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */
if (priv->tpc_total == 14) { /* 470, 3/3/4/4, 5 */
priv->magic_not_rop_nr = 0x05;
} else
if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */
if (priv->tpc_total == 15) { /* 480, 3/4/4/4, 6 */
priv->magic_not_rop_nr = 0x06;
}
break;
Expand Down Expand Up @@ -900,8 +900,8 @@ nvc0_graph_create(struct drm_device *dev)

if (!priv->magic_not_rop_nr) {
NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n",
priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2],
priv->tp_nr[3], priv->rop_nr);
priv->tpc_nr[0], priv->tpc_nr[1], priv->tpc_nr[2],
priv->tpc_nr[3], priv->rop_nr);
priv->magic_not_rop_nr = 0x00;
}

Expand Down
Loading

0 comments on commit c4afbe7

Please sign in to comment.