]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - drivers/video/tegra/host/t20/t20.c
video: tegra: host: Refactor context handling logic
[linux-2.6.git] / drivers / video / tegra / host / t20 / t20.c
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
46 struct nvhost_device devices[] = {
47 {
48         /* channel 0 */
49         .name          = "display",
50         .id            = -1,
51         .syncpts       = BIT(NVSYNCPT_DISP0_A) | BIT(NVSYNCPT_DISP1_A) |
52                          BIT(NVSYNCPT_DISP0_B) | BIT(NVSYNCPT_DISP1_B) |
53                          BIT(NVSYNCPT_DISP0_C) | BIT(NVSYNCPT_DISP1_C) |
54                          BIT(NVSYNCPT_VBLANK0) | BIT(NVSYNCPT_VBLANK1),
55         .modulemutexes = BIT(NVMODMUTEX_DISPLAYA) | BIT(NVMODMUTEX_DISPLAYB),
56         NVHOST_MODULE_NO_POWERGATE_IDS,
57         NVHOST_DEFAULT_CLOCKGATE_DELAY,
58         .moduleid      = NVHOST_MODULE_NONE,
59 },
60 {
61         /* channel 1 */
62         .name          = "gr3d",
63         .id            = -1,
64         .syncpts       = BIT(NVSYNCPT_3D),
65         .waitbases     = BIT(NVWAITBASE_3D),
66         .modulemutexes = BIT(NVMODMUTEX_3D),
67         .class         = NV_GRAPHICS_3D_CLASS_ID,
68         .prepare_poweroff = nvhost_gr3d_prepare_power_off,
69         .alloc_hwctx_handler = nvhost_gr3d_t20_ctxhandler_init,
70         .clocks = {{"gr3d", UINT_MAX}, {"emc", UINT_MAX}, {} },
71         .powergate_ids = {TEGRA_POWERGATE_3D, -1},
72         NVHOST_DEFAULT_CLOCKGATE_DELAY,
73         .moduleid      = NVHOST_MODULE_NONE,
74 },
75 {
76         /* channel 2 */
77         .name          = "gr2d",
78         .id            = -1,
79         .syncpts       = BIT(NVSYNCPT_2D_0) | BIT(NVSYNCPT_2D_1),
80         .waitbases     = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1),
81         .modulemutexes = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) |
82                          BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B),
83         .clocks = {{"gr2d", UINT_MAX} ,
84                         {"epp", UINT_MAX} ,
85                         {"emc", UINT_MAX} },
86         NVHOST_MODULE_NO_POWERGATE_IDS,
87         .clockgate_delay = 0,
88         .moduleid      = NVHOST_MODULE_NONE,
89 },
90 {
91         /* channel 3 */
92         .name    = "isp",
93         .id            = -1,
94         .syncpts = 0,
95         NVHOST_MODULE_NO_POWERGATE_IDS,
96         NVHOST_DEFAULT_CLOCKGATE_DELAY,
97         .moduleid      = NVHOST_MODULE_ISP,
98 },
99 {
100         /* channel 4 */
101         .name          = "vi",
102         .id            = -1,
103         .syncpts       = BIT(NVSYNCPT_CSI_VI_0) | BIT(NVSYNCPT_CSI_VI_1) |
104                          BIT(NVSYNCPT_VI_ISP_0) | BIT(NVSYNCPT_VI_ISP_1) |
105                          BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) |
106                          BIT(NVSYNCPT_VI_ISP_4),
107         .modulemutexes = BIT(NVMODMUTEX_VI),
108         .exclusive     = true,
109         NVHOST_MODULE_NO_POWERGATE_IDS,
110         NVHOST_DEFAULT_CLOCKGATE_DELAY,
111         .moduleid      = NVHOST_MODULE_VI,
112 },
113 {
114         /* channel 5 */
115         .name          = "mpe",
116         .id            = -1,
117         .syncpts       = BIT(NVSYNCPT_MPE) | BIT(NVSYNCPT_MPE_EBM_EOF) |
118                          BIT(NVSYNCPT_MPE_WR_SAFE),
119         .waitbases     = BIT(NVWAITBASE_MPE),
120         .class         = NV_VIDEO_ENCODE_MPEG_CLASS_ID,
121         .waitbasesync  = true,
122         .keepalive     = true,
123         .prepare_poweroff = nvhost_mpe_prepare_power_off,
124         .alloc_hwctx_handler = nvhost_mpe_ctxhandler_init,
125         .clocks = {{"mpe", UINT_MAX}, {"emc", UINT_MAX}, {} },
126         .powergate_ids = {TEGRA_POWERGATE_MPE, -1},
127         NVHOST_DEFAULT_CLOCKGATE_DELAY,
128         .moduleid      = NVHOST_MODULE_MPE,
129 },
130 {
131         /* channel 6 */
132         .name          = "dsi",
133         .id            = -1,
134         .syncpts       = BIT(NVSYNCPT_DSI),
135         .modulemutexes = BIT(NVMODMUTEX_DSI),
136         NVHOST_MODULE_NO_POWERGATE_IDS,
137         NVHOST_DEFAULT_CLOCKGATE_DELAY,
138         .moduleid      = NVHOST_MODULE_NONE,
139 } };
140
141 static inline void __iomem *t20_channel_aperture(void __iomem *p, int ndx)
142 {
143         p += NV_HOST1X_CHANNEL0_BASE;
144         p += ndx * NV_HOST1X_CHANNEL_MAP_SIZE_BYTES;
145         return p;
146 }
147
148 static inline int t20_nvhost_hwctx_handler_init(struct nvhost_channel *ch)
149 {
150         int err = 0;
151         unsigned long syncpts = ch->dev->syncpts;
152         unsigned long waitbases = ch->dev->waitbases;
153         u32 syncpt = find_first_bit(&syncpts, BITS_PER_LONG);
154         u32 waitbase = find_first_bit(&waitbases, BITS_PER_LONG);
155
156         if (ch->dev->alloc_hwctx_handler) {
157                 ch->ctxhandler = ch->dev->alloc_hwctx_handler(syncpt,
158                                 waitbase, ch);
159                 if (!ch->ctxhandler)
160                         err = -ENOMEM;
161         }
162
163         return err;
164 }
165
166 static int t20_channel_init(struct nvhost_channel *ch,
167                             struct nvhost_master *dev, int index)
168 {
169         ch->chid = index;
170         ch->dev = &devices[index];
171         mutex_init(&ch->reflock);
172         mutex_init(&ch->submitlock);
173
174         nvhost_device_register(ch->dev);
175         ch->aperture = t20_channel_aperture(dev->aperture, index);
176
177         return t20_nvhost_hwctx_handler_init(ch);
178 }
179
180 int nvhost_init_t20_channel_support(struct nvhost_master *host)
181 {
182         host->nb_channels =  NVHOST_NUMCHANNELS;
183
184         host->op.channel.init = t20_channel_init;
185         host->op.channel.submit = host1x_channel_submit;
186         host->op.channel.read3dreg = host1x_channel_read_3d_reg;
187
188         return 0;
189 }
190
191 int nvhost_init_t20_support(struct nvhost_master *host)
192 {
193         int err;
194
195         /* don't worry about cleaning up on failure... "remove" does it. */
196         err = nvhost_init_t20_channel_support(host);
197         if (err)
198                 return err;
199         err = host1x_init_cdma_support(host);
200         if (err)
201                 return err;
202         err = nvhost_init_t20_debug_support(host);
203         if (err)
204                 return err;
205         err = host1x_init_syncpt_support(host);
206         if (err)
207                 return err;
208         err = nvhost_init_t20_intr_support(host);
209         if (err)
210                 return err;
211         return 0;
212 }