1c39f472eSBen Skeggs /*
2c39f472eSBen Skeggs  * Copyright 2012 Red Hat Inc.
3c39f472eSBen Skeggs  *
4c39f472eSBen Skeggs  * Permission is hereby granted, free of charge, to any person obtaining a
5c39f472eSBen Skeggs  * copy of this software and associated documentation files (the "Software"),
6c39f472eSBen Skeggs  * to deal in the Software without restriction, including without limitation
7c39f472eSBen Skeggs  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8c39f472eSBen Skeggs  * and/or sell copies of the Software, and to permit persons to whom the
9c39f472eSBen Skeggs  * Software is furnished to do so, subject to the following conditions:
10c39f472eSBen Skeggs  *
11c39f472eSBen Skeggs  * The above copyright notice and this permission notice shall be included in
12c39f472eSBen Skeggs  * all copies or substantial portions of the Software.
13c39f472eSBen Skeggs  *
14c39f472eSBen Skeggs  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15c39f472eSBen Skeggs  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16c39f472eSBen Skeggs  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17c39f472eSBen Skeggs  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18c39f472eSBen Skeggs  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19c39f472eSBen Skeggs  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20c39f472eSBen Skeggs  * OTHER DEALINGS IN THE SOFTWARE.
21c39f472eSBen Skeggs  *
22c39f472eSBen Skeggs  * Authors: Ben Skeggs
23c39f472eSBen Skeggs  */
2454dcadd5SBen Skeggs #include "priv.h"
25c39f472eSBen Skeggs 
2687f313e6SBen Skeggs const struct nvkm_mc_map
27667e99abSBen Skeggs nv04_mc_reset[] = {
28667e99abSBen Skeggs 	{ 0x00001000, NVKM_ENGINE_GR },
29667e99abSBen Skeggs 	{ 0x00000100, NVKM_ENGINE_FIFO },
30667e99abSBen Skeggs 	{}
31667e99abSBen Skeggs };
32667e99abSBen Skeggs 
33ebb195dbSBen Skeggs static void
nv04_mc_device_disable(struct nvkm_mc * mc,u32 mask)34ebb195dbSBen Skeggs nv04_mc_device_disable(struct nvkm_mc *mc, u32 mask)
35ebb195dbSBen Skeggs {
36ebb195dbSBen Skeggs 	nvkm_mask(mc->subdev.device, 0x000200, mask, 0x00000000);
37ebb195dbSBen Skeggs }
38ebb195dbSBen Skeggs 
39ebb195dbSBen Skeggs static void
nv04_mc_device_enable(struct nvkm_mc * mc,u32 mask)40ebb195dbSBen Skeggs nv04_mc_device_enable(struct nvkm_mc *mc, u32 mask)
41ebb195dbSBen Skeggs {
42ebb195dbSBen Skeggs 	struct nvkm_device *device = mc->subdev.device;
43ebb195dbSBen Skeggs 
44ebb195dbSBen Skeggs 	nvkm_mask(device, 0x000200, mask, mask);
45ebb195dbSBen Skeggs 	nvkm_rd32(device, 0x000200);
46ebb195dbSBen Skeggs }
47ebb195dbSBen Skeggs 
48ebb195dbSBen Skeggs static bool
nv04_mc_device_enabled(struct nvkm_mc * mc,u32 mask)49ebb195dbSBen Skeggs nv04_mc_device_enabled(struct nvkm_mc *mc, u32 mask)
50ebb195dbSBen Skeggs {
51ebb195dbSBen Skeggs 	return (nvkm_rd32(mc->subdev.device, 0x000200) & mask) == mask;
52ebb195dbSBen Skeggs }
53ebb195dbSBen Skeggs 
54ebb195dbSBen Skeggs const struct nvkm_mc_device_func
55ebb195dbSBen Skeggs nv04_mc_device = {
56ebb195dbSBen Skeggs 	.enabled = nv04_mc_device_enabled,
57ebb195dbSBen Skeggs 	.enable = nv04_mc_device_enable,
58ebb195dbSBen Skeggs 	.disable = nv04_mc_device_disable,
59ebb195dbSBen Skeggs };
60ebb195dbSBen Skeggs 
61fe76fe49SBen Skeggs static const struct nvkm_intr_data
62fe76fe49SBen Skeggs nv04_mc_intrs[] = {
63fe76fe49SBen Skeggs 	{ NVKM_ENGINE_DISP , 0, 0, 0x01010000, true },
64fe76fe49SBen Skeggs 	{ NVKM_ENGINE_GR   , 0, 0, 0x00001000, true },
65*2fc71a05SBen Skeggs 	{ NVKM_ENGINE_FIFO , 0, 0, 0x00000100 },
66fe76fe49SBen Skeggs 	{ NVKM_SUBDEV_BUS  , 0, 0, 0x10000000, true },
67fe76fe49SBen Skeggs 	{ NVKM_SUBDEV_TIMER, 0, 0, 0x00100000, true },
68c39f472eSBen Skeggs 	{}
69c39f472eSBen Skeggs };
70c39f472eSBen Skeggs 
7154dcadd5SBen Skeggs void
nv04_mc_intr_rearm(struct nvkm_intr * intr)72fe76fe49SBen Skeggs nv04_mc_intr_rearm(struct nvkm_intr *intr)
73d4c4cc83SBen Skeggs {
74fe76fe49SBen Skeggs 	struct nvkm_mc *mc = container_of(intr, typeof(*mc), intr);
75fe76fe49SBen Skeggs 	int leaf;
76fe76fe49SBen Skeggs 
77fe76fe49SBen Skeggs 	for (leaf = 0; leaf < intr->leaves; leaf++)
78fe76fe49SBen Skeggs 		nvkm_wr32(mc->subdev.device, 0x000140 + (leaf * 4), 0x00000001);
79d4c4cc83SBen Skeggs }
80d4c4cc83SBen Skeggs 
81d4c4cc83SBen Skeggs void
nv04_mc_intr_unarm(struct nvkm_intr * intr)82fe76fe49SBen Skeggs nv04_mc_intr_unarm(struct nvkm_intr *intr)
83d4c4cc83SBen Skeggs {
84fe76fe49SBen Skeggs 	struct nvkm_mc *mc = container_of(intr, typeof(*mc), intr);
85fe76fe49SBen Skeggs 	int leaf;
86fe76fe49SBen Skeggs 
87fe76fe49SBen Skeggs 	for (leaf = 0; leaf < intr->leaves; leaf++)
88fe76fe49SBen Skeggs 		nvkm_wr32(mc->subdev.device, 0x000140 + (leaf * 4), 0x00000000);
89fe76fe49SBen Skeggs 
90fe76fe49SBen Skeggs 	nvkm_rd32(mc->subdev.device, 0x000140);
91d4c4cc83SBen Skeggs }
92d4c4cc83SBen Skeggs 
93fe76fe49SBen Skeggs bool
nv04_mc_intr_pending(struct nvkm_intr * intr)94fe76fe49SBen Skeggs nv04_mc_intr_pending(struct nvkm_intr *intr)
95d4c4cc83SBen Skeggs {
96fe76fe49SBen Skeggs 	struct nvkm_mc *mc = container_of(intr, typeof(*mc), intr);
97fe76fe49SBen Skeggs 	bool pending = false;
98fe76fe49SBen Skeggs 	int leaf;
99fe76fe49SBen Skeggs 
100fe76fe49SBen Skeggs 	for (leaf = 0; leaf < intr->leaves; leaf++) {
101fe76fe49SBen Skeggs 		intr->stat[leaf] = nvkm_rd32(mc->subdev.device, 0x000100 + (leaf * 4));
102fe76fe49SBen Skeggs 		if (intr->stat[leaf])
103fe76fe49SBen Skeggs 			pending = true;
104d4c4cc83SBen Skeggs 	}
105d4c4cc83SBen Skeggs 
106fe76fe49SBen Skeggs 	return pending;
107fe76fe49SBen Skeggs }
108fe76fe49SBen Skeggs 
109fe76fe49SBen Skeggs const struct nvkm_intr_func
110fe76fe49SBen Skeggs nv04_mc_intr = {
111fe76fe49SBen Skeggs 	.pending = nv04_mc_intr_pending,
112fe76fe49SBen Skeggs 	.unarm = nv04_mc_intr_unarm,
113fe76fe49SBen Skeggs 	.rearm = nv04_mc_intr_rearm,
114fe76fe49SBen Skeggs };
115fe76fe49SBen Skeggs 
116d4c4cc83SBen Skeggs void
nv04_mc_init(struct nvkm_mc * mc)11754dcadd5SBen Skeggs nv04_mc_init(struct nvkm_mc *mc)
118c39f472eSBen Skeggs {
11925e3a463SBen Skeggs 	struct nvkm_device *device = mc->subdev.device;
12025e3a463SBen Skeggs 	nvkm_wr32(device, 0x000200, 0xffffffff); /* everything enabled */
12125e3a463SBen Skeggs 	nvkm_wr32(device, 0x001850, 0x00000001); /* disable rom access */
122c39f472eSBen Skeggs }
123c39f472eSBen Skeggs 
12454dcadd5SBen Skeggs static const struct nvkm_mc_func
12554dcadd5SBen Skeggs nv04_mc = {
12654dcadd5SBen Skeggs 	.init = nv04_mc_init,
127fe76fe49SBen Skeggs 	.intr = &nv04_mc_intr,
128fe76fe49SBen Skeggs 	.intrs = nv04_mc_intrs,
129ebb195dbSBen Skeggs 	.device = &nv04_mc_device,
130d85e2a8dSBen Skeggs 	.reset = nv04_mc_reset,
13154dcadd5SBen Skeggs };
13254dcadd5SBen Skeggs 
133c39f472eSBen Skeggs int
nv04_mc_new(struct nvkm_device * device,enum nvkm_subdev_type type,int inst,struct nvkm_mc ** pmc)1341fc2fddfSBen Skeggs nv04_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc)
135c39f472eSBen Skeggs {
1361fc2fddfSBen Skeggs 	return nvkm_mc_new_(&nv04_mc, device, type, inst, pmc);
137c39f472eSBen Skeggs }
138