aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/tegra/host/t30/t30.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/tegra/host/t30/t30.c')
-rw-r--r--drivers/video/tegra/host/t30/t30.c251
1 files changed, 251 insertions, 0 deletions
diff --git a/drivers/video/tegra/host/t30/t30.c b/drivers/video/tegra/host/t30/t30.c
new file mode 100644
index 00000000000..8a8b1f4d924
--- /dev/null
+++ b/drivers/video/tegra/host/t30/t30.c
@@ -0,0 +1,251 @@
1/*
2 * drivers/video/tegra/host/t30/t30.c
3 *
4 * Tegra Graphics Init for T30 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/mutex.h>
22#include <mach/powergate.h>
23#include <mach/iomap.h>
24#include "dev.h"
25#include "t20/t20.h"
26#include "t30.h"
27#include "gr3d/gr3d.h"
28#include "mpe/mpe.h"
29#include "gr3d/gr3d_t30.h"
30#include "gr3d/scale3d.h"
31#include "host1x/host1x_hardware.h"
32#include "host1x/host1x_cdma.h"
33#include "host1x/host1x_syncpt.h"
34#include "chip_support.h"
35
36#define NVMODMUTEX_2D_FULL (1)
37#define NVMODMUTEX_2D_SIMPLE (2)
38#define NVMODMUTEX_2D_SB_A (3)
39#define NVMODMUTEX_2D_SB_B (4)
40#define NVMODMUTEX_3D (5)
41#define NVMODMUTEX_DISPLAYA (6)
42#define NVMODMUTEX_DISPLAYB (7)
43#define NVMODMUTEX_VI (8)
44#define NVMODMUTEX_DSI (9)
45
46#define NVHOST_CHANNEL_BASE 0
47
48struct nvhost_device t30_devices[] = {
49{
50 /* channel 0 */
51 .name = "display",
52 .id = -1,
53 .index = 0,
54 .syncpts = BIT(NVSYNCPT_DISP0_A) | BIT(NVSYNCPT_DISP1_A) |
55 BIT(NVSYNCPT_DISP0_B) | BIT(NVSYNCPT_DISP1_B) |
56 BIT(NVSYNCPT_DISP0_C) | BIT(NVSYNCPT_DISP1_C) |
57 BIT(NVSYNCPT_VBLANK0) | BIT(NVSYNCPT_VBLANK1),
58 .modulemutexes = BIT(NVMODMUTEX_DISPLAYA) | BIT(NVMODMUTEX_DISPLAYB),
59 NVHOST_MODULE_NO_POWERGATE_IDS,
60 NVHOST_DEFAULT_CLOCKGATE_DELAY,
61 .moduleid = NVHOST_MODULE_NONE,
62},
63{
64 /* channel 1 */
65 .name = "gr3d",
66 .id = -1,
67 .index = 1,
68 .syncpts = BIT(NVSYNCPT_3D),
69 .waitbases = BIT(NVWAITBASE_3D),
70 .modulemutexes = BIT(NVMODMUTEX_3D),
71 .class = NV_GRAPHICS_3D_CLASS_ID,
72 .prepare_poweroff = nvhost_gr3d_prepare_power_off,
73 .busy = nvhost_scale3d_notify_busy,
74 .idle = nvhost_scale3d_notify_idle,
75 .init = nvhost_scale3d_init,
76 .deinit = nvhost_scale3d_deinit,
77 .suspend = nvhost_scale3d_suspend,
78 .alloc_hwctx_handler = nvhost_gr3d_t30_ctxhandler_init,
79 .clocks = { {"gr3d", UINT_MAX},
80 {"gr3d2", UINT_MAX},
81 {"emc", UINT_MAX} },
82 .powergate_ids = { TEGRA_POWERGATE_3D,
83 TEGRA_POWERGATE_3D1 },
84 NVHOST_DEFAULT_CLOCKGATE_DELAY,
85 .can_powergate = false,
86 .powergate_delay = 250,
87 .moduleid = NVHOST_MODULE_NONE,
88},
89{
90 /* channel 2 */
91 .name = "gr2d",
92 .id = -1,
93 .index = 2,
94 .syncpts = BIT(NVSYNCPT_2D_0) | BIT(NVSYNCPT_2D_1),
95 .waitbases = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1),
96 .modulemutexes = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) |
97 BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B),
98 .clocks = { {"gr2d", 0},
99 {"epp", 0},
100 {"emc", 300000000} },
101 NVHOST_MODULE_NO_POWERGATE_IDS,
102 .clockgate_delay = 0,
103 .moduleid = NVHOST_MODULE_NONE,
104},
105{
106 /* channel 3 */
107 .name = "isp",
108 .id = -1,
109 .index = 3,
110 .syncpts = 0,
111 NVHOST_MODULE_NO_POWERGATE_IDS,
112 NVHOST_DEFAULT_CLOCKGATE_DELAY,
113 .moduleid = NVHOST_MODULE_ISP,
114},
115{
116 /* channel 4 */
117 .name = "vi",
118 .id = -1,
119 .index = 4,
120 .syncpts = BIT(NVSYNCPT_CSI_VI_0) | BIT(NVSYNCPT_CSI_VI_1) |
121 BIT(NVSYNCPT_VI_ISP_0) | BIT(NVSYNCPT_VI_ISP_1) |
122 BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) |
123 BIT(NVSYNCPT_VI_ISP_4),
124 .modulemutexes = BIT(NVMODMUTEX_VI),
125 .exclusive = true,
126 NVHOST_MODULE_NO_POWERGATE_IDS,
127 NVHOST_DEFAULT_CLOCKGATE_DELAY,
128 .moduleid = NVHOST_MODULE_VI,
129},
130{
131 /* channel 5 */
132 .name = "mpe",
133 .id = -1,
134 .index = 5,
135 .syncpts = BIT(NVSYNCPT_MPE) | BIT(NVSYNCPT_MPE_EBM_EOF) |
136 BIT(NVSYNCPT_MPE_WR_SAFE),
137 .waitbases = BIT(NVWAITBASE_MPE),
138 .class = NV_VIDEO_ENCODE_MPEG_CLASS_ID,
139 .waitbasesync = true,
140 .keepalive = true,
141 .prepare_poweroff = nvhost_mpe_prepare_power_off,
142 .alloc_hwctx_handler = nvhost_mpe_ctxhandler_init,
143 .clocks = { {"mpe", UINT_MAX},
144 {"emc", UINT_MAX} },
145 .powergate_ids = {TEGRA_POWERGATE_MPE, -1},
146 NVHOST_DEFAULT_CLOCKGATE_DELAY,
147 .can_powergate = true,
148 .powergate_delay = 100,
149 .moduleid = NVHOST_MODULE_MPE,
150},
151{
152 /* channel 6 */
153 .name = "dsi",
154 .id = -1,
155 .index = 6,
156 .syncpts = BIT(NVSYNCPT_DSI),
157 .modulemutexes = BIT(NVMODMUTEX_DSI),
158 NVHOST_MODULE_NO_POWERGATE_IDS,
159 NVHOST_DEFAULT_CLOCKGATE_DELAY,
160 .moduleid = NVHOST_MODULE_NONE,
161} };
162
163static inline int t30_nvhost_hwctx_handler_init(struct nvhost_channel *ch)
164{
165 int err = 0;
166 unsigned long syncpts = ch->dev->syncpts;
167 unsigned long waitbases = ch->dev->waitbases;
168 u32 syncpt = find_first_bit(&syncpts, BITS_PER_LONG);
169 u32 waitbase = find_first_bit(&waitbases, BITS_PER_LONG);
170
171 if (ch->dev->alloc_hwctx_handler) {
172 ch->ctxhandler = ch->dev->alloc_hwctx_handler(syncpt,
173 waitbase, ch);
174 if (!ch->ctxhandler)
175 err = -ENOMEM;
176 }
177
178 return err;
179}
180
181static inline void __iomem *t30_channel_aperture(void __iomem *p, int ndx)
182{
183 ndx += NVHOST_CHANNEL_BASE;
184 p += NV_HOST1X_CHANNEL0_BASE;
185 p += ndx * NV_HOST1X_CHANNEL_MAP_SIZE_BYTES;
186 return p;
187}
188
189static int t30_channel_init(struct nvhost_channel *ch,
190 struct nvhost_master *dev, int index)
191{
192 ch->chid = index;
193 mutex_init(&ch->reflock);
194 mutex_init(&ch->submitlock);
195
196 ch->aperture = t30_channel_aperture(dev->aperture, index);
197
198 return t30_nvhost_hwctx_handler_init(ch);
199}
200
201int nvhost_init_t30_channel_support(struct nvhost_master *host)
202{
203 int result = nvhost_init_t20_channel_support(host);
204 host->op.channel.init = t30_channel_init;
205
206 return result;
207}
208int nvhost_init_t30_debug_support(struct nvhost_master *host)
209{
210 nvhost_init_t20_debug_support(host);
211 host->op.debug.debug_init = nvhost_scale3d_debug_init;
212
213 return 0;
214}
215
216struct nvhost_device *t30_get_nvhost_device(struct nvhost_master *host,
217 char *name)
218{
219 int i;
220
221 for (i = 0; i < host->nb_channels; i++) {
222 if (strcmp(t30_devices[i].name, name) == 0)
223 return &t30_devices[i];
224 }
225
226 return NULL;
227}
228
229int nvhost_init_t30_support(struct nvhost_master *host)
230{
231 int err;
232
233 /* don't worry about cleaning up on failure... "remove" does it. */
234 err = nvhost_init_t30_channel_support(host);
235 if (err)
236 return err;
237 err = host1x_init_cdma_support(host);
238 if (err)
239 return err;
240 err = nvhost_init_t30_debug_support(host);
241 if (err)
242 return err;
243 err = host1x_init_syncpt_support(host);
244 if (err)
245 return err;
246 err = nvhost_init_t20_intr_support(host);
247 if (err)
248 return err;
249 host->op.nvhost_dev.get_nvhost_device = t30_get_nvhost_device;
250 return 0;
251}