Loading drivers/gpu/drm/nouveau/Makefile +2 −1 Original line number Diff line number Diff line Loading @@ -139,7 +139,8 @@ nouveau-y += core/subdev/instmem/base.o nouveau-y += core/subdev/instmem/nv04.o nouveau-y += core/subdev/instmem/nv40.o nouveau-y += core/subdev/instmem/nv50.o nouveau-y += core/subdev/ltcg/nvc0.o nouveau-y += core/subdev/ltcg/gf100.o nouveau-y += core/subdev/ltcg/gm107.o nouveau-y += core/subdev/mc/base.o nouveau-y += core/subdev/mc/nv04.o nouveau-y += core/subdev/mc/nv40.o Loading drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +9 −9 Original line number Diff line number Diff line Loading @@ -70,7 +70,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -102,7 +102,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -134,7 +134,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -165,7 +165,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -197,7 +197,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -229,7 +229,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -260,7 +260,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -292,7 +292,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -323,7 +323,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading drivers/gpu/drm/nouveau/core/engine/device/nve0.c +5 −5 Original line number Diff line number Diff line Loading @@ -70,7 +70,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -103,7 +103,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -136,7 +136,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -169,7 +169,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -204,7 +204,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h +2 −1 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ nouveau_ltcg(void *obj) #define _nouveau_ltcg_init _nouveau_subdev_init #define _nouveau_ltcg_fini _nouveau_subdev_fini extern struct nouveau_oclass nvc0_ltcg_oclass; extern struct nouveau_oclass *gf100_ltcg_oclass; extern struct nouveau_oclass *gm107_ltcg_oclass; #endif drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c→drivers/gpu/drm/nouveau/core/subdev/ltcg/gf100.c +50 −59 Original line number Diff line number Diff line Loading @@ -22,44 +22,35 @@ * Authors: Ben Skeggs */ #include <subdev/ltcg.h> #include <subdev/fb.h> #include <subdev/timer.h> struct nvc0_ltcg_priv { struct nouveau_ltcg base; u32 part_nr; u32 subp_nr; u32 num_tags; u32 tag_base; struct nouveau_mm tags; struct nouveau_mm_node *tag_ram; }; #include "gf100.h" static void nvc0_ltcg_subp_isr(struct nvc0_ltcg_priv *priv, int unit, int subp) gf100_ltcg_lts_isr(struct gf100_ltcg_priv *priv, int ltc, int lts) { u32 subp_base = 0x141000 + (unit * 0x2000) + (subp * 0x400); u32 stat = nv_rd32(priv, subp_base + 0x020); u32 base = 0x141000 + (ltc * 0x2000) + (lts * 0x400); u32 stat = nv_rd32(priv, base + 0x020); if (stat) { nv_info(priv, "LTC%d_LTS%d: 0x%08x\n", unit, subp, stat); nv_wr32(priv, subp_base + 0x020, stat); nv_info(priv, "LTC%d_LTS%d: 0x%08x\n", ltc, lts, stat); nv_wr32(priv, base + 0x020, stat); } } static void nvc0_ltcg_intr(struct nouveau_subdev *subdev) gf100_ltcg_intr(struct nouveau_subdev *subdev) { struct nvc0_ltcg_priv *priv = (void *)subdev; u32 units; units = nv_rd32(priv, 0x00017c); while (units) { u32 subp, unit = ffs(units) - 1; for (subp = 0; subp < priv->subp_nr; subp++) nvc0_ltcg_subp_isr(priv, unit, subp); units &= ~(1 << unit); struct gf100_ltcg_priv *priv = (void *)subdev; u32 mask; mask = nv_rd32(priv, 0x00017c); while (mask) { u32 lts, ltc = __ffs(mask); for (lts = 0; lts < priv->lts_nr; lts++) gf100_ltcg_lts_isr(priv, ltc, lts); mask &= ~(1 << ltc); } /* we do something horribly wrong and upset PMFB a lot, so mask off Loading @@ -68,11 +59,11 @@ nvc0_ltcg_intr(struct nouveau_subdev *subdev) nv_mask(priv, 0x000640, 0x02000000, 0x00000000); } static int nvc0_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n, int gf100_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n, struct nouveau_mm_node **pnode) { struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; int ret; ret = nouveau_mm_head(&priv->tags, 1, n, n, 1, pnode); Loading @@ -82,18 +73,18 @@ nvc0_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n, return ret; } static void nvc0_ltcg_tags_free(struct nouveau_ltcg *ltcg, struct nouveau_mm_node **pnode) void gf100_ltcg_tags_free(struct nouveau_ltcg *ltcg, struct nouveau_mm_node **pnode) { struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; nouveau_mm_free(&priv->tags, pnode); } static void nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) gf100_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) { struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; u32 last = first + count - 1; int p, i; Loading @@ -104,16 +95,16 @@ nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) nv_wr32(priv, 0x17e8c8, 0x4); /* trigger clear */ /* wait until it's finished with clearing */ for (p = 0; p < priv->part_nr; ++p) { for (i = 0; i < priv->subp_nr; ++i) for (p = 0; p < priv->ltc_nr; ++p) { for (i = 0; i < priv->lts_nr; ++i) nv_wait(priv, 0x1410c8 + p * 0x2000 + i * 0x400, ~0, 0); } } /* TODO: Figure out tag memory details and drop the over-cautious allocation. */ static int nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv) int gf100_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct gf100_ltcg_priv *priv) { u32 tag_size, tag_margin, tag_align; int ret; Loading @@ -124,7 +115,7 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv) priv->num_tags = 1 << 17; /* we have 17 bits in PTE */ priv->num_tags = (priv->num_tags + 63) & ~63; /* round up to 64 */ tag_align = priv->part_nr * 0x800; tag_align = priv->ltc_nr * 0x800; tag_margin = (tag_align < 0x6000) ? 0x6000 : tag_align; /* 4 part 4 sub: 0x2000 bytes for 56 tags */ Loading Loading @@ -157,11 +148,11 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv) } static int nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, gf100_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { struct nvc0_ltcg_priv *priv; struct gf100_ltcg_priv *priv; struct nouveau_fb *pfb = nouveau_fb(parent); u32 parts, mask; int ret, i; Loading @@ -175,27 +166,27 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, mask = nv_rd32(priv, 0x022554); for (i = 0; i < parts; i++) { if (!(mask & (1 << i))) priv->part_nr++; priv->ltc_nr++; } priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28; priv->lts_nr = nv_rd32(priv, 0x17e8dc) >> 28; ret = nvc0_ltcg_init_tag_ram(pfb, priv); ret = gf100_ltcg_init_tag_ram(pfb, priv); if (ret) return ret; priv->base.tags_alloc = nvc0_ltcg_tags_alloc; priv->base.tags_free = nvc0_ltcg_tags_free; priv->base.tags_clear = nvc0_ltcg_tags_clear; priv->base.tags_alloc = gf100_ltcg_tags_alloc; priv->base.tags_free = gf100_ltcg_tags_free; priv->base.tags_clear = gf100_ltcg_tags_clear; nv_subdev(priv)->intr = nvc0_ltcg_intr; nv_subdev(priv)->intr = gf100_ltcg_intr; return 0; } static void nvc0_ltcg_dtor(struct nouveau_object *object) void gf100_ltcg_dtor(struct nouveau_object *object) { struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object; struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; struct nouveau_fb *pfb = nouveau_fb(ltcg->base.base.parent); nouveau_mm_fini(&priv->tags); Loading @@ -205,10 +196,10 @@ nvc0_ltcg_dtor(struct nouveau_object *object) } static int nvc0_ltcg_init(struct nouveau_object *object) gf100_ltcg_init(struct nouveau_object *object) { struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object; struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; int ret; ret = nouveau_ltcg_init(ltcg); Loading @@ -216,20 +207,20 @@ nvc0_ltcg_init(struct nouveau_object *object) return ret; nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */ nv_wr32(priv, 0x17e8d8, priv->part_nr); nv_wr32(priv, 0x17e8d8, priv->ltc_nr); if (nv_device(ltcg)->card_type >= NV_E0) nv_wr32(priv, 0x17e000, priv->part_nr); nv_wr32(priv, 0x17e000, priv->ltc_nr); nv_wr32(priv, 0x17e8d4, priv->tag_base); return 0; } struct nouveau_oclass nvc0_ltcg_oclass = { struct nouveau_oclass * gf100_ltcg_oclass = &(struct nouveau_oclass) { .handle = NV_SUBDEV(LTCG, 0xc0), .ofuncs = &(struct nouveau_ofuncs) { .ctor = nvc0_ltcg_ctor, .dtor = nvc0_ltcg_dtor, .init = nvc0_ltcg_init, .ctor = gf100_ltcg_ctor, .dtor = gf100_ltcg_dtor, .init = gf100_ltcg_init, .fini = _nouveau_ltcg_fini, }, }; Loading
drivers/gpu/drm/nouveau/Makefile +2 −1 Original line number Diff line number Diff line Loading @@ -139,7 +139,8 @@ nouveau-y += core/subdev/instmem/base.o nouveau-y += core/subdev/instmem/nv04.o nouveau-y += core/subdev/instmem/nv40.o nouveau-y += core/subdev/instmem/nv50.o nouveau-y += core/subdev/ltcg/nvc0.o nouveau-y += core/subdev/ltcg/gf100.o nouveau-y += core/subdev/ltcg/gm107.o nouveau-y += core/subdev/mc/base.o nouveau-y += core/subdev/mc/nv04.o nouveau-y += core/subdev/mc/nv40.o Loading
drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +9 −9 Original line number Diff line number Diff line Loading @@ -70,7 +70,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -102,7 +102,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -134,7 +134,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -165,7 +165,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -197,7 +197,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -229,7 +229,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -260,7 +260,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -292,7 +292,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -323,7 +323,7 @@ nvc0_identify(struct nouveau_device *device) 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_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading
drivers/gpu/drm/nouveau/core/engine/device/nve0.c +5 −5 Original line number Diff line number Diff line Loading @@ -70,7 +70,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -103,7 +103,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -136,7 +136,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -169,7 +169,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading Loading @@ -204,7 +204,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; Loading
drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h +2 −1 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ nouveau_ltcg(void *obj) #define _nouveau_ltcg_init _nouveau_subdev_init #define _nouveau_ltcg_fini _nouveau_subdev_fini extern struct nouveau_oclass nvc0_ltcg_oclass; extern struct nouveau_oclass *gf100_ltcg_oclass; extern struct nouveau_oclass *gm107_ltcg_oclass; #endif
drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c→drivers/gpu/drm/nouveau/core/subdev/ltcg/gf100.c +50 −59 Original line number Diff line number Diff line Loading @@ -22,44 +22,35 @@ * Authors: Ben Skeggs */ #include <subdev/ltcg.h> #include <subdev/fb.h> #include <subdev/timer.h> struct nvc0_ltcg_priv { struct nouveau_ltcg base; u32 part_nr; u32 subp_nr; u32 num_tags; u32 tag_base; struct nouveau_mm tags; struct nouveau_mm_node *tag_ram; }; #include "gf100.h" static void nvc0_ltcg_subp_isr(struct nvc0_ltcg_priv *priv, int unit, int subp) gf100_ltcg_lts_isr(struct gf100_ltcg_priv *priv, int ltc, int lts) { u32 subp_base = 0x141000 + (unit * 0x2000) + (subp * 0x400); u32 stat = nv_rd32(priv, subp_base + 0x020); u32 base = 0x141000 + (ltc * 0x2000) + (lts * 0x400); u32 stat = nv_rd32(priv, base + 0x020); if (stat) { nv_info(priv, "LTC%d_LTS%d: 0x%08x\n", unit, subp, stat); nv_wr32(priv, subp_base + 0x020, stat); nv_info(priv, "LTC%d_LTS%d: 0x%08x\n", ltc, lts, stat); nv_wr32(priv, base + 0x020, stat); } } static void nvc0_ltcg_intr(struct nouveau_subdev *subdev) gf100_ltcg_intr(struct nouveau_subdev *subdev) { struct nvc0_ltcg_priv *priv = (void *)subdev; u32 units; units = nv_rd32(priv, 0x00017c); while (units) { u32 subp, unit = ffs(units) - 1; for (subp = 0; subp < priv->subp_nr; subp++) nvc0_ltcg_subp_isr(priv, unit, subp); units &= ~(1 << unit); struct gf100_ltcg_priv *priv = (void *)subdev; u32 mask; mask = nv_rd32(priv, 0x00017c); while (mask) { u32 lts, ltc = __ffs(mask); for (lts = 0; lts < priv->lts_nr; lts++) gf100_ltcg_lts_isr(priv, ltc, lts); mask &= ~(1 << ltc); } /* we do something horribly wrong and upset PMFB a lot, so mask off Loading @@ -68,11 +59,11 @@ nvc0_ltcg_intr(struct nouveau_subdev *subdev) nv_mask(priv, 0x000640, 0x02000000, 0x00000000); } static int nvc0_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n, int gf100_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n, struct nouveau_mm_node **pnode) { struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; int ret; ret = nouveau_mm_head(&priv->tags, 1, n, n, 1, pnode); Loading @@ -82,18 +73,18 @@ nvc0_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n, return ret; } static void nvc0_ltcg_tags_free(struct nouveau_ltcg *ltcg, struct nouveau_mm_node **pnode) void gf100_ltcg_tags_free(struct nouveau_ltcg *ltcg, struct nouveau_mm_node **pnode) { struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; nouveau_mm_free(&priv->tags, pnode); } static void nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) gf100_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) { struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; u32 last = first + count - 1; int p, i; Loading @@ -104,16 +95,16 @@ nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) nv_wr32(priv, 0x17e8c8, 0x4); /* trigger clear */ /* wait until it's finished with clearing */ for (p = 0; p < priv->part_nr; ++p) { for (i = 0; i < priv->subp_nr; ++i) for (p = 0; p < priv->ltc_nr; ++p) { for (i = 0; i < priv->lts_nr; ++i) nv_wait(priv, 0x1410c8 + p * 0x2000 + i * 0x400, ~0, 0); } } /* TODO: Figure out tag memory details and drop the over-cautious allocation. */ static int nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv) int gf100_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct gf100_ltcg_priv *priv) { u32 tag_size, tag_margin, tag_align; int ret; Loading @@ -124,7 +115,7 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv) priv->num_tags = 1 << 17; /* we have 17 bits in PTE */ priv->num_tags = (priv->num_tags + 63) & ~63; /* round up to 64 */ tag_align = priv->part_nr * 0x800; tag_align = priv->ltc_nr * 0x800; tag_margin = (tag_align < 0x6000) ? 0x6000 : tag_align; /* 4 part 4 sub: 0x2000 bytes for 56 tags */ Loading Loading @@ -157,11 +148,11 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv) } static int nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, gf100_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { struct nvc0_ltcg_priv *priv; struct gf100_ltcg_priv *priv; struct nouveau_fb *pfb = nouveau_fb(parent); u32 parts, mask; int ret, i; Loading @@ -175,27 +166,27 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, mask = nv_rd32(priv, 0x022554); for (i = 0; i < parts; i++) { if (!(mask & (1 << i))) priv->part_nr++; priv->ltc_nr++; } priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28; priv->lts_nr = nv_rd32(priv, 0x17e8dc) >> 28; ret = nvc0_ltcg_init_tag_ram(pfb, priv); ret = gf100_ltcg_init_tag_ram(pfb, priv); if (ret) return ret; priv->base.tags_alloc = nvc0_ltcg_tags_alloc; priv->base.tags_free = nvc0_ltcg_tags_free; priv->base.tags_clear = nvc0_ltcg_tags_clear; priv->base.tags_alloc = gf100_ltcg_tags_alloc; priv->base.tags_free = gf100_ltcg_tags_free; priv->base.tags_clear = gf100_ltcg_tags_clear; nv_subdev(priv)->intr = nvc0_ltcg_intr; nv_subdev(priv)->intr = gf100_ltcg_intr; return 0; } static void nvc0_ltcg_dtor(struct nouveau_object *object) void gf100_ltcg_dtor(struct nouveau_object *object) { struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object; struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; struct nouveau_fb *pfb = nouveau_fb(ltcg->base.base.parent); nouveau_mm_fini(&priv->tags); Loading @@ -205,10 +196,10 @@ nvc0_ltcg_dtor(struct nouveau_object *object) } static int nvc0_ltcg_init(struct nouveau_object *object) gf100_ltcg_init(struct nouveau_object *object) { struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object; struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; int ret; ret = nouveau_ltcg_init(ltcg); Loading @@ -216,20 +207,20 @@ nvc0_ltcg_init(struct nouveau_object *object) return ret; nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */ nv_wr32(priv, 0x17e8d8, priv->part_nr); nv_wr32(priv, 0x17e8d8, priv->ltc_nr); if (nv_device(ltcg)->card_type >= NV_E0) nv_wr32(priv, 0x17e000, priv->part_nr); nv_wr32(priv, 0x17e000, priv->ltc_nr); nv_wr32(priv, 0x17e8d4, priv->tag_base); return 0; } struct nouveau_oclass nvc0_ltcg_oclass = { struct nouveau_oclass * gf100_ltcg_oclass = &(struct nouveau_oclass) { .handle = NV_SUBDEV(LTCG, 0xc0), .ofuncs = &(struct nouveau_ofuncs) { .ctor = nvc0_ltcg_ctor, .dtor = nvc0_ltcg_dtor, .init = nvc0_ltcg_init, .ctor = gf100_ltcg_ctor, .dtor = gf100_ltcg_dtor, .init = gf100_ltcg_init, .fini = _nouveau_ltcg_fini, }, };