Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 317b07b5 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-nouveau-next' of...

Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-fixes

regression fixes and null derefs and oops fixes.

* 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6:
  drm/nv04/disp: fix framebuffer pin refcounting
  drm/nouveau/mc: fix race condition between constructor and request_irq()
  drm/nouveau: fix reclocking on nv40
  drm/nouveau/ltcg: fix allocating memory as free
  drm/nouveau/ltcg: fix ltcg memory initialization after suspend
  drm/nouveau/fb: fix null derefs in nv49 and nv4e init
parents 3387ed83 78ae0ad4
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -98,6 +98,8 @@ nouveau_mm_head(struct nouveau_mm *mm, u8 type, u32 size_max, u32 size_min,
	u32 splitoff;
	u32 splitoff;
	u32 s, e;
	u32 s, e;


	BUG_ON(!type);

	list_for_each_entry(this, &mm->free, fl_entry) {
	list_for_each_entry(this, &mm->free, fl_entry) {
		e = this->offset + this->length;
		e = this->offset + this->length;
		s = this->offset;
		s = this->offset;
@@ -162,6 +164,8 @@ nouveau_mm_tail(struct nouveau_mm *mm, u8 type, u32 size_max, u32 size_min,
	struct nouveau_mm_node *prev, *this, *next;
	struct nouveau_mm_node *prev, *this, *next;
	u32 mask = align - 1;
	u32 mask = align - 1;


	BUG_ON(!type);

	list_for_each_entry_reverse(this, &mm->free, fl_entry) {
	list_for_each_entry_reverse(this, &mm->free, fl_entry) {
		u32 e = this->offset + this->length;
		u32 e = this->offset + this->length;
		u32 s = this->offset;
		u32 s = this->offset;
+4 −3
Original line number Original line Diff line number Diff line
@@ -20,8 +20,8 @@ nouveau_mc(void *obj)
	return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_MC];
	return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_MC];
}
}


#define nouveau_mc_create(p,e,o,d)                                             \
#define nouveau_mc_create(p,e,o,m,d)                                           \
	nouveau_mc_create_((p), (e), (o), sizeof(**d), (void **)d)
	nouveau_mc_create_((p), (e), (o), (m), sizeof(**d), (void **)d)
#define nouveau_mc_destroy(p) ({                                               \
#define nouveau_mc_destroy(p) ({                                               \
	struct nouveau_mc *pmc = (p); _nouveau_mc_dtor(nv_object(pmc));        \
	struct nouveau_mc *pmc = (p); _nouveau_mc_dtor(nv_object(pmc));        \
})
})
@@ -33,7 +33,8 @@ nouveau_mc(void *obj)
})
})


int  nouveau_mc_create_(struct nouveau_object *, struct nouveau_object *,
int  nouveau_mc_create_(struct nouveau_object *, struct nouveau_object *,
			struct nouveau_oclass *, int, void **);
			struct nouveau_oclass *, const struct nouveau_mc_intr *,
			int, void **);
void _nouveau_mc_dtor(struct nouveau_object *);
void _nouveau_mc_dtor(struct nouveau_object *);
int  _nouveau_mc_init(struct nouveau_object *);
int  _nouveau_mc_init(struct nouveau_object *);
int  _nouveau_mc_fini(struct nouveau_object *, bool);
int  _nouveau_mc_fini(struct nouveau_object *, bool);
+6 −6
Original line number Original line Diff line number Diff line
@@ -40,15 +40,15 @@ nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
		return ret;
		return ret;


	switch (pfb914 & 0x00000003) {
	switch (pfb914 & 0x00000003) {
	case 0x00000000: pfb->ram->type = NV_MEM_TYPE_DDR1; break;
	case 0x00000000: ram->type = NV_MEM_TYPE_DDR1; break;
	case 0x00000001: pfb->ram->type = NV_MEM_TYPE_DDR2; break;
	case 0x00000001: ram->type = NV_MEM_TYPE_DDR2; break;
	case 0x00000002: pfb->ram->type = NV_MEM_TYPE_GDDR3; break;
	case 0x00000002: ram->type = NV_MEM_TYPE_GDDR3; break;
	case 0x00000003: break;
	case 0x00000003: break;
	}
	}


	pfb->ram->size  =  nv_rd32(pfb, 0x10020c) & 0xff000000;
	ram->size  =  nv_rd32(pfb, 0x10020c) & 0xff000000;
	pfb->ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
	ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
	pfb->ram->tags  =  nv_rd32(pfb, 0x100320);
	ram->tags  =  nv_rd32(pfb, 0x100320);
	return 0;
	return 0;
}
}


+2 −2
Original line number Original line Diff line number Diff line
@@ -38,8 +38,8 @@ nv4e_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
	if (ret)
	if (ret)
		return ret;
		return ret;


	pfb->ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
	ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
	pfb->ram->type = NV_MEM_TYPE_STOLEN;
	ram->type = NV_MEM_TYPE_STOLEN;
	return 0;
	return 0;
}
}


+24 −10
Original line number Original line Diff line number Diff line
@@ -30,8 +30,9 @@ struct nvc0_ltcg_priv {
	struct nouveau_ltcg base;
	struct nouveau_ltcg base;
	u32 part_nr;
	u32 part_nr;
	u32 subp_nr;
	u32 subp_nr;
	struct nouveau_mm tags;
	u32 num_tags;
	u32 num_tags;
	u32 tag_base;
	struct nouveau_mm tags;
	struct nouveau_mm_node *tag_ram;
	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;
	u32 tag_size, tag_margin, tag_align;
	int ret;
	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) */
	/* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */
	priv->num_tags = (pfb->ram->size >> 17) / 4;
	priv->num_tags = (pfb->ram->size >> 17) / 4;
	if (priv->num_tags > (1 << 17))
	if (priv->num_tags > (1 << 17))
@@ -142,7 +139,7 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
	tag_size += tag_align;
	tag_size += tag_align;
	tag_size  = (tag_size + 0xfff) >> 12; /* round up */
	tag_size  = (tag_size + 0xfff) >> 12; /* round up */


	ret = nouveau_mm_tail(&pfb->vram, 0, tag_size, tag_size, 1,
	ret = nouveau_mm_tail(&pfb->vram, 1, tag_size, tag_size, 1,
	                      &priv->tag_ram);
	                      &priv->tag_ram);
	if (ret) {
	if (ret) {
		priv->num_tags = 0;
		priv->num_tags = 0;
@@ -152,7 +149,7 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
		tag_base += tag_align - 1;
		tag_base += tag_align - 1;
		ret = do_div(tag_base, tag_align);
		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);
	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;
	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);
	ret = nvc0_ltcg_init_tag_ram(pfb, priv);
	if (ret)
	if (ret)
		return ret;
		return ret;
@@ -209,13 +204,32 @@ nvc0_ltcg_dtor(struct nouveau_object *object)
	nouveau_ltcg_destroy(ltcg);
	nouveau_ltcg_destroy(ltcg);
}
}


static 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;
	int ret;

	ret = nouveau_ltcg_init(ltcg);
	if (ret)
		return ret;

	nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
	nv_wr32(priv, 0x17e8d8, priv->part_nr);
	if (nv_device(ltcg)->card_type >= NV_E0)
		nv_wr32(priv, 0x17e000, priv->part_nr);
	nv_wr32(priv, 0x17e8d4, priv->tag_base);
	return 0;
}

struct nouveau_oclass
struct nouveau_oclass
nvc0_ltcg_oclass = {
nvc0_ltcg_oclass = {
	.handle = NV_SUBDEV(LTCG, 0xc0),
	.handle = NV_SUBDEV(LTCG, 0xc0),
	.ofuncs = &(struct nouveau_ofuncs) {
	.ofuncs = &(struct nouveau_ofuncs) {
		.ctor = nvc0_ltcg_ctor,
		.ctor = nvc0_ltcg_ctor,
		.dtor = nvc0_ltcg_dtor,
		.dtor = nvc0_ltcg_dtor,
		.init = _nouveau_ltcg_init,
		.init = nvc0_ltcg_init,
		.fini = _nouveau_ltcg_fini,
		.fini = _nouveau_ltcg_fini,
	},
	},
};
};
Loading