| .. | .. |
|---|
| 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); |
|---|