Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpu: host1x: Add Tegra186 support

Add support for the implementation of Host1x present on the Tegra186.
The register space has been shuffled around a little bit, requiring
addition of some chip-specific code sections. Tegra186 also adds
several new features, most importantly the hypervisor, but those are
not yet supported with this commit.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Tested-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>

authored by

Mikko Perttunen and committed by
Thierry Reding
f1b53c4e d3b3efa1

+876 -168
+2 -1
drivers/gpu/host1x/Makefile
··· 11 11 hw/host1x01.o \ 12 12 hw/host1x02.o \ 13 13 hw/host1x04.o \ 14 - hw/host1x05.o 14 + hw/host1x05.o \ 15 + hw/host1x06.o 15 16 16 17 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
+50 -5
drivers/gpu/host1x/dev.c
··· 39 39 #include "hw/host1x02.h" 40 40 #include "hw/host1x04.h" 41 41 #include "hw/host1x05.h" 42 + #include "hw/host1x06.h" 43 + 44 + void host1x_hypervisor_writel(struct host1x *host1x, u32 v, u32 r) 45 + { 46 + writel(v, host1x->hv_regs + r); 47 + } 48 + 49 + u32 host1x_hypervisor_readl(struct host1x *host1x, u32 r) 50 + { 51 + return readl(host1x->hv_regs + r); 52 + } 42 53 43 54 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r) 44 55 { ··· 115 104 .dma_mask = DMA_BIT_MASK(34), 116 105 }; 117 106 107 + static const struct host1x_info host1x06_info = { 108 + .nb_channels = 63, 109 + .nb_pts = 576, 110 + .nb_mlocks = 24, 111 + .nb_bases = 16, 112 + .init = host1x06_init, 113 + .sync_offset = 0x0, 114 + .dma_mask = DMA_BIT_MASK(34), 115 + .has_hypervisor = true, 116 + }; 117 + 118 118 static const struct of_device_id host1x_of_match[] = { 119 + { .compatible = "nvidia,tegra186-host1x", .data = &host1x06_info, }, 119 120 { .compatible = "nvidia,tegra210-host1x", .data = &host1x05_info, }, 120 121 { .compatible = "nvidia,tegra124-host1x", .data = &host1x04_info, }, 121 122 { .compatible = "nvidia,tegra114-host1x", .data = &host1x02_info, }, ··· 140 117 static int host1x_probe(struct platform_device *pdev) 141 118 { 142 119 struct host1x *host; 143 - struct resource *regs; 120 + struct resource *regs, *hv_regs = NULL; 144 121 int syncpt_irq; 145 122 int err; 146 123 ··· 150 127 151 128 host->info = of_device_get_match_data(&pdev->dev); 152 129 153 - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 154 - if (!regs) { 155 - dev_err(&pdev->dev, "failed to get registers\n"); 156 - return -ENXIO; 130 + if (host->info->has_hypervisor) { 131 + regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vm"); 132 + if (!regs) { 133 + dev_err(&pdev->dev, "failed to get vm registers\n"); 134 + return -ENXIO; 135 + } 136 + 137 + hv_regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, 138 + "hypervisor"); 139 + if (!hv_regs) { 140 + dev_err(&pdev->dev, 141 + "failed to get hypervisor registers\n"); 142 + return -ENXIO; 143 + } 144 + } else { 145 + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 146 + if (!regs) { 147 + dev_err(&pdev->dev, "failed to get registers\n"); 148 + return -ENXIO; 149 + } 157 150 } 158 151 159 152 syncpt_irq = platform_get_irq(pdev, 0); ··· 189 150 host->regs = devm_ioremap_resource(&pdev->dev, regs); 190 151 if (IS_ERR(host->regs)) 191 152 return PTR_ERR(host->regs); 153 + 154 + if (host->info->has_hypervisor) { 155 + host->hv_regs = devm_ioremap_resource(&pdev->dev, hv_regs); 156 + if (IS_ERR(host->hv_regs)) 157 + return PTR_ERR(host->hv_regs); 158 + } 192 159 193 160 dma_set_mask_and_coherent(host->dev, host->info->dma_mask); 194 161
+4
drivers/gpu/host1x/dev.h
··· 100 100 int (*init)(struct host1x *host1x); /* initialize per SoC ops */ 101 101 unsigned int sync_offset; /* offset of syncpoint registers */ 102 102 u64 dma_mask; /* mask of addressable memory */ 103 + bool has_hypervisor; /* has hypervisor registers */ 103 104 }; 104 105 105 106 struct host1x { 106 107 const struct host1x_info *info; 107 108 108 109 void __iomem *regs; 110 + void __iomem *hv_regs; /* hypervisor region */ 109 111 struct host1x_syncpt *syncpt; 110 112 struct host1x_syncpt_base *bases; 111 113 struct device *dev; ··· 142 140 struct list_head list; 143 141 }; 144 142 143 + void host1x_hypervisor_writel(struct host1x *host1x, u32 r, u32 v); 144 + u32 host1x_hypervisor_readl(struct host1x *host1x, u32 r); 145 145 void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v); 146 146 u32 host1x_sync_readl(struct host1x *host1x, u32 r); 147 147 void host1x_ch_writel(struct host1x_channel *ch, u32 r, u32 v);
+30 -19
drivers/gpu/host1x/hw/cdma_hw.c
··· 172 172 mutex_unlock(&cdma->lock); 173 173 } 174 174 175 + static 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 + 190 + static 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 200 * Stops both channel's command processor and CDMA immediately. 177 201 * Also, tears down the channel and resets corresponding module. ··· 204 180 { 205 181 struct host1x *host = cdma_to_host1x(cdma); 206 182 struct host1x_channel *ch = cdma_to_channel(cdma); 207 - u32 cmdproc_stop; 208 183 209 184 if (cdma->torndown && !cdma->running) { 210 185 dev_warn(host->dev, "Already torn down\n"); ··· 212 189 213 190 dev_dbg(host->dev, "freezing channel (id %d)\n", ch->id); 214 191 215 - cmdproc_stop = host1x_sync_readl(host, HOST1X_SYNC_CMDPROC_STOP); 216 - cmdproc_stop |= BIT(ch->id); 217 - host1x_sync_writel(host, cmdproc_stop, HOST1X_SYNC_CMDPROC_STOP); 192 + cdma_hw_cmdproc_stop(host, ch, true); 218 193 219 194 dev_dbg(host->dev, "%s: DMA GET 0x%x, PUT HW 0x%x / shadow 0x%x\n", 220 195 __func__, host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET), ··· 222 201 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP, 223 202 HOST1X_CHANNEL_DMACTRL); 224 203 225 - host1x_sync_writel(host, BIT(ch->id), HOST1X_SYNC_CH_TEARDOWN); 204 + cdma_hw_teardown(host, ch); 226 205 227 206 cdma->running = false; 228 207 cdma->torndown = true; ··· 232 211 { 233 212 struct host1x *host1x = cdma_to_host1x(cdma); 234 213 struct host1x_channel *ch = cdma_to_channel(cdma); 235 - u32 cmdproc_stop; 236 214 237 215 dev_dbg(host1x->dev, 238 216 "resuming channel (id %u, DMAGET restart = 0x%x)\n", 239 217 ch->id, getptr); 240 218 241 - cmdproc_stop = host1x_sync_readl(host1x, HOST1X_SYNC_CMDPROC_STOP); 242 - cmdproc_stop &= ~BIT(ch->id); 243 - host1x_sync_writel(host1x, cmdproc_stop, HOST1X_SYNC_CMDPROC_STOP); 219 + cdma_hw_cmdproc_stop(host1x, ch, false); 244 220 245 221 cdma->torndown = false; 246 222 cdma_timeout_restart(cdma, getptr); ··· 250 232 */ 251 233 static void cdma_timeout_handler(struct work_struct *work) 252 234 { 253 - u32 prev_cmdproc, cmdproc_stop, syncpt_val; 235 + u32 syncpt_val; 254 236 struct host1x_cdma *cdma; 255 237 struct host1x *host1x; 256 238 struct host1x_channel *ch; ··· 272 254 } 273 255 274 256 /* stop processing to get a clean snapshot */ 275 - prev_cmdproc = host1x_sync_readl(host1x, HOST1X_SYNC_CMDPROC_STOP); 276 - cmdproc_stop = prev_cmdproc | BIT(ch->id); 277 - host1x_sync_writel(host1x, cmdproc_stop, HOST1X_SYNC_CMDPROC_STOP); 278 - 279 - dev_dbg(host1x->dev, "cdma_timeout: cmdproc was 0x%x is 0x%x\n", 280 - prev_cmdproc, cmdproc_stop); 257 + cdma_hw_cmdproc_stop(host1x, ch, true); 281 258 282 259 syncpt_val = host1x_syncpt_load(cdma->timeout.syncpt); 283 260 ··· 281 268 dev_dbg(host1x->dev, 282 269 "cdma_timeout: expired, but buffer had completed\n"); 283 270 /* restore */ 284 - cmdproc_stop = prev_cmdproc & ~(BIT(ch->id)); 285 - host1x_sync_writel(host1x, cmdproc_stop, 286 - HOST1X_SYNC_CMDPROC_STOP); 271 + cdma_hw_cmdproc_stop(host1x, ch, false); 287 272 mutex_unlock(&cdma->lock); 288 273 return; 289 274 }
+5 -132
drivers/gpu/host1x/hw/debug_hw.c
··· 174 174 } 175 175 } 176 176 177 - static void host1x_debug_show_channel_cdma(struct host1x *host, 178 - struct host1x_channel *ch, 179 - struct output *o) 180 - { 181 - struct host1x_cdma *cdma = &ch->cdma; 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 - 230 - static 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 - 289 - static 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 - } 177 + #if HOST1X_HW >= 6 178 + #include "debug_hw_1x06.c" 179 + #else 180 + #include "debug_hw_1x01.c" 181 + #endif 309 182 310 183 static const struct host1x_debug_ops host1x_debug_ops = { 311 184 .show_channel_cdma = host1x_debug_show_channel_cdma,
+154
drivers/gpu/host1x/hw/debug_hw_1x01.c
··· 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 + 23 + static 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 + 76 + static 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 + 135 + static 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 + }
+133
drivers/gpu/host1x/hw/debug_hw_1x06.c
··· 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 + 23 + static 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 + 61 + static 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 + 130 + static void host1x_debug_show_mlocks(struct host1x *host, struct output *o) 131 + { 132 + /* TODO */ 133 + }
+2
drivers/gpu/host1x/hw/host1x01.c
··· 21 21 #include "host1x01_hardware.h" 22 22 23 23 /* include code */ 24 + #define HOST1X_HW 1 25 + 24 26 #include "cdma_hw.c" 25 27 #include "channel_hw.c" 26 28 #include "debug_hw.c"
+2
drivers/gpu/host1x/hw/host1x02.c
··· 21 21 #include "host1x02_hardware.h" 22 22 23 23 /* include code */ 24 + #define HOST1X_HW 2 25 + 24 26 #include "cdma_hw.c" 25 27 #include "channel_hw.c" 26 28 #include "debug_hw.c"
+2
drivers/gpu/host1x/hw/host1x04.c
··· 21 21 #include "host1x04_hardware.h" 22 22 23 23 /* include code */ 24 + #define HOST1X_HW 4 25 + 24 26 #include "cdma_hw.c" 25 27 #include "channel_hw.c" 26 28 #include "debug_hw.c"
+2
drivers/gpu/host1x/hw/host1x05.c
··· 21 21 #include "host1x05_hardware.h" 22 22 23 23 /* include code */ 24 + #define HOST1X_HW 5 25 + 24 26 #include "cdma_hw.c" 25 27 #include "channel_hw.c" 26 28 #include "debug_hw.c"
+44
drivers/gpu/host1x/hw/host1x06.c
··· 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 + 34 + int 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 + }
+26
drivers/gpu/host1x/hw/host1x06.h
··· 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 + 22 + struct host1x; 23 + 24 + int host1x06_init(struct host1x *host); 25 + 26 + #endif
+142
drivers/gpu/host1x/hw/host1x06_hardware.h
··· 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 + 29 + static 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 + 36 + static 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 + 43 + static 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 + 51 + static 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 + 58 + static 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 + 65 + static 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 + 76 + static 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 */ 88 + static 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 + 94 + static inline u32 host1x_opcode_incr(unsigned offset, unsigned count) 95 + { 96 + return (1 << 28) | (offset << 16) | count; 97 + } 98 + 99 + static inline u32 host1x_opcode_nonincr(unsigned offset, unsigned count) 100 + { 101 + return (2 << 28) | (offset << 16) | count; 102 + } 103 + 104 + static inline u32 host1x_opcode_mask(unsigned offset, unsigned mask) 105 + { 106 + return (3 << 28) | (offset << 16) | mask; 107 + } 108 + 109 + static inline u32 host1x_opcode_imm(unsigned offset, unsigned value) 110 + { 111 + return (4 << 28) | (offset << 16) | value; 112 + } 113 + 114 + static 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 + 120 + static inline u32 host1x_opcode_restart(unsigned address) 121 + { 122 + return (5 << 28) | (address >> 4); 123 + } 124 + 125 + static inline u32 host1x_opcode_gather(unsigned count) 126 + { 127 + return (6 << 28) | count; 128 + } 129 + 130 + static inline u32 host1x_opcode_gather_nonincr(unsigned offset, unsigned count) 131 + { 132 + return (6 << 28) | (offset << 16) | BIT(15) | count; 133 + } 134 + 135 + static 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
+32
drivers/gpu/host1x/hw/hw_host1x06_hypervisor.h
··· 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
+181
drivers/gpu/host1x/hw/hw_host1x06_uclass.h
··· 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 + 54 + static 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() 60 + static 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) 66 + static 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) 72 + static 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() 78 + static 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) 84 + static 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) 90 + static 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() 96 + static 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) 102 + static 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) 108 + static 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) 114 + static 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() 120 + static 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) 126 + static 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) 132 + static 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) 138 + static 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) 144 + static inline u32 host1x_uclass_indoff_r(void) 145 + { 146 + return 0x2d; 147 + } 148 + #define HOST1X_UCLASS_INDOFF \ 149 + host1x_uclass_indoff_r() 150 + static 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) 156 + static 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) 162 + static 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) 168 + static 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) 174 + static 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
+47
drivers/gpu/host1x/hw/hw_host1x06_vm.h
··· 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)
+18 -11
drivers/gpu/host1x/hw/intr_hw.c
··· 72 72 } 73 73 } 74 74 75 + static 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 + 75 92 static int 76 93 _host1x_intr_init_host_sync(struct host1x *host, u32 cpm, 77 94 void (*syncpt_thresh_work)(struct work_struct *)) ··· 109 92 return err; 110 93 } 111 94 112 - /* disable the ip_busy_timeout. this prevents write drops */ 113 - host1x_sync_writel(host, 0, HOST1X_SYNC_IP_BUSY_TIMEOUT); 114 - 115 - /* 116 - * increase the auto-ack timout to the maximum value. 2d will hang 117 - * otherwise on Tegra2. 118 - */ 119 - host1x_sync_writel(host, 0xff, HOST1X_SYNC_CTXSW_TIMEOUT_CFG); 120 - 121 - /* update host clocks per usec */ 122 - host1x_sync_writel(host, cpm, HOST1X_SYNC_USEC_CLK); 95 + intr_hw_init(host, cpm); 123 96 124 97 return 0; 125 98 }