brintos

brintos / linux-shallow public Read only

0
0
Text · 7.2 KiB · e50a94b Raw
253 lines · c
1/*2 * Copyright 2012 Red Hat Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: Ben Skeggs23 */24#include "priv.h"25#include "cgrp.h"26#include "chan.h"27#include "chid.h"28#include "runl.h"29 30#include "regsnv04.h"31 32#include <core/ramht.h>33#include <subdev/fb.h>34#include <subdev/instmem.h>35 36#include <nvif/class.h>37 38static int39nv40_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, bool priv)40{41	struct nvkm_memory *ramfc = chan->cgrp->runl->fifo->engine.subdev.device->imem->ramfc;42	const u32 base = chan->id * 128;43 44	chan->ramfc_offset = base;45 46	nvkm_kmap(ramfc);47	nvkm_wo32(ramfc, base + 0x00, offset);48	nvkm_wo32(ramfc, base + 0x04, offset);49	nvkm_wo32(ramfc, base + 0x0c, chan->push->addr >> 4);50	nvkm_wo32(ramfc, base + 0x18, 0x30000000 |51				      NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |52				      NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |53#ifdef __BIG_ENDIAN54				      NV_PFIFO_CACHE1_BIG_ENDIAN |55#endif56				      NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);57	nvkm_wo32(ramfc, base + 0x3c, 0x0001ffff);58	nvkm_done(ramfc);59	return 0;60}61 62static const struct nvkm_chan_func_ramfc63nv40_chan_ramfc = {64	.layout = (const struct nvkm_ramfc_layout[]) {65		{ 32,  0, 0x00,  0, NV04_PFIFO_CACHE1_DMA_PUT },66		{ 32,  0, 0x04,  0, NV04_PFIFO_CACHE1_DMA_GET },67		{ 32,  0, 0x08,  0, NV10_PFIFO_CACHE1_REF_CNT },68		{ 32,  0, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_INSTANCE },69		{ 32,  0, 0x10,  0, NV04_PFIFO_CACHE1_DMA_DCOUNT },70		{ 32,  0, 0x14,  0, NV04_PFIFO_CACHE1_DMA_STATE },71		{ 28,  0, 0x18,  0, NV04_PFIFO_CACHE1_DMA_FETCH },72		{  2, 28, 0x18, 28, 0x002058 },73		{ 32,  0, 0x1c,  0, NV04_PFIFO_CACHE1_ENGINE },74		{ 32,  0, 0x20,  0, NV04_PFIFO_CACHE1_PULL1 },75		{ 32,  0, 0x24,  0, NV10_PFIFO_CACHE1_ACQUIRE_VALUE },76		{ 32,  0, 0x28,  0, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP },77		{ 32,  0, 0x2c,  0, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT },78		{ 32,  0, 0x30,  0, NV10_PFIFO_CACHE1_SEMAPHORE },79		{ 32,  0, 0x34,  0, NV10_PFIFO_CACHE1_DMA_SUBROUTINE },80		{ 32,  0, 0x38,  0, NV40_PFIFO_GRCTX_INSTANCE },81		{ 17,  0, 0x3c,  0, NV04_PFIFO_DMA_TIMESLICE },82		{ 32,  0, 0x40,  0, 0x0032e4 },83		{ 32,  0, 0x44,  0, 0x0032e8 },84		{ 32,  0, 0x4c,  0, 0x002088 },85		{ 32,  0, 0x50,  0, 0x003300 },86		{ 32,  0, 0x54,  0, 0x00330c },87		{}88	},89	.write = nv40_chan_ramfc_write,90	.clear = nv04_chan_ramfc_clear,91	.ctxdma = true,92};93 94static const struct nvkm_chan_func_userd95nv40_chan_userd = {96	.bar = 0,97	.base = 0xc00000,98	.size = 0x001000,99};100 101static const struct nvkm_chan_func102nv40_chan = {103	.inst = &nv04_chan_inst,104	.userd = &nv40_chan_userd,105	.ramfc = &nv40_chan_ramfc,106	.start = nv04_chan_start,107	.stop = nv04_chan_stop,108};109 110static int111nv40_eobj_ramht_add(struct nvkm_engn *engn, struct nvkm_object *eobj, struct nvkm_chan *chan)112{113	struct nvkm_fifo *fifo = chan->cgrp->runl->fifo;114	struct nvkm_instmem *imem = fifo->engine.subdev.device->imem;115	u32 context = chan->id << 23 | engn->id << 20;116	int hash;117 118	mutex_lock(&fifo->mutex);119	hash = nvkm_ramht_insert(imem->ramht, eobj, chan->id, 4, eobj->handle, context);120	mutex_unlock(&fifo->mutex);121	return hash;122}123 124static void125nv40_ectx_bind(struct nvkm_engn *engn, struct nvkm_cctx *cctx, struct nvkm_chan *chan)126{127	struct nvkm_fifo *fifo = chan->cgrp->runl->fifo;128	struct nvkm_device *device = fifo->engine.subdev.device;129	struct nvkm_memory *ramfc = device->imem->ramfc;130	u32 inst = 0x00000000, reg, ctx;131	int chid;132 133	switch (engn->engine->subdev.type) {134	case NVKM_ENGINE_GR:135		reg = 0x0032e0;136		ctx = 0x38;137		break;138	case NVKM_ENGINE_MPEG:139		if (WARN_ON(device->chipset < 0x44))140			return;141		reg = 0x00330c;142		ctx = 0x54;143		break;144	default:145		WARN_ON(1);146		return;147	}148 149	if (cctx)150		inst = cctx->vctx->inst->addr >> 4;151 152	spin_lock_irq(&fifo->lock);153	nvkm_mask(device, 0x002500, 0x00000001, 0x00000000);154 155	chid = nvkm_rd32(device, 0x003204) & (fifo->chid->nr - 1);156	if (chid == chan->id)157		nvkm_wr32(device, reg, inst);158 159	nvkm_kmap(ramfc);160	nvkm_wo32(ramfc, chan->ramfc_offset + ctx, inst);161	nvkm_done(ramfc);162 163	nvkm_mask(device, 0x002500, 0x00000001, 0x00000001);164	spin_unlock_irq(&fifo->lock);165}166 167static const struct nvkm_engn_func168nv40_engn = {169	.bind = nv40_ectx_bind,170	.ramht_add = nv40_eobj_ramht_add,171	.ramht_del = nv04_eobj_ramht_del,172};173 174static const struct nvkm_engn_func175nv40_engn_sw = {176	.ramht_add = nv40_eobj_ramht_add,177	.ramht_del = nv04_eobj_ramht_del,178};179 180static void181nv40_fifo_init(struct nvkm_fifo *fifo)182{183	struct nvkm_device *device = fifo->engine.subdev.device;184	struct nvkm_fb *fb = device->fb;185	struct nvkm_instmem *imem = device->imem;186	struct nvkm_ramht *ramht = imem->ramht;187	struct nvkm_memory *ramro = imem->ramro;188	struct nvkm_memory *ramfc = imem->ramfc;189 190	nvkm_wr32(device, 0x002040, 0x000000ff);191	nvkm_wr32(device, 0x002044, 0x2101ffff);192	nvkm_wr32(device, 0x002058, 0x00000001);193 194	nvkm_wr32(device, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |195					    ((ramht->bits - 9) << 16) |196					    (ramht->gpuobj->addr >> 8));197	nvkm_wr32(device, NV03_PFIFO_RAMRO, nvkm_memory_addr(ramro) >> 8);198 199	switch (device->chipset) {200	case 0x47:201	case 0x49:202	case 0x4b:203		nvkm_wr32(device, 0x002230, 0x00000001);204		fallthrough;205	case 0x40:206	case 0x41:207	case 0x42:208	case 0x43:209	case 0x45:210	case 0x48:211		nvkm_wr32(device, 0x002220, 0x00030002);212		break;213	default:214		nvkm_wr32(device, 0x002230, 0x00000000);215		nvkm_wr32(device, 0x002220, ((fb->ram->size - 512 * 1024 +216					      nvkm_memory_addr(ramfc)) >> 16) |217					    0x00030000);218		break;219	}220 221	nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH1, fifo->chid->mask);222 223	nvkm_wr32(device, NV03_PFIFO_INTR_0, 0xffffffff);224	nvkm_wr32(device, NV03_PFIFO_INTR_EN_0, 0xffffffff);225 226	nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH0, 1);227	nvkm_wr32(device, NV04_PFIFO_CACHE1_PULL0, 1);228	nvkm_wr32(device, NV03_PFIFO_CACHES, 1);229}230 231static const struct nvkm_fifo_func232nv40_fifo = {233	.chid_nr = nv10_fifo_chid_nr,234	.chid_ctor = nv04_fifo_chid_ctor,235	.runl_ctor = nv04_fifo_runl_ctor,236	.init = nv40_fifo_init,237	.intr = nv04_fifo_intr,238	.pause = nv04_fifo_pause,239	.start = nv04_fifo_start,240	.runl = &nv04_runl,241	.engn = &nv40_engn,242	.engn_sw = &nv40_engn_sw,243	.cgrp = {{                        }, &nv04_cgrp },244	.chan = {{ 0, 0, NV40_CHANNEL_DMA }, &nv40_chan },245};246 247int248nv40_fifo_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,249	      struct nvkm_fifo **pfifo)250{251	return nvkm_fifo_new_(&nv40_fifo, device, type, inst, pfifo);252}253