hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/drivers/gpu/host1x/hw/channel_hw.c
....@@ -1,22 +1,12 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Tegra host1x Channel
34 *
45 * 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/>.
176 */
187
198 #include <linux/host1x.h>
9
+#include <linux/iommu.h>
2010 #include <linux/slab.h>
2111
2212 #include <trace/events/host1x.h>
....@@ -26,7 +16,6 @@
2616 #include "../intr.h"
2717 #include "../job.h"
2818
29
-#define HOST1X_CHANNEL_SIZE 16384
3019 #define TRACE_MAX_LENGTH 128U
3120
3221 static void trace_write_gather(struct host1x_cdma *cdma, struct host1x_bo *bo,
....@@ -61,15 +50,37 @@
6150 static void submit_gathers(struct host1x_job *job)
6251 {
6352 struct host1x_cdma *cdma = &job->channel->cdma;
53
+#if HOST1X_HW < 6
54
+ struct device *dev = job->channel->dev;
55
+#endif
6456 unsigned int i;
6557
6658 for (i = 0; i < job->num_gathers; i++) {
6759 struct host1x_job_gather *g = &job->gathers[i];
68
- u32 op1 = host1x_opcode_gather(g->words);
69
- u32 op2 = g->base + g->offset;
60
+ dma_addr_t addr = g->base + g->offset;
61
+ u32 op2, op3;
7062
71
- trace_write_gather(cdma, g->bo, g->offset, op1 & 0xffff);
72
- host1x_cdma_push(cdma, op1, op2);
63
+ op2 = lower_32_bits(addr);
64
+ op3 = upper_32_bits(addr);
65
+
66
+ trace_write_gather(cdma, g->bo, g->offset, g->words);
67
+
68
+ if (op3 != 0) {
69
+#if HOST1X_HW >= 6
70
+ u32 op1 = host1x_opcode_gather_wide(g->words);
71
+ u32 op4 = HOST1X_OPCODE_NOP;
72
+
73
+ host1x_cdma_push_wide(cdma, op1, op2, op3, op4);
74
+#else
75
+ dev_err(dev, "invalid gather for push buffer %pad\n",
76
+ &addr);
77
+ continue;
78
+#endif
79
+ } else {
80
+ u32 op1 = host1x_opcode_gather(g->words);
81
+
82
+ host1x_cdma_push(cdma, op1, op2);
83
+ }
7384 }
7485 }
7586
....@@ -88,6 +99,20 @@
8899 HOST1X_UCLASS_LOAD_SYNCPT_BASE, 1),
89100 HOST1X_UCLASS_LOAD_SYNCPT_BASE_BASE_INDX_F(id) |
90101 HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(value));
102
+}
103
+
104
+static void host1x_channel_set_streamid(struct host1x_channel *channel)
105
+{
106
+#if HOST1X_HW >= 6
107
+ u32 sid = 0x7f;
108
+#ifdef CONFIG_IOMMU_API
109
+ struct iommu_fwspec *spec = dev_iommu_fwspec_get(channel->dev->parent);
110
+ if (spec)
111
+ sid = spec->ids[0] & 0xffff;
112
+#endif
113
+
114
+ host1x_ch_writel(channel, sid, HOST1X_CHANNEL_SMMU_STREAMID);
115
+#endif
91116 }
92117
93118 static int channel_submit(struct host1x_job *job)
....@@ -120,6 +145,8 @@
120145 err = -ENOMEM;
121146 goto error;
122147 }
148
+
149
+ host1x_channel_set_streamid(ch);
123150
124151 /* begin a CDMA submit */
125152 err = host1x_cdma_begin(&ch->cdma, job);
....@@ -203,7 +230,11 @@
203230 static int host1x_channel_init(struct host1x_channel *ch, struct host1x *dev,
204231 unsigned int index)
205232 {
206
- ch->regs = dev->regs + index * HOST1X_CHANNEL_SIZE;
233
+#if HOST1X_HW < 6
234
+ ch->regs = dev->regs + index * 0x4000;
235
+#else
236
+ ch->regs = dev->regs + index * 0x100;
237
+#endif
207238 enable_gather_filter(dev, ch);
208239 return 0;
209240 }