Skip to contentSkip to conversation

drm/nouveau: fix ltcg memory initialization after suspend

PATCH In review Maarten Lankhorst 2 participants 3 messages Aug 12, 2013 – Aug 13, 2013 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 drm/nouveau: fix ltcg memory initialization after suspend

Some registers were not initialized in init, this causes them to be uninitialized after suspend.

---

drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +27 -9
index bcca883..7288940 100644
@@ -30,8 +30,9 @@ struct nvc0_ltcg_priv {
 	struct nouveau_ltcg base;
 	u32 part_nr;
 	u32 subp_nr;
-	struct nouveau_mm tags;
 	u32 num_tags;
+	u32 tag_base;
+	struct nouveau_mm tags;
 	struct nouveau_mm_node *tag_ram;
 };
 
@@ -117,10 +118,6 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
 	u32 tag_size, tag_margin, tag_align;
 	int ret;
 
-	nv_wr32(priv, 0x17e8d8, priv->part_nr);
-	if (nv_device(pfb)->card_type >= NV_E0)
-		nv_wr32(priv, 0x17e000, priv->part_nr);
-
 	/* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */
 	priv->num_tags = (pfb->ram->size >> 17) / 4;
 	if (priv->num_tags > (1 << 17))
@@ -152,7 +149,7 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
 		tag_base += tag_align - 1;
 		ret = do_div(tag_base, tag_align);
 
-		nv_wr32(priv, 0x17e8d4, tag_base);
+		priv->tag_base = tag_base;
 	}
 	ret = nouveau_mm_init(&priv->tags, 0, priv->num_tags, 1);
 
@@ -182,8 +179,6 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	}
 	priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28;
 
-	nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
-
 	ret = nvc0_ltcg_init_tag_ram(pfb, priv);
 	if (ret)
 		return ret;
@@ -209,13 +204,36 @@ nvc0_ltcg_dtor(struct nouveau_object *object)
 	nouveau_ltcg_destroy(ltcg);
 }
 
+int
+nvc0_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 nouveau_fb *pfb = nouveau_fb(ltcg->base.base.parent);
+	int ret;
+
+	ret = nouveau_subdev_init(&pfb->base);
+	if (ret)
+		return ret;
+
+	nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
+
+	nv_wr32(priv, 0x17e8d8, priv->part_nr);
+	if (nv_device(pfb)->card_type >= NV_E0)
+		nv_wr32(priv, 0x17e000, priv->part_nr);
+
+	nv_wr32(priv, 0x17e8d4, priv->tag_base);
+
+	return 0;
+}
+
 struct nouveau_oclass
 nvc0_ltcg_oclass = {
 	.handle = NV_SUBDEV(LTCG, 0xc0),
 	.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nvc0_ltcg_ctor,
 		.dtor = nvc0_ltcg_dtor,
-		.init = _nouveau_ltcg_init,
+		.init = nvc0_ltcg_init,
 		.fini = _nouveau_ltcg_fini,
 	},
 };
#1 lore raw
Quoted 50 lines · Maarten Lankhorst

Some registers were not initialized in init, this causes them to be uninitialized after suspend.

---

drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +3 -8
index bcca883..7288940 100644
@@ -30,8 +30,9 @@ struct nvc0_ltcg_priv {
        struct nouveau_ltcg base;
        u32 part_nr;
        u32 subp_nr;
-       struct nouveau_mm tags;
        u32 num_tags;
+       u32 tag_base;
+       struct nouveau_mm tags;
        struct nouveau_mm_node *tag_ram;
 };
 
@@ -117,10 +118,6 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
        u32 tag_size, tag_margin, tag_align;
        int ret;
 
-       nv_wr32(priv, 0x17e8d8, priv->part_nr);
-       if (nv_device(pfb)->card_type >= NV_E0)
-               nv_wr32(priv, 0x17e000, priv->part_nr);
-
        /* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */
        priv->num_tags = (pfb->ram->size >> 17) / 4;
        if (priv->num_tags > (1 << 17))
@@ -152,7 +149,7 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
                tag_base += tag_align - 1;
                ret = do_div(tag_base, tag_align);
 
-               nv_wr32(priv, 0x17e8d4, tag_base);
+               priv->tag_base = tag_base;
        }
        ret = nouveau_mm_init(&priv->tags, 0, priv->num_tags, 1);
 
@@ -182,8 +179,6 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        }
        priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28;
 
-       nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
-
        ret = nvc0_ltcg_init_tag_ram(pfb, priv);
        if (ret)
                return ret;

drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c nvc0_ltcg_dtor(struct nouveau_object *object) · line 208

Quoted 5 lines
drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +2 -0
@@ -209,13 +204,36 @@ nvc0_ltcg_dtor(struct nouveau_object *object)
        nouveau_ltcg_destroy(ltcg);
 }
 
+int
+nvc0_ltcg_init(struct nouveau_object *object)

This should probably be a static int.

drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c nvc0_ltcg_dtor(struct nouveau_object *object) · line 212

Quoted 4 lines
drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +4 -0
+{
+       struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object;
+       struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
+       struct nouveau_fb *pfb = nouveau_fb(ltcg->base.base.parent);

Hm, it's all a bit confusing, but wouldn't nouveau_fb(ltcg) (or priv) work just fine here? nv_device looks at ->parent... but perhaps not hard enough :)

drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c nvc0_ltcg_dtor(struct nouveau_object *object) · line 215

Quoted 3 lines
drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +3 -0
+       int ret;
+
+       ret = nouveau_subdev_init(&pfb->base);

Should this be &ltcg->base? (Or nouveau_ltcg_init(ltcg) for consistency...)

Quoted 30 lines
drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +15 -1
+       if (ret)
+               return ret;
+
+       nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
+
+       nv_wr32(priv, 0x17e8d8, priv->part_nr);
+       if (nv_device(pfb)->card_type >= NV_E0)
+               nv_wr32(priv, 0x17e000, priv->part_nr);
+
+       nv_wr32(priv, 0x17e8d4, priv->tag_base);
+
+       return 0;
+}
+
 struct nouveau_oclass
 nvc0_ltcg_oclass = {
        .handle = NV_SUBDEV(LTCG, 0xc0),
        .ofuncs = &(struct nouveau_ofuncs) {
                .ctor = nvc0_ltcg_ctor,
                .dtor = nvc0_ltcg_dtor,
-               .init = _nouveau_ltcg_init,
+               .init = nvc0_ltcg_init,
                .fini = _nouveau_ltcg_fini,
        },
 };

_______________________________________________
Nouveau mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau

A message that is not in the archive (sent off-list or not yet received): CAKb7UvgddSoPofO4pHoFjp74oWErxHWK=JTykvJ4JkpiCxoLWg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org

#3 lore raw

Op 12-08-13 18:19, Ilia Mirkin schreef:

Quoted 55 lines
Quoted 53 lines · Maarten Lankhorst

Some registers were not initialized in init, this causes them to be uninitialized after suspend.

---

drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +3 -8
index bcca883..7288940 100644
@@ -30,8 +30,9 @@ struct nvc0_ltcg_priv {
        struct nouveau_ltcg base;
        u32 part_nr;
        u32 subp_nr;
-       struct nouveau_mm tags;
        u32 num_tags;
+       u32 tag_base;
+       struct nouveau_mm tags;
        struct nouveau_mm_node *tag_ram;
 };
 
@@ -117,10 +118,6 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
        u32 tag_size, tag_margin, tag_align;
        int ret;
 
-       nv_wr32(priv, 0x17e8d8, priv->part_nr);
-       if (nv_device(pfb)->card_type >= NV_E0)
-               nv_wr32(priv, 0x17e000, priv->part_nr);
-
        /* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */
        priv->num_tags = (pfb->ram->size >> 17) / 4;
        if (priv->num_tags > (1 << 17))
@@ -152,7 +149,7 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
                tag_base += tag_align - 1;
                ret = do_div(tag_base, tag_align);
 
-               nv_wr32(priv, 0x17e8d4, tag_base);
+               priv->tag_base = tag_base;
        }
        ret = nouveau_mm_init(&priv->tags, 0, priv->num_tags, 1);
 
@@ -182,8 +179,6 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        }
        priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28;
 
-       nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
-
        ret = nvc0_ltcg_init_tag_ram(pfb, priv);
        if (ret)
                return ret;
@@ -209,13 +204,36 @@ nvc0_ltcg_dtor(struct nouveau_object *object)
        nouveau_ltcg_destroy(ltcg);
 }
 
Quoted 3 lines

drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c nvc0_ltcg_dtor(struct nouveau_object *object) · line 208

Quoted 2 lines
drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +2 -0
+int
+nvc0_ltcg_init(struct nouveau_object *object)

This should probably be a static int.

Yeah.

Quoted 7 lines

drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c nvc0_ltcg_dtor(struct nouveau_object *object) · line 212

Quoted 4 lines
drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +4 -0
+{
+       struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object;
+       struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
+       struct nouveau_fb *pfb = nouveau_fb(ltcg->base.base.parent);

Hm, it's all a bit confusing, but wouldn't nouveau_fb(ltcg) (or priv) work just fine here? nv_device looks at ->parent... but perhaps not hard enough :)

I was copying the assignments from the dtor. I guess it could be cleaned up.

Quoted 4 lines

drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c nvc0_ltcg_dtor(struct nouveau_object *object) · line 215

Quoted 3 lines
drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +3 -0
+       int ret;
+
+       ret = nouveau_subdev_init(&pfb->base);

Should this be &ltcg->base? (Or nouveau_ltcg_init(ltcg) for consistency...)

Ugh you're right. Thanks for catching it.

Quoted 31 lines
Quoted 31 lines
drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +15 -1
+       if (ret)
+               return ret;
+
+       nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
+
+       nv_wr32(priv, 0x17e8d8, priv->part_nr);
+       if (nv_device(pfb)->card_type >= NV_E0)
+               nv_wr32(priv, 0x17e000, priv->part_nr);
+
+       nv_wr32(priv, 0x17e8d4, priv->tag_base);
+
+       return 0;
+}
+
 struct nouveau_oclass
 nvc0_ltcg_oclass = {
        .handle = NV_SUBDEV(LTCG, 0xc0),
        .ofuncs = &(struct nouveau_ofuncs) {
                .ctor = nvc0_ltcg_ctor,
                .dtor = nvc0_ltcg_dtor,
-               .init = _nouveau_ltcg_init,
+               .init = nvc0_ltcg_init,
                .fini = _nouveau_ltcg_fini,
        },
 };

_______________________________________________
Nouveau mailing list [email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau