drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c
Extension
.c
Size
6166 bytes
Lines
217
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct nv44_mpeg {
	struct nvkm_engine engine;
	struct list_head chan;
};

/*******************************************************************************
 * PMPEG context
 ******************************************************************************/
#define nv44_mpeg_chan(p) container_of((p), struct nv44_mpeg_chan, object)

struct nv44_mpeg_chan {
	struct nvkm_object object;
	struct nv44_mpeg *mpeg;
	struct nvkm_chan *fifo;
	struct list_head head;
	u32 inst;
};

static int
nv44_mpeg_chan_bind(struct nvkm_object *object, struct nvkm_gpuobj *parent,
		    int align, struct nvkm_gpuobj **pgpuobj)
{
	struct nv44_mpeg_chan *chan = nv44_mpeg_chan(object);
	int ret = nvkm_gpuobj_new(chan->object.engine->subdev.device, 264 * 4,
				  align, true, parent, pgpuobj);
	if (ret == 0) {
		chan->inst = (*pgpuobj)->addr;
		nvkm_kmap(*pgpuobj);
		nvkm_wo32(*pgpuobj, 0x78, 0x02001ec1);
		nvkm_done(*pgpuobj);
	}
	return ret;
}

static int
nv44_mpeg_chan_fini(struct nvkm_object *object, enum nvkm_suspend_state suspend)
{

	struct nv44_mpeg_chan *chan = nv44_mpeg_chan(object);
	struct nv44_mpeg *mpeg = chan->mpeg;
	struct nvkm_device *device = mpeg->engine.subdev.device;
	u32 inst = 0x80000000 | (chan->inst >> 4);

	nvkm_mask(device, 0x00b32c, 0x00000001, 0x00000000);
	if (nvkm_rd32(device, 0x00b318) == inst)
		nvkm_mask(device, 0x00b318, 0x80000000, 0x00000000);
	nvkm_mask(device, 0x00b32c, 0x00000001, 0x00000001);
	return 0;
}

static void *
nv44_mpeg_chan_dtor(struct nvkm_object *object)
{
	struct nv44_mpeg_chan *chan = nv44_mpeg_chan(object);
	struct nv44_mpeg *mpeg = chan->mpeg;
	unsigned long flags;
	spin_lock_irqsave(&mpeg->engine.lock, flags);
	list_del(&chan->head);
	spin_unlock_irqrestore(&mpeg->engine.lock, flags);
	return chan;
}

static const struct nvkm_object_func
nv44_mpeg_chan = {
	.dtor = nv44_mpeg_chan_dtor,
	.fini = nv44_mpeg_chan_fini,
	.bind = nv44_mpeg_chan_bind,
};

static int
nv44_mpeg_chan_new(struct nvkm_chan *fifoch, const struct nvkm_oclass *oclass,
		   struct nvkm_object **pobject)
{
	struct nv44_mpeg *mpeg = nv44_mpeg(oclass->engine);
	struct nv44_mpeg_chan *chan;
	unsigned long flags;

	if (!(chan = kzalloc_obj(*chan)))
		return -ENOMEM;
	nvkm_object_ctor(&nv44_mpeg_chan, oclass, &chan->object);
	chan->mpeg = mpeg;
	chan->fifo = fifoch;
	*pobject = &chan->object;

	spin_lock_irqsave(&mpeg->engine.lock, flags);
	list_add(&chan->head, &mpeg->chan);
	spin_unlock_irqrestore(&mpeg->engine.lock, flags);
	return 0;
}

Annotation

Implementation Notes