diff options
-rw-r--r-- | drivers/gpu/host1x/Makefile | 3 | ||||
-rw-r--r-- | drivers/gpu/host1x/dev.c | 55 | ||||
-rw-r--r-- | drivers/gpu/host1x/dev.h | 4 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/cdma_hw.c | 49 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/debug_hw.c | 137 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/debug_hw_1x01.c | 154 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/debug_hw_1x06.c | 133 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/host1x01.c | 2 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/host1x02.c | 2 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/host1x04.c | 2 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/host1x05.c | 2 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/host1x06.c | 44 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/host1x06.h | 26 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/host1x06_hardware.h | 142 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/hw_host1x06_hypervisor.h | 32 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/hw_host1x06_uclass.h | 181 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/hw_host1x06_vm.h | 47 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/intr_hw.c | 29 |
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 | ||
16 | obj-$(CONFIG_TEGRA_HOST1X) += host1x.o | 17 | obj-$(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 | |||
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 | void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r) | 54 | void 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 | ||
118 | static 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 | |||
107 | static const struct of_device_id host1x_of_match[] = { | 129 | static 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); | |||
117 | static int host1x_probe(struct platform_device *pdev) | 140 | static 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 | ||
105 | struct host1x { | 106 | struct 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 | ||
145 | void host1x_hypervisor_writel(struct host1x *host1x, u32 r, u32 v); | ||
146 | u32 host1x_hypervisor_readl(struct host1x *host1x, u32 r); | ||
143 | void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v); | 147 | void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v); |
144 | u32 host1x_sync_readl(struct host1x *host1x, u32 r); | 148 | u32 host1x_sync_readl(struct host1x *host1x, u32 r); |
145 | void host1x_ch_writel(struct host1x_channel *ch, u32 r, u32 v); | 149 | void 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 | ||
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 | * 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 | */ |
233 | static void cdma_timeout_handler(struct work_struct *work) | 251 | static 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 | ||
177 | static 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 | |||
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 | } | ||
309 | 182 | ||
310 | static const struct host1x_debug_ops host1x_debug_ops = { | 183 | static 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 | |||
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 | } | ||
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 | |||
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 | } | ||
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 | |||
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 | } | ||
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 | |||
22 | struct host1x; | ||
23 | |||
24 | int 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 | |||
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 | ||
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 | |||
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 | ||
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 | ||
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 | static int | 92 | static 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 | } |