Skip to content

Commit

Permalink
drm/nouveau/fb: implement various bits of work towards memory reclocking
Browse files Browse the repository at this point in the history
Not even remotely ready for the vast majority of the world.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information
Ben Skeggs committed Nov 8, 2013
1 parent 26fdd78 commit aae95ca
Show file tree
Hide file tree
Showing 21 changed files with 3,093 additions and 60 deletions.
4 changes: 4 additions & 0 deletions drivers/gpu/drm/nouveau/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ nouveau-y += core/subdev/fb/nva3.o
nouveau-y += core/subdev/fb/nvaa.o
nouveau-y += core/subdev/fb/nvaf.o
nouveau-y += core/subdev/fb/nvc0.o
nouveau-y += core/subdev/fb/nve0.o
nouveau-y += core/subdev/fb/ramnv04.o
nouveau-y += core/subdev/fb/ramnv10.o
nouveau-y += core/subdev/fb/ramnv1a.o
Expand All @@ -107,6 +108,9 @@ nouveau-y += core/subdev/fb/ramnv50.o
nouveau-y += core/subdev/fb/ramnva3.o
nouveau-y += core/subdev/fb/ramnvaa.o
nouveau-y += core/subdev/fb/ramnvc0.o
nouveau-y += core/subdev/fb/ramnve0.o
nouveau-y += core/subdev/fb/sddr3.o
nouveau-y += core/subdev/fb/gddr5.o
nouveau-y += core/subdev/gpio/base.o
nouveau-y += core/subdev/gpio/nv10.o
nouveau-y += core/subdev/gpio/nv50.o
Expand Down
10 changes: 5 additions & 5 deletions drivers/gpu/drm/nouveau/core/engine/device/nve0.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
Expand Down Expand Up @@ -102,7 +102,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
Expand Down Expand Up @@ -135,7 +135,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
Expand Down Expand Up @@ -168,7 +168,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
Expand Down Expand Up @@ -203,7 +203,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
Expand Down
9 changes: 9 additions & 0 deletions drivers/gpu/drm/nouveau/core/include/subdev/fb.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ extern struct nouveau_oclass *nva3_fb_oclass;
extern struct nouveau_oclass *nvaa_fb_oclass;
extern struct nouveau_oclass *nvaf_fb_oclass;
extern struct nouveau_oclass *nvc0_fb_oclass;
extern struct nouveau_oclass *nve0_fb_oclass;

struct nouveau_ram {
struct nouveau_object base;
Expand All @@ -125,9 +126,17 @@ struct nouveau_ram {
int (*get)(struct nouveau_fb *, u64 size, u32 align,
u32 size_nc, u32 type, struct nouveau_mem **);
void (*put)(struct nouveau_fb *, struct nouveau_mem **);

int (*calc)(struct nouveau_fb *, u32 freq);
int (*prog)(struct nouveau_fb *);
void (*tidy)(struct nouveau_fb *);
struct {
u8 version;
u32 data;
u8 size;
} rammap, ramcfg, timing;
u32 freq;
u32 mr[16];
};

#endif
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ nva3_pll_calc(struct nouveau_subdev *subdev, struct nvbios_pll *info,
lM = max(lM, (int)info->vco1.min_m);
hM = (info->refclk + info->vco1.min_inputfreq) / info->vco1.min_inputfreq;
hM = min(hM, (int)info->vco1.max_m);
lM = min(lM, hM);

for (M = lM; M <= hM; M++) {
u32 tmp = freq * *P * M;
Expand Down
96 changes: 96 additions & 0 deletions drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Copyright 2013 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/

#include <subdev/bios.h>
#include "priv.h"

int
nouveau_gddr5_calc(struct nouveau_ram *ram)
{
struct nouveau_bios *bios = nouveau_bios(ram);
int pd, lf, xd, vh, vr, vo;
int WL, CL, WR, at, dt, ds;
int rq = ram->freq < 1000000; /* XXX */

switch (!!ram->ramcfg.data * ram->ramcfg.version) {
case 0x11:
pd = (nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x80) >> 7;
lf = (nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x40) >> 6;
xd = !(nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x20);
vh = (nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x10) >> 4;
vr = (nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x04) >> 2;
vo = nv_ro08(bios, ram->ramcfg.data + 0x06) & 0xff;
break;
default:
return -ENOSYS;
}

switch (!!ram->timing.data * ram->timing.version) {
case 0x20:
WL = (nv_ro16(bios, ram->timing.data + 0x04) & 0x0f80) >> 7;
CL = nv_ro08(bios, ram->timing.data + 0x04) & 0x1f;
WR = nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f;
at = (nv_ro08(bios, ram->timing.data + 0x2e) & 0xc0) >> 6;
dt = nv_ro08(bios, ram->timing.data + 0x2e) & 0x03;
ds = nv_ro08(bios, ram->timing.data + 0x2f) & 0x03;
break;
default:
return -ENOSYS;
}

if (WL < 1 || WL > 7 || CL < 5 || CL > 36 || WR < 4 || WR > 35)
return -EINVAL;
CL -= 5;
WR -= 4;

ram->mr[0] &= ~0xf7f;
ram->mr[0] |= (WR & 0x0f) << 8;
ram->mr[0] |= (CL & 0x0f) << 3;
ram->mr[0] |= (WL & 0x07) << 0;

ram->mr[1] &= ~0x0bf;
ram->mr[1] |= (xd & 0x01) << 7;
ram->mr[1] |= (at & 0x03) << 4;
ram->mr[1] |= (dt & 0x03) << 2;
ram->mr[1] |= (ds & 0x03) << 0;

ram->mr[3] &= ~0x020;
ram->mr[3] |= (rq & 0x01) << 5;

if (!vo)
vo = (ram->mr[6] & 0xff0) >> 4;
if (ram->mr[6] & 0x001)
pd = 1; /* binary driver does this.. bug? */
ram->mr[6] &= ~0xff1;
ram->mr[6] |= (vo & 0xff) << 4;
ram->mr[6] |= (pd & 0x01) << 0;

if (!(ram->mr[7] & 0x100))
vr = 0; /* binary driver does this.. bug? */
ram->mr[7] &= ~0x188;
ram->mr[7] |= (vr & 0x01) << 8;
ram->mr[7] |= (vh & 0x01) << 7;
ram->mr[7] |= (lf & 0x01) << 3;
return 0;
}
17 changes: 17 additions & 0 deletions drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef __NVKM_FB_NV40_H__
#define __NVKM_FB_NV40_H__

#include "priv.h"

struct nv40_ram {
struct nouveau_ram base;
u32 ctrl;
u32 coef;
};


int nv40_ram_calc(struct nouveau_fb *, u32);
int nv40_ram_prog(struct nouveau_fb *);
void nv40_ram_tidy(struct nouveau_fb *);

#endif
16 changes: 5 additions & 11 deletions drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,18 @@
* Authors: Ben Skeggs
*/

#include "nv04.h"

struct nvc0_fb_priv {
struct nouveau_fb base;
struct page *r100c10_page;
dma_addr_t r100c10;
};
#include "nvc0.h"

extern const u8 nvc0_pte_storage_type_map[256];

static bool
bool
nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
{
u8 memtype = (tile_flags & 0x0000ff00) >> 8;
return likely((nvc0_pte_storage_type_map[memtype] != 0xff));
}

static int
int
nvc0_fb_init(struct nouveau_object *object)
{
struct nvc0_fb_priv *priv = (void *)object;
Expand All @@ -54,7 +48,7 @@ nvc0_fb_init(struct nouveau_object *object)
return 0;
}

static void
void
nvc0_fb_dtor(struct nouveau_object *object)
{
struct nouveau_device *device = nv_device(object);
Expand All @@ -69,7 +63,7 @@ nvc0_fb_dtor(struct nouveau_object *object)
nouveau_fb_destroy(&priv->base);
}

static int
int
nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
Expand Down
29 changes: 29 additions & 0 deletions drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef __NVKM_RAM_NVC0_H__
#define __NVKM_RAM_NVC0_H__

#include "priv.h"
#include "nv50.h"

struct nvc0_fb_priv {
struct nouveau_fb base;
struct page *r100c10_page;
dma_addr_t r100c10;
};

int nvc0_fb_ctor(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, void *, u32,
struct nouveau_object **);
void nvc0_fb_dtor(struct nouveau_object *);
int nvc0_fb_init(struct nouveau_object *);
bool nvc0_fb_memtype_valid(struct nouveau_fb *, u32);


#define nvc0_ram_create(p,e,o,d) \
nvc0_ram_create_((p), (e), (o), sizeof(**d), (void **)d)
int nvc0_ram_create_(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, int, void **);
int nvc0_ram_get(struct nouveau_fb *, u64, u32, u32, u32,
struct nouveau_mem **);
void nvc0_ram_put(struct nouveau_fb *, struct nouveau_mem **);

#endif
38 changes: 38 additions & 0 deletions drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2012 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/

#include "nvc0.h"

struct nouveau_oclass *
nve0_fb_oclass = &(struct nouveau_fb_impl) {
.base.handle = NV_SUBDEV(FB, 0xe0),
.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_fb_ctor,
.dtor = nvc0_fb_dtor,
.init = nvc0_fb_init,
.fini = _nouveau_fb_fini,
},
.memtype = nvc0_fb_memtype_valid,
.ram = &nve0_ram_oclass,
}.base;
4 changes: 4 additions & 0 deletions drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ extern struct nouveau_oclass nv50_ram_oclass;
extern struct nouveau_oclass nva3_ram_oclass;
extern struct nouveau_oclass nvaa_ram_oclass;
extern struct nouveau_oclass nvc0_ram_oclass;
extern struct nouveau_oclass nve0_ram_oclass;

int nouveau_sddr3_calc(struct nouveau_ram *ram);
int nouveau_gddr5_calc(struct nouveau_ram *ram);

#define nouveau_fb_create(p,e,c,d) \
nouveau_fb_create_((p), (e), (c), sizeof(**d), (void **)d)
Expand Down
Loading

0 comments on commit aae95ca

Please sign in to comment.