aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/host1x/Makefile3
-rw-r--r--drivers/gpu/host1x/dev.c55
-rw-r--r--drivers/gpu/host1x/dev.h4
-rw-r--r--drivers/gpu/host1x/hw/cdma_hw.c49
-rw-r--r--drivers/gpu/host1x/hw/debug_hw.c137
-rw-r--r--drivers/gpu/host1x/hw/debug_hw_1x01.c154
-rw-r--r--drivers/gpu/host1x/hw/debug_hw_1x06.c133
-rw-r--r--drivers/gpu/host1x/hw/host1x01.c2
-rw-r--r--drivers/gpu/host1x/hw/host1x02.c2
-rw-r--r--drivers/gpu/host1x/hw/host1x04.c2
-rw-r--r--drivers/gpu/host1x/hw/host1x05.c2
-rw-r--r--drivers/gpu/host1x/hw/host1x06.c44
-rw-r--r--drivers/gpu/host1x/hw/host1x06.h26
-rw-r--r--drivers/gpu/host1x/hw/host1x06_hardware.h142
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x06_hypervisor.h32
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x06_uclass.h181
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x06_vm.h47
-rw-r--r--drivers/gpu/host1x/hw/intr_hw.c29
18 files changed, 876 insertions, 168 deletions
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index a1d9974cfcb5..4fb61bd57aee 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -11,6 +11,7 @@ host1x-y = \
11 hw/host1x01.o \ 11 hw/host1x01.o \
12 hw/host1x02.o \ 12 hw/host1x02.o \
13 hw/host1x04.o \ 13 hw/host1x04.o \
14 hw/host1x05.o 14 hw/host1x05.o \
15 hw/host1x06.o
15 16
16obj-$(CONFIG_TEGRA_HOST1X) += host1x.o 17obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 34a3583e4502..773d6337aa30 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -39,6 +39,17 @@
39#include "hw/host1x02.h" 39#include "hw/host1x02.h"
40#include "hw/host1x04.h" 40#include "hw/host1x04.h"
41#include "hw/host1x05.h" 41#include "hw/host1x05.h"
42#include "hw/host1x06.h"
43
44void host1x_hypervisor_writel(struct host1x *host1x, u32 v, u32 r)
45{
46 writel(v, host1x->hv_regs + r);
47}
48
49u32 host1x_hypervisor_readl(struct host1x *host1x, u32 r)
50{
51 return readl(host1x->hv_regs + r);
52}
42 53
43void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r) 54void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
44{ 55{
@@ -104,7 +115,19 @@ static const struct host1x_info host1x05_info = {
104 .dma_mask = DMA_BIT_MASK(34), 115 .dma_mask = DMA_BIT_MASK(34),
105}; 116};
106 117
118static const struct host1x_info host1x06_info = {
119 .nb_channels = 63,
120 .nb_pts = 576,
121 .nb_mlocks = 24,
122 .nb_bases = 16,
123 .init = host1x06_init,
124 .sync_offset = 0x0,
125 .dma_mask = DMA_BIT_MASK(34),
126 .has_hypervisor = true,
127};
128
107static const struct of_device_id host1x_of_match[] = { 129static const struct of_device_id host1x_of_match[] = {
130 { .compatible = "nvidia,tegra186-host1x", .data = &host1x06_info, },
108 { .compatible = "nvidia,tegra210-host1x", .data = &host1x05_info, }, 131 { .compatible = "nvidia,tegra210-host1x", .data = &host1x05_info, },
109 { .compatible = "nvidia,tegra124-host1x", .data = &host1x04_info, }, 132 { .compatible = "nvidia,tegra124-host1x", .data = &host1x04_info, },
110 { .compatible = "nvidia,tegra114-host1x", .data = &host1x02_info, }, 133 { .compatible = "nvidia,tegra114-host1x", .data = &host1x02_info, },
@@ -117,7 +140,7 @@ MODULE_DEVICE_TABLE(of, host1x_of_match);
117static int host1x_probe(struct platform_device *pdev) 140static int host1x_probe(struct platform_device *pdev)
118{ 141{
119 struct host1x *host; 142 struct host1x *host;
120 struct resource *regs; 143 struct resource *regs, *hv_regs = NULL;
121 int syncpt_irq; 144 int syncpt_irq;
122 int err; 145 int err;
123 146
@@ -127,10 +150,26 @@ static int host1x_probe(struct platform_device *pdev)
127 150
128 host->info = of_device_get_match_data(&pdev->dev); 151 host->info = of_device_get_match_data(&pdev->dev);
129 152
130 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 153 if (host->info->has_hypervisor) {
131 if (!regs) { 154 regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vm");
132 dev_err(&pdev->dev, "failed to get registers\n"); 155 if (!regs) {
133 return -ENXIO; 156 dev_err(&pdev->dev, "failed to get vm registers\n");
157 return -ENXIO;
158 }
159
160 hv_regs = platform_get_resource_byname(pdev, IORESOURCE_MEM,
161 "hypervisor");
162 if (!hv_regs) {
163 dev_err(&pdev->dev,
164 "failed to get hypervisor registers\n");
165 return -ENXIO;
166 }
167 } else {
168 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
169 if (!regs) {
170 dev_err(&pdev->dev, "failed to get registers\n");
171 return -ENXIO;
172 }
134 } 173 }
135 174
136 syncpt_irq = platform_get_irq(pdev, 0); 175 syncpt_irq = platform_get_irq(pdev, 0);
@@ -151,6 +190,12 @@ static int host1x_probe(struct platform_device *pdev)
151 if (IS_ERR(host->regs)) 190 if (IS_ERR(host->regs))
152 return PTR_ERR(host->regs); 191 return PTR_ERR(host->regs);
153 192
193 if (host->info->has_hypervisor) {
194 host->hv_regs = devm_ioremap_resource(&pdev->dev, hv_regs);
195 if (IS_ERR(host->hv_regs))
196 return PTR_ERR(host->hv_regs);
197 }
198
154 dma_set_mask_and_coherent(host->dev, host->info->dma_mask); 199 dma_set_mask_and_coherent(host->dev, host->info->dma_mask);
155 200
156 if (host->info->init) { 201 if (host->info->init) {
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index ffdbc15b749b..def802c0a6bf 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -100,12 +100,14 @@ struct host1x_info {
100 int (*init)(struct host1x *host1x); /* initialize per SoC ops */ 100 int (*init)(struct host1x *host1x); /* initialize per SoC ops */
101 unsigned int sync_offset; /* offset of syncpoint registers */ 101 unsigned int sync_offset; /* offset of syncpoint registers */
102 u64 dma_mask; /* mask of addressable memory */ 102 u64 dma_mask; /* mask of addressable memory */
103 bool has_hypervisor; /* has hypervisor registers */
103}; 104};
104 105
105struct host1x { 106struct host1x {
106 const struct host1x_info *info; 107 const struct host1x_info *info;
107 108
108 void __iomem *regs; 109 void __iomem *regs;
110 void __iomem *hv_regs; /* hypervisor region */
109 struct host1x_syncpt *syncpt; 111 struct host1x_syncpt *syncpt;
110 struct host1x_syncpt_base *bases; 112 struct host1x_syncpt_base *bases;
111 struct device *dev; 113 struct device *dev;
@@ -140,6 +142,8 @@ struct host1x {
140 struct list_head list; 142 struct list_head list;
141}; 143};
142 144
145void host1x_hypervisor_writel(struct host1x *host1x, u32 r, u32 v);
146u32 host1x_hypervisor_readl(struct host1x *host1x, u32 r);
143void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v); 147void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v);
144u32 host1x_sync_readl(struct host1x *host1x, u32 r); 148u32 host1x_sync_readl(struct host1x *host1x, u32 r);
145void host1x_ch_writel(struct host1x_channel *ch, u32 r, u32 v); 149void host1x_ch_writel(struct host1x_channel *ch, u32 r, u32 v);
diff --git a/drivers/gpu/host1x/hw/cdma_hw.c b/drivers/gpu/host1x/hw/cdma_hw.c
index 6b231119193e..ce320534cbed 100644
--- a/drivers/gpu/host1x/hw/cdma_hw.c
+++ b/drivers/gpu/host1x/hw/cdma_hw.c
@@ -172,6 +172,30 @@ static void cdma_stop(struct host1x_cdma *cdma)
172 mutex_unlock(&cdma->lock); 172 mutex_unlock(&cdma->lock);
173} 173}
174 174
175static void cdma_hw_cmdproc_stop(struct host1x *host, struct host1x_channel *ch,
176 bool stop)
177{
178#if HOST1X_HW >= 6
179 host1x_ch_writel(ch, stop ? 0x1 : 0x0, HOST1X_CHANNEL_CMDPROC_STOP);
180#else
181 u32 cmdproc_stop = host1x_sync_readl(host, HOST1X_SYNC_CMDPROC_STOP);
182 if (stop)
183 cmdproc_stop |= BIT(ch->id);
184 else
185 cmdproc_stop &= ~BIT(ch->id);
186 host1x_sync_writel(host, cmdproc_stop, HOST1X_SYNC_CMDPROC_STOP);
187#endif
188}
189
190static void cdma_hw_teardown(struct host1x *host, struct host1x_channel *ch)
191{
192#if HOST1X_HW >= 6
193 host1x_ch_writel(ch, 0x1, HOST1X_CHANNEL_TEARDOWN);
194#else
195 host1x_sync_writel(host, BIT(ch->id), HOST1X_SYNC_CH_TEARDOWN);
196#endif
197}
198
175/* 199/*
176 * Stops both channel's command processor and CDMA immediately. 200 * Stops both channel's command processor and CDMA immediately.
177 * Also, tears down the channel and resets corresponding module. 201 * Also, tears down the channel and resets corresponding module.
@@ -180,7 +204,6 @@ static void cdma_freeze(struct host1x_cdma *cdma)
180{ 204{
181 struct host1x *host = cdma_to_host1x(cdma); 205 struct host1x *host = cdma_to_host1x(cdma);
182 struct host1x_channel *ch = cdma_to_channel(cdma); 206 struct host1x_channel *ch = cdma_to_channel(cdma);
183 u32 cmdproc_stop;
184 207
185 if (cdma->torndown && !cdma->running) { 208 if (cdma->torndown && !cdma->running) {
186 dev_warn(host->dev, "Already torn down\n"); 209 dev_warn(host->dev, "Already torn down\n");
@@ -189,9 +212,7 @@ static void cdma_freeze(struct host1x_cdma *cdma)
189 212
190 dev_dbg(host->dev, "freezing channel (id %d)\n", ch->id); 213 dev_dbg(host->dev, "freezing channel (id %d)\n", ch->id);
191 214
192 cmdproc_stop = host1x_sync_readl(host, HOST1X_SYNC_CMDPROC_STOP); 215 cdma_hw_cmdproc_stop(host, ch, true);
193 cmdproc_stop |= BIT(ch->id);
194 host1x_sync_writel(host, cmdproc_stop, HOST1X_SYNC_CMDPROC_STOP);
195 216
196 dev_dbg(host->dev, "%s: DMA GET 0x%x, PUT HW 0x%x / shadow 0x%x\n", 217 dev_dbg(host->dev, "%s: DMA GET 0x%x, PUT HW 0x%x / shadow 0x%x\n",
197 __func__, host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET), 218 __func__, host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET),
@@ -201,7 +222,7 @@ static void cdma_freeze(struct host1x_cdma *cdma)
201 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP, 222 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP,
202 HOST1X_CHANNEL_DMACTRL); 223 HOST1X_CHANNEL_DMACTRL);
203 224
204 host1x_sync_writel(host, BIT(ch->id), HOST1X_SYNC_CH_TEARDOWN); 225 cdma_hw_teardown(host, ch);
205 226
206 cdma->running = false; 227 cdma->running = false;
207 cdma->torndown = true; 228 cdma->torndown = true;
@@ -211,15 +232,12 @@ static void cdma_resume(struct host1x_cdma *cdma, u32 getptr)
211{ 232{
212 struct host1x *host1x = cdma_to_host1x(cdma); 233 struct host1x *host1x = cdma_to_host1x(cdma);
213 struct host1x_channel *ch = cdma_to_channel(cdma); 234 struct host1x_channel *ch = cdma_to_channel(cdma);
214 u32 cmdproc_stop;
215 235
216 dev_dbg(host1x->dev, 236 dev_dbg(host1x->dev,
217 "resuming channel (id %u, DMAGET restart = 0x%x)\n", 237 "resuming channel (id %u, DMAGET restart = 0x%x)\n",
218 ch->id, getptr); 238 ch->id, getptr);
219 239
220 cmdproc_stop = host1x_sync_readl(host1x, HOST1X_SYNC_CMDPROC_STOP); 240 cdma_hw_cmdproc_stop(host1x, ch, false);
221 cmdproc_stop &= ~BIT(ch->id);
222 host1x_sync_writel(host1x, cmdproc_stop, HOST1X_SYNC_CMDPROC_STOP);
223 241
224 cdma->torndown = false; 242 cdma->torndown = false;
225 cdma_timeout_restart(cdma, getptr); 243 cdma_timeout_restart(cdma, getptr);
@@ -232,7 +250,7 @@ static void cdma_resume(struct host1x_cdma *cdma, u32 getptr)
232 */ 250 */
233static void cdma_timeout_handler(struct work_struct *work) 251static void cdma_timeout_handler(struct work_struct *work)
234{ 252{
235 u32 prev_cmdproc, cmdproc_stop, syncpt_val; 253 u32 syncpt_val;
236 struct host1x_cdma *cdma; 254 struct host1x_cdma *cdma;
237 struct host1x *host1x; 255 struct host1x *host1x;
238 struct host1x_channel *ch; 256 struct host1x_channel *ch;
@@ -254,12 +272,7 @@ static void cdma_timeout_handler(struct work_struct *work)
254 } 272 }
255 273
256 /* stop processing to get a clean snapshot */ 274 /* stop processing to get a clean snapshot */
257 prev_cmdproc = host1x_sync_readl(host1x, HOST1X_SYNC_CMDPROC_STOP); 275 cdma_hw_cmdproc_stop(host1x, ch, true);
258 cmdproc_stop = prev_cmdproc | BIT(ch->id);
259 host1x_sync_writel(host1x, cmdproc_stop, HOST1X_SYNC_CMDPROC_STOP);
260
261 dev_dbg(host1x->dev, "cdma_timeout: cmdproc was 0x%x is 0x%x\n",
262 prev_cmdproc, cmdproc_stop);
263 276
264 syncpt_val = host1x_syncpt_load(cdma->timeout.syncpt); 277 syncpt_val = host1x_syncpt_load(cdma->timeout.syncpt);
265 278
@@ -268,9 +281,7 @@ static void cdma_timeout_handler(struct work_struct *work)
268 dev_dbg(host1x->dev, 281 dev_dbg(host1x->dev,
269 "cdma_timeout: expired, but buffer had completed\n"); 282 "cdma_timeout: expired, but buffer had completed\n");
270 /* restore */ 283 /* restore */
271 cmdproc_stop = prev_cmdproc & ~(BIT(ch->id)); 284 cdma_hw_cmdproc_stop(host1x, ch, false);
272 host1x_sync_writel(host1x, cmdproc_stop,
273 HOST1X_SYNC_CMDPROC_STOP);
274 mutex_unlock(&cdma->lock); 285 mutex_unlock(&cdma->lock);
275 return; 286 return;
276 } 287 }
diff --git a/drivers/gpu/host1x/hw/debug_hw.c b/drivers/gpu/host1x/hw/debug_hw.c
index 7a4a3286e4a7..770d92e62d69 100644
--- a/drivers/gpu/host1x/hw/debug_hw.c
+++ b/drivers/gpu/host1x/hw/debug_hw.c
@@ -174,138 +174,11 @@ static void show_channel_gathers(struct output *o, struct host1x_cdma *cdma)
174 } 174 }
175} 175}
176 176
177static void host1x_debug_show_channel_cdma(struct host1x *host, 177#if HOST1X_HW >= 6
178 struct host1x_channel *ch, 178#include "debug_hw_1x06.c"
179 struct output *o) 179#else
180{ 180#include "debug_hw_1x01.c"
181 struct host1x_cdma *cdma = &ch->cdma; 181#endif
182 u32 dmaput, dmaget, dmactrl;
183 u32 cbstat, cbread;
184 u32 val, base, baseval;
185
186 dmaput = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAPUT);
187 dmaget = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET);
188 dmactrl = host1x_ch_readl(ch, HOST1X_CHANNEL_DMACTRL);
189 cbread = host1x_sync_readl(host, HOST1X_SYNC_CBREAD(ch->id));
190 cbstat = host1x_sync_readl(host, HOST1X_SYNC_CBSTAT(ch->id));
191
192 host1x_debug_output(o, "%u-%s: ", ch->id, dev_name(ch->dev));
193
194 if (HOST1X_CHANNEL_DMACTRL_DMASTOP_V(dmactrl) ||
195 !ch->cdma.push_buffer.mapped) {
196 host1x_debug_output(o, "inactive\n\n");
197 return;
198 }
199
200 if (HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat) == HOST1X_CLASS_HOST1X &&
201 HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat) ==
202 HOST1X_UCLASS_WAIT_SYNCPT)
203 host1x_debug_output(o, "waiting on syncpt %d val %d\n",
204 cbread >> 24, cbread & 0xffffff);
205 else if (HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat) ==
206 HOST1X_CLASS_HOST1X &&
207 HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat) ==
208 HOST1X_UCLASS_WAIT_SYNCPT_BASE) {
209 base = (cbread >> 16) & 0xff;
210 baseval =
211 host1x_sync_readl(host, HOST1X_SYNC_SYNCPT_BASE(base));
212 val = cbread & 0xffff;
213 host1x_debug_output(o, "waiting on syncpt %d val %d (base %d = %d; offset = %d)\n",
214 cbread >> 24, baseval + val, base,
215 baseval, val);
216 } else
217 host1x_debug_output(o, "active class %02x, offset %04x, val %08x\n",
218 HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat),
219 HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat),
220 cbread);
221
222 host1x_debug_output(o, "DMAPUT %08x, DMAGET %08x, DMACTL %08x\n",
223 dmaput, dmaget, dmactrl);
224 host1x_debug_output(o, "CBREAD %08x, CBSTAT %08x\n", cbread, cbstat);
225
226 show_channel_gathers(o, cdma);
227 host1x_debug_output(o, "\n");
228}
229
230static void host1x_debug_show_channel_fifo(struct host1x *host,
231 struct host1x_channel *ch,
232 struct output *o)
233{
234 u32 val, rd_ptr, wr_ptr, start, end;
235 unsigned int data_count = 0;
236
237 host1x_debug_output(o, "%u: fifo:\n", ch->id);
238
239 val = host1x_ch_readl(ch, HOST1X_CHANNEL_FIFOSTAT);
240 host1x_debug_output(o, "FIFOSTAT %08x\n", val);
241 if (HOST1X_CHANNEL_FIFOSTAT_CFEMPTY_V(val)) {
242 host1x_debug_output(o, "[empty]\n");
243 return;
244 }
245
246 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL);
247 host1x_sync_writel(host, HOST1X_SYNC_CFPEEK_CTRL_ENA_F(1) |
248 HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(ch->id),
249 HOST1X_SYNC_CFPEEK_CTRL);
250
251 val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_PTRS);
252 rd_ptr = HOST1X_SYNC_CFPEEK_PTRS_CF_RD_PTR_V(val);
253 wr_ptr = HOST1X_SYNC_CFPEEK_PTRS_CF_WR_PTR_V(val);
254
255 val = host1x_sync_readl(host, HOST1X_SYNC_CF_SETUP(ch->id));
256 start = HOST1X_SYNC_CF_SETUP_BASE_V(val);
257 end = HOST1X_SYNC_CF_SETUP_LIMIT_V(val);
258
259 do {
260 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL);
261 host1x_sync_writel(host, HOST1X_SYNC_CFPEEK_CTRL_ENA_F(1) |
262 HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(ch->id) |
263 HOST1X_SYNC_CFPEEK_CTRL_ADDR_F(rd_ptr),
264 HOST1X_SYNC_CFPEEK_CTRL);
265 val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_READ);
266
267 if (!data_count) {
268 host1x_debug_output(o, "%08x:", val);
269 data_count = show_channel_command(o, val);
270 } else {
271 host1x_debug_output(o, "%08x%s", val,
272 data_count > 0 ? ", " : "])\n");
273 data_count--;
274 }
275
276 if (rd_ptr == end)
277 rd_ptr = start;
278 else
279 rd_ptr++;
280 } while (rd_ptr != wr_ptr);
281
282 if (data_count)
283 host1x_debug_output(o, ", ...])\n");
284 host1x_debug_output(o, "\n");
285
286 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL);
287}
288
289static void host1x_debug_show_mlocks(struct host1x *host, struct output *o)
290{
291 unsigned int i;
292
293 host1x_debug_output(o, "---- mlocks ----\n");
294
295 for (i = 0; i < host1x_syncpt_nb_mlocks(host); i++) {
296 u32 owner =
297 host1x_sync_readl(host, HOST1X_SYNC_MLOCK_OWNER(i));
298 if (HOST1X_SYNC_MLOCK_OWNER_CH_OWNS_V(owner))
299 host1x_debug_output(o, "%u: locked by channel %u\n",
300 i, HOST1X_SYNC_MLOCK_OWNER_CHID_V(owner));
301 else if (HOST1X_SYNC_MLOCK_OWNER_CPU_OWNS_V(owner))
302 host1x_debug_output(o, "%u: locked by cpu\n", i);
303 else
304 host1x_debug_output(o, "%u: unlocked\n", i);
305 }
306
307 host1x_debug_output(o, "\n");
308}
309 182
310static const struct host1x_debug_ops host1x_debug_ops = { 183static const struct host1x_debug_ops host1x_debug_ops = {
311 .show_channel_cdma = host1x_debug_show_channel_cdma, 184 .show_channel_cdma = host1x_debug_show_channel_cdma,
diff --git a/drivers/gpu/host1x/hw/debug_hw_1x01.c b/drivers/gpu/host1x/hw/debug_hw_1x01.c
new file mode 100644
index 000000000000..8f243903cc7f
--- /dev/null
+++ b/drivers/gpu/host1x/hw/debug_hw_1x01.c
@@ -0,0 +1,154 @@
1/*
2 * Copyright (C) 2010 Google, Inc.
3 * Author: Erik Gilling <konkers@android.com>
4 *
5 * Copyright (C) 2011-2013 NVIDIA Corporation
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include "../dev.h"
19#include "../debug.h"
20#include "../cdma.h"
21#include "../channel.h"
22
23static void host1x_debug_show_channel_cdma(struct host1x *host,
24 struct host1x_channel *ch,
25 struct output *o)
26{
27 struct host1x_cdma *cdma = &ch->cdma;
28 u32 dmaput, dmaget, dmactrl;
29 u32 cbstat, cbread;
30 u32 val, base, baseval;
31
32 dmaput = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAPUT);
33 dmaget = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET);
34 dmactrl = host1x_ch_readl(ch, HOST1X_CHANNEL_DMACTRL);
35 cbread = host1x_sync_readl(host, HOST1X_SYNC_CBREAD(ch->id));
36 cbstat = host1x_sync_readl(host, HOST1X_SYNC_CBSTAT(ch->id));
37
38 host1x_debug_output(o, "%u-%s: ", ch->id, dev_name(ch->dev));
39
40 if (HOST1X_CHANNEL_DMACTRL_DMASTOP_V(dmactrl) ||
41 !ch->cdma.push_buffer.mapped) {
42 host1x_debug_output(o, "inactive\n\n");
43 return;
44 }
45
46 if (HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat) == HOST1X_CLASS_HOST1X &&
47 HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat) ==
48 HOST1X_UCLASS_WAIT_SYNCPT)
49 host1x_debug_output(o, "waiting on syncpt %d val %d\n",
50 cbread >> 24, cbread & 0xffffff);
51 else if (HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat) ==
52 HOST1X_CLASS_HOST1X &&
53 HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat) ==
54 HOST1X_UCLASS_WAIT_SYNCPT_BASE) {
55 base = (cbread >> 16) & 0xff;
56 baseval =
57 host1x_sync_readl(host, HOST1X_SYNC_SYNCPT_BASE(base));
58 val = cbread & 0xffff;
59 host1x_debug_output(o, "waiting on syncpt %d val %d (base %d = %d; offset = %d)\n",
60 cbread >> 24, baseval + val, base,
61 baseval, val);
62 } else
63 host1x_debug_output(o, "active class %02x, offset %04x, val %08x\n",
64 HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat),
65 HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat),
66 cbread);
67
68 host1x_debug_output(o, "DMAPUT %08x, DMAGET %08x, DMACTL %08x\n",
69 dmaput, dmaget, dmactrl);
70 host1x_debug_output(o, "CBREAD %08x, CBSTAT %08x\n", cbread, cbstat);
71
72 show_channel_gathers(o, cdma);
73 host1x_debug_output(o, "\n");
74}
75
76static void host1x_debug_show_channel_fifo(struct host1x *host,
77 struct host1x_channel *ch,
78 struct output *o)
79{
80 u32 val, rd_ptr, wr_ptr, start, end;
81 unsigned int data_count = 0;
82
83 host1x_debug_output(o, "%u: fifo:\n", ch->id);
84
85 val = host1x_ch_readl(ch, HOST1X_CHANNEL_FIFOSTAT);
86 host1x_debug_output(o, "FIFOSTAT %08x\n", val);
87 if (HOST1X_CHANNEL_FIFOSTAT_CFEMPTY_V(val)) {
88 host1x_debug_output(o, "[empty]\n");
89 return;
90 }
91
92 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL);
93 host1x_sync_writel(host, HOST1X_SYNC_CFPEEK_CTRL_ENA_F(1) |
94 HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(ch->id),
95 HOST1X_SYNC_CFPEEK_CTRL);
96
97 val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_PTRS);
98 rd_ptr = HOST1X_SYNC_CFPEEK_PTRS_CF_RD_PTR_V(val);
99 wr_ptr = HOST1X_SYNC_CFPEEK_PTRS_CF_WR_PTR_V(val);
100
101 val = host1x_sync_readl(host, HOST1X_SYNC_CF_SETUP(ch->id));
102 start = HOST1X_SYNC_CF_SETUP_BASE_V(val);
103 end = HOST1X_SYNC_CF_SETUP_LIMIT_V(val);
104
105 do {
106 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL);
107 host1x_sync_writel(host, HOST1X_SYNC_CFPEEK_CTRL_ENA_F(1) |
108 HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(ch->id) |
109 HOST1X_SYNC_CFPEEK_CTRL_ADDR_F(rd_ptr),
110 HOST1X_SYNC_CFPEEK_CTRL);
111 val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_READ);
112
113 if (!data_count) {
114 host1x_debug_output(o, "%08x:", val);
115 data_count = show_channel_command(o, val);
116 } else {
117 host1x_debug_output(o, "%08x%s", val,
118 data_count > 0 ? ", " : "])\n");
119 data_count--;
120 }
121
122 if (rd_ptr == end)
123 rd_ptr = start;
124 else
125 rd_ptr++;
126 } while (rd_ptr != wr_ptr);
127
128 if (data_count)
129 host1x_debug_output(o, ", ...])\n");
130 host1x_debug_output(o, "\n");
131
132 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL);
133}
134
135static void host1x_debug_show_mlocks(struct host1x *host, struct output *o)
136{
137 unsigned int i;
138
139 host1x_debug_output(o, "---- mlocks ----\n");
140
141 for (i = 0; i < host1x_syncpt_nb_mlocks(host); i++) {
142 u32 owner =
143 host1x_sync_readl(host, HOST1X_SYNC_MLOCK_OWNER(i));
144 if (HOST1X_SYNC_MLOCK_OWNER_CH_OWNS_V(owner))
145 host1x_debug_output(o, "%u: locked by channel %u\n",
146 i, HOST1X_SYNC_MLOCK_OWNER_CHID_V(owner));
147 else if (HOST1X_SYNC_MLOCK_OWNER_CPU_OWNS_V(owner))
148 host1x_debug_output(o, "%u: locked by cpu\n", i);
149 else
150 host1x_debug_output(o, "%u: unlocked\n", i);
151 }
152
153 host1x_debug_output(o, "\n");
154}
diff --git a/drivers/gpu/host1x/hw/debug_hw_1x06.c b/drivers/gpu/host1x/hw/debug_hw_1x06.c
new file mode 100644
index 000000000000..9cdee657fb46
--- /dev/null
+++ b/drivers/gpu/host1x/hw/debug_hw_1x06.c
@@ -0,0 +1,133 @@
1/*
2 * Copyright (C) 2010 Google, Inc.
3 * Author: Erik Gilling <konkers@android.com>
4 *
5 * Copyright (C) 2011-2017 NVIDIA Corporation
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include "../dev.h"
19#include "../debug.h"
20#include "../cdma.h"
21#include "../channel.h"
22
23static void host1x_debug_show_channel_cdma(struct host1x *host,
24 struct host1x_channel *ch,
25 struct output *o)
26{
27 struct host1x_cdma *cdma = &ch->cdma;
28 u32 dmaput, dmaget, dmactrl;
29 u32 offset, class;
30 u32 ch_stat;
31
32 dmaput = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAPUT);
33 dmaget = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET);
34 dmactrl = host1x_ch_readl(ch, HOST1X_CHANNEL_DMACTRL);
35 offset = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDP_OFFSET);
36 class = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDP_CLASS);
37 ch_stat = host1x_ch_readl(ch, HOST1X_CHANNEL_CHANNELSTAT);
38
39 host1x_debug_output(o, "%u-%s: ", ch->id, dev_name(ch->dev));
40
41 if (dmactrl & HOST1X_CHANNEL_DMACTRL_DMASTOP ||
42 !ch->cdma.push_buffer.mapped) {
43 host1x_debug_output(o, "inactive\n\n");
44 return;
45 }
46
47 if (class == HOST1X_CLASS_HOST1X && offset == HOST1X_UCLASS_WAIT_SYNCPT)
48 host1x_debug_output(o, "waiting on syncpt\n");
49 else
50 host1x_debug_output(o, "active class %02x, offset %04x\n",
51 class, offset);
52
53 host1x_debug_output(o, "DMAPUT %08x, DMAGET %08x, DMACTL %08x\n",
54 dmaput, dmaget, dmactrl);
55 host1x_debug_output(o, "CHANNELSTAT %02x\n", ch_stat);
56
57 show_channel_gathers(o, cdma);
58 host1x_debug_output(o, "\n");
59}
60
61static void host1x_debug_show_channel_fifo(struct host1x *host,
62 struct host1x_channel *ch,
63 struct output *o)
64{
65 u32 val, rd_ptr, wr_ptr, start, end;
66 unsigned int data_count = 0;
67
68 host1x_debug_output(o, "%u: fifo:\n", ch->id);
69
70 val = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDFIFO_STAT);
71 host1x_debug_output(o, "CMDFIFO_STAT %08x\n", val);
72 if (val & HOST1X_CHANNEL_CMDFIFO_STAT_EMPTY) {
73 host1x_debug_output(o, "[empty]\n");
74 return;
75 }
76
77 val = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDFIFO_RDATA);
78 host1x_debug_output(o, "CMDFIFO_RDATA %08x\n", val);
79
80 /* Peek pointer values are invalid during SLCG, so disable it */
81 host1x_hypervisor_writel(host, 0x1, HOST1X_HV_ICG_EN_OVERRIDE);
82
83 val = 0;
84 val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_ENABLE;
85 val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_CHANNEL(ch->id);
86 host1x_hypervisor_writel(host, val, HOST1X_HV_CMDFIFO_PEEK_CTRL);
87
88 val = host1x_hypervisor_readl(host, HOST1X_HV_CMDFIFO_PEEK_PTRS);
89 rd_ptr = HOST1X_HV_CMDFIFO_PEEK_PTRS_RD_PTR_V(val);
90 wr_ptr = HOST1X_HV_CMDFIFO_PEEK_PTRS_WR_PTR_V(val);
91
92 val = host1x_hypervisor_readl(host, HOST1X_HV_CMDFIFO_SETUP(ch->id));
93 start = HOST1X_HV_CMDFIFO_SETUP_BASE_V(val);
94 end = HOST1X_HV_CMDFIFO_SETUP_LIMIT_V(val);
95
96 do {
97 val = 0;
98 val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_ENABLE;
99 val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_CHANNEL(ch->id);
100 val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_ADDR(rd_ptr);
101 host1x_hypervisor_writel(host, val,
102 HOST1X_HV_CMDFIFO_PEEK_CTRL);
103
104 val = host1x_hypervisor_readl(host,
105 HOST1X_HV_CMDFIFO_PEEK_READ);
106
107 if (!data_count) {
108 host1x_debug_output(o, "%08x:", val);
109 data_count = show_channel_command(o, val);
110 } else {
111 host1x_debug_output(o, "%08x%s", val,
112 data_count > 0 ? ", " : "])\n");
113 data_count--;
114 }
115
116 if (rd_ptr == end)
117 rd_ptr = start;
118 else
119 rd_ptr++;
120 } while (rd_ptr != wr_ptr);
121
122 if (data_count)
123 host1x_debug_output(o, ", ...])\n");
124 host1x_debug_output(o, "\n");
125
126 host1x_hypervisor_writel(host, 0x0, HOST1X_HV_CMDFIFO_PEEK_CTRL);
127 host1x_hypervisor_writel(host, 0x0, HOST1X_HV_ICG_EN_OVERRIDE);
128}
129
130static void host1x_debug_show_mlocks(struct host1x *host, struct output *o)
131{
132 /* TODO */
133}
diff --git a/drivers/gpu/host1x/hw/host1x01.c b/drivers/gpu/host1x/hw/host1x01.c
index 859b73beb4d0..bb124f8b4af8 100644
--- a/drivers/gpu/host1x/hw/host1x01.c
+++ b/drivers/gpu/host1x/hw/host1x01.c
@@ -21,6 +21,8 @@
21#include "host1x01_hardware.h" 21#include "host1x01_hardware.h"
22 22
23/* include code */ 23/* include code */
24#define HOST1X_HW 1
25
24#include "cdma_hw.c" 26#include "cdma_hw.c"
25#include "channel_hw.c" 27#include "channel_hw.c"
26#include "debug_hw.c" 28#include "debug_hw.c"
diff --git a/drivers/gpu/host1x/hw/host1x02.c b/drivers/gpu/host1x/hw/host1x02.c
index 928946c2144b..c5f85dbedb98 100644
--- a/drivers/gpu/host1x/hw/host1x02.c
+++ b/drivers/gpu/host1x/hw/host1x02.c
@@ -21,6 +21,8 @@
21#include "host1x02_hardware.h" 21#include "host1x02_hardware.h"
22 22
23/* include code */ 23/* include code */
24#define HOST1X_HW 2
25
24#include "cdma_hw.c" 26#include "cdma_hw.c"
25#include "channel_hw.c" 27#include "channel_hw.c"
26#include "debug_hw.c" 28#include "debug_hw.c"
diff --git a/drivers/gpu/host1x/hw/host1x04.c b/drivers/gpu/host1x/hw/host1x04.c
index 8007c70fa9c4..f102a1a7743f 100644
--- a/drivers/gpu/host1x/hw/host1x04.c
+++ b/drivers/gpu/host1x/hw/host1x04.c
@@ -21,6 +21,8 @@
21#include "host1x04_hardware.h" 21#include "host1x04_hardware.h"
22 22
23/* include code */ 23/* include code */
24#define HOST1X_HW 4
25
24#include "cdma_hw.c" 26#include "cdma_hw.c"
25#include "channel_hw.c" 27#include "channel_hw.c"
26#include "debug_hw.c" 28#include "debug_hw.c"
diff --git a/drivers/gpu/host1x/hw/host1x05.c b/drivers/gpu/host1x/hw/host1x05.c
index 047097ce3bad..2b1239d6ec67 100644
--- a/drivers/gpu/host1x/hw/host1x05.c
+++ b/drivers/gpu/host1x/hw/host1x05.c
@@ -21,6 +21,8 @@
21#include "host1x05_hardware.h" 21#include "host1x05_hardware.h"
22 22
23/* include code */ 23/* include code */
24#define HOST1X_HW 5
25
24#include "cdma_hw.c" 26#include "cdma_hw.c"
25#include "channel_hw.c" 27#include "channel_hw.c"
26#include "debug_hw.c" 28#include "debug_hw.c"
diff --git a/drivers/gpu/host1x/hw/host1x06.c b/drivers/gpu/host1x/hw/host1x06.c
new file mode 100644
index 000000000000..a66230827c59
--- /dev/null
+++ b/drivers/gpu/host1x/hw/host1x06.c
@@ -0,0 +1,44 @@
1/*
2 * Host1x init for Tegra186 SoCs
3 *
4 * Copyright (c) 2017 NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/* include hw specification */
20#include "host1x06.h"
21#include "host1x06_hardware.h"
22
23/* include code */
24#define HOST1X_HW 6
25
26#include "cdma_hw.c"
27#include "channel_hw.c"
28#include "debug_hw.c"
29#include "intr_hw.c"
30#include "syncpt_hw.c"
31
32#include "../dev.h"
33
34int host1x06_init(struct host1x *host)
35{
36 host->channel_op = &host1x_channel_ops;
37 host->cdma_op = &host1x_cdma_ops;
38 host->cdma_pb_op = &host1x_pushbuffer_ops;
39 host->syncpt_op = &host1x_syncpt_ops;
40 host->intr_op = &host1x_intr_ops;
41 host->debug_op = &host1x_debug_ops;
42
43 return 0;
44}
diff --git a/drivers/gpu/host1x/hw/host1x06.h b/drivers/gpu/host1x/hw/host1x06.h
new file mode 100644
index 000000000000..d9abe1489241
--- /dev/null
+++ b/drivers/gpu/host1x/hw/host1x06.h
@@ -0,0 +1,26 @@
1/*
2 * Host1x init for Tegra186 SoCs
3 *
4 * Copyright (c) 2017 NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef HOST1X_HOST1X06_H
20#define HOST1X_HOST1X06_H
21
22struct host1x;
23
24int host1x06_init(struct host1x *host);
25
26#endif
diff --git a/drivers/gpu/host1x/hw/host1x06_hardware.h b/drivers/gpu/host1x/hw/host1x06_hardware.h
new file mode 100644
index 000000000000..3039c92ea605
--- /dev/null
+++ b/drivers/gpu/host1x/hw/host1x06_hardware.h
@@ -0,0 +1,142 @@
1/*
2 * Tegra host1x Register Offsets for Tegra186
3 *
4 * Copyright (c) 2017 NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef __HOST1X_HOST1X06_HARDWARE_H
20#define __HOST1X_HOST1X06_HARDWARE_H
21
22#include <linux/types.h>
23#include <linux/bitops.h>
24
25#include "hw_host1x06_uclass.h"
26#include "hw_host1x06_vm.h"
27#include "hw_host1x06_hypervisor.h"
28
29static inline u32 host1x_class_host_wait_syncpt(
30 unsigned indx, unsigned threshold)
31{
32 return host1x_uclass_wait_syncpt_indx_f(indx)
33 | host1x_uclass_wait_syncpt_thresh_f(threshold);
34}
35
36static inline u32 host1x_class_host_load_syncpt_base(
37 unsigned indx, unsigned threshold)
38{
39 return host1x_uclass_load_syncpt_base_base_indx_f(indx)
40 | host1x_uclass_load_syncpt_base_value_f(threshold);
41}
42
43static inline u32 host1x_class_host_wait_syncpt_base(
44 unsigned indx, unsigned base_indx, unsigned offset)
45{
46 return host1x_uclass_wait_syncpt_base_indx_f(indx)
47 | host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
48 | host1x_uclass_wait_syncpt_base_offset_f(offset);
49}
50
51static inline u32 host1x_class_host_incr_syncpt_base(
52 unsigned base_indx, unsigned offset)
53{
54 return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
55 | host1x_uclass_incr_syncpt_base_offset_f(offset);
56}
57
58static inline u32 host1x_class_host_incr_syncpt(
59 unsigned cond, unsigned indx)
60{
61 return host1x_uclass_incr_syncpt_cond_f(cond)
62 | host1x_uclass_incr_syncpt_indx_f(indx);
63}
64
65static inline u32 host1x_class_host_indoff_reg_write(
66 unsigned mod_id, unsigned offset, bool auto_inc)
67{
68 u32 v = host1x_uclass_indoff_indbe_f(0xf)
69 | host1x_uclass_indoff_indmodid_f(mod_id)
70 | host1x_uclass_indoff_indroffset_f(offset);
71 if (auto_inc)
72 v |= host1x_uclass_indoff_autoinc_f(1);
73 return v;
74}
75
76static inline u32 host1x_class_host_indoff_reg_read(
77 unsigned mod_id, unsigned offset, bool auto_inc)
78{
79 u32 v = host1x_uclass_indoff_indmodid_f(mod_id)
80 | host1x_uclass_indoff_indroffset_f(offset)
81 | host1x_uclass_indoff_rwn_read_v();
82 if (auto_inc)
83 v |= host1x_uclass_indoff_autoinc_f(1);
84 return v;
85}
86
87/* cdma opcodes */
88static inline u32 host1x_opcode_setclass(
89 unsigned class_id, unsigned offset, unsigned mask)
90{
91 return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
92}
93
94static inline u32 host1x_opcode_incr(unsigned offset, unsigned count)
95{
96 return (1 << 28) | (offset << 16) | count;
97}
98
99static inline u32 host1x_opcode_nonincr(unsigned offset, unsigned count)
100{
101 return (2 << 28) | (offset << 16) | count;
102}
103
104static inline u32 host1x_opcode_mask(unsigned offset, unsigned mask)
105{
106 return (3 << 28) | (offset << 16) | mask;
107}
108
109static inline u32 host1x_opcode_imm(unsigned offset, unsigned value)
110{
111 return (4 << 28) | (offset << 16) | value;
112}
113
114static inline u32 host1x_opcode_imm_incr_syncpt(unsigned cond, unsigned indx)
115{
116 return host1x_opcode_imm(host1x_uclass_incr_syncpt_r(),
117 host1x_class_host_incr_syncpt(cond, indx));
118}
119
120static inline u32 host1x_opcode_restart(unsigned address)
121{
122 return (5 << 28) | (address >> 4);
123}
124
125static inline u32 host1x_opcode_gather(unsigned count)
126{
127 return (6 << 28) | count;
128}
129
130static inline u32 host1x_opcode_gather_nonincr(unsigned offset, unsigned count)
131{
132 return (6 << 28) | (offset << 16) | BIT(15) | count;
133}
134
135static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count)
136{
137 return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
138}
139
140#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0)
141
142#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x06_hypervisor.h b/drivers/gpu/host1x/hw/hw_host1x06_hypervisor.h
new file mode 100644
index 000000000000..c05dab8a178b
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x06_hypervisor.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) 2017 NVIDIA Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18#define HOST1X_HV_SYNCPT_PROT_EN 0x1ac4
19#define HOST1X_HV_SYNCPT_PROT_EN_CH_EN BIT(1)
20#define HOST1X_HV_CH_KERNEL_FILTER_GBUFFER(x) (0x2020 + (x * 4))
21#define HOST1X_HV_CMDFIFO_PEEK_CTRL 0x233c
22#define HOST1X_HV_CMDFIFO_PEEK_CTRL_ADDR(x) (x)
23#define HOST1X_HV_CMDFIFO_PEEK_CTRL_CHANNEL(x) ((x) << 16)
24#define HOST1X_HV_CMDFIFO_PEEK_CTRL_ENABLE BIT(31)
25#define HOST1X_HV_CMDFIFO_PEEK_READ 0x2340
26#define HOST1X_HV_CMDFIFO_PEEK_PTRS 0x2344
27#define HOST1X_HV_CMDFIFO_PEEK_PTRS_WR_PTR_V(x) (((x) >> 16) & 0xfff)
28#define HOST1X_HV_CMDFIFO_PEEK_PTRS_RD_PTR_V(x) ((x) & 0xfff)
29#define HOST1X_HV_CMDFIFO_SETUP(x) (0x2588 + (x * 4))
30#define HOST1X_HV_CMDFIFO_SETUP_LIMIT_V(x) (((x) >> 16) & 0xfff)
31#define HOST1X_HV_CMDFIFO_SETUP_BASE_V(x) ((x) & 0xfff)
32#define HOST1X_HV_ICG_EN_OVERRIDE 0x2aa8
diff --git a/drivers/gpu/host1x/hw/hw_host1x06_uclass.h b/drivers/gpu/host1x/hw/hw_host1x06_uclass.h
new file mode 100644
index 000000000000..4457486c72b0
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x06_uclass.h
@@ -0,0 +1,181 @@
1/*
2 * Copyright (c) 2017 NVIDIA Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18 /*
19 * Function naming determines intended use:
20 *
21 * <x>_r(void) : Returns the offset for register <x>.
22 *
23 * <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
24 *
25 * <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
26 *
27 * <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
28 * and masked to place it at field <y> of register <x>. This value
29 * can be |'d with others to produce a full register value for
30 * register <x>.
31 *
32 * <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
33 * value can be ~'d and then &'d to clear the value of field <y> for
34 * register <x>.
35 *
36 * <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
37 * to place it at field <y> of register <x>. This value can be |'d
38 * with others to produce a full register value for <x>.
39 *
40 * <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
41 * <x> value 'r' after being shifted to place its LSB at bit 0.
42 * This value is suitable for direct comparison with other unshifted
43 * values appropriate for use in field <y> of register <x>.
44 *
45 * <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
46 * field <y> of register <x>. This value is suitable for direct
47 * comparison with unshifted values appropriate for use in field <y>
48 * of register <x>.
49 */
50
51#ifndef HOST1X_HW_HOST1X06_UCLASS_H
52#define HOST1X_HW_HOST1X06_UCLASS_H
53
54static inline u32 host1x_uclass_incr_syncpt_r(void)
55{
56 return 0x0;
57}
58#define HOST1X_UCLASS_INCR_SYNCPT \
59 host1x_uclass_incr_syncpt_r()
60static inline u32 host1x_uclass_incr_syncpt_cond_f(u32 v)
61{
62 return (v & 0xff) << 8;
63}
64#define HOST1X_UCLASS_INCR_SYNCPT_COND_F(v) \
65 host1x_uclass_incr_syncpt_cond_f(v)
66static inline u32 host1x_uclass_incr_syncpt_indx_f(u32 v)
67{
68 return (v & 0xff) << 0;
69}
70#define HOST1X_UCLASS_INCR_SYNCPT_INDX_F(v) \
71 host1x_uclass_incr_syncpt_indx_f(v)
72static inline u32 host1x_uclass_wait_syncpt_r(void)
73{
74 return 0x8;
75}
76#define HOST1X_UCLASS_WAIT_SYNCPT \
77 host1x_uclass_wait_syncpt_r()
78static inline u32 host1x_uclass_wait_syncpt_indx_f(u32 v)
79{
80 return (v & 0xff) << 24;
81}
82#define HOST1X_UCLASS_WAIT_SYNCPT_INDX_F(v) \
83 host1x_uclass_wait_syncpt_indx_f(v)
84static inline u32 host1x_uclass_wait_syncpt_thresh_f(u32 v)
85{
86 return (v & 0xffffff) << 0;
87}
88#define HOST1X_UCLASS_WAIT_SYNCPT_THRESH_F(v) \
89 host1x_uclass_wait_syncpt_thresh_f(v)
90static inline u32 host1x_uclass_wait_syncpt_base_r(void)
91{
92 return 0x9;
93}
94#define HOST1X_UCLASS_WAIT_SYNCPT_BASE \
95 host1x_uclass_wait_syncpt_base_r()
96static inline u32 host1x_uclass_wait_syncpt_base_indx_f(u32 v)
97{
98 return (v & 0xff) << 24;
99}
100#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_INDX_F(v) \
101 host1x_uclass_wait_syncpt_base_indx_f(v)
102static inline u32 host1x_uclass_wait_syncpt_base_base_indx_f(u32 v)
103{
104 return (v & 0xff) << 16;
105}
106#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_BASE_INDX_F(v) \
107 host1x_uclass_wait_syncpt_base_base_indx_f(v)
108static inline u32 host1x_uclass_wait_syncpt_base_offset_f(u32 v)
109{
110 return (v & 0xffff) << 0;
111}
112#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_OFFSET_F(v) \
113 host1x_uclass_wait_syncpt_base_offset_f(v)
114static inline u32 host1x_uclass_load_syncpt_base_r(void)
115{
116 return 0xb;
117}
118#define HOST1X_UCLASS_LOAD_SYNCPT_BASE \
119 host1x_uclass_load_syncpt_base_r()
120static inline u32 host1x_uclass_load_syncpt_base_base_indx_f(u32 v)
121{
122 return (v & 0xff) << 24;
123}
124#define HOST1X_UCLASS_LOAD_SYNCPT_BASE_BASE_INDX_F(v) \
125 host1x_uclass_load_syncpt_base_base_indx_f(v)
126static inline u32 host1x_uclass_load_syncpt_base_value_f(u32 v)
127{
128 return (v & 0xffffff) << 0;
129}
130#define HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(v) \
131 host1x_uclass_load_syncpt_base_value_f(v)
132static inline u32 host1x_uclass_incr_syncpt_base_base_indx_f(u32 v)
133{
134 return (v & 0xff) << 24;
135}
136#define HOST1X_UCLASS_INCR_SYNCPT_BASE_BASE_INDX_F(v) \
137 host1x_uclass_incr_syncpt_base_base_indx_f(v)
138static inline u32 host1x_uclass_incr_syncpt_base_offset_f(u32 v)
139{
140 return (v & 0xffffff) << 0;
141}
142#define HOST1X_UCLASS_INCR_SYNCPT_BASE_OFFSET_F(v) \
143 host1x_uclass_incr_syncpt_base_offset_f(v)
144static inline u32 host1x_uclass_indoff_r(void)
145{
146 return 0x2d;
147}
148#define HOST1X_UCLASS_INDOFF \
149 host1x_uclass_indoff_r()
150static inline u32 host1x_uclass_indoff_indbe_f(u32 v)
151{
152 return (v & 0xf) << 28;
153}
154#define HOST1X_UCLASS_INDOFF_INDBE_F(v) \
155 host1x_uclass_indoff_indbe_f(v)
156static inline u32 host1x_uclass_indoff_autoinc_f(u32 v)
157{
158 return (v & 0x1) << 27;
159}
160#define HOST1X_UCLASS_INDOFF_AUTOINC_F(v) \
161 host1x_uclass_indoff_autoinc_f(v)
162static inline u32 host1x_uclass_indoff_indmodid_f(u32 v)
163{
164 return (v & 0xff) << 18;
165}
166#define HOST1X_UCLASS_INDOFF_INDMODID_F(v) \
167 host1x_uclass_indoff_indmodid_f(v)
168static inline u32 host1x_uclass_indoff_indroffset_f(u32 v)
169{
170 return (v & 0xffff) << 2;
171}
172#define HOST1X_UCLASS_INDOFF_INDROFFSET_F(v) \
173 host1x_uclass_indoff_indroffset_f(v)
174static inline u32 host1x_uclass_indoff_rwn_read_v(void)
175{
176 return 1;
177}
178#define HOST1X_UCLASS_INDOFF_INDROFFSET_F(v) \
179 host1x_uclass_indoff_indroffset_f(v)
180
181#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x06_vm.h b/drivers/gpu/host1x/hw/hw_host1x06_vm.h
new file mode 100644
index 000000000000..e54b33902332
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x06_vm.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2017 NVIDIA Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18#define HOST1X_CHANNEL_DMASTART 0x0000
19#define HOST1X_CHANNEL_DMASTART_HI 0x0004
20#define HOST1X_CHANNEL_DMAPUT 0x0008
21#define HOST1X_CHANNEL_DMAPUT_HI 0x000c
22#define HOST1X_CHANNEL_DMAGET 0x0010
23#define HOST1X_CHANNEL_DMAGET_HI 0x0014
24#define HOST1X_CHANNEL_DMAEND 0x0018
25#define HOST1X_CHANNEL_DMAEND_HI 0x001c
26#define HOST1X_CHANNEL_DMACTRL 0x0020
27#define HOST1X_CHANNEL_DMACTRL_DMASTOP BIT(0)
28#define HOST1X_CHANNEL_DMACTRL_DMAGETRST BIT(1)
29#define HOST1X_CHANNEL_DMACTRL_DMAINITGET BIT(2)
30#define HOST1X_CHANNEL_CMDFIFO_STAT 0x0024
31#define HOST1X_CHANNEL_CMDFIFO_STAT_EMPTY BIT(13)
32#define HOST1X_CHANNEL_CMDFIFO_RDATA 0x0028
33#define HOST1X_CHANNEL_CMDP_OFFSET 0x0030
34#define HOST1X_CHANNEL_CMDP_CLASS 0x0034
35#define HOST1X_CHANNEL_CHANNELSTAT 0x0038
36#define HOST1X_CHANNEL_CMDPROC_STOP 0x0048
37#define HOST1X_CHANNEL_TEARDOWN 0x004c
38
39#define HOST1X_SYNC_SYNCPT_CPU_INCR(x) (0x6400 + 4*(x))
40#define HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(x) (0x6464 + 4*(x))
41#define HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(x) (0x652c + 4*(x))
42#define HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(x) (0x6590 + 4*(x))
43#define HOST1X_SYNC_SYNCPT_BASE(x) (0x8000 + 4*(x))
44#define HOST1X_SYNC_SYNCPT(x) (0x8080 + 4*(x))
45#define HOST1X_SYNC_SYNCPT_INT_THRESH(x) (0x8a00 + 4*(x))
46#define HOST1X_SYNC_SYNCPT_CH_APP(x) (0x9384 + 4*(x))
47#define HOST1X_SYNC_SYNCPT_CH_APP_CH(v) (((v) & 0x3f) << 8)
diff --git a/drivers/gpu/host1x/hw/intr_hw.c b/drivers/gpu/host1x/hw/intr_hw.c
index 37ebb51703fa..329239237090 100644
--- a/drivers/gpu/host1x/hw/intr_hw.c
+++ b/drivers/gpu/host1x/hw/intr_hw.c
@@ -72,6 +72,23 @@ static void _host1x_intr_disable_all_syncpt_intrs(struct host1x *host)
72 } 72 }
73} 73}
74 74
75static void intr_hw_init(struct host1x *host, u32 cpm)
76{
77#if HOST1X_HW < 6
78 /* disable the ip_busy_timeout. this prevents write drops */
79 host1x_sync_writel(host, 0, HOST1X_SYNC_IP_BUSY_TIMEOUT);
80
81 /*
82 * increase the auto-ack timout to the maximum value. 2d will hang
83 * otherwise on Tegra2.
84 */
85 host1x_sync_writel(host, 0xff, HOST1X_SYNC_CTXSW_TIMEOUT_CFG);
86
87 /* update host clocks per usec */
88 host1x_sync_writel(host, cpm, HOST1X_SYNC_USEC_CLK);
89#endif
90}
91
75static int 92static int
76_host1x_intr_init_host_sync(struct host1x *host, u32 cpm, 93_host1x_intr_init_host_sync(struct host1x *host, u32 cpm,
77 void (*syncpt_thresh_work)(struct work_struct *)) 94 void (*syncpt_thresh_work)(struct work_struct *))
@@ -92,17 +109,7 @@ _host1x_intr_init_host_sync(struct host1x *host, u32 cpm,
92 return err; 109 return err;
93 } 110 }
94 111
95 /* disable the ip_busy_timeout. this prevents write drops */ 112 intr_hw_init(host, cpm);
96 host1x_sync_writel(host, 0, HOST1X_SYNC_IP_BUSY_TIMEOUT);
97
98 /*
99 * increase the auto-ack timout to the maximum value. 2d will hang
100 * otherwise on Tegra2.
101 */
102 host1x_sync_writel(host, 0xff, HOST1X_SYNC_CTXSW_TIMEOUT_CFG);
103
104 /* update host clocks per usec */
105 host1x_sync_writel(host, cpm, HOST1X_SYNC_USEC_CLK);
106 113
107 return 0; 114 return 0;
108} 115}