nv40.c 4.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 * Copyright 2012 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: Ben Skeggs
 */
24
#include "nv04.h"
25

26
#include <core/ramht.h>
27
#include <engine/gr/nv40.h>
28

29 30 31 32 33
/******************************************************************************
 * instmem subdev implementation
 *****************************************************************************/

static u32
34
nv40_instmem_rd32(struct nvkm_object *object, u64 addr)
35 36 37 38 39 40
{
	struct nv04_instmem_priv *priv = (void *)object;
	return ioread32_native(priv->iomem + addr);
}

static void
41
nv40_instmem_wr32(struct nvkm_object *object, u64 addr, u32 data)
42 43 44 45 46
{
	struct nv04_instmem_priv *priv = (void *)object;
	iowrite32_native(data, priv->iomem + addr);
}

47
static int
48 49 50
nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
		  struct nvkm_oclass *oclass, void *data, u32 size,
		  struct nvkm_object **pobject)
51
{
52
	struct nvkm_device *device = nv_device(parent);
53
	struct nv04_instmem_priv *priv;
54
	int ret, bar, vs;
55

56
	ret = nvkm_instmem_create(parent, engine, oclass, &priv);
57 58 59 60 61
	*pobject = nv_object(priv);
	if (ret)
		return ret;

	/* map bar */
A
Alexandre Courbot 已提交
62
	if (nv_device_resource_len(device, 2))
63 64 65 66
		bar = 2;
	else
		bar = 3;

A
Alexandre Courbot 已提交
67 68
	priv->iomem = ioremap(nv_device_resource_start(device, bar),
			      nv_device_resource_len(device, bar));
69 70 71 72
	if (!priv->iomem) {
		nv_error(priv, "unable to map PRAMIN BAR\n");
		return -EFAULT;
	}
73

74 75
	/* PRAMIN aperture maps over the end of vram, reserve enough space
	 * to fit graphics contexts for every channel, the magics come
76
	 * from engine/gr/nv40.c
77
	 */
78 79 80
	vs = hweight8((nv_rd32(priv, 0x001540) & 0x0000ff00) >> 8);
	if      (device->chipset == 0x40) priv->base.reserved = 0x6aa0 * vs;
	else if (device->chipset  < 0x43) priv->base.reserved = 0x4f00 * vs;
81
	else if (nv44_gr_class(priv))  priv->base.reserved = 0x4980 * vs;
82 83 84 85 86 87 88 89
	else				  priv->base.reserved = 0x4a40 * vs;
	priv->base.reserved += 16 * 1024;
	priv->base.reserved *= 32;		/* per-channel */
	priv->base.reserved += 512 * 1024;	/* pci(e)gart table */
	priv->base.reserved += 512 * 1024;	/* object storage */

	priv->base.reserved = round_up(priv->base.reserved, 4096);

90
	ret = nvkm_mm_init(&priv->heap, 0, priv->base.reserved, 1);
91 92 93
	if (ret)
		return ret;

94
	/* 0x00000-0x10000: reserve for probable vbios image */
95 96
	ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x10000, 0, 0,
			      &priv->vbios);
97 98 99
	if (ret)
		return ret;

100
	/* 0x10000-0x18000: reserve for RAMHT */
101
	ret = nvkm_ramht_new(nv_object(priv), NULL, 0x08000, 0, &priv->ramht);
102 103 104
	if (ret)
		return ret;

105 106 107
	/* 0x18000-0x18200: reserve for RAMRO
	 * 0x18200-0x20000: padding
	 */
108 109
	ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x08000, 0, 0,
			      &priv->ramro);
110 111 112
	if (ret)
		return ret;

113
	/* 0x20000-0x21000: reserve for RAMFC
114
	 * 0x21000-0x40000: padding and some unknown crap
115
	 */
116 117
	ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x20000, 0,
			      NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc);
118
	if (ret)
119 120 121 122 123
		return ret;

	return 0;
}

124 125
struct nvkm_oclass *
nv40_instmem_oclass = &(struct nvkm_instmem_impl) {
126
	.base.handle = NV_SUBDEV(INSTMEM, 0x40),
127
	.base.ofuncs = &(struct nvkm_ofuncs) {
128 129
		.ctor = nv40_instmem_ctor,
		.dtor = nv04_instmem_dtor,
130 131
		.init = _nvkm_instmem_init,
		.fini = _nvkm_instmem_fini,
132 133 134
		.rd32 = nv40_instmem_rd32,
		.wr32 = nv40_instmem_wr32,
	},
135
	.instobj = &nv04_instobj_oclass.base,
136
}.base;