aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/tegra/host/t20/t20.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/tegra/host/t20/t20.c')
-rw-r--r--drivers/video/tegra/host/t20/t20.c233
1 files changed, 233 insertions, 0 deletions
diff --git a/drivers/video/tegra/host/t20/t20.c b/drivers/video/tegra/host/t20/t20.c
new file mode 100644
index 00000000000..24ddedc842e
--- /dev/null
+++ b/drivers/video/tegra/host/t20/t20.c
@@ -0,0 +1,233 @@
1/*
2 * drivers/video/tegra/host/t20/t20.c
3 *
4 * Tegra Graphics Init for T20 Architecture Chips
5 *
6 * Copyright (c) 2011-2012, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/slab.h>
22#include <mach/powergate.h>
23#include "dev.h"
24#include "t20.h"
25#include "host1x/host1x_channel.h"
26#include "host1x/host1x_syncpt.h"
27#include "host1x/host1x_hardware.h"
28#include "host1x/host1x_cdma.h"
29#include "gr3d/gr3d.h"
30#include "gr3d/gr3d_t20.h"
31#include "mpe/mpe.h"
32#include "nvhost_hwctx.h"
33
34#define NVMODMUTEX_2D_FULL (1)
35#define NVMODMUTEX_2D_SIMPLE (2)
36#define NVMODMUTEX_2D_SB_A (3)
37#define NVMODMUTEX_2D_SB_B (4)
38#define NVMODMUTEX_3D (5)
39#define NVMODMUTEX_DISPLAYA (6)
40#define NVMODMUTEX_DISPLAYB (7)
41#define NVMODMUTEX_VI (8)
42#define NVMODMUTEX_DSI (9)
43
44#define NVHOST_NUMCHANNELS (NV_HOST1X_CHANNELS - 1)
45
46struct nvhost_device t20_devices[] = {
47{
48 /* channel 0 */
49 .name = "display",
50 .id = -1,
51 .index = 0,
52 .syncpts = BIT(NVSYNCPT_DISP0_A) | BIT(NVSYNCPT_DISP1_A) |
53 BIT(NVSYNCPT_DISP0_B) | BIT(NVSYNCPT_DISP1_B) |
54 BIT(NVSYNCPT_DISP0_C) | BIT(NVSYNCPT_DISP1_C) |
55 BIT(NVSYNCPT_VBLANK0) | BIT(NVSYNCPT_VBLANK1),
56 .modulemutexes = BIT(NVMODMUTEX_DISPLAYA) | BIT(NVMODMUTEX_DISPLAYB),
57 NVHOST_MODULE_NO_POWERGATE_IDS,
58 NVHOST_DEFAULT_CLOCKGATE_DELAY,
59 .moduleid = NVHOST_MODULE_NONE,
60},
61{
62 /* channel 1 */
63 .name = "gr3d",
64 .id = -1,
65 .index = 1,
66 .syncpts = BIT(NVSYNCPT_3D),
67 .waitbases = BIT(NVWAITBASE_3D),
68 .modulemutexes = BIT(NVMODMUTEX_3D),
69 .class = NV_GRAPHICS_3D_CLASS_ID,
70 .prepare_poweroff = nvhost_gr3d_prepare_power_off,
71 .alloc_hwctx_handler = nvhost_gr3d_t20_ctxhandler_init,
72 .clocks = {{"gr3d", UINT_MAX}, {"emc", UINT_MAX}, {} },
73 .powergate_ids = {TEGRA_POWERGATE_3D, -1},
74 NVHOST_DEFAULT_CLOCKGATE_DELAY,
75 .moduleid = NVHOST_MODULE_NONE,
76},
77{
78 /* channel 2 */
79 .name = "gr2d",
80 .id = -1,
81 .index = 2,
82 .syncpts = BIT(NVSYNCPT_2D_0) | BIT(NVSYNCPT_2D_1),
83 .waitbases = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1),
84 .modulemutexes = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) |
85 BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B),
86 .clocks = { {"gr2d", UINT_MAX},
87 {"epp", UINT_MAX},
88 {"emc", UINT_MAX} },
89 NVHOST_MODULE_NO_POWERGATE_IDS,
90 .clockgate_delay = 0,
91 .moduleid = NVHOST_MODULE_NONE,
92},
93{
94 /* channel 3 */
95 .name = "isp",
96 .id = -1,
97 .index = 3,
98 .syncpts = 0,
99 NVHOST_MODULE_NO_POWERGATE_IDS,
100 NVHOST_DEFAULT_CLOCKGATE_DELAY,
101 .moduleid = NVHOST_MODULE_ISP,
102},
103{
104 /* channel 4 */
105 .name = "vi",
106 .id = -1,
107 .index = 4,
108 .syncpts = BIT(NVSYNCPT_CSI_VI_0) | BIT(NVSYNCPT_CSI_VI_1) |
109 BIT(NVSYNCPT_VI_ISP_0) | BIT(NVSYNCPT_VI_ISP_1) |
110 BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) |
111 BIT(NVSYNCPT_VI_ISP_4),
112 .modulemutexes = BIT(NVMODMUTEX_VI),
113 .exclusive = true,
114 NVHOST_MODULE_NO_POWERGATE_IDS,
115 NVHOST_DEFAULT_CLOCKGATE_DELAY,
116 .moduleid = NVHOST_MODULE_VI,
117},
118{
119 /* channel 5 */
120 .name = "mpe",
121 .id = -1,
122 .index = 5,
123 .syncpts = BIT(NVSYNCPT_MPE) | BIT(NVSYNCPT_MPE_EBM_EOF) |
124 BIT(NVSYNCPT_MPE_WR_SAFE),
125 .waitbases = BIT(NVWAITBASE_MPE),
126 .class = NV_VIDEO_ENCODE_MPEG_CLASS_ID,
127 .waitbasesync = true,
128 .keepalive = true,
129 .prepare_poweroff = nvhost_mpe_prepare_power_off,
130 .alloc_hwctx_handler = nvhost_mpe_ctxhandler_init,
131 .clocks = { {"mpe", UINT_MAX},
132 {"emc", UINT_MAX} },
133 .powergate_ids = {TEGRA_POWERGATE_MPE, -1},
134 NVHOST_DEFAULT_CLOCKGATE_DELAY,
135 .moduleid = NVHOST_MODULE_MPE,
136},
137{
138 /* channel 6 */
139 .name = "dsi",
140 .id = -1,
141 .index = 6,
142 .syncpts = BIT(NVSYNCPT_DSI),
143 .modulemutexes = BIT(NVMODMUTEX_DSI),
144 NVHOST_MODULE_NO_POWERGATE_IDS,
145 NVHOST_DEFAULT_CLOCKGATE_DELAY,
146 .moduleid = NVHOST_MODULE_NONE,
147} };
148
149
150static inline void __iomem *t20_channel_aperture(void __iomem *p, int ndx)
151{
152 p += NV_HOST1X_CHANNEL0_BASE;
153 p += ndx * NV_HOST1X_CHANNEL_MAP_SIZE_BYTES;
154 return p;
155}
156
157static inline int t20_nvhost_hwctx_handler_init(struct nvhost_channel *ch)
158{
159 int err = 0;
160 unsigned long syncpts = ch->dev->syncpts;
161 unsigned long waitbases = ch->dev->waitbases;
162 u32 syncpt = find_first_bit(&syncpts, BITS_PER_LONG);
163 u32 waitbase = find_first_bit(&waitbases, BITS_PER_LONG);
164
165 if (ch->dev->alloc_hwctx_handler) {
166 ch->ctxhandler = ch->dev->alloc_hwctx_handler(syncpt,
167 waitbase, ch);
168 if (!ch->ctxhandler)
169 err = -ENOMEM;
170 }
171
172 return err;
173}
174
175static int t20_channel_init(struct nvhost_channel *ch,
176 struct nvhost_master *dev, int index)
177{
178 ch->chid = index;
179 mutex_init(&ch->reflock);
180 mutex_init(&ch->submitlock);
181
182 ch->aperture = t20_channel_aperture(dev->aperture, index);
183
184 return t20_nvhost_hwctx_handler_init(ch);
185}
186
187int nvhost_init_t20_channel_support(struct nvhost_master *host)
188{
189 host->nb_channels = NVHOST_NUMCHANNELS;
190
191 host->op.channel.init = t20_channel_init;
192 host->op.channel.submit = host1x_channel_submit;
193 host->op.channel.read3dreg = host1x_channel_read_3d_reg;
194
195 return 0;
196}
197
198struct nvhost_device *t20_get_nvhost_device(struct nvhost_master *host,
199 char *name)
200{
201 int i;
202
203 for (i = 0; i < host->nb_channels; i++) {
204 if (strcmp(t20_devices[i].name, name) == 0)
205 return &t20_devices[i];
206 }
207
208 return NULL;
209}
210
211int nvhost_init_t20_support(struct nvhost_master *host)
212{
213 int err;
214
215 /* don't worry about cleaning up on failure... "remove" does it. */
216 err = nvhost_init_t20_channel_support(host);
217 if (err)
218 return err;
219 err = host1x_init_cdma_support(host);
220 if (err)
221 return err;
222 err = nvhost_init_t20_debug_support(host);
223 if (err)
224 return err;
225 err = host1x_init_syncpt_support(host);
226 if (err)
227 return err;
228 err = nvhost_init_t20_intr_support(host);
229 if (err)
230 return err;
231 host->op.nvhost_dev.get_nvhost_device = t20_get_nvhost_device;
232 return 0;
233}