.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Tegra host1x Command DMA |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (c) 2010-2013, 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 | 6 | */ |
---|
18 | 7 | |
---|
19 | 8 | #include <linux/slab.h> |
---|
.. | .. |
---|
39 | 28 | static void cdma_timeout_cpu_incr(struct host1x_cdma *cdma, u32 getptr, |
---|
40 | 29 | u32 syncpt_incrs, u32 syncval, u32 nr_slots) |
---|
41 | 30 | { |
---|
42 | | - struct host1x *host1x = cdma_to_host1x(cdma); |
---|
43 | | - struct push_buffer *pb = &cdma->push_buffer; |
---|
44 | 31 | unsigned int i; |
---|
45 | 32 | |
---|
46 | 33 | for (i = 0; i < syncpt_incrs; i++) |
---|
.. | .. |
---|
48 | 35 | |
---|
49 | 36 | /* after CPU incr, ensure shadow is up to date */ |
---|
50 | 37 | host1x_syncpt_load(cdma->timeout.syncpt); |
---|
51 | | - |
---|
52 | | - /* NOP all the PB slots */ |
---|
53 | | - while (nr_slots--) { |
---|
54 | | - u32 *p = (u32 *)(pb->mapped + getptr); |
---|
55 | | - *(p++) = HOST1X_OPCODE_NOP; |
---|
56 | | - *(p++) = HOST1X_OPCODE_NOP; |
---|
57 | | - dev_dbg(host1x->dev, "%s: NOP at %pad+%#x\n", __func__, |
---|
58 | | - &pb->dma, getptr); |
---|
59 | | - getptr = (getptr + 8) & (pb->size - 1); |
---|
60 | | - } |
---|
61 | | - |
---|
62 | | - wmb(); |
---|
63 | 38 | } |
---|
64 | 39 | |
---|
65 | 40 | /* |
---|
.. | .. |
---|
68 | 43 | static void cdma_start(struct host1x_cdma *cdma) |
---|
69 | 44 | { |
---|
70 | 45 | struct host1x_channel *ch = cdma_to_channel(cdma); |
---|
| 46 | + u64 start, end; |
---|
71 | 47 | |
---|
72 | 48 | if (cdma->running) |
---|
73 | 49 | return; |
---|
74 | 50 | |
---|
75 | 51 | cdma->last_pos = cdma->push_buffer.pos; |
---|
| 52 | + start = cdma->push_buffer.dma; |
---|
| 53 | + end = cdma->push_buffer.size + 4; |
---|
76 | 54 | |
---|
77 | 55 | host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP, |
---|
78 | 56 | HOST1X_CHANNEL_DMACTRL); |
---|
79 | 57 | |
---|
80 | 58 | /* set base, put and end pointer */ |
---|
81 | | - host1x_ch_writel(ch, cdma->push_buffer.dma, HOST1X_CHANNEL_DMASTART); |
---|
| 59 | + host1x_ch_writel(ch, lower_32_bits(start), HOST1X_CHANNEL_DMASTART); |
---|
| 60 | +#if HOST1X_HW >= 6 |
---|
| 61 | + host1x_ch_writel(ch, upper_32_bits(start), HOST1X_CHANNEL_DMASTART_HI); |
---|
| 62 | +#endif |
---|
82 | 63 | host1x_ch_writel(ch, cdma->push_buffer.pos, HOST1X_CHANNEL_DMAPUT); |
---|
83 | | - host1x_ch_writel(ch, cdma->push_buffer.dma + cdma->push_buffer.size + 4, |
---|
84 | | - HOST1X_CHANNEL_DMAEND); |
---|
| 64 | +#if HOST1X_HW >= 6 |
---|
| 65 | + host1x_ch_writel(ch, 0, HOST1X_CHANNEL_DMAPUT_HI); |
---|
| 66 | +#endif |
---|
| 67 | + host1x_ch_writel(ch, lower_32_bits(end), HOST1X_CHANNEL_DMAEND); |
---|
| 68 | +#if HOST1X_HW >= 6 |
---|
| 69 | + host1x_ch_writel(ch, upper_32_bits(end), HOST1X_CHANNEL_DMAEND_HI); |
---|
| 70 | +#endif |
---|
85 | 71 | |
---|
86 | 72 | /* reset GET */ |
---|
87 | 73 | host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP | |
---|
.. | .. |
---|
104 | 90 | { |
---|
105 | 91 | struct host1x *host1x = cdma_to_host1x(cdma); |
---|
106 | 92 | struct host1x_channel *ch = cdma_to_channel(cdma); |
---|
| 93 | + u64 start, end; |
---|
107 | 94 | |
---|
108 | 95 | if (cdma->running) |
---|
109 | 96 | return; |
---|
.. | .. |
---|
113 | 100 | host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP, |
---|
114 | 101 | HOST1X_CHANNEL_DMACTRL); |
---|
115 | 102 | |
---|
| 103 | + start = cdma->push_buffer.dma; |
---|
| 104 | + end = cdma->push_buffer.size + 4; |
---|
| 105 | + |
---|
116 | 106 | /* set base, end pointer (all of memory) */ |
---|
117 | | - host1x_ch_writel(ch, cdma->push_buffer.dma, HOST1X_CHANNEL_DMASTART); |
---|
118 | | - host1x_ch_writel(ch, cdma->push_buffer.dma + cdma->push_buffer.size, |
---|
119 | | - HOST1X_CHANNEL_DMAEND); |
---|
| 107 | + host1x_ch_writel(ch, lower_32_bits(start), HOST1X_CHANNEL_DMASTART); |
---|
| 108 | +#if HOST1X_HW >= 6 |
---|
| 109 | + host1x_ch_writel(ch, upper_32_bits(start), HOST1X_CHANNEL_DMASTART_HI); |
---|
| 110 | +#endif |
---|
| 111 | + host1x_ch_writel(ch, lower_32_bits(end), HOST1X_CHANNEL_DMAEND); |
---|
| 112 | +#if HOST1X_HW >= 6 |
---|
| 113 | + host1x_ch_writel(ch, upper_32_bits(end), HOST1X_CHANNEL_DMAEND_HI); |
---|
| 114 | +#endif |
---|
120 | 115 | |
---|
121 | 116 | /* set GET, by loading the value in PUT (then reset GET) */ |
---|
122 | 117 | host1x_ch_writel(ch, getptr, HOST1X_CHANNEL_DMAPUT); |
---|